AndyS01 Posted February 22, 2016 Posted February 22, 2016 I have a script that uses the Tab control with 3 tabs on it and I want to ignore clicks on the other tabs if I have certain items selected on the current tab. I'm pretty sure I can do it in WM_NOTIFY handler, but I've tried and failed to detect the Tab switch notification. here is my test script: expandcollapse popup#include <Debug.au3> _DebugSetup(@ScriptName & "_debug.txt", False, 5, "") ; 6 = Notepad; 2 = to console; 4 = to a file _DebugOut("=============== " & @MON & "/" & @MDAY & "/" & @YEAR & " " & @HOUR & ":" & @MIN & ":" & @SEC & " ====================" & @CRLF) #NoTrayIcon #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseUpx=n #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 #AutoIt3Wrapper_UseX64=N #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <Array.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <GuiTab.au3> #include <GuiListView.au3> Opt("GUICloseOnESC", 1) ; ESC closes GUI? (0 = no, 1 = yes) Opt("GUIOnEventMode", 1) ; Change to OnEvent mode Opt('MustDeclareVars', 1) OnAutoItExitRegister("Event_GUIClose") Opt("GUIEventOptions", 1) ;0=default, 1=just notification, 2=GuiCtrlRead tab index Opt("WinTitleMatchMode", -2) ;1=start, 2=subStr, 3=exact, 4=advanced, -1 to -4=Nocase Global $hMainWin = 0 Global $hTab = 0 Global $aIDs = StringSplit("", "") Global $ahWnds = StringSplit("", "") Global $aTypes = StringSplit("", "") Global $iCounter = 0 _Main() Exit (0) Func _Main() $hMainWin = 0 CreateAllControls() fillListViews() GUISetOnEvent($GUI_EVENT_CLOSE, 'Event_GUIClose') GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") GUISetState(@SW_SHOW) ; Make everything visible While 1 Sleep(250) WEnd Exit (0) EndFunc ;==>_Main Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam) ;_DebugOut("+++:[" & $iCounter & "]: WM_NOTIFY(" & Hex($hWnd) & "|" & Hex($iMsg) & "|" & Hex($iwParam) & "|" & Hex($ilParam) & ") entered") Local $iCode, $tNMHDR, $param, $ret, $hWndFrom #forceref $hWnd, $iMsg, $iwParam, $param, $ret, $hWndFrom, $iCode $iCounter += 1 $tNMHDR = DllStructCreate($tagNMHDR, $ilParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iCode = DllStructGetData($tNMHDR, "Code") ;_DebugOut("+++: $iCode = " & $iCode) ; -12 = $NM_CUSTOMDRAW Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY Func CreateAllControls() Local $mw, $mh, $iID_Menu ; Create the Main window first $mw = 600 $mh = 400 $hMainWin = GUICreate("Test 7", $mw, $mh, 383, 54) ; Create the File menu and it's choices $iID_Menu = GUICtrlCreateMenu("&File") GUICtrlCreateMenuItem("", $iID_Menu) GUICtrlCreateMenuItem("a-Exit", $iID_Menu) ; ; Create all controls that will be common to all tabs ; GUICtrlCreateButton("Btn1", 10, 5, 50, 25) GUICtrlCreateButton("Btn2", 70, 5, 45, 25) GUICtrlCreateButton("Btn3", $mw - 55, 5, 40, 25) GUICtrlSetOnEvent(-1, "handle_Btn3") GUICtrlCreateButton("Exit", 10, $mh - 50, 45, 25) GUICtrlSetOnEvent(-1, "Event_GUIClose") GUICtrlCreateButton("Save", ($mw / 2), $mh - 50, 45, 25) GUICtrlCreateButton("Quit", $mw - 55, $mh - 50, 45, 25) create_tabs($mw, $mh) ; Create the tabbed interface ; Create a listview beside the Tabs createListView("X", 250, 60, 200, 200) EndFunc ;==>CreateAllControls Func create_tabs($mw, $mh) $hTab = GUICtrlCreateTab(20, 35, $mw - 50, $mh - 90) createTabItem("Games") createTabItem("Payments") createTabItem("Items") _GUICtrlTab_ActivateTab($hTab, 0) EndFunc ;==>create_tabs Func createTabItem($sTitle) Local $tabnum, $chu, $chl $tabnum = _GUICtrlTab_GetItemCount($hTab) _DebugOut("+++: $tabnum = " & $tabnum) $chu = StringLeft($sTitle, 1) $chl = StringLower($chu) GUICtrlCreateTabItem($sTitle & "-" & $chl) _GUICtrlTab_ActivateTab($hTab, $tabnum) createListView("T", 25, 60, 200, 200) GUICtrlCreateButton("TEST-" & $chu, 25, 260, 70, 20) GUICtrlCreateTabItem("") EndFunc ;==>createTabItem Func createListView($type, $x, $y, $w, $h, $lnum = @ScriptLineNumber) #forceref $lnum _DebugOut("+++:" & $lnum & ": createListView(" & $type & ", " & $x & "," & $y & "," & $w & "," & $h & ") entered") Local $str, $flags, $id $str = "col1" & @TAB & "|col2" & @TAB & "|col3" & @TAB $flags = 0 $flags = BitOR($flags, $WS_BORDER) $flags = BitOR($flags, $WS_VSCROLL) $flags = BitOR($flags, $WS_HSCROLL) $flags = BitOR($flags, $WS_TABSTOP) ;$flags = BitOR($flags, $LBS_NOTIFY) $flags = BitOR($flags, $LVS_SHOWSELALWAYS) $id = GUICtrlCreateListView($str, $x, $y, $w, $h) _ArrayAdd($aIDs, $id) _ArrayAdd($ahWnds, GUICtrlGetHandle($id)) _ArrayAdd($aTypes, $type) EndFunc ;==>createListView Func Event_GUIClose() Exit (1) EndFunc ;==>Event_GUIClose Func handle_Btn3() Local $tabnum = _GUICtrlTab_GetCurSel($hTab) + 1 If ($tabnum > 2) Then $tabnum = 0 _GUICtrlTab_ActivateTab($hTab, $tabnum) EndFunc ;==>handle_Btn3 Func fillListViews() Local $ndx, $id, $hWnd, $cnt, $subndx, $iIndex, $str, $chu For $ndx = 1 To UBound($aIDs) - 1 $id = $aIDs[$ndx] $hWnd = GUICtrlGetHandle($id) If ($aTypes[$ndx] == "T") Then $chu = StringLeft(_GUICtrlTab_GetItemText($hTab, $ndx - 1), 1) Else $chu = "X" EndIf For $cnt = 1 To 5 $iIndex = _GUICtrlListView_AddItem($hWnd, "Item" & $ndx) For $subndx = 1 To 3 $str = "Sub" & $cnt & $chu & $subndx _GUICtrlListView_AddSubItem($hWnd, $iIndex, $str, $subndx - 1) Next Next Next EndFunc ;==>fillListViews
InunoTaishou Posted February 22, 2016 Posted February 22, 2016 (edited) I think WM_COMMAND would actually get a message when a tab is selected. This works though #include <guitab.au3> #include <GuiConstants.au3> Global $hGUI = GUICreate("Tab Blocking", 412, 280, 302, 218) Global $tabTab = GUICtrlCreateTab(8, 8, 396, 256) Global $idTab1 = GUICtrlCreateTabItem("Tab 1") Global $chkBlock1 = GUICtrlCreateCheckbox("Block tab switching to 2 and 3", 20, 30, 200, 20) Global $idTab2 = GUICtrlCreateTabItem("Tab 2") Global $idTab3 = GUICtrlCreateTabItem("Tab 3") Global $selected_tab = _GUICtrlTab_GetCurSel($tabTab) GUISetState(@SW_SHOW, $hGUI) While (True) Switch (GUIGetMsg()) Case $GUI_EVENT_CLOSE GUIDelete($hGUI) Exit 0 Case $tabTab If (GUICtrlRead($chkBlock1) = $GUI_CHECKED) Then _GUICtrlTab_SetCurFocus($tabTab, $selected_tab) Else $selected_tab = _GUICtrlTab_GetCurSel($tabTab) EndIf EndSwitch WEnd You'd probably need a Window proc in order to intercept the message to change tabs on your tab control before it is sent to your tab control. Here are some constants defined in the TabConstants file that might help you Global Const $TCN_FOCUSCHANGE = ($TCN_FIRST - 4) Global Const $TCN_KEYDOWN = ($TCN_FIRST - 0) Global Const $TCN_SELCHANGING = ($TCN_FIRST - 2) I'll play with it later and see if there's another solution that prevents the tab from ever changing. The above code just sets the focus back to the original tab after the tab has actually changed. (Just looks like a flicker) Edited February 22, 2016 by InunoTaishou
InunoTaishou Posted February 23, 2016 Posted February 23, 2016 I was wrong, WM_NOTIFY will let you block the command to change tab. Returning 1 in the WM_NOTIFY prevents the tab from ever changing. expandcollapse popup#include <GUITab.au3> #include <GuiConstants.au3> Global $hGUI = GUICreate("Tab Blocking", 412, 280, 302, 218) Global $tabTab = GUICtrlCreateTab(8, 8, 396, 256) Global $idTab1 = GUICtrlCreateTabItem("Tab 1") Global $chkBlock1 = GUICtrlCreateCheckbox("Block tab switching to 2 and 3", 20, 50, 200, 20) Global $idTab2 = GUICtrlCreateTabItem("Tab 2") Global $chkBlock2 = GUICtrlCreateCheckbox("Block tab switching to 1 and 3", 20, 50, 200, 20) Global $idTab3 = GUICtrlCreateTabItem("Tab 3") Global $chkBlock3 = GUICtrlCreateCheckbox("Block tab switching to 1 and 2", 20, 50, 200, 20) GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") GUISetState(@SW_SHOW, $hGUI) While (True) Switch (GUIGetMsg()) Case $GUI_EVENT_CLOSE GUIDelete($hGUI) Exit 0 Case $tabTab ConsoleWrite("Tab Clicked" & @LF) EndSwitch WEnd Func WM_NOTIFY($hWndFrom, $iMsg, $wParam, $lParam) #forceref $hWndFrom, $lParam Local $hWndStruct = DllStructCreate($tagNMHDR, $lParam) Local $iCode = DllStructGetData($hWndStruct, "Code") Local $idFrom = DllStructGetData($hWndStruct, "IDFrom") Switch ($hWndFrom) Case $hGUI Switch ($iCode) Case $TCN_SELCHANGING Switch (_GUICtrlTab_GetCurSel($tabTab)) Case 0 If (GUICtrlRead($chkBlock1) = $GUI_CHECKED) Then Return 1 Case 1 If (GUICtrlRead($chkBlock2) = $GUI_CHECKED) Then Return 1 Case 2 If (GUICtrlRead($chkBlock3) = $GUI_CHECKED) Then Return 1 EndSwitch EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc
Moderators Melba23 Posted February 23, 2016 Moderators Posted February 23, 2016 AndySO1, I did it this way: expandcollapse popup#include <GUIConstantsEx.au3> Global $aTabs[5] $hGUI = GUICreate("Test", 500, 500) $cTab = GUICtrlCreateTab(10, 10, 480, 200) For $i = 0 To 4 $aTabs[$i] = GUICtrlCreateTabItem("Tab " & $i) Next GUICtrlCreateTabItem("") GUICtrlCreateLabel("Select tab to disable", 10, 230, 200, 20) $cCombo = GUICtrlCreateCombo("", 10, 250, 200, 20) GUICtrlSetData($cCombo, "0|1|2|3|4") GUISetState() $iCurrDisabledTab = -1 $iCurrTab = 0 While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $cCombo $iDisableTab = GUICtrlRead($cCombo) If $iDisableTab <> $iCurrDisabledTab Then If $iCurrDisabledTab <> -1 Then GUICtrlSetData($aTabs[$iCurrDisabledTab], "Tab " & $iCurrDisabledTab) EndIf GUICtrlSetData($aTabs[$iDisableTab], "Disabled") $iCurrDisabledTab = $iDisableTab EndIf Case $cTab $iSelTab = GUICtrlRead($cTab) If $iSelTab = $iCurrDisabledTab Then GUICtrlSetState($aTabs[$iCurrTab], $GUI_SHOW) Else $iCurrTab = $iSelTab EndIf EndSwitch WEnd M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now