argumentum Posted June 6, 2020 Posted June 6, 2020 (edited) expandcollapse popup#include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> Opt("GUIOnEventMode", 1) Global $edit, $GuiChild = 0 GuiExample() Func GuiExample() ; https://www.autoitscript.com/forum/topic/202986-parent-child-guis-and-input-control-fails/ Local $GuiMain = GUICreate("GuiExample w/child (parent)", 350, 300) GUISetOnEvent($GUI_EVENT_CLOSE, "GuiOnEvent_CLOSE", $GuiMain) GUISetState(@SW_SHOW, $GuiMain) $edit = GUICtrlCreateEdit("", 10, 70, 300, 200) ; It does not matter what GUI is on, GUICtrlSetData($edit, "play around with the inputs" & _ ; the parent's controls will @CRLF & "and press enter." & _ ; bleed through a $WS_CHILD gui. @CRLF & @CRLF & "It should trigger the" & _ @CRLF & " GUICtrlSetOnEvent()") GUICtrlCreateButton("reload alt.", 225, 40, 120, 25) ; run alternate versions, GUICtrlSetOnEvent(-1, "OnBttnRunAlt") ; with and without child GUI. GUICtrlSetTip(-1, "run alternate versions," & @LF & "with and without child GUI.") ;I need this child(s), but with it, it does not behave as expected. ;..for this test you can comment it out, to see that it should work. ;..but with the child, instead it executes after clicking another control. If Not StringInStr($CmdLineRaw, "/ExampleOnlyParent") Then $GuiChild = GUICreate("GuiExample w/child (child)", 320, 280, 5, 5, $WS_CHILD, $WS_TABSTOP, $GuiMain) EndIf If $GuiChild Then GUISetBkColor(0x888888, $GuiChild) ; for the dramatic effect :) If $GuiChild Then GUISwitch($GuiChild) ; ..just in case.. tho should not matter. GUICtrlCreateInput("This text 1", 5, 10, 200, 21, BitOR($GUI_SS_DEFAULT_INPUT, $ES_WANTRETURN)) GUICtrlSetOnEvent(-1, "OnInputEnterKeyOne") GUICtrlCreateInput("This text 2", 5, 35, 200, 21, BitOR($GUI_SS_DEFAULT_INPUT, $ES_WANTRETURN)) GUICtrlSetOnEvent(-1, "OnInputEnterKeyTwo") If $GuiChild Then GUICtrlCreateButton("flash child", 220, 8, 120, 25) GUICtrlSetOnEvent(-1, "OnFlashBttn") GUISetState(@SW_SHOW, $GuiChild) OnFlashBttn() EndIf MainLoopExample() EndFunc Func MainLoopExample() While 1 Sleep(100) WEnd EndFunc Func OnInputEnterKeyOne() GUICtrlSetData($edit, @SEC &'.' & @MSEC& ' - Func OnInputEnterKey One ()' & @CRLF) EndFunc Func OnInputEnterKeyTwo() GUICtrlSetData($edit, @SEC &'.' & @MSEC& ' - Func OnInputEnterKey Two ()' & @CRLF) EndFunc Func OnFlashBttn() WinSetTrans($GuiChild, "", 50) Sleep(300) WinSetTrans($GuiChild, "", 255) EndFunc Func OnBttnRunAlt() If StringInStr($CmdLineRaw, "/ExampleOnlyParent") Then ShellExecute(@ScriptFullPath, "") Else ShellExecute(@ScriptFullPath, "/ExampleOnlyParent") EndIf GuiOnEvent_CLOSE() EndFunc Func GuiOnEvent_CLOSE() GUIDelete() Exit EndFunc I need this child(s), but with it, it does not behave as expected. ..for this test you can comment the child GUI out, to see that it should work. With the child, instead it executes after clicking another control. Thanks Edit: Modified the example for dramatic effect Edit 2: Solved my problems at a post somewhere down this thread. Edited June 7, 2020 by argumentum solved my problem Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
Moderators Melba23 Posted June 6, 2020 Moderators Posted June 6, 2020 argumentum, If I move the child creation line AFTER the creation of the controls, it seems to work the way you want. I imagine AutoIt is getting very confused by the fact you have 2 GUIs and do not specify which GUI is to receive the controls - it puts the controls in the visible one and is then uncertain of how to act with the child not having a "state" set. 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
argumentum Posted June 6, 2020 Author Posted June 6, 2020 1 minute ago, Melba23 said: move the child creation line AFTER the creation of the controls yes, but I need the controls in the children and in my project there is more than one child. Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
argumentum Posted June 6, 2020 Author Posted June 6, 2020 The OnEvent should trigger the event regardless. I would call this a bug but I'm not at that level of knowing, so.., will see. If the only solution is to register WM_COMMAND then is a bug. Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
Moderators Melba23 Posted June 6, 2020 Moderators Posted June 6, 2020 (edited) argumentum, You do realise that the child never actually appears? Why are you using the $WS_CHILD style when you are explicitly setting the parent parameter? M23 P.S. Family calls - back tomorrow. Edited June 6, 2020 by Melba23 argumentum 1 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
argumentum Posted June 6, 2020 Author Posted June 6, 2020 (edited) 36 minutes ago, Melba23 said: You do realise that the child never actually appears? I've modified the example to have better visual cues. 36 minutes ago, Melba23 said: Why are you using the $WS_CHILD style when you are explicitly setting the parent parameter? That style will not overlap the parent GUI, when the child GUI is bigger than the parent GUI. Edited June 6, 2020 by argumentum Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
argumentum Posted June 6, 2020 Author Posted June 6, 2020 (edited) ..and to top it off, the OnEvent, triggers when the input control got edited and clicked down another control or tabbing ( basically loosing focus ), with or w/o child GUI, w/o pressing an enter key. Edited June 6, 2020 by argumentum specify the event Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
argumentum Posted June 7, 2020 Author Posted June 7, 2020 (edited) ..here we go: ( is better to look at the next entry down this thread ) expandcollapse popup#include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #Include <WinAPI.au3> ;~ #include <WinAPIDlg.au3> Opt("GUIOnEventMode", 1) Global $iIsRegistered = 0, $iCtrlsAndFuncs = 0, $aCtrlsAndFuncs[11][2], $i_Ctrl = 0 Global $edit, $GuiChild = 0 Global $i_IDFrom = 0 GuiExample() Func GuiExample() ; https://www.autoitscript.com/forum/topic/202986-parent-child-guis-and-input-control-fails/ Local $GuiMain = GUICreate("GuiExample w/child (parent)", 400, 300, -1, -1, BitOR($GUI_SS_DEFAULT_GUI,$WS_MAXIMIZEBOX,$WS_SIZEBOX,$WS_THICKFRAME,$WS_TABSTOP)) GUISetOnEvent($GUI_EVENT_CLOSE, "GuiOnEvent_CLOSE", $GuiMain) GUISetOnEvent($GUI_EVENT_PRIMARYDOWN, "GuiOnEvent_PRIMARYDOWN_Parent", $GuiMain) GUISetState(@SW_SHOW, $GuiMain) $edit = GUICtrlCreateEdit("", 10, 70, 300, 200) ; It does not matter what GUI is on, GUICtrlSetData($edit, "play around with the inputs" & _ ; the parent's controls will @CRLF & "and press enter." & _ ; bleed through a $WS_CHILD gui. @CRLF & @CRLF & "It should trigger the" & _ @CRLF & " GUICtrlSetOnEvent()") myColors() GUICtrlCreateLabel('v.' & @AutoItVersion, 290, 280) GUICtrlCreateButton("reload alt.", 225, 40, 120, 25) ; run alternate versions, GUICtrlSetOnEvent(-1, "OnBttnRunAlt") ; with and without child GUI. GUICtrlSetTip(-1, "run alternate versions," & @LF & "with and without child GUI.") ;I need this child(s), but with it, it does not behave as expected. ;..for this test you can comment it out, to see that it should work. ;..but with the child, instead it executes after clicking another control. If Not StringInStr($CmdLineRaw, "/ExampleOnlyParent") Then $GuiChild = GUICreate("GuiExample w/child (child)", 320, 380, 5, 5, $WS_CHILD, 0x00010000, $GuiMain) GUISetOnEvent($GUI_EVENT_PRIMARYDOWN, "GuiOnEvent_PRIMARYDOWN_Child", $GuiChild) EndIf ; so the magic number is $WS_TABSTOP = 0x00010000 ; added as a magic due to that is "Common Styles" and not "Common Extended Styles" ; and does indeed allows to tab around but it also "makes the GUI dragable" and tho, ; much desired to those looking for the feature, I need it not. ; The again, running under 3.2.12.1 it works as one would expect from $WS_TABSTOP ; without the dragging of the child If $GuiChild Then GUISetBkColor(0x888888, $GuiChild) ; for the dramatic effect :) If $GuiChild Then GUISwitch($GuiChild) ; ..just in case.. tho should not matter. ;---------------------------------------------------------------------------------- ;;;; this part, the _GUICtrlInputSetOnEventEnterKey() solves the Enter key issue with GUICtrlSetOnEvent() Local $iCtrl = GUICtrlCreateInput("This text 1", 5, 10, 200, 21, BitOR($GUI_SS_DEFAULT_INPUT, $ES_WANTRETURN)) ;~ GUICtrlSetOnEvent($iCtrl, "OnInputEnterKeyOne") ; ..this line is here for you to campare with the one below, _GUICtrlInputSetOnEventEnterKey($iCtrl, "OnInputEnterKeyOne") ; if you'd want to compare. myColors() GUICtrlCreateInput("This text 2", 5, 35, 200, 21, BitOR($GUI_SS_DEFAULT_INPUT, $ES_WANTRETURN)) ;~ GUICtrlSetOnEvent(-1, "OnInputEnterKeyTwo") _GUICtrlInputSetOnEventEnterKey(-1, "OnInputEnterKeyTwo") myColors() ;---------------------------------------------------------------------------------- If $GuiChild Then GUICtrlCreateButton("flash child", 220, 8, 120, 25) GUICtrlSetOnEvent(-1, "OnFlashBttn") GUISetState(@SW_SHOW, $GuiChild) OnFlashBttn() ; ..in v3.2.12.1 this does not work, and it should not work, EndIf ; but in newer versions it does. ( it may be related to the $WS_TABSTOP ) MainLoopExample() EndFunc ;==>GuiExample Func myColors() GUICtrlSetColor(-1, 0x222222 ) GUICtrlSetBkColor(-1, 0xEEEEEE ) EndFunc #Region tha hack for the enter key Func _GUICtrlInputSetOnEventEnterKey($iCtrl = 0, $sFunc = "", $iInternal_IsFrom_WM_COMMAND = 0) ConsoleWrite('+ Func _GUICtrlInputSetOnEventEnterKey($iCtrl = "' & Eval("iCtrl") & '", $sFunc = "' & Eval("sFunc") & '", $iInternal_IsFrom_WM_COMMAND = "' & Eval("iInternal_IsFrom_WM_COMMAND") & '")' & @CRLF) ;~ Local Static $iIsRegistered = 0, $iCtrlsAndFuncs = 0, $aCtrlsAndFuncs[11][2], $i_Ctrl = 0 If $iIsRegistered = 0 Then $iIsRegistered = Int(Not GUIRegisterMsg($WM_COMMAND, 'WM_COMMAND')) ; or register your own later. If Eval("iInternal_IsFrom_WM_COMMAND") Then ConsoleWrite(@TAB & "iInternal_IsFrom_WM_COMMAND: " & $iInternal_IsFrom_WM_COMMAND & @CRLF) $i_Ctrl = $iInternal_IsFrom_WM_COMMAND ;~ AdlibRegister("_GUICtrlInputSetOnEventEnterKey", 50) If StringInStr(@AutoItVersion, "3.2.") = 1 Then Execute('AdlibEnable("_GUICtrlInputSetOnEventEnterKey", 50)') Else Execute('AdlibRegister("_GUICtrlInputSetOnEventEnterKey", 50)') EndIf Return ; return to the GUIRegisterMsg() ASAP ElseIf Eval("iCtrl") Then $iCtrlsAndFuncs += 1 If UBound($aCtrlsAndFuncs) < $iCtrlsAndFuncs + 1 Then ReDim $aCtrlsAndFuncs[UBound($aCtrlsAndFuncs) + 100][2] $aCtrlsAndFuncs[0][0] = $iCtrlsAndFuncs ; useless but a force of habit :) If $iCtrl = -1 Then $iCtrl = _WinAPI_GetDlgCtrlID(GUICtrlGetHandle($iCtrl)) ConsoleWrite(@TAB & "iCtrl: " & $iCtrl & @CRLF) $aCtrlsAndFuncs[$iCtrlsAndFuncs][0] = $iCtrl $aCtrlsAndFuncs[$iCtrlsAndFuncs][1] = $sFunc Return Else ;~ AdlibUnRegister("_GUICtrlInputSetOnEventEnterKey") If StringInStr(@AutoItVersion, "3.2.") = 1 Then Execute('AdlibDisable()') Else Execute('AdlibUnRegister("_GUICtrlInputSetOnEventEnterKey")') EndIf ConsoleWrite(@TAB & "run" & @CRLF) For $n = 1 To $iCtrlsAndFuncs ConsoleWrite("?" & $aCtrlsAndFuncs[$n][0] & " = " & $i_Ctrl & @CRLF) If $i_Ctrl = $aCtrlsAndFuncs[$n][0] Then ConsoleWrite(@TAB & "run: " & $aCtrlsAndFuncs[$n][1] & @CRLF) Call($aCtrlsAndFuncs[$n][1]) Return EndIf Next EndIf EndFunc ;==>_GUICtrlInputSetOnEventEnterKey #EndRegion tha hack for the enter key Func GuiOnEvent_PRIMARYDOWN_Parent() GUICtrlSetData($edit, @SEC & '.' & Execute("@MSEC") & ' - Func GuiOnEvent_PRIMARYDOWN_Parent ()' & @CRLF) EndFunc Func GuiOnEvent_PRIMARYDOWN_Child() GUICtrlSetData($edit, @SEC & '.' & Execute("@MSEC") & ' - Func GuiOnEvent_PRIMARYDOWN_Child ()' & @CRLF) EndFunc ;==>GuiOnEvent_PRIMARYDOWN Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam, $lParam ;~ Local Static $i_IDFrom = 0 ; ..you'd have to add this line to your WM_COMMAND Local $iIDFrom = BitAND($wParam, 0xFFFF) ; Low Word Local $iCode = BitShift($wParam, 16) ; Hi Word ;~ ConsoleWrite('+ Func WM_COMMAND(' & $hWnd & ', ' & $iMsg & ', ' & $wParam & ', ' & $lParam & ') $iIDFrom: ' & $iIDFrom & ', $iCode: 0x' & Hex($iCode, 4) & @CRLF) If $wParam = 1 And $lParam = 0 Then _GUICtrlInputSetOnEventEnterKey(0, "", $i_IDFrom) If $lParam And $iCode Then $i_IDFrom = $iIDFrom ; ..you'd have to add these 2 lines to your WM_COMMAND Return $GUI_RUNDEFMSG EndFunc ;==>WM_COMMAND Func MainLoopExample() While 1 Sleep(100) WEnd EndFunc ;==>MainLoopExample Func OnInputEnterKeyOne() GUICtrlSetData($edit, @SEC & '.' & Execute("@MSEC") & ' - Func OnInputEnterKey One ()' & @CRLF) EndFunc ;==>OnInputEnterKeyOne Func OnInputEnterKeyTwo() GUICtrlSetData($edit, @SEC & '.' & Execute("@MSEC") & ' - Func OnInputEnterKey Two ()' & @CRLF) EndFunc ;==>OnInputEnterKeyTwo Func OnFlashBttn() WinSetTrans($GuiChild, "", 50) Sleep(300) WinSetTrans($GuiChild, "", 255) EndFunc ;==>OnFlashBttn Func OnBttnRunAlt() If StringInStr($CmdLineRaw, "/ExampleOnlyParent") Then ShellExecute(@AutoItExe, '"' & @ScriptFullPath & '"') Else ShellExecute(@AutoItExe, '"' & @ScriptFullPath & '" /ExampleOnlyParent') EndIf GuiOnEvent_CLOSE() EndFunc ;==>OnBttnRunAlt Func GuiOnEvent_CLOSE() If $GuiChild Then GUIDelete($GuiChild) GUIDelete() Exit EndFunc ;==>GuiOnEvent_CLOSE This will run in v3.2.12.1 and v3.3.14.5 and 3.3.15.3. The reason is to identify behavior. Regarding the OnEvent behavior, I coded around it to overcome the issue. but the $WS_TABSTOP = 0x00010000, I can not. $WS_TABSTOP behaves as expected in v3.2.12.1 but not in the v3.3.x.x versions. So there is more than one issue to look at. @jpm, would you kindly add them to the ticket tracker ? I don't believe I would do a good job adding them. If you rather not, let me know and I'll squeeze something out of my brain but again, I'm not the best for discerning each in a clear and explicit format. Meanwhile, if anyone can code something ( that don't use Send() ) to stop the dragging of the child GUI, I'll appreciate it. Fortunately found a way ( unless told to not go this way ) with this bellow: ( unless it brakes something else, will see ) ConsoleWrite((GUIRegisterMsg($WM_NCHITTEST, '__WM_NCHITTEST') ? '+ ' : '! ') & 'WM_NCHITTEST' & @CRLF) ; $WM_NCHITTEST = 0x0084 Func __WM_NCHITTEST($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam, $lParam ConsoleWrite('+ Func __WM_NCHITTEST(' & $hWnd & ', ' & $iMsg & ', ' & $wParam & ', ' & $lParam & ')' & @CRLF) Return 0 ; ..to not continue ;~ Return $GUI_RUNDEFMSG EndFunc ;==>__WM_NCHITTEST ...and it broke the resize. I'm using WM_GETMINMAXINFO to snap it back into place. Edit 3: I'm finally using WM_WINDOWPOSCHANGING to keep it in place, anchored to a Ctrl in the main GUI. ..and in case someone wants to register almost all 219 messages from the help file, here is the discovery/brute force tool GUIRegisterMsgThemAll_UDF_v2.zip Edited July 6, 2020 by argumentum updated the UDF/tool Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
argumentum Posted July 6, 2020 Author Posted July 6, 2020 ok, the solution to my need is at Much better than the code from the prior post Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
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