Jump to content
Sign in to follow this  
is8591

combo misbehaving?

Recommended Posts

is8591

Simple GUI with Input and readonly combo.

When Tabbing into combo does not show the dropdown, but when Mouse click on Edit portion dropdown shows.

Is this a bug or is it suppose to be like this?

I need the dropdown to show up only when clicking on dropdown icon.

Thanks

#include <GuiConstants.au3>
GuiCreate("GUI", 200, 60,-1, -1 , BitOR($WS_OVERLAPPEDWINDOW, $WS_CLIPSIBLINGS))
$Input = GuiCtrlCreateInput("", 10, 10, 100, 20)
$combo = GUICtrlCreateCombo("item1", 120, 10,60,200,BitOR($CBS_DROPDOWN,$CBS_DROPDOWNLIST,$WS_VSCROLL))
GUICtrlSetData(-1, "item2|item3", "item3")
GuiSetState()
While 1
    if GuiGetMsg() = $GUI_EVENT_CLOSE Then Exit
WEnd

Share this post


Link to post
Share on other sites
smashly

Hi, work around for it

#include <GuiConstants.au3>
GuiCreate("GUI", 200, 60,-1, -1 , BitOR($WS_OVERLAPPEDWINDOW, $WS_CLIPSIBLINGS))
$Input = GuiCtrlCreateInput("", 10, 10, 100, 20)
$Label = GUICtrlCreateLabel("", 120, 10, 40, 20)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
$combo = GUICtrlCreateCombo("item1", 120, 10, 60, 20, BitOR($CBS_DROPDOWN,$CBS_DROPDOWNLIST,$WS_VSCROLL))
GUICtrlSetData(-1, "item2|item3", "item3")
GuiSetState()

While 1
    $msg = GuiGetMsg() 
    Select 
        Case $msg = $GUI_EVENT_CLOSE 
            Exit
        Case $msg = $Label
            GUICtrlSetState($combo, $GUI_FOCUS)
    EndSelect       
WEnd

Cheers

Share this post


Link to post
Share on other sites
is8591

Hi, work around for it

#include <GuiConstants.au3>
GuiCreate("GUI", 200, 60,-1, -1 , BitOR($WS_OVERLAPPEDWINDOW, $WS_CLIPSIBLINGS))
$Input = GuiCtrlCreateInput("", 10, 10, 100, 20)
$Label = GUICtrlCreateLabel("", 120, 10, 40, 20)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
$combo = GUICtrlCreateCombo("item1", 120, 10, 60, 20, BitOR($CBS_DROPDOWN,$CBS_DROPDOWNLIST,$WS_VSCROLL))
GUICtrlSetData(-1, "item2|item3", "item3")
GuiSetState()

While 1
    $msg = GuiGetMsg() 
    Select 
        Case $msg = $GUI_EVENT_CLOSE 
            Exit
        Case $msg = $Label
            GUICtrlSetState($combo, $GUI_FOCUS)
    EndSelect       
WEnd

Cheers

Thanks. Very nice approach.

But is it a bug?

Or may be there is a way to do it through GuiCtrlSendMsg?

Share this post


Link to post
Share on other sites
smashly

Sorry , I don't know if it's a bug or not , hence the work around ..lol

I was thinking more along the lines of GUIRegisterMsg() , but I didn't like the idea of stealing the the default msg just to stop combo from dropping down.

Cheers

Share this post


Link to post
Share on other sites
is8591

Sorry , I don't know if it's a bug or not , hence the work around ..lol

I was thinking more along the lines of GUIRegisterMsg() , but I didn't like the idea of stealing the the default msg just to stop combo from dropping down.

Cheers

I already run GUIRegisterMsg() to catch GetFocus, LostFocus, Selection Change. So I wouldn't mind another switch in the routine.

It would be better than adding bunch of Labels.

Problem - I have no idea how to figure out proper Messages. I always look up Gary's examples and reuse it.

So if it's not a big deal, let me know how to setup GUIRegisterMsg() for this purpose.

Thanks

Share this post


Link to post
Share on other sites
Siao

To see if it's normal behaviour or not, try any combobox you find in Windows (such as, Date & Time Properties - doubleclick tray clock; or Display Properties - rightclick desktop, properties...) :)

