Jump to content
Sign in to follow this  
Angel

ComboBox OnChange Event not triggered after typing

Recommended Posts

Angel

Hi,

I tried to find an answer to this problem on the forums but I did not find it. Hopefully this is not a duplicate of a previous post.

I have an editable combo box in a GUI (i.e. you can both type on the combobox or select one item on the list). I used GUISetOnEvent to trigger a function whenever the combo changes. However, the function only seems to be triggered when I select an element from the list. When I simply type something on the combo editbox the event handler function does not execute.

Is there a way to get around this problem?

Thanks,

Angel

Share this post


Link to post
Share on other sites
GaryFrost

#include <GuiConstants.au3>

Global Const $WM_COMMAND = 0x0111
Global Const $CBN_EDITCHANGE = 5;
Global Const $CBN_SELCHANGE = 1;
Global Const $CBN_EDITUPDATE = 6;
Global Const $DebugIt = 1

GUICreate("My GUI combo")  ; will create a dialog box that when displayed is centered

$combo = GUICtrlCreateCombo("item1", 10, 10) ; create first item
GUICtrlSetData(-1, "item2|item3", "item3") ; add other item snd set a new default
$btn = GUICtrlCreateButton("Ok", 40, 75, 60, 20)

GUISetState()
GUIRegisterMsg($WM_COMMAND, "MY_WM_COMMAND")

$msg = 0
While $msg <> $GUI_EVENT_CLOSE
    $msg = GUIGetMsg()
    Select
        Case $msg = $btn
            ExitLoop
    EndSelect
WEnd

Func _Combo_Changed()
    ;----------------------------------------------------------------------------------------------
    If $DebugIt Then _DebugPrint("Combo Changed:" & GUICtrlRead($combo))
    ;----------------------------------------------------------------------------------------------
EndFunc   ;==>_Combo_Changed

Func MY_WM_COMMAND($hWnd, $msg, $wParam, $lParam)
    Local $nNotifyCode = _HiWord($wParam)
    Local $nID = _LoWord($wParam)
    Local $hCtrl = $lParam
    
    Switch $nID
        Case $combo
            Switch $nNotifyCode
                Case $CBN_EDITUPDATE, $CBN_EDITCHANGE ; when user types in new data
                    _Combo_Changed()
                Case $CBN_SELCHANGE ; item from drop down selected
                    _Combo_Changed()
            EndSwitch
    EndSwitch
    ; Proceed the default Autoit3 internal message commands.
    ; You also can complete let the line out.
    ; !!! But only 'Return' (without any value) will not proceed
    ; the default Autoit3-message in the future !!!
    Return $GUI_RUNDEFMSG
EndFunc   ;==>MY_WM_COMMAND

Func _DebugPrint($s_Text, $line = @ScriptLineNumber)
    ConsoleWrite( _
            "!===========================================================" & @LF & _
            "+======================================================" & @LF & _
            "-->Line(" & StringFormat("%04d", $line) & "):" & @TAB & $s_Text & @LF & _
            "+======================================================" & @LF)
EndFunc   ;==>_DebugPrint



Func _HiWord($x)
    Return BitShift($x, 16)
EndFunc   ;==>_HiWord

Func _LoWord($x)
    Return BitAND($x, 0xFFFF)
EndFunc   ;==>_LoWord


SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Share this post


Link to post
Share on other sites
Angel

gafrost,

thanks a lot for the reply. I have a question though:

In the example you do not use the event mode. Is that a requirement for this to work? The combo box with which I am having problems is part of a pretty big GUI that I already made and which uses the Event mode. It would be quite difficult to change it all to a message loop type of GUI.

So would this work in the on event mode too? Perhaps you could explain a bit more how this works?

Thanks!

Angel

Share this post


Link to post
Share on other sites
GaryFrost

#include <GuiConstants.au3>

Opt("GUIOnEventMode", 1)
Global Const $WM_COMMAND = 0x0111
Global Const $CBN_EDITCHANGE = 5;
Global Const $CBN_SELCHANGE = 1;
Global Const $CBN_EDITUPDATE = 6;
Global Const $DebugIt = 1

GUICreate("My GUI combo")  ; will create a dialog box that when displayed is centered

$combo = GUICtrlCreateCombo("item1", 10, 10) ; create first item
GUISetOnEvent($GUI_EVENT_CLOSE, "_Terminate")
GUICtrlSetData(-1, "item2|item3", "item3") ; add other item snd set a new default
$btn = GUICtrlCreateButton("Ok", 40, 75, 60, 20)
GUICtrlSetOnEvent(-1, "OKPressed")

