wolflake Posted November 5, 2018 Posted November 5, 2018 (edited) I was playing around with _GUICtrlComboBox_AutoComplete example code and wanted to test using the enter key in the combobox. I added an accelerator key to catch the enter key but it wasn't being picked up so I tried putting a sleep in GUIGetMsg loop and that worked but then when you click on the X close window button it isn't picked up. If I reduce the pause in the loop it get more responsive for closing the window but misses some of the enter key presses. I have an alternative using _IsPressed which works but I like the idea of the accelerator key just working in the one window. I'd like to understand why there isn't a balance between the accelerator key, the GUIRegisterMsg, and the close window. In my example you can see that when you press the enter key it picks up whats in the edit box and writes it and a count of how many times you pressed enter to the console and puts a tooltip up. But if you try to close the window clicking on the X or using Ctrl-F4 it usually doesn't work. Using the drop down menu on the left and choosing close works pretty well. If you comment out the Sleep(100) line in the GuiGetMsg loop you pick up some of the enter keys but often miss them. On the other hand closing the window works as expected. Thanks for your consideration. expandcollapse popup;Auto complete combobox #include <GuiComboBox.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include<array.au3> #include<misc.au3> Global $g_idCombo Example() Func Example() ; Create GUI GUICreate("ComboBox Auto Complete", 200, 25) $g_idCombo = GUICtrlCreateCombo("", 2, 2, 196, 300) $myEnter = GUICtrlCreateDummy() $myEsc = GUICtrlCreateDummy() Global $iCnt = 0 ;Set GUIAccelerators to capture Enter key ; Local $aAcc[1][2] = [["{Enter}", $myEnter]] Local $aAcc[2][2] = [["{Enter}", $myEnter],["{Esc}", $myEsc]] GUISetAccelerators($aAcc) GUISetState(@SW_SHOW) ; Add files and strings and sort ; You could use InsertString at 0 index instead of AddString to see most recent first additions. _GUICtrlComboBox_BeginUpdate($g_idCombo) _GUICtrlComboBox_AddDir($g_idCombo, @WindowsDir & "\*.exe") Global $aStrings[4] = ["Rock","Paper","Scissors","Rubber"] for $i = 0 to 3 _GUICtrlComboBox_AddString($g_idCombo, $aStrings[$i]) Next $aStrings = _GUICtrlComboBox_GetListArray($g_idCombo) _ArraySort($aStrings) _GUICtrlComboBox_ResetContent($g_idCombo) for $i = 0 to UBound($aStrings) -1 ;ConsoleWrite($aStrings[$i] & @CRLF) _GUICtrlComboBox_AddString($g_idCombo, $aStrings[$i]) Next _GUICtrlComboBox_EndUpdate($g_idCombo) GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") ; Loop until the user exits. Do Sleep(100) ;<----- helps get enter key but hurts using close window button X Switch GUIGetMsg() Case $myEnter $iCnt +=1 $sCtrlRead = GUICtrlRead($g_idCombo) ConsoleWrite("Entered " & $iCnt & " " & $sCtrlRead & @CRLF) ToolTip("Entered " & $iCnt & " " & $sCtrlRead,10,10) Case $myEsc GUICtrlSetData($g_idCombo,"Set") ;~ ;GUIDelete() EndSwitch ;Alternative to Accelerator Keys ;~ if chk_key("0d") then ;~ $iCnt +=1 ;~ $sCtrlRead = GUICtrlRead($g_idCombo) ;~ ConsoleWrite("Press-Entered " & $iCnt & " " & $sCtrlRead & @CRLF) ;~ EndIf ;~ if chk_key("1b") then ;~ ConsoleWrite("Esc" & @CRLF) ;~ Exit ;~ EndIf ;and WinActive("ComboBox Auto Complete") Until GUIGetMsg() = $GUI_EVENT_CLOSE GUIDelete() EndFunc ;==>Example func chk_key($sK) ; 0d,1b Enter, Esc if _IsPressed($sK) and WinActive("ComboBox Auto Complete") then While _IsPressed($sK) Sleep(200) WEnd return True EndIf return False EndFunc Func _Edit_Changed() _GUICtrlComboBox_AutoComplete($g_idCombo) EndFunc ;==>_Edit_Changed Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg Local $hWndFrom, $iIDFrom, $iCode, $hWndCombo If Not IsHWnd($g_idCombo) Then $hWndCombo = GUICtrlGetHandle($g_idCombo) $hWndFrom = $lParam $iIDFrom = BitAND($wParam, 0xFFFF) ; Low Word $iCode = BitShift($wParam, 16) ; Hi Word Switch $hWndFrom Case $g_idCombo, $hWndCombo Switch $iCode Case $CBN_CLOSEUP ; Sent when the list box of a combo box has been closed _DebugPrint("$CBN_CLOSEUP" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _ "-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _ "-->Code:" & @TAB & $iCode) ; no return value Case $CBN_DBLCLK ; Sent when the user double-clicks a string in the list box of a combo box _DebugPrint("$CBN_DBLCLK" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _ "-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _ "-->Code:" & @TAB & $iCode) ; no return value Case $CBN_DROPDOWN ; Sent when the list box of a combo box is about to be made visible _DebugPrint("$CBN_DROPDOWN" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _ "-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _ "-->Code:" & @TAB & $iCode) ; no return value Case $CBN_EDITCHANGE ; Sent after the user has taken an action that may have altered the text in the edit control portion of a combo box _DebugPrint("$CBN_EDITCHANGE" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _ "-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _ "-->Code:" & @TAB & $iCode) _Edit_Changed() ; no return value Case $CBN_EDITUPDATE ; Sent when the edit control portion of a combo box is about to display altered text _DebugPrint("$CBN_EDITUPDATE" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _ "-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _ "-->Code:" & @TAB & $iCode) ; no return value Case $CBN_ERRSPACE ; Sent when a combo box cannot allocate enough memory to meet a specific request _DebugPrint("$CBN_ERRSPACE" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _ "-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _ "-->Code:" & @TAB & $iCode) ; no return value Case $CBN_KILLFOCUS ; Sent when a combo box loses the keyboard focus _DebugPrint("$CBN_KILLFOCUS" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _ "-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _ "-->Code:" & @TAB & $iCode) ; no return value Case $CBN_SELCHANGE ; Sent when the user changes the current selection in the list box of a combo box _DebugPrint("$CBN_SELCHANGE" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _ "-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _ "-->Code:" & @TAB & $iCode) ; no return value Case $CBN_SELENDCANCEL ; Sent when the user selects an item, but then selects another control or closes the dialog box _DebugPrint("$CBN_SELENDCANCEL" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _ "-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _ "-->Code:" & @TAB & $iCode) ; no return value Case $CBN_SELENDOK ; Sent when the user selects a list item, or selects an item and then closes the list _DebugPrint("$CBN_SELENDOK" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _ "-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _ "-->Code:" & @TAB & $iCode) ; no return value Case $CBN_SETFOCUS ; Sent when a combo box receives the keyboard focus _DebugPrint("$CBN_SETFOCUS" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _ "-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _ "-->Code:" & @TAB & $iCode) ; no return value EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_COMMAND Func _DebugPrint($s_Text, $sLine = @ScriptLineNumber) ConsoleWrite( _ "!===========================================================" & @CRLF & _ "+======================================================" & @CRLF & _ "-->Line(" & StringFormat("%04d", $sLine) & "):" & @TAB & $s_Text & @CRLF & _ "+======================================================" & @CRLF) EndFunc ;==>_DebugPrint auto_complete combobox.au3 Edited November 5, 2018 by wolflake
Moderators Melba23 Posted November 5, 2018 Moderators Posted November 5, 2018 wolflake, You are calling GUIGetMsg twice in your idle loop - once to check for the Accel keys and then again in the Do...Until structure you use to look for the closure [X]. Little wonder you miss the odd event! Replace the Do...Until with a While...WEnd and add a Case $GUI_EVENT_CLOSE case in the Switch structure and all should work correctly. And you can remove the Sleep too - GUIGetMsg has a built-in pause to keep the CPU from frying. M23 wolflake and FrancescoDiMuro 2 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
wolflake Posted November 5, 2018 Author Posted November 5, 2018 Melba23, Great answer! I started with code in the Example but I shouldn't have taken it so literally with the Do Until. It works perfectly with your changes. I learned something today. Thank you!
odaylton Posted February 21, 2019 Posted February 21, 2019 On 05/11/2018 at 5:32 PM, Melba23 said: wolflake, You are calling GUIGetMsg twice in your idle loop - once to check for the Accel keys and then again in the Do...Until structure you use to look for the closure [X]. Little wonder you miss the odd event! Replace the Do...Until with a While...WEnd and add a Case $GUI_EVENT_CLOSE case in the Switch structure and all should work correctly. And you can remove the Sleep too - GUIGetMsg has a built-in pause to keep the CPU from frying. M23 Hello I love using combobox in my applications and I have been using this subtle modification for a long time so that Dropper opens by typing something. most recently I had an unpleasant surprise to press the [ESC] key for 2x in the first one it collects the Dropper (which would be expected) but when pressing again [ESC] the program simply closes It must be something so stupid I'm not noticing. expandcollapse popup;� ;nunca Apagar #Region para $EditDebug #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #EndRegion para $EditDebug #include <GuiComboBox.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> Global $g_idCombo Example() Func Example() ; Create GUI GUICreate("ComboBox Auto Complete", 600, 600) $g_idCombo = GUICtrlCreateCombo("", 2, 2, 396, 296) Global $EditDebug = GUICtrlCreateEdit("debug", 2, 600 - 150 - 4, _ 600 - 4, 150, _ $ES_AUTOVSCROLL + $WS_VSCROLL) GUISetState(@SW_SHOW) ; Add files _GUICtrlComboBox_BeginUpdate($g_idCombo) _GUICtrlComboBox_AddDir($g_idCombo, @WindowsDir & "\*.exe") _GUICtrlComboBox_EndUpdate($g_idCombo) GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") ; Loop until the user exits. While 1 $idMsg = GUIGetMsg() Select Case $idMsg = $GUI_EVENT_CLOSE MsgBox($MB_SYSTEMMODAL, "", "Dialog was closed") ExitLoop EndSelect WEnd ;~ Do ;~ Until GUIGetMsg() = $GUI_EVENT_CLOSE GUIDelete() EndFunc ;==>Example Func _Edit_Changed() If Not __GUICtrlComboBox_IsPressed('08') And Not __GUICtrlComboBox_IsPressed("2E") Then ;backspace pressed or Del ;==>> my update: _GUICtrlComboBox_ShowDropDown($g_idCombo, True) ;<<=== EndIf _GUICtrlComboBox_AutoComplete($g_idCombo) EndFunc ;==>_Edit_Changed Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg Local $hWndFrom, $iIDFrom, $iCode, $hWndCombo If Not IsHWnd($g_idCombo) Then $hWndCombo = GUICtrlGetHandle($g_idCombo) $hWndFrom = $lParam $iIDFrom = BitAND($wParam, 0xFFFF) ; Low Word $iCode = BitShift($wParam, 16) ; Hi Word Switch $hWndFrom Case $g_idCombo, $hWndCombo Switch $iCode Case $CBN_CLOSEUP ; Sent when the list box of a combo box has been closed _DebugPrint("$CBN_CLOSEUP" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _ "-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _ "-->Code:" & @TAB & $iCode) ; no return value Case $CBN_DBLCLK ; Sent when the user double-clicks a string in the list box of a combo box _DebugPrint("$CBN_DBLCLK" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _ "-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _ "-->Code:" & @TAB & $iCode) ; no return value Case $CBN_DROPDOWN ; Sent when the list box of a combo box is about to be made visible _DebugPrint("$CBN_DROPDOWN" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _ "-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _ "-->Code:" & @TAB & $iCode) ; no return value Case $CBN_EDITCHANGE ; Sent after the user has taken an action that may have altered the text in the edit control portion of a combo box _DebugPrint("$CBN_EDITCHANGE" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _ "-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _ "-->Code:" & @TAB & $iCode) _Edit_Changed() ; no return value Case $CBN_EDITUPDATE ; Sent when the edit control portion of a combo box is about to display altered text _DebugPrint("$CBN_EDITUPDATE" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _ "-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _ "-->Code:" & @TAB & $iCode) ; no return value Case $CBN_ERRSPACE ; Sent when a combo box cannot allocate enough memory to meet a specific request _DebugPrint("$CBN_ERRSPACE" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _ "-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _ "-->Code:" & @TAB & $iCode) ; no return value Case $CBN_KILLFOCUS ; Sent when a combo box loses the keyboard focus _DebugPrint("$CBN_KILLFOCUS" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _ "-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _ "-->Code:" & @TAB & $iCode) ; no return value Case $CBN_SELCHANGE ; Sent when the user changes the current selection in the list box of a combo box _DebugPrint("$CBN_SELCHANGE" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _ "-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _ "-->Code:" & @TAB & $iCode) ; no return value Case $CBN_SELENDCANCEL ; Sent when the user selects an item, but then selects another control or closes the dialog box _DebugPrint("$CBN_SELENDCANCEL" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _ "-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _ "-->Code:" & @TAB & $iCode) ; no return value Case $CBN_SELENDOK ; Sent when the user selects a list item, or selects an item and then closes the list _DebugPrint("$CBN_SELENDOK" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _ "-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _ "-->Code:" & @TAB & $iCode) ; no return value Case $CBN_SETFOCUS ; Sent when a combo box receives the keyboard focus _DebugPrint("$CBN_SETFOCUS" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _ "-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _ "-->Code:" & @TAB & $iCode) ; no return value EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_COMMAND #Region Meu DebugPrint ;incerir esta linha apos a criação fo formulario com 600x600 de tamanho ;Define caixa de texto para o Debug ; Global $EditDebug = GUICtrlCreateEdit("debug", 2, 600 - 150 - 4, _ ;X,Y ; 600 - 4, 150, _ ;Altura, Largura ; $ES_AUTOVSCROLL + $WS_VSCROLL) Func _DebugPrint($s_Text, $sLine = @ScriptLineNumber) If IsDeclared("EditDebug") Then GUICtrlSetData($EditDebug, _ "Dados da Linha[" & $sLine & "]" & @CRLF & _ "+======================================================" & @CRLF & _ "-->Line(" & StringFormat("%04d", $sLine) & "):" & @TAB & $s_Text & @CRLF & _ "+======================================================" & @CRLF, 1) Else ;se não for possivel encontrar o EditBox então mostrar com msgbox e no console MsgBox(0, "Dados da Linha[" & $sLine & "]", _ "+======================================================" & @CRLF & _ "-->Line(" & StringFormat("%04d", $sLine) & "):" & @TAB & $s_Text & @CRLF & _ "+======================================================") EndIf _DebugPrintConsole($s_Text, $sLine ) EndFunc ;==>_DebugPrint Func _DebugPrintConsole($s_Text, $sLine = @ScriptLineNumber) ConsoleWrite( _ "!===========================================================" & @CRLF & _ "+======================================================" & @CRLF & _ "-->Line(" & StringFormat("%04d", $sLine) & "):" & @TAB & $s_Text & @CRLF & _ "+======================================================" & @CRLF) EndFunc ;==>_DebugPrintConsole #EndRegion Meu DebugPrint PS follows an improvement of AutoComplete => AutoComplete2 Func _GUICtrlComboBox_AutoComplete2($hWnd) If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd) If Not __GUICtrlComboBox_IsPressed('08') And Not __GUICtrlComboBox_IsPressed("2E") Then ;backspace pressed or Del Local $sEditText = _GUICtrlComboBox_GetEditText($hWnd) ;==>> my update: _GUICtrlComboBox_ShowDropDown($hWnd, True) ;<<=== If StringLen($sEditText) Then Local $sInputText Local $ret = _GUICtrlComboBox_FindString($hWnd, $sEditText) If ($ret <> $CB_ERR) Then _GUICtrlComboBox_GetLBText($hWnd, $ret, $sInputText) _GUICtrlComboBox_SetEditText($hWnd, $sInputText) _GUICtrlComboBox_SetEditSel($hWnd, StringLen($sEditText), StringLen($sInputText)) EndIf EndIf EndIf EndFunc ;==>_GUICtrlComboBox_AutoComplete2
dmob Posted February 21, 2019 Posted February 21, 2019 55 minutes ago, odaylton said: but when pressing again [ESC] the program simply closes Opt("GUICloseOnESC", 0)
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