Sign in to follow this  
Followers 0
RandomClown

GUISetOnEvent() Key Press?

12 posts in this topic

#1 ·  Posted (edited)

Hai!

I scripted many little tools to do whatever, but I wanted to add more features to them all.

I need a better way to monitor key presses though.

=== Details ===

  • I need a way to detect a key press
  • I cant use HotKey because I do not want to interfere with the user activity
  • My GUI loops every second or longer, so I cant use $msg=GUIGetMsg()

#include <GUIConstantsEx.au3>
#include <Misc.au3>

...GUI Stuff...

    GUISetOnEvent(_IsPressed(70),"Help") ; something of this sort, except a working mothod..

    GUISetOnEvent($GUI_EVENT_CLOSE,"Quit")

...GUI Stuff...

    While 1
        Sleep(2000)
    WEnd

That 1st GUISetOnEvent line crashes the program....cause I = fail..

Does anyone know how to get that working?

Thanks

Edited by RandomClown

Share this post


Link to post
Share on other sites



Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

This is a good question and one I have had. I have always relied on guisetaccelerators but this requires an associated guictrl.

There is no guisetonevent for a keypress, yet there is for mousepress. Why? Yes there is the _ispressed option but that is only a mediocre solution.

Guiregistermsg seemed to be an option but I could never get it to register a keypress so I'm sure I'm missing something.

GUIRegisterMsg(0x0100,"keypress")

;WM_KEYDOWN 0x0100
;WM_KEYFIRST 0x0100
;WM_KEYLAST 0x0108
;WM_KEYLAST 0x0109
;WM_KEYUP 0x0101
Edited by picea892

Share this post


Link to post
Share on other sites

This is a good question and one I have had. I have always relied on guisetaccelerators but this requires an associated guictrl.

How is that a problem? There's always GUICtrlCreateDummy() if you don't already have any control the accelerator would fit to.

Share this post


Link to post
Share on other sites

And what's the problem with HotKeySet()? You can map many keys to one function. That function knows which key triggered it with the @HotKeyPressed macro. If the function is slow and poorly written it will interfere with the rest of the script regardless of how it is called.

I cant use HotKey because I do not want to interfere with the user activity

What does it mean to handle a hot key without the user noticing it? How is that not just a key logger, then?

:)


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

Maybe read to much into what the OP had wanted. I thought he wanted it gui specific, that was why hotkeyset was out and he was looking for a guisetonevent for keypresses.

So if he wants keypresses for a gui I guess we have laid out his 3 options:

1) accelerators with GUICtrlCreateDummy() is the solution I presently use for onevent scripts.

2) _ispressed is the solution I use for non onevent scripts.

3) HotKeySet() with an if gui is active statement would be another option.

Share this post


Link to post
Share on other sites

Maybe read to much into what the OP had wanted. I thought he wanted it gui specific, that was why hotkeyset was out and he was looking for a guisetonevent for keypresses.

Yeah, I could see that being what was meant, so mine may have been over reacting.

The accelerators still look best, in combination with a dummy control if needed, as AdmiralAlkex was suggesting.

:)


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

LOL

The reason is not key logging. in fact, I want the exact opposite.

Key loggers [HotKeySet] will see the input no matter what window your on.

I wanted to see the input only when the window is selected.

Here is one of my tools I am "adding on" to:

Main Program:

Opt("GUIOnEventMode",1)
Opt("TrayIconHide",1)
#include <GUIConstantsEx.au3>
#include <Misc.au3>

#include <..\..\..\FuncSpace.h>



;           //      Highest value for each byte type before moving to the next unit:
            $Highest=1200
            
;           //      Drive Polling Interval
            $UpdateInterval=400


Local $ByteType,$Drive,$DriveType,$msg,$Status
$Low=$Highest/1024
    $SpaceInfo=GUICreate("Space Info",300,100,-1,-1,0,0x00000008)
        GUISetOnEvent($GUI_EVENT_CLOSE,"Quit")
        $InputDrive     =GUICtrlCreateInput("",             4,32,       24,-1,  0x0009)
        $DisplayType    =GUICtrlCreateLabel($DriveType, 4,0,        300,32, 0x0001)
        $DisplayTotal   =GUICtrlCreateLabel($DriveType, 40,32,      80,32,  0x0001)
        $DisplayFree    =GUICtrlCreateLabel($DriveType, 120,32,     80,32,  0x0001)
        $DisplayUsed    =GUICtrlCreateLabel($DriveType, 200,32,     80,32,  0x0001)
    Do
        $msg=GUIGetMsg()
        
        $Drive=GUICtrlRead($InputDrive)&":"
        
        If Not(DriveStatus($Drive)="READY")And(DriveGetType($Drive))Then
            $Status="     "&DriveStatus($Drive)
        Else
            $Status=""
        EndIf
        
        $DriveType=DriveGetType($Drive)
        
        $Label=DriveGetLabel($Drive)
        
        $DriveTotal=DriveSpaceTotal($Drive)
            Space($DriveTotal)
        $DriveFree=DriveSpaceFree($Drive)
            Space($DriveFree)
        $DriveUsed=DriveSpaceTotal($Drive)-DriveSpaceFree($Drive)
            Space($DriveUsed)
        
        GUICtrlSetData($DisplayType,$Drive&"     "&DriveGetFileSystem($Drive)&"     "&$DriveType&$Status&@CRLF&$Label)
        GUICtrlSetData($DisplayTotal,"Total"&@CRLF&$DriveTotal)
        GUICtrlSetData($DisplayFree,"Free"&@CRLF&$DriveFree)
        GUICtrlSetData($DisplayUsed,"Used"&@CRLF&$DriveUsed)
        
        GUISetState()
        Sleep($UpdateInterval)
    Until $msg = $GUI_EVENT_CLOSE