GUISetState()
GUIRegisterMsg($WM_COMMAND, "MY_WM_COMMAND")

; Just idle around
While 1
    Sleep(10)
WEnd

Func OKPressed()
    MsgBox(0, "OK Pressed", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle & " CtrlHandle=" & @GUI_CtrlHandle)
EndFunc   ;==>OKPressed

Func _Terminate()
    Exit
EndFunc   ;==>_Terminate

Func _Combo_Changed()
    ;----------------------------------------------------------------------------------------------
    If $DebugIt Then _DebugPrint("Combo Changed:" & GUICtrlRead($combo))
    ;----------------------------------------------------------------------------------------------
EndFunc   ;==>_Combo_Changed

Func MY_WM_COMMAND($hWnd, $msg, $wParam, $lParam)
    Local $nNotifyCode = _HiWord($wParam)
    Local $nID = _LoWord($wParam)
    Local $hCtrl = $lParam

    Switch $nID
        Case $combo
            Switch $nNotifyCode
                Case $CBN_EDITUPDATE, $CBN_EDITCHANGE ; when user types in new data
                    _Combo_Changed()
                Case $CBN_SELCHANGE ; item from drop down selected
                    _Combo_Changed()
            EndSwitch
    EndSwitch
    ; Proceed the default Autoit3 internal message commands.
    ; You also can complete let the line out.
    ; !!! But only 'Return' (without any value) will not proceed
    ; the default Autoit3-message in the future !!!
    Return $GUI_RUNDEFMSG
EndFunc   ;==>MY_WM_COMMAND

Func _DebugPrint($s_Text, $line = @ScriptLineNumber)
    ConsoleWrite( _
            "!===========================================================" & @LF & _
            "+======================================================" & @LF & _
            "-->Line(" & StringFormat("%04d", $line) & "):" & @TAB & $s_Text & @LF & _
            "+======================================================" & @LF)
EndFunc   ;==>_DebugPrint



Func _HiWord($x)
    Return BitShift($x, 16)
EndFunc   ;==>_HiWord

Func _LoWord($x)
    Return BitAND($x, 0xFFFF)
EndFunc   ;==>_LoWord


SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Share this post


Link to post
Share on other sites
Angel

Awesome! Thanks a lot gafrost...

Is there any way to only trigger the function (or at least recognize) when the combo loses its focus or when the user types ENTER?

Also, what is the difference between $CBN_EDITUPDATE and $CBN_EDITCHANGE? I tried enabling or disabling each of those but it did not make any difference...

Angel

Edited by Angel

Share this post


Link to post
Share on other sites
GaryFrost

http://msdn2.microsoft.com/en-us/library/bb507832.aspx

#include <GuiConstants.au3>

Opt("GUIOnEventMode", 1)
Global Const $WM_COMMAND = 0x0111
Global Const $CBN_EDITCHANGE = 5
Global Const $CBN_SELCHANGE = 1
Global Const $CBN_EDITUPDATE = 6
Global Const $CBN_KILLFOCUS = 4
Global Const $CBN_SETFOCUS = 3

Global Const $DebugIt = 1

GUICreate("My GUI combo")  ; will create a dialog box that when displayed is centered

$combo = GUICtrlCreateCombo("item1", 10, 10) ; create first item
GUISetOnEvent($GUI_EVENT_CLOSE, "_Terminate")
GUICtrlSetData(-1, "item2|item3", "item3") ; add other item snd set a new default
$btn = GUICtrlCreateButton("Ok", 40, 75, 60, 20)
GUICtrlSetOnEvent(-1, "OKPressed")

GUISetState()
GUIRegisterMsg($WM_COMMAND, "MY_WM_COMMAND")

; Just idle around
While 1
    Sleep(10)
WEnd

Func OKPressed()
    MsgBox(0, "OK Pressed", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle & " CtrlHandle=" & @GUI_CtrlHandle)
EndFunc   ;==>OKPressed

Func _Terminate()
    Exit
EndFunc   ;==>_Terminate

Func _Combo_GotFocus()
    ;----------------------------------------------------------------------------------------------
    If $DebugIt Then _DebugPrint("_Combo_GotFocus")
    ;----------------------------------------------------------------------------------------------
EndFunc   ;==>_Combo_GotFocus

Func _Combo_LostFocus()
    ;----------------------------------------------------------------------------------------------
    If $DebugIt Then _DebugPrint("_Combo_LostFocus")
    ;----------------------------------------------------------------------------------------------
EndFunc   ;==>_Combo_LostFocus

