Sign in to follow this  
Followers 0
taurus905

Selecting ComboBox with Arrow Keys and Mouse

4 posts in this topic

I need help combining the functionality of how a combobox reacts using the up and down arrow keys and using the mouse.

I thought this would be easy to do, but the solution is eluding me. I am hoping that I am just missing something simple and somebody will set me straight.

As always, I greatly appreciate any input which points me in the right direction.

taurus905

; Works with Arrow Keys.au3
Global Const $GUI_EVENT_CLOSE = -3
Opt('MustDeclareVars', 1)

Dim $hGui
Dim $cBlack = 0x000000, $cRed = 0xFF0000
Dim $sCombo, $hCombo
Dim $hLabel
Dim $msg

$hGui = GUICreate("Works right using Arrow Keys to choose.", 350, 100)
GUISetBkColor($cBlack)

GUICtrlCreateLabel("But does not work right with Mouse.", 30, 10)
GUICtrlSetBkColor(-1, 0xFFFFFF)

For $i = 1 To 100
    $sCombo &= $i & "|"
Next

$hCombo = GUICtrlCreateCombo("", 50, 40, 70)
GUICtrlSetData(-1, $sCombo, "1")

$hLabel = GUICtrlCreateLabel("1", 150, 40, 70)
GUICtrlSetBkColor(-1, 0xFFFFFF)

GUISetState(@SW_SHOW)

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $hCombo
            If _IsPressed("26") Or _IsPressed("28") Then ; UP ARROW and DOWN ARROW
                While _IsPressed("26") Or _IsPressed("28")
                    Sleep(10)
                WEnd
                Set_Label_Data()
            EndIf

        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd
Exit

Func Set_Label_Data()
    GUICtrlSetData($hLabel, GUICtrlRead($hCombo))
    If Mod(GUICtrlRead($hCombo), 2) = 0 Then
        GUISetBkColor($cRed, $hGui)
    Else
        GUISetBkColor($cBlack, $hGui)
    EndIf
    Sleep(500)
EndFunc

Func _IsPressed($sHexKey, $vDLL = 'user32.dll')
    Local $a_R = DllCall($vDLL, "short", "GetAsyncKeyState", "int", '0x' & $sHexKey)
    If @error Then Return SetError(@error, @extended, False)
    Return BitAND($a_R[0], 0x8000) <> 0
EndFunc ; ==> _IsPressed

This second script loops too many times when you hold down the up or down arrow key.

; Works with Mouse.au3
Global Const $GUI_EVENT_CLOSE = -3
Opt('MustDeclareVars', 1)

Dim $hGui
Dim $cBlack = 0x000000, $cRed = 0xFF0000
Dim $sCombo, $hCombo
Dim $hLabel
Dim $msg

$hGui = GUICreate("Works right using Mouse to choose.", 350, 100)
GUISetBkColor($cBlack)

GUICtrlCreateLabel("But does not work right with Arrow Keys.", 30, 10)
GUICtrlSetBkColor(-1, 0xFFFFFF)

For $i = 1 To 100
    $sCombo &= $i & "|"
Next

$hCombo = GUICtrlCreateCombo("", 50, 40, 70)
GUICtrlSetData(-1, $sCombo, "1")

$hLabel = GUICtrlCreateLabel("1", 150, 40, 70)
GUICtrlSetBkColor(-1, 0xFFFFFF)

GUISetState(@SW_SHOW)

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $hCombo
            Set_Label_Data()

        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd
Exit

Func Set_Label_Data()
    GUICtrlSetData($hLabel, GUICtrlRead($hCombo))
    If Mod(GUICtrlRead($hCombo), 2) = 0 Then
        GUISetBkColor($cRed, $hGui)
    Else
        GUISetBkColor($cBlack, $hGui)
    EndIf
    Sleep(500)
EndFunc

"Never mistake kindness for weakness."-- Author Unknown --"The highest point to which a weak but experienced mind can rise is detecting the weakness of better men."-- Georg Lichtenberg --Simple Obfuscator (Beta not needed.), Random names for Vars and Funcs

Share this post


Link to post
Share on other sites



taurus905,

Does this work as you want? ;)

#include <GUIConstantsEx.au3>

; Works with Arrow Keys and mouse
Opt('MustDeclareVars', 1)

Global $cBlack = 0x000000, $cRed = 0xFF0000, $sCombo, $msg

Global $hGui = GUICreate("Works right using Arrow Keys to choose.", 350, 100)
GUISetBkColor($cBlack)

GUICtrlCreateLabel("And works with Mouse!!!", 30, 10)
GUICtrlSetBkColor(-1, 0xFFFFFF)

For $i = 1 To 100
    $sCombo &= $i & "|"
Next

Global $hCombo = GUICtrlCreateCombo("", 50, 40, 70)
GUICtrlSetData(-1, $sCombo, "1")

