Jump to content
Sign in to follow this  
WoodGrain

Change Label if key Is Pressed

Recommended Posts

Hi guys,

I'm learning about GUI's, I'm trying the below code, the idea being if I press the letter "e" while I have the GUI open I want the label color to change to green (I'm using a UDF for label colors). But every time I press "e" on my keyboard I just get a "ding" sound from my speakers and nothing changes with the label.

I've looked at using something like "While GUIGetMsg() <> $GUI_EVENT_CLOSE" as I've seen it in other code instead of "While 1", but I don't think it's relevant.

#include <GUIConstantsEx.au3>; for GUI...
#include <GUIRichLabel.au3>; UDF for rich text label fonts
#include <Misc.au3>; for _IsPressed

$myLetter = "e"

$hGUI = GUICreate("test", 700, 60)

$lbl2 = _GUICtrlRichLabel_Create($hGUI, '<font color="purple">' & $myLetter & '</font>', 10, 10); , 260, 25

GUISetState(@SW_SHOW)


Local $hDLL = DllOpen("user32.dll")
While 1
   if _IsPressed(Hex($myLetter), $hDLL) Then
      While _IsPressed(Hex($myLetter), $hDLL)
         Sleep(250)
      WEnd
      _GUICtrlRichLabel_SetData($lbl2, '<font color="green">' & $myLetter & '</font>')
      Sleep(2000)
      DllClose($hDLL)
      Exit
   EndIf
   Sleep(50)
WEnd
DllClose($hDLL)

I am using an array of letters that I'm wanting to do this for, but as I can't get it to work I've stripped it down to the simplest code I can think of to try and get this working first. Appreciate any help.

Thanks!

Share this post


Link to post
Share on other sites

@WoodGrain

16 hours ago, WoodGrain said:

But every time I press "e" on my keyboard I just get a "ding" sound from my speakers and nothing changes with the label.

I think that this is caused by the GUI that hasn't the focus, and so, that sound indicates an invalid action of the current focussed GUI.

I think that you have to see when you are in your GUI, using WinGetState() to see if you are able to interact with your GUI, and, if it is not, you could use the other Win* functions to make it possible.

Try that and let us know :)


Click here to see my signature:

Spoiler

ALWAYS GOOD TO READ:

 

Share this post


Link to post
Share on other sites

I saw this code which looks interesting

#include <GuiConstants.au3>
#include <windowsconstants.au3>

GUICreate("MyGUI")

GUISetState()
GUIRegisterMsg(0x101,"WM_KEYDOWN")


While 1
    $msg = GUIGetMsg()
    Select
        Case $msg = $GUI_EVENT_CLOSE
            ExitLoop
    EndSelect
WEnd
Func WM_KEYDOWN($hWnd, $msg, $wParam, $lParam)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $wParam = ' & $wParam & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
EndFunc

 

Share this post


Link to post
Share on other sites

WoodGrain,

The "letter" parameter required for _IsPressed is not Hex("E") but Hex(Asc("E")) - as explained in the Help file. Once you set that parameter correctly, the label colour changes (at least with native labels):

#include <GUIConstantsEx.au3>; for GUI...
#include <Misc.au3>; for _IsPressed

$myLetter = "E" ; This is the letter
$iCode = Hex(Asc($myLetter), 2) ; and this is the code required for _IsPressed

$hGUI = GUICreate("test", 700, 60)
$cLabel = GUICtrlCreateLabel($myLetter, 10, 10, 200, 20)
GUISetState(@SW_SHOW)

Local $hDLL = DllOpen("user32.dll")
While 1
   if _IsPressed($iCode, $hDLL) Then
      While _IsPressed($iCode, $hDLL)
         Sleep(250)
      WEnd
      GUICtrlSetBkColor($cLabel, 0x00FF00)
      Sleep(2000)
      DllClose($hDLL)
      Exit
   EndIf
   Sleep(50)
WEnd
DllClose($hDLL)

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

 

Share this post


Link to post
Share on other sites