Func _Combo_Changed()
    ;----------------------------------------------------------------------------------------------
    If $DebugIt Then _DebugPrint("Combo Changed:" & GUICtrlRead($combo))
    ;----------------------------------------------------------------------------------------------
EndFunc   ;==>_Combo_Changed

Func MY_WM_COMMAND($hWnd, $msg, $wParam, $lParam)
    Local $nNotifyCode = _HiWord($wParam)
    Local $nID = _LoWord($wParam)
    Local $hCtrl = $lParam

    Switch $nID
        Case $combo
            Switch $nNotifyCode
                Case $CBN_EDITUPDATE, $CBN_EDITCHANGE ; when user types in new data
                    _Combo_Changed()
                Case $CBN_SELCHANGE ; item from drop down selected
                    _Combo_Changed()
                Case $CBN_KILLFOCUS
                    _Combo_LostFocus()
                Case $CBN_SETFOCUS
                    _Combo_GotFocus()
            EndSwitch
    EndSwitch
    ; Proceed the default Autoit3 internal message commands.
    ; You also can complete let the line out.
    ; !!! But only 'Return' (without any value) will not proceed
    ; the default Autoit3-message in the future !!!
    Return $GUI_RUNDEFMSG
EndFunc   ;==>MY_WM_COMMAND

Func _DebugPrint($s_Text, $line = @ScriptLineNumber)
    ConsoleWrite( _
            "!===========================================================" & @LF & _
            "+======================================================" & @LF & _
            "-->Line(" & StringFormat("%04d", $line) & "):" & @TAB & $s_Text & @LF & _
            "+======================================================" & @LF)
EndFunc   ;==>_DebugPrint

Func _HiWord($x)
    Return BitShift($x, 16)
EndFunc   ;==>_HiWord

Func _LoWord($x)
    Return BitAND($x, 0xFFFF)
EndFunc   ;==>_LoWord

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Share this post


Link to post
Share on other sites
Angel

Thanks again gafrost,

actually I just found that MSDN message on my own and fond about the KILLFOCUS message.

This is an extremely powerful technique! It is very flexible and basically it gives you access to the full power of the Windows GUI API in AutoIt. Thanks _a lot_ for sharing this with me :-))))

Actually, I think that this merits some sort of section on the AutoIt manual. It is really really useful. And all the windows GUI constants should be also included with AutoIt, in my opinion.

Thanks again!

Angel

Share this post


Link to post
Share on other sites
encode

I'm trying to do something similar, except to detect focus on an input field (created with GUICtrlCreateInput) while in Event mode.

I took a look at the MSDN link, but I can't see any mention of input fields - any ideas as to how I can do this?

Thanks.

Share this post


Link to post
Share on other sites
GaryFrost

I'm trying to do something similar, except to detect focus on an input field (created with GUICtrlCreateInput) while in Event mode.

I took a look at the MSDN link, but I can't see any mention of input fields - any ideas as to how I can do this?

Thanks.

An Input control is just a trimmed down edit control I believe, if you look at the section for edit controls you'll see where I got the information from.


SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Share this post


Link to post
Share on other sites
encode

An Input control is just a trimmed down edit control I believe, if you look at the section for edit controls you'll see where I got the information from.

Thanks for such a quick response.

I did some more experimenting with the relevant section of code taken from your example, and discovered that it works fine for input fields also. The only difference was the values for $nNotifyCode - 256 and 512 instead of 3 and 4, for getting and losing focus respectively.

Share this post


Link to post
Share on other sites
CleM71

Hi everybody,

I try to work with the "onchange" event on a Combobox

Theses examples are very usefull to work with a Combo that has been created by a simple GuiCtrlCreateCombo

How can I do the same thing with a extended Combo created by _GUICtrlComboEx_Create()

I tried these iCode :

# CBEN_BEGINEDIT

# CBEN_DELETEITEM

# CBEN_DRAGBEGIN

# CBEN_ENDEDIT

# CBEN_GETDISPINFO

# CBEN_INSERTITEM

No one seems to correspond to the onchange behaviour I'm looking for.

Can someone help me ?

Thank you so much from France !

Share this post


Link to post
Share on other sites
CleM71

Hi everybody,

I try to work with the "onchange" event on a Combobox

Theses examples are very usefull to work with a Combo that has been created by a simple GuiCtrlCreateCombo

How can I do the same thing with a extended Combo created by _GUICtrlComboEx_Create()

I tried these iCode :

# CBEN_BEGINEDIT

# CBEN_DELETEITEM

# CBEN_DRAGBEGIN

# CBEN_ENDEDIT

# CBEN_GETDISPINFO

# CBEN_INSERTITEM