Exit

Func VersionInfo()      ; Add a function key
    MsgBox(1,"Version","Date:   2009.11.5"&@CRLF&"Release: 1")
EndFunc
Func Quit()
    Exit
EndFunc

FuncSpace:

Func Space(ByRef $Space)
    If($Highest<$Space)Then
        $Space=$Space/1024
        $ByteType="GB"
        If($Highest<$Space)Then
            $Space=$Space/1024
            $ByteType="TB"
            If($Highest<$Space)Then
                $Space=$Space/1024
                $ByteType="PB"
                If($Highest<$Space)Then
                    $Space=$Space/1024
                    $ByteType="EB"
                    If($Highest<$Space)Then
                        $Space=$Space/1024
                        $ByteType="ZB"
                        If($Highest<$Space)Then
                            $Space=$Space/1024
                            $ByteType="YB"
                        EndIf
                    EndIf
                EndIf
            EndIf
        EndIf
    ElseIf($Low<$Space)And($Space<=$Highest)Then
        $ByteType="MB"
    ElseIf($Space<=$Low)Then
        $Space=$Space*1024
        $ByteType="KB"
        If($Space<=$Low)Then
            $Space=$Space*1024
            $ByteType="Byte"
            If Not(1=$Space)Then $ByteType=$ByteType&"s"
        EndIf
    ElseIf($Space=0)Then
        $ByteType=""
    EndIf
    $Space=Round($Space,2)&$ByteType
EndFunc

This program will constantly poll the hard drive space.

As you can see [if you compiled], not a key logger.

:)

GUI Accelerator seems like it will do, but is it going to work?

This is one of my project sample from [another thread].

I saw in the help file that they used $msg.

I cannot do if($msg=="blah") in any of my programs for the sake of resource usage.

Especially in that program I posted.

Who wants their hard drive polled every millisecond?

Edited by RandomClown

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

Are you asking if the accelerators work while using GuiOnEventMode? They certainly do:

#include <GUIConstantsEx.au3>

Opt("GuiOnEventMode", 1)

GUICreate("Custom Msgbox", 210, 80)

GUICtrlCreateLabel("Please click a button!", 10, 10)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Quit")
$YesID = GUICtrlCreateButton("Yes", 10, 50, 50, 20)
GUICtrlSetOnEvent(-1, "_ButtonEvent")
$NoID = GUICtrlCreateButton("No", 80, 50, 50, 20)
GUICtrlSetOnEvent(-1, "_ButtonEvent")
$ExitID = GUICtrlCreateButton("Exit", 150, 50, 50, 20)
GUICtrlSetOnEvent(-1, "_ButtonEvent")
GUISetState()  ; display the GUI

; Set accelerators for Ctrl+y and Ctrl+n
Dim $AccelKeys[3][2]=[["^y", $YesID], ["^n", $NoID], ["^x", $ExitID]]
GUISetAccelerators($AccelKeys)

While 1
    Sleep(10)
WEnd

Func _ButtonEvent()
    Switch @GUI_CtrlId
        Case $YesID
            MsgBox(0, "You clicked on", "Yes", 2)
        Case $NoID
            MsgBox(0, "You clicked on", "No", 2)
        Case $ExitID
            _Quit()
    EndSwitch
EndFunc

Func _Quit()
    Exit
EndFunc

:)

Edit: That's actually a bad example because a blocking function (MsgBox) should NEVER be used inside an event function. But just to show that event mode can handle many GUIs at once, with accelerators, try this one:

#include <GUIConstantsEx.au3>
#include <Array.au3>

Opt("GuiOnEventMode", 1)

Global $YesID, $NoID, $ExitID