Global $hLabel = GUICtrlCreateLabel("1", 150, 40, 70)
GUICtrlSetBkColor(-1, 0xFFFFFF)

GUISetState(@SW_SHOW)

Global $sCombo_Text = ""

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $hCombo
            If _IsPressed("26") Or _IsPressed("28") Then ; UP ARROW and DOWN ARROW
                While _IsPressed("26") Or _IsPressed("28")
                    Sleep(10)
                WEnd
                Set_Label_Data()
            EndIf

        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch

    If GUICtrlRead($hCombo) <> $sCombo_Text Then
        $sCombo_Text = GUICtrlRead($hCombo)
        Set_Label_Data()
    EndIf

WEnd
Exit

Func Set_Label_Data()
    GUICtrlSetData($hLabel, GUICtrlRead($hCombo))
    If Mod(GUICtrlRead($hCombo), 2) = 0 Then
        GUISetBkColor($cRed, $hGui)
    Else
        GUISetBkColor($cBlack, $hGui)
    EndIf
    Sleep(500)
EndFunc

Func _IsPressed($sHexKey, $vDLL = 'user32.dll')
    Local $a_R = DllCall($vDLL, "short", "GetAsyncKeyState", "int", '0x' & $sHexKey)
    If @error Then Return SetError(@error, @extended, False)
    Return BitAND($a_R[0], 0x8000) <> 0
EndFunc ; ==> _IsPressed

You will notice that I have used Global/Local rather then Dim. AutoIt will do its best to get the variables scoped correctly, but it is always best to make it explicit. :evil:

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______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

 

Share this post


Link to post
Share on other sites

taurus905,

Does this work as you want? ;)

#include <GUIConstantsEx.au3>

; Works with Arrow Keys and mouse
Opt('MustDeclareVars', 1)

Global $cBlack = 0x000000, $cRed = 0xFF0000, $sCombo, $msg

Global $hGui = GUICreate("Works right using Arrow Keys to choose.", 350, 100)
GUISetBkColor($cBlack)

GUICtrlCreateLabel("And works with Mouse!!!", 30, 10)
GUICtrlSetBkColor(-1, 0xFFFFFF)

For $i = 1 To 100
    $sCombo &= $i & "|"
Next

Global $hCombo = GUICtrlCreateCombo("", 50, 40, 70)
GUICtrlSetData(-1, $sCombo, "1")

Global $hLabel = GUICtrlCreateLabel("1", 150, 40, 70)
GUICtrlSetBkColor(-1, 0xFFFFFF)

GUISetState(@SW_SHOW)

Global $sCombo_Text = ""

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $hCombo
            If _IsPressed("26") Or _IsPressed("28") Then ; UP ARROW and DOWN ARROW
                While _IsPressed("26") Or _IsPressed("28")
                    Sleep(10)
                WEnd
                Set_Label_Data()
            EndIf

        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch

    If GUICtrlRead($hCombo) <> $sCombo_Text Then
        $sCombo_Text = GUICtrlRead($hCombo)
        Set_Label_Data()
    EndIf

WEnd
Exit

Func Set_Label_Data()
    GUICtrlSetData($hLabel, GUICtrlRead($hCombo))
    If Mod(GUICtrlRead($hCombo), 2) = 0 Then
        GUISetBkColor($cRed, $hGui)
    Else
        GUISetBkColor($cBlack, $hGui)
    EndIf
    Sleep(500)
EndFunc

Func _IsPressed($sHexKey, $vDLL = 'user32.dll')
    Local $a_R = DllCall($vDLL, "short", "GetAsyncKeyState", "int", '0x' & $sHexKey)
    If @error Then Return SetError(@error, @extended, False)
    Return BitAND($a_R[0], 0x8000) <> 0
EndFunc ; ==> _IsPressed

You will notice that I have used Global/Local rather then Dim. AutoIt will do its best to get the variables scoped correctly, but it is always best to make it explicit. :evil:

M23

Hello Melba23,

Very nice and simple solution. Thank you for taking the time to get me back on track.

And thanks for the tip on variable scope. I usually use Dim and Local, but maybe I should go back to using Global and Local.

I did make one change to your solution, but I am not sure which one I will use yet. I may have to tweak it a little more. But it is nice to have a choice.

Thanks again,

taurus905

#include <GUIConstantsEx.au3>

; Works with Arrow Keys and mouse
Opt('MustDeclareVars', 1)

Global $cBlack = 0x000000, $cRed = 0xFF0000, $sCombo, $msg

Global $hGui = GUICreate("Works right using Arrow Keys to choose.", 350, 100)
GUISetBkColor($cBlack)

GUICtrlCreateLabel("And works with Mouse!!!", 30, 10)
GUICtrlSetBkColor(-1, 0xFFFFFF)