Thanks M23, your script works for me too. Would you be so kind to explain to me how you derived the ASC() requirement from the help file? Please be sure I'm not trying to question your comment so much as understand it for myself so I can better understand the doco before posting here next time. I can see the reference to HEX() in that it mentions the 1st parameter as "$sHexKey". Is it just that you already happen to know that those number codes in the list correlate to their ASCII numbers (assuming that's what they are)?

Wow, I also noted in the help file, now that I've tried both lower and upper case letters after noting in your script you used an upper case E, that, as listed in the help file, only upper case letters will work in this scenario! So, after changing my "e" to "E" and adding in the Asc() inside the 2 _IsPressed functions my script worked!

Only remaining question is how do I stop it from making the "ding" noise when I press a key in the GUI lol? That's going to otherwise drive me spare!

Thanks!

Share this post


Link to post
Share on other sites

A cute workaround (and more selective/secure IMHO) could be to use GUISetAccelerators and a hidden button  :)
Of course it works only if the gui is active...

#include <GUIConstantsEx.au3>

$hGUI = GUICreate("test", 700, 60)
$cLabel = GUICtrlCreateLabel("test", 10, 10, 200, 20)
$fake = GUICtrlCreateButton("", -10, 0, 1, 1)
Local $aAccelKeys[1][2] = [["e", $fake]]
GUISetAccelerators($aAccelKeys)
GUISetState(@SW_SHOW)
Local $n

While 1
      Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                Exit
            Case $fake
                $n = not $n
                GUICtrlSetBkColor($cLabel, ($n? 0x00FF00 : 0xFF0000))
     EndSwitch
WEnd

 

Edited by mikell

Share this post


Link to post
Share on other sites

Thanks Mikell! I can confirm that if I press the correct key ("e" in this example) it doesn't make any sound and does change the color (in fact toggles the color?), however if I press any other key on my keyboard it still makes that awful ding sound. I'll have to spend some time looking at how to get this to work with my array of letters too. Thanks.

Share this post


Link to post
Share on other sites

WoodGrain,

Quote

how you derived the ASC() requirement from the help file? [...] Is it just that you already happen to know that those number codes in the list correlate to their ASCII numbers (assuming that's what they are)?

Exactly that - knowing how the function works internally helps too.

Quote

I'll have to spend some time looking at how to get this to work with my array of letters too

Please read this announcement before you post again - not being accusatory but just offering some friendly advice.

M23

Edited by Melba23
Fixed link

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

 

Share this post


Link to post
Share on other sites

All good M23, I'm aware of that, I'm writing myself a touch-typing app so I can do dvorak training.

I'm using Klavaro atm to learn dvorak, but it has to be up in the middle of my screen, and I have to type 400+ characters per lesson, I'm writing an app that will just pop-up and hide on hotkey, pull in the current lesson from my lesson plans, and as I type if I press the right key for the letter it will change the color to green, then at the end of the text will load the next random letters from the lesson. "Dinging" every time I make a typo will certainly annoy the staff around me in no time lol.

Share this post


Link to post
Share on other sites

<offtopic>tbh I've been doing some c++ training on the side and would love to learn to start doing this sort of stuff in c++ instead of AutoIT, but haven't got past console basics with if/loops/etc, wouldn't know where to start with a GUI in c++, from what I can see you need to use 3rd party tools to do this.. so here I am writing it in AutoIT lol.</offtopic>

Share this post


Link to post
Share on other sites

@WoodGrain

For C++ GUI Editor, I'd suggest Borland C++ Builder, which is a very complete and powerful tool to build your GUIs, and much more.

But, if you wanna make it easy, why don't you use Koda Form Designer, which comes with AutoIt, and it's a complete and powerful tool too ( which generates .au3 code too )? ;)


Click here to see my signature:

Spoiler

ALWAYS GOOD TO READ:

 

Share this post


Link to post
Share on other sites

Anyone have any thoughts as to how I can stop the noise in my GUI?

Do I need to use an Input Box and have the program read the last letter on input and use that?
Wouldn't look as clean though.

Share this post


Link to post
Share on other sites

So, after thinking this through it looks like the best method will be to add in an Input Control that I can type into and then use GUIGetMsg to poll it for any changes and then from that run my function to check if the last char they typed in the control is correct compared to the current letter from my array, I've read about $SS_NOTIFY with the control to assist with this.

