Jump to content

combo misbehaving?


is8591
 Share

Recommended Posts

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
Link to comment
Share on other sites

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

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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"

Link to comment
Share on other sites

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"

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...