Jump to content

A strange problem in combo box.


Recommended Posts

Hi all,

I am playing with a combo box. The code from help file is working. But the code i wrote is not working. Help file uses "_GUICtrlComboBox_Create" for creating combo box. But i used native "GUICtrlCreateCombo". Then i replaced my native combo creation function with the UDF. Then my code worked. I think the hi word and low word parameters are the problem. 

Here is my code.

#include <ComboConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
Local $sCMB_Items = "Apple|Orange|Mango|Banana|Grape"
#Region ### START Koda GUI section ### Form=
Global $hForm1 = GUICreate("Form1", 283, 188, 312, 166)
Global $hCombo1 = GUICtrlCreateCombo("", 40, 48, 185, 25, BitOR($CBS_DROPDOWN,$CBS_AUTOHSCROLL))
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###
GUICtrlSetData($hCombo1, $sCMB_Items)
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit

    EndSwitch
WEnd

Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg
    Local $hWndFrom, $iIDFrom, $iCode
    $hWndFrom = $lParam
    $iIDFrom = BitAND($wParam, 0xFFFF) ; Low Word
    $iCode = BitShift($wParam, 16) ; Hi Word
    Switch $hWndFrom
        Case $hCombo1
            Switch $iCode
                Case $CBN_DBLCLK
                    ; Insert your code here
                    MsgBox(0,"","$CBN_DBLCLK")
                Case $CBN_DROPDOWN
                    ; Insert your code here
                    MsgBox(0,"","$CBN_DROPDOWN")
                Case $CBN_EDITCHANGE
                    ; Insert your code here
                    MsgBox(0,"","$CBN_EDITCHANGE")
                Case $CBN_SELCHANGE
                    ; Insert your code here
                    MsgBox(0,"","$CBN_SELCHANGE")

            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

And this is the code from help file. Slightly modified. But working

#include <GuiComboBox.au3>
#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <WindowsConstants.au3>

Global $g_hCombo

Example()

Func Example()
    Local $hGUI

    ; Create GUI
    $hGUI = GUICreate("(UDF) ComboBox Create", 400, 296)
    $g_hCombo = _GUICtrlComboBox_Create($hGUI, "", 2, 2, 396, 296)
    GUISetState(@SW_SHOW)

    ; Add files
    _GUICtrlComboBox_BeginUpdate($g_hCombo)
    _GUICtrlComboBox_AddDir($g_hCombo, "", $DDL_DRIVES, False)
    _GUICtrlComboBox_EndUpdate($g_hCombo)

    GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")

    ; Loop until the user exits.
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
    GUIDelete()
EndFunc   ;==>Example

Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg
    Local $hWndFrom, $iIDFrom, $iCode
    $hWndFrom = $lParam
    $iIDFrom = BitAND($wParam, 0xFFFF) ; Low Word
    $iCode = BitShift($wParam, 16) ; Hi Word
    Switch $hWndFrom
        Case $g_hCombo
            Switch $iCode
                Case $CBN_CLOSEUP ; Sent when the list box of a combo box has been closed
                    MsgBox(0,"","$CBN_CLOSEUP")
                Case $CBN_DBLCLK ; Sent when the user double-clicks a string in the list box of a combo box
                    MsgBox(0,"","$CBN_DBLCLK")
                Case $CBN_DROPDOWN ; Sent when the list box of a combo box is about to be made visible
                    MsgBox(0,"","$CBN_DROPDOWN")
                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
                    MsgBox(0,"","$CBN_EDITCHANGE")
                Case $CBN_EDITUPDATE ; Sent when the edit control portion of a combo box is about to display altered text

                Case $CBN_ERRSPACE ; Sent when a combo box cannot allocate enough memory to meet a specific request

                Case $CBN_KILLFOCUS ; Sent when a combo box loses the keyboard focus

                Case $CBN_SELCHANGE ; Sent when the user changes the current selection in the list box of a combo box
                    MsgBox(0,"","$CBN_SELCHANGE")

            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

For those who wants the au3 file;

Here it is

 

Code From help file.au3