Share this post


Link to post
Share on other sites
1 hour ago, WoodGrain said:

and then use GUIGetMsg to poll it for any changes and then from that run my function to check if the last char they typed in the control is correct compared to the current letter from my array

You can use a WM_COMMAND too :)

#include <Date.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Opt("GUIOnEventMode", 1)

#Region ### START Koda GUI section ### Form=
Global $frmMainForm = GUICreate("A Form", 235, 62, -1, -1)
GUISetOnEvent($GUI_EVENT_CLOSE, "ExitApplication")
Global $txtInput = GUICtrlCreateInput("", 19, 22, 201, 21)
GUICtrlSetFont(-1, 10, 400)
GUISetState(@SW_SHOW, $frmMainForm)
#EndRegion ### END Koda GUI section ###

GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")

While 1
    Sleep(100)
WEnd


Func ExitApplication()
    Exit
EndFunc

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

    Local $hdlWindowFrom, _
          $intMessageCode, _
          $intControlID_From

    $intControlID_From =  BitAND($wParam, 0xFFFF)
    $intMessageCode = BitShift($wParam, 16)

    Switch $intControlID_From
        Case $txtInput
            Switch $intMessageCode
                Case $EN_CHANGE
                    ConsoleWrite("[" & _Now() & "] - The text in the $txtInput control has changed! Text = " & GUICtrlRead($txtInput) & @CRLF)
            EndSwitch
    EndSwitch

    Return $GUI_RUNDEFMSG

EndFunc

 


Click here to see my signature:

Spoiler

