Jump to content

_GUICtrlComboBoxEx_Create handle array


Blaxxun
 Share

Go to solution Solved by Blaxxun,

Recommended Posts

Hello Forum,

What is the proper way to dynamically create ComboBoxes that are able to us WM_NOTIFY.

I get correct messaging when i dont use an handle array.
But with handle array it stops working to trigger messages. (User changes content in Editbox my typing or choosing from the dropdown list)

Link to comment
Share on other sites

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiComboBoxEx.au3>

Global $hCombo[4]
Global $hGUI = GUICreate("GUI", 450, 200, 0, 0, BitOR($WS_MAXIMIZEBOX, $WS_MINIMIZEBOX, $WS_SIZEBOX))

For $i = 0 To 3
    $hCombo[$i] = _GUICtrlComboBoxEx_Create($hGUI, "Item1", 10 + ($i * 101), 10, 100, 200)
    _GUICtrlComboBoxEx_AddString($hCombo[$i], "Item2")
Next

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUISetState(@SW_SHOW)

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)

    Local $tNMCOMBOBOXEX = DllStructCreate($tagNMCOMBOBOXEX, $lParam)
    Local $hWndFrom = DllStructGetData($tNMCOMBOBOXEX, 'hWndFrom')
    Local $Code = DllStructGetData($tNMCOMBOBOXEX, 'Code')

    Switch $hWndFrom
        Case $hCombo[0] To $hCombo[UBound($hCombo) - 1]
            Switch $Code
                Case $CBEN_GETDISPINFOA, $CBEN_GETDISPINFOW
                    ConsoleWrite(DllStructGetData($tNMCOMBOBOXEX, 'Item') & @LF)
            EndSwitch
    EndSwitch
EndFunc   ;==>WM_NOTIFY

Now it seems to work but sometimes stops messaging. After SciTE restart and Tidy it works again. Weird somehow.
At the moment it reports the Item ID Number everytime i hover over an Item in the dropdown list.
How can i limit this to just report once, once an item is actually selected?

Thanks

Link to comment
Share on other sites

This line is the problem :

Case $hCombo[0] To $hCombo[UBound($hCombo) - 1]

Handles are not created sequentially.  Consider looping into the array, or another solution would be to use control ids.

As for your single report, you could use a Static variable to check if it is the last reported or not...

Link to comment
Share on other sites

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiComboBoxEx.au3>
#include <Array.au3>

Global $hCombo[4]
Global $ComboID[4]
Global $hGUI = GUICreate("GUI", 450, 200, 0, 0, BitOR($WS_MAXIMIZEBOX, $WS_MINIMIZEBOX, $WS_SIZEBOX))

For $i = 0 To 3
    $hCombo[$i] = _GUICtrlComboBoxEx_Create($hGUI, "Item1", 10 + ($i * 101), 10, 100, 200)
    $ComboID[$i] = _WinAPI_GetDlgCtrlID($hCombo[$i])
    _GUICtrlComboBoxEx_AddString($hCombo[$i], "Item2")
    _GUICtrlComboBoxEx_SetExtendedStyle($hCombo[$i], $CBES_EX_NOSIZELIMIT)
Next

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUISetState(@SW_SHOW)

_ArrayDisplay($ComboID,"$ComboID")

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
    Sleep(10)
WEnd

Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)

    Local $tNMCOMBOBOXEX = DllStructCreate($tagNMCOMBOBOXEX, $lParam)
    Local $hWndFrom = DllStructGetData($tNMCOMBOBOXEX, 'hWndFrom')
    Local $Code = DllStructGetData($tNMCOMBOBOXEX, 'Code')

    Switch $hWndFrom
        Case $ComboID[0] To $ComboID[UBound($hCombo) - 1]
            Switch $Code
                Case $CBEN_GETDISPINFOA, $CBEN_GETDISPINFOW
                    ConsoleWrite(DllStructGetData($tNMCOMBOBOXEX, 'Item') & " - " & $hWndFrom & @LF)
            EndSwitch
    EndSwitch

    Return $GUI_RUNDEFMSG