No one seems to correspond to the onchange behaviour I'm looking for.

Can someone help me ?

Thank you so much from France !

No one can help me ? :-(

Share this post


Link to post
Share on other sites
MrCreatoR

How can I do the same thing with a extended Combo created by _GUICtrlComboEx_Create()

#include <GuiConstantsEx.au3>
#include <GuiComboBox.au3>

Opt("GUIOnEventMode", 1)

Global $ComboBox_Changed = False
Global Const $DebugIt = 1

Global Const $WM_COMMAND = 0x0111

$hGUI = GUICreate("My GUI combo")  ; Will create a dialog box that when displayed is centered
GUISetOnEvent($GUI_EVENT_CLOSE, "_Terminate")

$hCombo = _GUICtrlComboBox_Create($hGUI, "item1|item2|item3", 10, 10) ; Create Combo items

; Set a default item
_GUICtrlComboBox_SelectString ($hCombo, "item2")

$btn = GUICtrlCreateButton("Ok", 40, 75, 60, 20)
GUICtrlSetOnEvent(-1, "OKPressed")

GUISetState()
GUIRegisterMsg($WM_COMMAND, "MY_WM_COMMAND")

; Just idle around
While 1
    Sleep(10)
    
    If $ComboBox_Changed Then
        $ComboBox_Changed = False
        
        _Combo_Changed()
    EndIf
WEnd

Func OKPressed()
    MsgBox(0, "OK Pressed", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle & " CtrlHandle=" & @GUI_CtrlHandle)
EndFunc   ;==>OKPressed

Func _Terminate()
    Exit
EndFunc   ;==>_Terminate

Func _Combo_GotFocus()
    ;----------------------------------------------------------------------------------------------
    If $DebugIt Then _DebugPrint("_Combo_GotFocus")
    ;----------------------------------------------------------------------------------------------
EndFunc   ;==>_Combo_GotFocus

Func _Combo_LostFocus()
    ;----------------------------------------------------------------------------------------------
    If $DebugIt Then _DebugPrint("_Combo_LostFocus")
    ;----------------------------------------------------------------------------------------------
EndFunc   ;==>_Combo_LostFocus

Func _Combo_Changed()
    ;----------------------------------------------------------------------------------------------
    If $DebugIt Then _DebugPrint("Combo Changed: " & _GUICtrlComboBox_GetEditText ($hCombo))
    ;----------------------------------------------------------------------------------------------
EndFunc   ;==>_Combo_Changed

Func MY_WM_COMMAND($hWnd, $msg, $wParam, $lParam)
    Local $nNotifyCode = _HiWord($wParam)
    Local $hID = _LoWord($wParam)
    Local $hCtrl = $lParam

    Switch $hCtrl
        Case $hCombo
            Switch $nNotifyCode
                Case $CBN_EDITUPDATE, $CBN_EDITCHANGE ; when user types in new data
                    ; _Combo_Changed()
                    $ComboBox_Changed = True
                Case $CBN_SELCHANGE ; item from drop down selected
                    ;_Combo_Changed()
                    $ComboBox_Changed = True
                Case $CBN_KILLFOCUS
                    _Combo_LostFocus()
                Case $CBN_SETFOCUS
                    _Combo_GotFocus()
            EndSwitch
    EndSwitch
    ; Proceed the default Autoit3 internal message commands.
    ; You also can complete let the line out.
    ; !!! But only 'Return' (without any value) will not proceed
    ; the default Autoit3-message in the future !!!
    Return $GUI_RUNDEFMSG
EndFunc   ;==>MY_WM_COMMAND

Func _DebugPrint($s_Text, $line = @ScriptLineNumber)
    ConsoleWrite( _
            "!===========================================================" & @LF & _
            "+======================================================" & @LF & _
            "-->Line(" & StringFormat("%04d", $line) & "):" & @TAB & $s_Text & @LF & _
            "+======================================================" & @LF)
EndFunc   ;==>_DebugPrint

Func _HiWord($x)
    Return BitShift($x, 16)
EndFunc   ;==>_HiWord

Func _LoWord($x)
    Return BitAND($x, 0xFFFF)
EndFunc   ;==>_LoWord

I used here the main loop, because for some reason when i call directly the function from MY_WM_COMMAND it print the last item, not the current one.


 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize Program

AutoIt_Icon_small.pngUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF
 
AutoIt_Icon_small.pngExamples: 
ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo

Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Share this post


Link to post
Share on other sites
CleM71

Thank you so much, it works !

I had the same problem you've got before

Using this loop, it runs perfectly

Good idea to use a boolean

Thanks again :)

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×