ALWAYS GOOD TO READ:

 

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  

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By roeselpi
      hello again,
      it has been a long time since i have been here and a long time since i last used autoit. ever so often when the time allows me to, then i follow up on an idea that i had a long time ago. i have done all the work on paper but now it is up to writing it in autoit and i keep stumbling over many little issues here and there. sometimes after a few days i will try again and get a step further but sometimes it just will not help no matter how long i try and think about a solution. for most of you it will be the basics but for me it is not all that easy, but at least i give it a try.
      right, down to business:
      here is my code:
      #include <MsgBoxConstants.au3> #include <StringConstants.au3> #include <Array.au3> #include <String.au3> ; ; PART 1: define replacements and check with msgbox ; Global $y, $z $y = "Yes" $z = "No" MsgBox(0,"replacements", $y & @CRLF & $z) ;the replacements in a message box ; ; PART 2: set the texts and check via console and msgbox ; Global $my1string = "abab" ;the first specified text MsgBox(0,"my1string", $my1string) ;the message box to output the first specified text Global $my2string = "icic" ;the second specified text MsgBox(0,"my2string", $my2string) ;the message box to output the second specified text ; ; PART 3: transform the strings to individual arrays ; $my1array = StringSplit($my1string, "") $my1array[0] = "" _ArrayDelete($my1array, 0) _ArrayDisplay($my1array, "my1array") ;the display of the first specified array $my2array = StringSplit($my2string, "") $my2array[0] = "" _ArrayDelete($my2array, 0) _ArrayDisplay($my2array, "my2array") ;the display of the first specified array ; ; PART 4: create an empty array for filling ; Global $OutputArray[4] $OutputArray[0] = "" _ArrayDisplay($OutputArray, "OutputArray") ;the display of the first specified array ; ; PART 5: compare & fill empty OutputArray with data after evaluation ; Global $i, $j, $k For $i = 0 to UBound($my1array) -1 For $j = 0 to UBound($my2array) -1 For $k = 0 to UBound($OutputArray) -1 If $my1array[$i] = "a" And $my2array[$j] = "i" Then $OutputArray[$k] = $y Else $OutputArray[$k] = $z EndIf Next Next Next _ArrayDisplay($OutputArray, "OutputArray") ;the display of the Newly filled Array In "Part 2" i make a string that is converted to an array in "Part 3" ... Now, I know that "a" and "i" are always in the exact same spot in both arrays and so i wanted to compare this and make a further array to document my findings by saying "yes" or "no" ... however my new array keeps saying just "no" allthough i can clearly see and know that it should say:
      yes no yes no my guess is that there is something wrong within my for-loops and that the counting is somehow "off" i guess that when the first for-loop is finished it reaches the second whilst the second for-loop is checking the first which would explain why it always says "no" instead of seeing the obvious.
      so my question would be: what is wrong with my for-loop? or where am i making an error that ultimately gives me the wrong results?
      help is much appreciated.
      kind regards
      roeselpi
       
       
      PS: sorry for my not so great english spelling ... stupid german sitting here trying out intermediate english skills.
    • By paw
      I use SetSoundDevice to control my audio devices but the UI was either
       
      blurry like this:
      or unusable like this:

      so I made this horrible thing to add scaling to the GUI:
      #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Change2CUI=y #AutoIt3Wrapper_Res_HiDpi=y #AutoIt3Wrapper_AU3Check_Parameters=-w 3 -w 4 -w 5 #AutoIt3Wrapper_Run_Au3Stripper=y #Au3Stripper_Parameters=/sf /sv /rm #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <File.au3> ;~ _convertGUI("") If $CmdLine[0] <> 0 Then _convertGUI($CmdLine[1]) Func _convertGUI($sFilePath) If $sFilePath <> "" Then Local $aArray = FileReadToArray($sFilePath) Else ;TEST DATA Local $aArray[6] = ['$H_Res_Language = GUICtrlCreateProgress(5, 120, 210 + 25, 480, 20, BitOR($GUI_SS_DEFAULT_COMBO, $CBS_SIMPLE)) ; $CBS_DROPDOWNLIST)', _ 'Local $h_Ok = GUICtrlCreateButton("Ok", 72, 224, 81, 33, 0)', _ 'GUICreate($Warning_TiTle, 700, 310, -1, -1, $WS_SIZEBOX + $WS_SYSMENU + $WS_MINIMIZEBOX)', _ 'GUICtrlCreateLabel("Output type: ", 30, 130, 65, 20) ;, $SS_RIGHT)', _ '$H_FieldNameEdit = GUICtrlCreateEdit($INP_FieldNameEdit, 100,260+25, 500, 150 - 25) ;comment', 'Local $H_CANCEL = GUICtrlCreateGraphic("Cancel", 224, 224, 97, 33, 0)'] EndIf Local $hTimer = TimerInit(), $iGUIElementCount = 0, $sResult = "", $sFileName = "", $sDrive = "", $sDir = "", $sExtension = "" If @Compiled Then _PathSplit($sFilePath, $sDrive, $sDir, $sFileName, $sExtension) $sFileName = StringRegExpReplace($sFilePath, "^.*\\", "") EndIf For $i = 0 To (UBound($aArray) - 1) If StringRegExp($aArray[$i], "GUICtrlCreate|GUICreate") Then $sResult = _splitComma($aArray[$i]) If Not @error Then $aArray[$i] = $sResult $iGUIElementCount += 1 EndIf Next ConsoleWrite("t = " & TimerDiff($hTimer) & " GUI elements = " & $iGUIElementCount & " lines = " & (UBound($aArray) - 1) & @CRLF) If $sFileName <> "" Then Local $hFile = FileOpen("edited." & $sFileName, 2) _FileWriteFromArray("edited." & $sFileName, $aArray) FileClose($hFile) EndIf Exit EndFunc ;==>_convertGUI Func _splitComma($sString) Local $sSplitResult = "", $sTrimmedR = "", $sTrimmedL = "" Local $aSplit = StringSplit($sString, ',') If Not @error Then $sTrimmedR = "" $sTrimmedL = "" For $j = 1 To $aSplit[0] If StringRegExp($aSplit[1], "(?:.GUICtrlCreateGraphic|GUICtrlCreateProgress|GUICtrlCreateSlider|GUICtrlCreateTab|GUICtrlCreateTreeView)") Then If $j = 1 Then While StringLeft($aSplit[$j], 1) <> '(' $sTrimmedL &= StringLeft($aSplit[$j], 1) $aSplit[$j] = StringTrimLeft($aSplit[$j], 1) WEnd $aSplit[$j] = StringTrimLeft($aSplit[$j], 1) EndIf EndIf If $j = $aSplit[0] Then While StringRight($aSplit[$j], 1) <> ')' $sTrimmedR &= StringRight($aSplit[$j], 1) $aSplit[$j] = StringTrimRight($aSplit[$j], 1) WEnd $aSplit[$j] = StringTrimRight($aSplit[$j], 1) EndIf If StringRegExp($aSplit[$j], "[0-9]") And $aSplit[$j] <> -1 And $aSplit[$j] <> 0 And $aSplit[$j] <> 1 And Not StringInStr($aSplit[$j], ')') Then If StringRegExp($aSplit[$j], "\-|\+") Then ;put parenthesis around + or - $aSplit[$j] = '(' & $aSplit[$j] & ")*$g_DPI" Else $aSplit[$j] = $aSplit[$j] & "*$g_DPI" EndIf EndIf If $j < $aSplit[0] Then $sSplitResult &= $aSplit[$j] & ',' ElseIf $j = $aSplit[0] Then $sSplitResult &= $aSplit[$j] & ')' Else $sSplitResult &= $aSplit[$j] EndIf Next If $sTrimmedR <> "" Then $sSplitResult &= StringReverse($sTrimmedR) If $sTrimmedL <> "" Then $sSplitResult = $sTrimmedL & '(' & $sSplitResult Else SetError(1) Return EndIf ConsoleWrite($sSplitResult & @CRLF) Return $sSplitResult EndFunc ;==>_splitComma
      And now it looks good: 
      but it doesn't work on everything, for example the "GUICtrlCreateLabel("Output type: ", 30, 130, 65, 20) ;, $SS_RIGHT)" (from the autoit3wrapper gui)
      because the comment contains a parenthesis and it would break completely if there were variables as parameters..
      Is there some kind of parser around that I could use instead or maybe someone who has already done something like this?
    • By Zobu
      Hey Guys,
      I want to add a new checkbox with its own variable every time the add button is clicked.
      The added checkboxes should remain when I close the window or exit the script and when I reopen I should be able to add new checkboxes aswell.
      here is what I have so far..
      #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <StaticConstants.au3> #include <EditConstants.au3> #include <MsgBoxConstants.au3> #include <GuiButton.au3> $test = GUICreate("adding test", 475, 345, 500, 175) $Check1 = GUICtrlCreateCheckbox("Checkbox 1", 15, 25, 300, 25) $Button = GUICtrlCreateButton("Add", 365, 25, 90, 20) $Check2 = GUICtrlCreateCheckbox("Checkbox 2", 15, 50, 300, 25) $Check3 = GUICtrlCreateCheckbox("Checkbox 3", 15, 75, 300, 25) GUICtrlSetState($Check2, $GUI_HIDE) GUICtrlSetState($Check3, $GUI_HIDE) GUISetState(@SW_SHOW) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ; Exit Case $Button GUICtrlSetPos($Check2, 15, 50, 300, 25) GUICtrlSetState($Check2, $GUI_SHOW) Case $Button GUICtrlSetPos($Check3, 15, 75, 300, 25) GUICtrlSetState($Check3, $GUI_SHOW) EndSwitch WEnd  
    • By TXTechie
      Hello Everyone,
      I've developed my own GUI using AutoIt and I'm allowing users to minimize the GUI, but I also want to include some kind of timer so that it will automatically restore the GUI after something like 30 minutes or an hour. However, I also want them to be able to manually restore the GUI by clicking the application's icon in the taskbar.
      I've searched through the forums, but I'm not sure how to get started.
      Any ideas or functions to research are appreciated!
      Regards,
      TX Techie
    • By Rskm
      Hi, recently i created a GUI for some calculations in AutoIT.  The GUI has 2 tabs and on the first tab, it has few inputboxes where i use to click with mouse and start entering the inputs. i recently made some changes in the position of these textboxes. I made this by changing the autoit code file instead of making changes in KODA. Now i cannot click inside these textboxes with mouse. However, i can use TAB key to cycle through/enter input in these input boxes. what could have made the inputboxes not responding to mouseclicks. thanks
×
×
  • Create New...