EndFunc   ;==>WM_NOTIFY

 

I changed the code, and i get the ID from the handle.
But now i don't get any event reported...

In the final program the comboboxes are generated by the user.
They are on top of a Listviews colums.
Colums can be added and removed and so the number of Comboboxes also change.
If i use a loop to go through the array i run into timing problems...

Link to comment
Share on other sites

🤦‍♂️ Yeah, now that you say it. Thank you!

Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)

    Local $tNMCOMBOBOXEX = DllStructCreate($tagNMCOMBOBOXEX, $lParam)
    Local $hWndFrom = DllStructGetData($tNMCOMBOBOXEX, 'hWndFrom')
    Local $WndFromID = _WinAPI_GetDlgCtrlID($hWndFrom)
    Local $Code = DllStructGetData($tNMCOMBOBOXEX, 'Code')

    Switch $WndFromID
        Case $ComboID[0] To $ComboID[UBound($hCombo) - 1]
            Switch $Code
                Case $CBEN_GETDISPINFOA, $CBEN_GETDISPINFOW
                    ConsoleWrite(DllStructGetData($tNMCOMBOBOXEX, 'Item') & " - " & $hWndFrom & @LF)
            EndSwitch
    EndSwitch

EndFunc   ;==>WM_NOTIFY

Now this works!

 

Case $CBEN_GETDISPINFOA, $CBEN_GETDISPINFOW

I just need a report when the user chose an item from the dropdown list and it appears in the editbox.
At the moment it fires already when i click the dropdown arrow.
What can i use to achive this?

Edited by Blaxxun
Link to comment
Share on other sites

Case $CBEN_ENDEDITW

"Sent when the user has concluded an operation within the edit box or has selected an item from the control's drop-down list."

In my case this reports already when i click the dropdown arrow. (Which is empty at first)
Then when i choose an actual Item it does not report anymore.

Just when i click in another combobox edit box it reports...
 

Link to comment
Share on other sites

  • Solution
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiComboBoxEx.au3>

Global $hCombo[4]
Global $iCombo[4]
Global $sComboTxt
Global $hGUI = GUICreate("GUI", 450, 200, 0, 0, BitOR($WS_MAXIMIZEBOX, $WS_MINIMIZEBOX, $WS_SIZEBOX))

For $i = 0 To 3
    $hCombo[$i] = _GUICtrlComboBoxEx_Create($hGUI, "Item1", 10 + ($i * 101), 10, 100, 200)
    $iCombo[$i] = _WinAPI_GetDlgCtrlID($hCombo[$i])
    _GUICtrlComboBoxEx_AddString($hCombo[$i], "Item2")
Next

GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
GUISetState(@SW_SHOW)

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

Func WM_COMMAND($hWnd, $msg, $wParam, $lParam)

    Local $nCode = BitShift($wParam, 16) ;      Hiword
    Local $iCtrl = BitAND($wParam, 0xFFFF) ;    Loword
    Local $hCtrl = $lParam

    Switch $iCtrl
        Case $iCombo[0] To $iCombo[UBound($iCombo) - 1]
            Switch $nCode
                ;Case $CBN_EDITUPDATE, $CBN_EDITCHANGE ; When user types in new Data
                ;ConsoleWrite("Types" & @LF)

                Case $CBN_SELCHANGE    ; Item from Dropdown selected
                    $iComboIdx = _GUICtrlComboBox_GetCurSel($hCtrl)
                    $aComboAtt = _GUICtrlComboBoxEx_GetItem($hCtrl, $iComboIdx)
                    $sComboTxt = $aComboAtt[0]
                    ConsoleWrite($sComboTxt & @TAB & $iCtrl & @TAB & $hCtrl & @LF)
            EndSwitch
    EndSwitch

    Return $GUI_RUNDEFMSG

EndFunc   ;==>WM_COMMAND

This works and only fires when an Item was selected

Edited by Blaxxun
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...