My code.au3

My Contributions

UDF Link Viewer   --- A tool to visit the links of some most important UDFs 

 Includer_2  ----- A tool to type the #include statement automatically 

 Digits To Date  ----- date from 3 integer values

PrintList ----- prints arrays into console for testing.

 Alert  ------ An alternative for MsgBox 

 MousePosition ------- A simple tooltip display of mouse position

GRM Helper -------- A littile tool to help writing code with GUIRegisterMsg function

Access_UDF  -------- An UDF for working with access database files. (.*accdb only)

 

Link to post
Share on other sites
  • Moderators

kcvinu,

When you create a control using a native GUICtrlCreate* function, the return value is a ControlID - an integer value. AutoIt uses this ControlID to identify the control - it is in fact the index of the internal array that AutoIt uses to track native control. When you create a control using a UDF, the return is a handle -  a special unique value used by Windows to track virtually everything in the system.

In your first script above you are using the native command - so the $hCombo1 variable holds a ControlID (and should really be named $idCombo1 or $cCombo1). However, in the message handler you are looking for the handle:

$hWndFrom = $lParam

$iIDFrom = BitAND($wParam, 0xFFFF) ; Low Word
$iCode = BitShift($wParam, 16) ; Hi Word
Switch $hWndFrom

    Case $hCombo1

If you replace $hWndFrom with $iIDFrom, you will find that the code works as expected - because you are now checking the ControlID and not the handle. In the second script, you create the combo via the UDF and so get a handle returned - unsurprisingly this works as you are this time checking the handle directly. All clear?

And as always I would counsel against using blocking functions (such as MsgBox) inside a message handle you do in both scripts - the Help file specifically mentions this and it is a warning that should be heeded.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png 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 columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to post
Share on other sites

@Melba23 Yes. everything is now clear. Thank you for detailed replay. And that MsgBoxes. That is only for testing purpose. I can use console write instead. Once again thanks a lot. :)

My Contributions

UDF Link Viewer   --- A tool to visit the links of some most important UDFs 

 Includer_2  ----- A tool to type the #include statement automatically 

 Digits To Date  ----- date from 3 integer values

PrintList ----- prints arrays into console for testing.

 Alert  ------ An alternative for MsgBox 

 MousePosition ------- A simple tooltip display of mouse position

GRM Helper -------- A littile tool to help writing code with GUIRegisterMsg function

