Zedna Posted August 22, 2019 Posted August 22, 2019 (edited) When I have CheckBox in StatusBar using SetParent API then there is problem because you can't catch its event by standard GUIGetMsg(). I need help how to catch Check/UnCheck event in this case. expandcollapse popup#AutoIt3Wrapper_UseX64=n #NoTrayIcon #include <GUIConstants.au3> #include <GuiStatusBar.au3> $Form1 = GUICreate("StatusBar Checkbox", 400, 300, -1, -1, BitOR($GUI_SS_DEFAULT_GUI,$WS_MAXIMIZEBOX,$WS_SIZEBOX)) $cbx1 = GUICtrlCreateCheckbox("Sum 1", 10, 100, 120, 20) GUICtrlSetResizing($cbx1, $GUI_DOCKLEFT+$GUI_DOCKTOP+$GUI_DOCKWIDTH+$GUI_DOCKHEIGHT) $cbx2 = GUICtrlCreateCheckbox("Sum 2", 3, 3, 58, 15) GUICtrlSetResizing($cbx2, $GUI_DOCKALL) $StatusBar1 = _GUICtrlStatusBar_Create($Form1) Dim $sb1_PartsWidth[3] = [62, 200, -1] _GUICtrlStatusBar_SetParts($StatusBar1, $sb1_PartsWidth) _GuiCtrlStatusBar_Resize($StatusBar1) _SetParent($cbx2, $StatusBar1) ; after this Checkbox doesn't fire event in GUIGetMsg() GUISetState(@SW_SHOW) GUIRegisterMsg($WM_SIZE, "WM_SIZE") While 1 $msg = GUIGetMsg() Switch $msg Case $GUI_EVENT_CLOSE Exit Case $cbx1 MsgBox(64, 'cbx1', 'Checked: ' & IsChecked($cbx1)) ; OK Case $cbx2 MsgBox(64, 'cbx2', 'Checked: ' & IsChecked($cbx2)) ; never fired EndSwitch WEnd Func WM_SIZE($hWnd, $Msg, $wParam, $lParam) _GuiCtrlStatusBar_Resize($StatusBar1) Return $GUI_RUNDEFMSG EndFunc Func _SetParent($ctrl_child, $ctrl_parent) ;~ $ctrl_parent = GUICtrlGetHandle($ctrl_parent) $ctrl_child = GUICtrlGetHandle($ctrl_child) DllCall("user32.dll", "hwnd", "SetParent", "hwnd", $ctrl_child, "hwnd", $ctrl_parent) EndFunc Func IsChecked($control) Return BitAnd(GUICtrlRead($control),$GUI_CHECKED) = $GUI_CHECKED EndFunc EDIT: Maybe some WM_COMMAND / WM_NOTIFY or SubClassing? Edited August 22, 2019 by Zedna solved Resources UDF ResourcesEx UDF AutoIt Forum Search
Subz Posted August 22, 2019 Posted August 22, 2019 Probably not the answer your looking for but, you could use ControlCommand and Adlibregister Global $g_bCbx2 = False ;~ ... AdlibRegister("_IsChecked") ;~ ... Func _IsChecked() Local $bCbx2 = ControlCommand($Form1, "", $cbx2, "IsChecked") ? True : False If $g_bCbx2 <> $bCbx2 Then MsgBox(64, 'cbx2', 'Checked: ' & $bCbx2) $g_bCbx2 = $bCbx2 EndIf EndFunc
Zedna Posted August 22, 2019 Author Posted August 22, 2019 (edited) I'm very close to solution. Basically this works, but it's not complete yet (see commented lines): expandcollapse popup#AutoIt3Wrapper_UseX64=n #NoTrayIcon #include <GUIConstants.au3> #include <GuiStatusBar.au3> Global $hTab, $hDll, $pDll, $hProc $Form1 = GUICreate("StatusBar Checkbox", 400, 300, -1, -1, BitOR($GUI_SS_DEFAULT_GUI,$WS_MAXIMIZEBOX,$WS_SIZEBOX)) $cbx1 = GUICtrlCreateCheckbox("Sum 1", 10, 100, 120, 20) GUICtrlSetResizing($cbx1, $GUI_DOCKLEFT+$GUI_DOCKTOP+$GUI_DOCKWIDTH+$GUI_DOCKHEIGHT) $cbx2 = GUICtrlCreateCheckbox("Sum 2", 3, 3, 58, 15) $hcbx2 = GUICtrlGetHandle($cbx2) GUICtrlSetResizing($cbx2, $GUI_DOCKALL) $StatusBar1 = _GUICtrlStatusBar_Create($Form1) Dim $sb1_PartsWidth[3] = [62, 200, -1] _GUICtrlStatusBar_SetParts($StatusBar1, $sb1_PartsWidth) _GuiCtrlStatusBar_Resize($StatusBar1) _SetParent($cbx2, $StatusBar1) ; after this Checkbox doesn't fire event in GUIGetMsg() GUISetState(@SW_SHOW) GUIRegisterMsg($WM_SIZE, "WM_SIZE") ; Register StatusBar window proc $hDll = DllCallbackRegister('_SBWinProc', 'ptr', 'hwnd;uint;wparam;lparam') $pDll = DllCallbackGetPtr($hDll) $hProc = _WinAPI_SetWindowLong($StatusBar1, $GWL_WNDPROC, $pDll) While 1 $msg = GUIGetMsg() Switch $msg Case $GUI_EVENT_CLOSE Exit Case $cbx1 MsgBox(64, 'cbx1', 'Checked: ' & IsChecked($cbx1)) ; OK Case $cbx2 MsgBox(64, 'cbx2', 'Checked: ' & IsChecked($cbx2)) ; never fired EndSwitch WEnd _WinAPI_SetWindowLong($StatusBar1, $GWL_WNDPROC, $hProc) DllCallbackFree($hDll) Func WM_SIZE($hWnd, $Msg, $wParam, $lParam) _GuiCtrlStatusBar_Resize($StatusBar1) Return $GUI_RUNDEFMSG EndFunc Func _SetParent($ctrl_child, $ctrl_parent) ;~ $ctrl_parent = GUICtrlGetHandle($ctrl_parent) $ctrl_child = GUICtrlGetHandle($ctrl_child) DllCall("user32.dll", "hwnd", "SetParent", "hwnd", $ctrl_child, "hwnd", $ctrl_parent) EndFunc Func IsChecked($control) Return BitAnd(GUICtrlRead($control),$GUI_CHECKED) = $GUI_CHECKED EndFunc Func _SBWinProc($hWnd, $iMsg, $wParam, $lParam) ;~ Local $i_code = BitAND($wparam, 0xFFFF) ;~ Local $i_notify = BitShift($wparam, 16) If $hWnd = $StatusBar1 Then Switch $iMsg Case $WM_COMMAND If $wParam = $cbx2 Then MsgBox(64, 'cbx2', 'Checked: ' & IsChecked($cbx2)) ;~ If $i_code = $cbx2 And $i_notify = $NM_CLICK Then MsgBox(64, 'cbx2', 'Checked: ' & IsChecked($cbx2)) EndSwitch EndIf Return _WinAPI_CallWindowProc($hProc, $hWnd, $iMsg, $wParam, $lParam) EndFunc EDIT: Explanation By default WM_COMMAND event/message from checkbox is delivered to main GUI form (and can be catch in main GUI loop) because it is its parent. Now when we change parent of checkbox to StatusBar then WM_COMMAND event/message from checkbox is delivered to StatusBar as its parent. So we have to register window procedure of StatusBar and catch WM_COMMAND (from our checkbox) there. This works but the only one remaining problem is how to distinguish notification code in this case (I want to react only to NM_CLICK), because in my example $i_notify is always zero. This problem is only cosmetic, because my checkbox generate only one WM_COMMAND (when clicked) so it works fine even if I don't do testing of NOTIFY/NM_CLICK. Edited August 22, 2019 by Zedna Resources UDF ResourcesEx UDF AutoIt Forum Search
UEZ Posted August 22, 2019 Posted August 22, 2019 What about this solution? expandcollapse popup#AutoIt3Wrapper_UseX64=n #NoTrayIcon #include <Array.au3> #include <GUIConstants.au3> #include <GuiStatusBar.au3> $Form1 = GUICreate("StatusBar Checkbox", 400, 300, -1, -1, BitOR($GUI_SS_DEFAULT_GUI,$WS_MAXIMIZEBOX,$WS_SIZEBOX)) $cbx1 = GUICtrlCreateCheckbox("Sum 1", 10, 100, 120, 20) GUICtrlSetResizing($cbx1, $GUI_DOCKLEFT+$GUI_DOCKTOP+$GUI_DOCKWIDTH+$GUI_DOCKHEIGHT) $cbx2 = GUICtrlCreateCheckbox("Sum 2", 3, 3, 58, 15) $hCbx2 = GUICtrlGetHandle($cbx2) GUICtrlSetResizing($cbx2, $GUI_DOCKALL) $StatusBar1 = _GUICtrlStatusBar_Create($Form1) Dim $sb1_PartsWidth[3] = [62, 200, -1] _GUICtrlStatusBar_SetParts($StatusBar1, $sb1_PartsWidth) _GuiCtrlStatusBar_Resize($StatusBar1) _SetParent($cbx2, $StatusBar1) ; after this Checkbox doesn't fire event in GUIGetMsg() GUISetState(@SW_SHOW) GUIRegisterMsg($WM_SIZE, "WM_SIZE") GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") Global $iDummy = GUICtrlCreateDummy() While 1 $msg = GUIGetMsg() Switch $msg Case $GUI_EVENT_CLOSE Exit Case $cbx1 MsgBox(64, 'cbx1', 'Checked: ' & IsChecked($cbx1)) ; OK Case $iDummy MsgBox(64, 'cbx2', 'Checked: ' & IsChecked($cbx2)) ; never fired EndSwitch WEnd Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam) #forceref $hWnd, $iMsg, $iwParam Local $tNMHDR = DllStructCreate($tagNMHDR, $ilParam) Switch $tNMHDR.hWndFrom Case $hCbx2 Local $aMPos = GUIGetCursorInfo($hWnd) Switch $aMPos[4] Case $cbx2 If $aMPos[2] Then While GUIGetCursorInfo($hWnd)[2] WEnd GUICtrlSendToDummy($iDummy) Return 0 EndIf EndSwitch EndSwitch Return "GUI_RUNDEFMSG" EndFunc Func WM_SIZE($hWnd, $Msg, $wParam, $lParam) _GuiCtrlStatusBar_Resize($StatusBar1) Return $GUI_RUNDEFMSG EndFunc Func _SetParent($ctrl_child, $ctrl_parent) ;~ $ctrl_parent = GUICtrlGetHandle($ctrl_parent) $ctrl_child = GUICtrlGetHandle($ctrl_child) DllCall("user32.dll", "hwnd", "SetParent", "hwnd", $ctrl_child, "hwnd", $ctrl_parent) EndFunc Func IsChecked($control) Return BitAnd(GUICtrlRead($control),$GUI_CHECKED) = $GUI_CHECKED EndFunc Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
Solution Zedna Posted August 22, 2019 Author Solution Posted August 22, 2019 Thanks all for alternative solutions. My final working solution: expandcollapse popup#AutoIt3Wrapper_UseX64=n #NoTrayIcon #include <GUIConstants.au3> #include <GuiStatusBar.au3> $Form1 = GUICreate("StatusBar Checkbox", 400, 300, -1, -1, BitOR($GUI_SS_DEFAULT_GUI,$WS_MAXIMIZEBOX,$WS_SIZEBOX)) $cbx1 = GUICtrlCreateCheckbox("Sum 1", 10, 100, 120, 20) GUICtrlSetResizing($cbx1, $GUI_DOCKLEFT+$GUI_DOCKTOP+$GUI_DOCKWIDTH+$GUI_DOCKHEIGHT) $cbx2 = GUICtrlCreateCheckbox("Sum 2", 3, 3, 58, 15) $hcbx2 = GUICtrlGetHandle($cbx2) GUICtrlSetResizing($cbx2, $GUI_DOCKALL) $cbx2_dummy = GUICtrlCreateDummy() $StatusBar1 = _GUICtrlStatusBar_Create($Form1) Dim $sb1_PartsWidth[3] = [62, 200, -1] _GUICtrlStatusBar_SetParts($StatusBar1, $sb1_PartsWidth) _GuiCtrlStatusBar_Resize($StatusBar1) _SetParent($cbx2, $StatusBar1) GUISetState(@SW_SHOW) GUIRegisterMsg($WM_SIZE, "WM_SIZE") ; Register StatusBar window proc Global $hDll, $pDll, $hProc $hDll = DllCallbackRegister('_SBWinProc', 'ptr', 'hwnd;uint;wparam;lparam') $pDll = DllCallbackGetPtr($hDll) $hProc = _WinAPI_SetWindowLong($StatusBar1, $GWL_WNDPROC, $pDll) While 1 $msg = GUIGetMsg() Switch $msg Case $GUI_EVENT_CLOSE Exit Case $cbx1 MsgBox(64, 'cbx1', 'Checked: ' & IsChecked($cbx1)) Case $cbx2_dummy MsgBox(64, 'cbx2', 'Checked: ' & IsChecked($cbx2)) EndSwitch WEnd _WinAPI_SetWindowLong($StatusBar1, $GWL_WNDPROC, $hProc) DllCallbackFree($hDll) Func WM_SIZE($hWnd, $Msg, $wParam, $lParam) _GuiCtrlStatusBar_Resize($StatusBar1) Return $GUI_RUNDEFMSG EndFunc Func _SetParent($ctrl_child, $ctrl_parent) ;~ $ctrl_parent = GUICtrlGetHandle($ctrl_parent) $ctrl_child = GUICtrlGetHandle($ctrl_child) DllCall("user32.dll", "hwnd", "SetParent", "hwnd", $ctrl_child, "hwnd", $ctrl_parent) EndFunc Func IsChecked($control) Return BitAnd(GUICtrlRead($control),$GUI_CHECKED) = $GUI_CHECKED EndFunc Func _SBWinProc($hWnd, $iMsg, $wParam, $lParam) If $hWnd = $StatusBar1 And $iMsg = $WM_COMMAND And $wParam = $cbx2 Then GUICtrlSendToDummy($cbx2_dummy) Return _WinAPI_CallWindowProc($hProc, $hWnd, $iMsg, $wParam, $lParam) EndFunc mLipok 1 Resources UDF ResourcesEx UDF AutoIt Forum Search
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