; 2D Array of timed GUIs
; [0][0] = Count
; [n][0] = HWND
; [n][1] = GUI life span (in seconds)
; [n][2] = Time created (from TimerInit)
Global $aTimedGUI[1][3] = [[0, "", ""]]

; Create GUI
GUICreate("Custom Msgbox", 210, 80)
GUICtrlCreateLabel("Please click a button!", 10, 10)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Quit")
$YesID = GUICtrlCreateButton("Yes", 10, 50, 50, 20)
GUICtrlSetOnEvent(-1, "_ButtonEvent")
$NoID = GUICtrlCreateButton("No", 80, 50, 50, 20)
GUICtrlSetOnEvent(-1, "_ButtonEvent")
$ExitID = GUICtrlCreateButton("Exit", 150, 50, 50, 20)
GUICtrlSetOnEvent(-1, "_ButtonEvent")
GUISetState() ; display the GUI

; Set accelerators for Ctrl+y and Ctrl+n
Dim $AccelKeys[3][2] = [["^y", $YesID],["^n", $NoID],["^x", $ExitID]]
GUISetAccelerators($AccelKeys)

; Start Timed GUI AdLib function
AdlibEnable("_GUI_Timer", 500)

; Idle loop
While 1
    Sleep(10)
WEnd

; Handle buttons on main GUI
Func _ButtonEvent()
    Switch @GUI_CtrlId
        Case $YesID
            _CreateTimedGUI("You clicked on: Yes", 9)
        Case $NoID
            _CreateTimedGUI("You clicked on: No", 11)
        Case $ExitID
            _Quit()
    EndSwitch
EndFunc   ;==>_ButtonEvent

; Create a GUI with a timed life
Func _CreateTimedGUI($sText, $iTime)
    ; Calculate location
    Local $iX = 100, $iY = 100, $aWinPos
    If $aTimedGUI[0][0] Then
        $aWinPos = WinGetPos($aTimedGUI[$aTimedGUI[0][0]][0], "")
        $iX = $aWinPos[0]
        $iY += $aWinPos[1]
        If $iY > @DesktopHeight - 100 Then
            $iX += 100
            If $iX > @DesktopWidth - 200 Then $iX = 100
            $iY = 100
        EndIf
    EndIf
    Local $hWnd = GUICreate("Timed GUI", 250, 100, $iX, $iY)
    GUICtrlCreateLabel($sText, 10, 10, 230, 40)
    GUICtrlCreateButton("Close", 25, 60, 100, 30)
    GUICtrlSetOnEvent(-1, "_CloseTimedGUI")
    ReDim $aTimedGUI[UBound($aTimedGUI) + 1][3]
    $aTimedGUI[0][0] = UBound($aTimedGUI) - 1
    $aTimedGUI[$aTimedGUI[0][0]][0] = $hWnd
    $aTimedGUI[$aTimedGUI[0][0]][1] = $iTime
    $aTimedGUI[$aTimedGUI[0][0]][2] = TimerInit()
    GUISetState(@SW_SHOW, $hWnd)
EndFunc   ;==>_CreateTimedGUI

; Handle Close button on a timed GUI
Func _CloseTimedGUI()
    _DeleteTimedGUI(@GUI_WinHandle)
EndFunc   ;==>_CloseTimedGUI

; Periodically test timeout of all timed GUIs
Func _GUI_Timer()
    If $aTimedGUI[0][0] > 0 Then
        ; Check each GUI for timeout
        For $n = $aTimedGUI[0][0] To 1 Step -1
            If TimerDiff($aTimedGUI[$n][2]) >= ($aTimedGUI[$n][1] * 1000) Then _DeleteTimedGUI($aTimedGUI[$n][0])
        Next
    EndIf
EndFunc   ;==>_GUI_Timer

; Delete a timed GUI and remove it from the array
Func _DeleteTimedGUI($hWnd)
    GUIDelete($hWnd)
    Local $iIndex = _ArraySearch($aTimedGUI, $hWnd, 1, 0, 0, 0, 1, 0)
    If Not @error Then _ArrayDelete($aTimedGUI, $iIndex)
    $aTimedGUI[0][0] = UBound($aTimedGUI) - 1
EndFunc   ;==>_DeleteTimedGUI

; Quit script
Func _Quit()
    Exit
EndFunc   ;==>_Quit

Replace AdLibEnable() with AdLibRegister() to run in Beta. Open many windows with Ctrl-y and/or Ctrl-n, then close a couple of the popups while waiting for the timer to take them out as they expire.

;)

Edited by PsaltyDS

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

lol wow, better than I expected of it.

:)

I will definitely check that out when I get the chance!

**book-marked**

Thanks for the detailed response!

PS: Sorry for this post being so late.

I must be getting old...I keep forgetting what I'm working on.

Edited by RandomClown

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