Access_UDF  -------- An UDF for working with access database files. (.*accdb only)

 

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
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By argumentum
      #AutoIt3Wrapper_AU3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #include "GuiChildTabUDF.au3" Global $__iFlashWindowEx = 0 ; ..see _WM_SETCURSOR() tabGUI_OPTs("RandomColor", 1) ; ..to add coloring to the GUIs, for debug. ( Default is 0 ) tabGUI_OPTs("SetCtrlDbgCreateWidth", 1) ; tells the UDF to leave some space for the debug buttons ( see tabGUI_CtrlDbgCreate() ). ( Default is 0 ) tabGUI_Example() Func tabGUI_Example() ; tabGUI_Create() has the same parameters as GUICreate() ; ..just skip the styles, as those are handled by the function. tabGUI_Create("Parent/Children Example") ; the first GUI will have to be the parent tabGUI_CtrlDbgCreate("Show GUI array") ; All these are tabGUI_CtrlDbgCreate("Show OPT array") ; for debug and tabGUI_CtrlDbgCreate("Swap GUIs/LABELs") ; are not needed tabGUI_CtrlDbgCreate("Can Drag child") ; to use the UDF tabGUI_CtrlDbgCreate("Self CPU usage") ; These are called after a GUI is present. ; search for "SetResizing:" to understand the TITLE modification ( used for tabGUI_DockStr2Int() ) tabGUI_Create("SetResizing:LBWH;1", 400, 400, 20, 20) ; all other GUI will be child addSomeControls() tabGUI_Create("2", 400, 400, 60, 60) addSomeControls() ; multiple child in child example ; ..skip the width and heigth, to have the function calculate the values. tabGUI_Create("3", Default, Default, 200, 230) tabGUI_Create("4", Default, Default, 20, 20, Default, Default, $__a_tabGUI[@extended][$eGui_HWindowSelf]) tabGUI_Create("5", Default, Default, 20, 20, Default, Default, $__a_tabGUI[@extended][$eGui_HWindowSelf]) Local $hGUI = tabGUI_Create("6", Default, Default, 20, 20, Default, Default, $__a_tabGUI[@extended][$eGui_HWindowSelf]) ; ..the function returns the windows handle, just like GUICreate() would. ConsoleWrite('$hGUI = ' & $hGUI & ' - @extended: ' & @extended & ' ( @extended returns the GUI index in the array )' & @CRLF) addSomeControls() GUISetState(@SW_SHOW, $__a_tabGUI[1][$eGui_HWindowSelf]) ; Time to show the parent GUI GUISwitch($__a_tabGUI[1][$eGui_HWindowSelf]) ; and get focus. GUIRegisterMsg($WM_SETCURSOR, "_WM_SETCURSOR") ; for _WinAPI_FlashWindowEx() While 1 Sleep(1000000) ; ..no need to sleep() a minimum in this loop, as is just there to not close the script in this example. WEnd EndFunc ;==>tabGUI_Example Func addSomeControls() ; ..some controls to add to the example GUICtrlCreateButton("bttn 1", 10, 10, 55, 25) GUICtrlSetOnEvent(-1, "addSomeEvents") GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKTOP + $GUI_DOCKWIDTH + $GUI_DOCKHEIGHT) GUICtrlCreateButton("bttn 2", 10, 35, 55, 25) GUICtrlSetOnEvent(-1, "addSomeEvents") GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKTOP + $GUI_DOCKWIDTH + $GUI_DOCKHEIGHT) GUICtrlCreateTab(10, 70, 380, 320) GUICtrlSetOnEvent(-1, "addSomeEvents") GUICtrlSetResizing(-1, $GUI_DOCKRIGHT + $GUI_DOCKTOP + $GUI_DOCKLEFT + $GUI_DOCKBOTTOM) GUICtrlCreateTabItem("TabSheet1") GUICtrlCreateTabItem("TabSheet2") GUICtrlCreateTabItem("") EndFunc ;==>addSomeControls Func addSomeEvents() ;~ $__iFlashWindowEx = TimerInit() MsgBox(0, "your ""OnEvent""", "@GUI_CtrlId = " & @GUI_CtrlId, 1, $__a_tabGUI[1][$eGui_HWindowSelf]) ;~ $__iFlashWindowEx = 0 EndFunc ;==>addSomeEvents Func _WM_SETCURSOR($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam ; FYI: this is meant to flash the Parent GUI of a MsgBox(), ; so the MsgBox() needs a Parent GUI declaration. ; If the 0xFFFE guess don't work, or just wanna save CPU cycles, then you'll need a trigger. ; Maybe something like this below. ;~ If $__iFlashWindowEx = 0 Then Return $GUI_RUNDEFMSG ;~ If TimerDiff($__iFlashWindowEx) < 100 Then Return $GUI_RUNDEFMSG Local Static $hTimerTooSoon = TimerInit(), $hTimerWaitAMoment = TimerInit() If _WinAPI_LoWord($lParam) <> 0xFFFE Then $hTimerWaitAMoment = TimerInit() Return $GUI_RUNDEFMSG EndIf If TimerDiff($hTimerWaitAMoment) < 200 Then Return $GUI_RUNDEFMSG If TimerDiff($hTimerTooSoon) < 500 Then Return $GUI_RUNDEFMSG Local $mouse = _WinAPI_HiWord($lParam) ; https://docs.microsoft.com/en-us/windows/win32/menurc/wm-setcursor ; https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-mousemove Local Const $MK_LBUTTON = 0x0001 Local Const $MK_RBUTTON = 0x0002 Local Const $MK_MBUTTON = 0x0010 Local Const $MK_XBUTTON1 = 0x0020 Local Const $MK_XBUTTON2 = 0x0040 ;~ If BitAND($mouse, $MK_LBUTTON) Then ConsoleWrite('- clicked MK_LBUTTON' & @CRLF) ;~ If BitAND($mouse, $MK_RBUTTON) Then ConsoleWrite('- clicked MK_RBUTTON' & @CRLF) ;~ If BitAND($mouse, $MK_MBUTTON) Then ConsoleWrite('- clicked MK_MBUTTON' & @CRLF) ;~ If BitAND($mouse, $MK_XBUTTON1) Then ConsoleWrite('- clicked MK_XBUTTON1' & @CRLF) ;~ If BitAND($mouse, $MK_XBUTTON2) Then ConsoleWrite('- clicked MK_XBUTTON2' & @CRLF) If BitAND($mouse, $MK_LBUTTON) Or BitAND($mouse, $MK_RBUTTON) Or _ BitAND($mouse, $MK_MBUTTON) Or BitAND($mouse, $MK_XBUTTON1) Or _ BitAND($mouse, $MK_XBUTTON2) Then $hTimerTooSoon = TimerInit() _WinAPI_MessageBeep(4) ; mimic what windows does by default when _WinAPI_FlashWindowEx($hWnd, 3, 6, 50) ; clicking the title. _WinAPI_FlashWindowEx(WinGetHandle("[CLASS:#32770;]"), 3, 6, 50) ; ..this works on the MsgBox() because is the "on top" in the Z order ; as the code just created it ( and it *is* on top ). EndIf Return $GUI_RUNDEFMSG EndFunc ;==>_WM_SETCURSOR This is a post of example(s).
      The code started due to the observation that controls don't look the same when in a tab control.
      Digging thru the forum I found chunks of code so I smash them together to solve my issues.
      The "UDF" is more of an useful include than an UDF, but it shows how to use Child GUIs instead of a TAB control.
      In each child GUI you can have a GUICtrlCreateTab(). ( something that I did not realize until I browse the Wiki )
      Working on the code I found myself having to GUIRegisterMsg(). Then why not register more and do more.
      Took me about a month to discover how to put it together. Then I'm like "this would make a good example".
      So try it out, use what you need ( or as is ). Hopefully it'll save you the learning curve. The code is in the downloads section.
      ( I'm a copy and paste kind of coder, so racking my brain is not my forte. But at times, is what it takes to get working code )
      PS: if you find a better way to do something or a gross misinterpretation in the code, do share. ( so I can copy and paste )
    • By Fenzik
      Hello,
      i searched the forum for something near, but with no success...
      I have Combobox control with $CBS_DROPDOWNLIST style with some items (for example (one, two, nine).
      When i want to select the item, using keyboard, the items are selected only on First letter base (for example when i type "on", Nine is selected).
      Is there some trick to force the combobox with $CBS_DROPDOWNLIST style to accept more than the First letter during selecting the items from the list?
      Mi wanted result is the same as for example - when you type "fir" on the desktop, Firefox is automatically selected.
      Thank you so much.
      Fenzik
    • By TheAutomator
      I'm working on a script that needs to work with a huge database inside a combobox.
      I'm looking for the best way to link a multidimensional array to that data to load that data on to textfields.

      example:
      combo item 0 = "A", data = [index linked to combo item 0] [1,0,5,4,87,9,"xyz"]
      combo item 1 = "B", data = [index linked to combo item 1] [1,6,5,4,87,9,"zzz"]
      combo item 3 = "A", data = [index linked to combo item 3] [1,6,4,4,87,9,"aaa"] ; yes also double items!
      Would also like to be able to delete and add items on the fly btw..
      Local $INDEX[0][10] ; ubound wil be resized like a stack while loading from a textfile ;inside gui: local $Combo = GUICtrlCreateCombo('...', 10, 10, 290, 25) ;gui loop: While True Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $Combo display() ; how do i link my array index to the combo labels to know what to show in the textfields? ; NOTE: (there are duplicate items in the combobox!) EndSwitch WEnd Any toughs are welcome.
      I was thinking about using _GUICtrlComboBox_GetCurSel($Combo) and use that integer to refer to the index (dimension 1) of the array 
      Thanks, TheAutomator
       
    • By Skysnake
      I have read the Tutorial. Used the Help File and used an example script by @Melba23.  I am still struggling.
      To use GUIRegisterMsg one needs the following
      a control in the GUI a GUIRegisterMsg instruction in the GUI to link the control to the WM_COMMAND function a Case statement in the Switch loop to run it a WM_COMMAND function and a processor function... Mine looks like this
      ;~ ; QuickSearch combo box $g_cbQwkSrch = GUICtrlCreateCombo("", 8, 26, 180, 17) ; start blank GUICtrlSetTip($g_cbQwkSrch, "Type to search", "QuickSearch") GUIRegisterMsg($WM_COMMAND, "__WM_COMMAND_QWKSEARCH_CMB") ;------------------------------------ ; use in Switch Loop ;~ ; QuickSearch Case $g_cbQwkSrch ConsoleWrite("221 Case $g_cbQwkSrch" & @CRLF) ;-------------------------------------- Func _QwkSrch_Edit_Changed() ConsoleWrite("41 _QwkSrch_Edit_Changed" & @CRLF) ; Autocomplete the edit _GUICtrlComboBox_AutoComplete($g_cbQwkSrch) ; Change the label to match the autocompleted edit entry EndFunc ;==>_QwkSrch_Edit_Changed Func __WM_COMMAND_QWKSEARCH_CMB($hWnd, $iMsg, $wParam, $lParam) ; GUIRegisterMsg($WM_COMMAND, "__WM_COMMAND_QWKSEARCH_CMB") ConsoleWrite("50 _WM_COMMAND_QWKSEARCH_CMB fired " & @CRLF) Local $Found = '' #forceref $hWnd, $iMsg If $lParam = GUICtrlGetHandle($g_cbQwkSrch) And BitShift($wParam, 16) = $CBN_EDITCHANGE Then ; Our combo edit content has changed ; get data from source ---------------------------- Local $datafromsource = fFindFilesForQuickSearch($stringtofind) ; datafromsource convert to Combo friendly format ; Add data to combo _GUICtrlComboBox_BeginUpdate($g_cbQwkSrch) GUICtrlSetData($g_cbQwkSrch, $Found) _GUICtrlComboBox_EndUpdate($g_cbQwkSrch) EndIf _QwkSrch_Edit_Changed() ; Action this function EndIf EndFunc ;==>_WM_COMMAND_QWKSEARCH_CMB Func fFindFilesForQuickSearch($stringtofind) ; helper function for QuickSearch ; get data here Return $aResult EndFunc ;==>fFindFilesForQuickSearch Now the following:
      Can I declare the variable $g_cbQwkSrch in Global, then use in multiple functions - reassigning different combo's to it as I go along? Should GUIRegisterMsg be expressly de-registered, or does that happen automatically at GuiDelete()? Where is the best/correct place to call GUIRegisterMsg? With the creation of its control, before the GUISetState, or before the start of the loop? The Help File contains this entry, what is the intent?  Must this always be called with four args, or a max of four...   !!! To make the user function workable you have to define it with maximum 4 function parameters otherwise the function won't be called !!!
    • By Skysnake
      Hi
      Best example I could find is here
      ::/html/libfunctions/_GUICtrlTreeView_ClickItem.htm
      The way I understand this, the standard Windows messages, such as Left/Right Click etc are covered by AutoIt macros, but the real power is locked up inside this WM_NOTIFY .  I have tried, but I am not even sure I understand what I am looking at.
      I need help understanding this.  What I am looking for is Help file or Tutorial explaining how this works?  
      Perhaps if there is a script showing both the working of an AutoIt macro and the WM_NOTIFY  in action, it would help.
      Right now I am so lost, I do not even know what are the right questions to ask.  One issue I have is on ListViews, how to combine the "Click" of a line with a standard Switch loop?  Like users clicks a line, then get the loop to detect the click and ;do something ...
      Any ideas?
      Skysnake
×
×
  • Create New...