Now why exactly would you want to change the default combo box behaviour is beyond me, but the proposed method with transparent labels is about as simple and efficient as it gets, even if you have multiple combo boxes to work with. There's no simple GuiRegisterMsg solution, as there are no documented messages to prevent dropdown from showing up, and the box doesn't expect any return value when sending notify, so you can't trick it that way either.

Probably the way to do it would be -

subclass each combobox (using Callback UDF) to be able to catch WM_LBUTTONDOWN messages, and either let them through or return, depending if the user clicked on dropdown button or not. To get button rect, either send CB_GETCOMBOBOXINFO message, or calculate approximately...

Edited by Siao

"be smart, drink your wine"

Share this post


Link to post
Share on other sites
Siao

Ok, here's the example of the abovementioned method. Requires that brilliant piccaso's Callback UDF

For whatever reasons I kept getting "invalid handle" errors while trying to use $hWnd calling GetComboBoxInfo() or when trying to pass it to ControlGetPos instead of controlID, so had to work around...

#include <GuiConstants.au3>
;~ #include <A3LWinAPI.au3>
#include "DllCallBack.au3"

$gui = GuiCreate("GUI", 200, 60,-1, -1 , BitOR($WS_OVERLAPPEDWINDOW, $WS_CLIPSIBLINGS))
$Input = GuiCtrlCreateInput("", 10, 10, 100, 20)
$combo = GUICtrlCreateCombo("item1", 120, 10,60,200,BitOR($CBS_DROPDOWN,$CBS_DROPDOWNLIST,$WS_VSCROLL))
GUICtrlSetData(-1, "item2|item3", "item3")
GuiSetState()

; Register callback function
$pMyWindowProc = _DllCallBack ("_MyWindowProc", "hwnd;uint;long;ptr", $_DllCallBack_Subclass)
; Retrieve a pointer to the original WindowProc and set the new one to our
; Callback function - Make sure to use a handle and not the internal id!
$pOriginalWindowProc = _WinSubclass(GUICtrlGetHandle($combo), $pMyWindowProc)

While 1
    Switch GuiGetMsg()
        Case $GUI_EVENT_CLOSE
            _DllCallBack_Free($pOriginalWindowProc)
            Exit
    EndSwitch
WEnd

Func _MyWindowProc($hWnd, $uiMsg, $wParam, $lParam)
    Switch $uiMsg
        Case 0x201, 0x203 ;WM_LBUTTONDOWN, WM_LBUTTONDBLCLK
            $X = BitAnd($lParam, 0x0000FFFF)
;~    $Y = BitShift($lParam, 16)
        ;check if cursor is over dropdown button via ControlGetPos
            $aCI = GUIGetCursorInfo()
            If @error Then Return $pOriginalWindowProc
            $aCBPos = ControlGetPos($gui, "", $aCI[4])
            If @error Then Return $pOriginalWindowProc
            If $X < ($aCBPos[2]-$aCBPos[3]) Then
        ;or via Auto3Lib 
;~    If $X < (_API_GetClientWidth($hWnd)-_API_GetClientHeight($hWnd)) Then
        ;and do stuff
                GUICtrlSetState($aCI[4], $GUI_FOCUS)
                Return 0
            EndIf
    EndSwitch
    ; Returning a Pointer to the original WindowProc means: We did not process this message.
    Return $pOriginalWindowProc
EndFunc   ;==>_MyWindowProc

;-- Wrapper for SetWindowLong API
Func _WinSubclass($hWnd, $lpNewWindowProc)
    ;#define GWL_WNDPROC (-4)
    Local $aTmp, $sFunc = "SetWindowLong"
    If @Unicode Then $sFunc &= "W"
    $aTmp = DllCall("user32.dll", "ptr", $sFunc, "hwnd", $hWnd, "int", -4, "ptr", $lpNewWindowProc)
    If @error Then Return SetError(1, 0, 0)
    If $aTmp[0] = 0 Then Return SetError(1, 0, 0)
    Return $aTmp[0]
EndFunc   ;==>_WinSubclass
Edited by Siao

"be smart, drink your wine"

Share this post


Link to post
Share on other sites
is8591

Thank you all for helping.

It seems dropdown is behaving normally and if it's a bug it's Windows.

After seeing the options - labels is the way to go.

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  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.