Jump to content

Selecting ComboBox with Arrow Keys and Mouse


Recommended Posts

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

Link to comment
Share on other sites

  • Moderators

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

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

Link to comment
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

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