For $i = 1 To 100
    $sCombo &= $i & "|"
Next

Global $hCombo = GUICtrlCreateCombo("", 50, 40, 70)
GUICtrlSetData(-1, $sCombo, "1")

Global $hLabel = GUICtrlCreateLabel("1", 150, 40, 70)
GUICtrlSetBkColor(-1, 0xFFFFFF)

GUISetState(@SW_SHOW)

Global $sCombo_Text = ""

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $hCombo
            If _IsPressed("26") Or _IsPressed("28") Then ; UP ARROW and DOWN ARROW
                While _IsPressed("26") Or _IsPressed("28")
                    Sleep(10)
                WEnd
                Set_Label_Data()
            EndIf

            If GUICtrlRead($hCombo) <> $sCombo_Text Then
                $sCombo_Text = GUICtrlRead($hCombo)
                Set_Label_Data()
            EndIf

        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd
Exit

Func Set_Label_Data()
    GUICtrlSetData($hLabel, GUICtrlRead($hCombo))
    If Mod(GUICtrlRead($hCombo), 2) = 0 Then
        GUISetBkColor($cRed, $hGui)
    Else
        GUISetBkColor($cBlack, $hGui)
    EndIf
    Sleep(500)
EndFunc

Func _IsPressed($sHexKey, $vDLL = 'user32.dll')
    Local $a_R = DllCall($vDLL, "short", "GetAsyncKeyState", "int", '0x' & $sHexKey)
    If @error Then Return SetError(@error, @extended, False)
    Return BitAND($a_R[0], 0x8000) <> 0
EndFunc ; ==> _IsPressed

"Never mistake kindness for weakness."-- Author Unknown --"The highest point to which a weak but experienced mind can rise is detecting the weakness of better men."-- Georg Lichtenberg --Simple Obfuscator (Beta not needed.), Random names for Vars and Funcs

Share this post


Link to post
Share on other sites

Melba23,

Just for the sake of completion, here is my final solution:

; Works using Arrow Keys or Mouse.au3
Opt('MustDeclareVars', 1)

Global $cBlack = 0x000000, $cRed = 0xFF0000, $sCombo, $msg

Global $hGui = GUICreate("Works using Arrow Keys or Mouse", 350, 100)
GUISetBkColor($cBlack)

For $i = 1 To 100
    $sCombo &= $i & "|"
Next

Global $hCombo = GUICtrlCreateCombo("", 50, 40, 70)
GUICtrlSetData(-1, $sCombo, "1")

Global $hLabel = GUICtrlCreateLabel("1", 150, 40, 70)
GUICtrlSetBkColor(-1, 0xFFFFFF)

Global $sFlag = "None"
Global $hFlag = GUICtrlCreateLabel($sFlag, 250, 40, 50)
GUICtrlSetBkColor(-1, 0xFFFFFF)

GUISetState(@SW_SHOW)

Global $sCombo_Text = GUICtrlRead($hCombo)

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $hCombo
            If _IsPressed("26") Or _IsPressed("28") Then ; UP ARROW or DOWN ARROW
                While _IsPressed("26") Or _IsPressed("28")
                    Sleep(10)
                WEnd
                Set_Label_Data()
                $sFlag = "Arrow"
                GUICtrlSetData($hFlag, $sFlag)
                $sCombo_Text = GUICtrlRead($hCombo)
            EndIf

            If GUICtrlRead($hCombo) <> $sCombo_Text Then
                $sCombo_Text = GUICtrlRead($hCombo)
                Set_Label_Data()
                $sFlag = "Mouse"
                GUICtrlSetData($hFlag, $sFlag)
            EndIf

        Case -3 ; $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd
Exit

Func Set_Label_Data()
    GUICtrlSetData($hLabel, GUICtrlRead($hCombo))
    If Mod(GUICtrlRead($hCombo), 2) = 0 Then
        GUISetBkColor($cRed, $hGui)
    Else
        GUISetBkColor($cBlack, $hGui)
    EndIf
EndFunc

Func _IsPressed($sHexKey, $vDLL = 'user32.dll')
    Local $a_R = DllCall($vDLL, "short", "GetAsyncKeyState", "int", '0x' & $sHexKey)
    If @error Then Return SetError(@error, @extended, False)
    Return BitAND($a_R[0], 0x8000) <> 0
EndFunc ; ==> _IsPressed

Thank you for this line which made all the difference:

If GUICtrlRead($hCombo) <> $sCombo_Text Then
        $sCombo_Text = GUICtrlRead($hCombo)
taurus905

"Never mistake kindness for weakness."-- Author Unknown --"The highest point to which a weak but experienced mind can rise is detecting the weakness of better men."-- Georg Lichtenberg --Simple Obfuscator (Beta not needed.), Random names for Vars and Funcs

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  
Followers 0