Sign in to follow this  
Followers 0
iCode

GUISetAccelerators() - best way to prevent repeating func?

8 posts in this topic

#1 ·  Posted (edited)

hi

when using GUISetAccelerators() i discovered that the function will keep repeating as long as the hotkey is pressed.

this seems strange in that the function would not repeat if you clicked the item with the mouse.

anyway i am wondering how best to disable the repeating so the func runs only once for each key press?

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

Local $Form1 = GUICreate("", 261, 62, 344, 145)
Local $MenuItem1 = GUICtrlCreateMenu("MenuItem1")
Local $MenuItem2 = GUICtrlCreateMenuItem("MenuItem2", $MenuItem1)
GUICtrlCreateLabel("press F2 and look at console output", 44, 8, 173, 17)
Local $_AccelTable[1][2] = [["{F2}", $MenuItem2]]
GUISetAccelerators($_AccelTable)
GUISetState(@SW_SHOW)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit

        Case $MenuItem2

            ConsoleWrite('F2...' & @CRLF)

    EndSwitch
WEnd

i even tried using Do-Sleep-Until _IsPressed() = 0 in a loop which didn't work (and is not very pretty anyway i think)

Edited by iCode

FUNCTIONS: WinDock (dock window to screen edge) | EditCtrl_ToggleLineWrap (line/word wrap for AU3 edit control) | SendEX (yet another alternative to Send( ) ) | Spell Checker (Hunspell wrapper) | SentenceCase (capitalize first letter of sentences)

CODE SNIPPITS: Dynamic tab width (set tab control width according to window width)

Share this post


Link to post
Share on other sites



i think that happends because usualy when you press a button with accelerators the button is deleted or you pass to another piece of code with the accelerator disabled

Share this post


Link to post
Share on other sites

yeah, there are different ways of getting around it but nothing i like ... especially since i have to do it for a number of keys. i thought i may be missing something more obvious


FUNCTIONS: WinDock (dock window to screen edge) | EditCtrl_ToggleLineWrap (line/word wrap for AU3 edit control) | SendEX (yet another alternative to Send( ) ) | Spell Checker (Hunspell wrapper) | SentenceCase (capitalize first letter of sentences)

CODE SNIPPITS: Dynamic tab width (set tab control width according to window width)

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

maybe... (doesn't look pretty but you'll get what you want)

...

sorry, seems to forgot the option for manually clicking the item with mouse button ^^ so... no, this won't work either... :/

edit: see post bellow,

Edited by dragan

Share this post


Link to post
Share on other sites

thanks dragan - i will see what i can do with that!


FUNCTIONS: WinDock (dock window to screen edge) | EditCtrl_ToggleLineWrap (line/word wrap for AU3 edit control) | SendEX (yet another alternative to Send( ) ) | Spell Checker (Hunspell wrapper) | SentenceCase (capitalize first letter of sentences)

CODE SNIPPITS: Dynamic tab width (set tab control width according to window width)

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

sort of fixed the script I posted above, now working both, hotkey and mouse clicking on menu, and will start function only once:

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>

Global $LastCode = -1 ;just to make sure no color console repeats

Local $Form1 = GUICreate("", 261, 62, 344, 145)
Local $MenuItem1 = GUICtrlCreateMenu("MenuItem1")
Local $MenuItem2 = GUICtrlCreateMenuItem("MenuItem2", $MenuItem1)
GUICtrlCreateLabel("press F2 and look at console output", 44, 8, 173, 17)
Local $_AccelTable[1][2] = [["{F2}", $MenuItem2]]
Local $_AccelTableHelp[1][2] = [[0, False]]
GUISetAccelerators($_AccelTable)
GUISetState(@SW_SHOW)

OnAutoItExitRegister("_Cleanup")

$hStub_KeyProc = DllCallbackRegister("_KeyProc", "long", "int;wparam;lparam")
$hmod = _WinAPI_GetModuleHandle(0)
$hHook = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($hStub_KeyProc), $hmod)

GUIRegisterMsg(0x011F, 'clickMenu')

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $MenuItem2
            If ($_AccelTableHelp[0][0] = 1) OR ($_AccelTableHelp[0][1] = True) then
                If $_AccelTableHelp[0][1] = True Then $_AccelTableHelp[0][1] = False
                If $_AccelTableHelp[0][0] = 1 Then $_AccelTableHelp[0][0] = 2
                ;---- operation goes here ----------
                Local $signs[4] = ['+','-','!','>']
                Local $SomeRandomNumber
                Do  ;just to make sure that no color console repeats
                    $SomeRandomNumber = Random(0, 3, 1)
                Until $SomeRandomNumber <> $LastCode
                $LastCode = $SomeRandomNumber
                ConsoleWrite($signs[$LastCode] & @TAB & 'F2 pressed' & @CRLF)
                ;---- end of operation -------------
            EndIf
    EndSwitch
WEnd

Func clickMenu($hWnd, $Msg, $wParam, $lParam)
    $_AccelTableHelp[0][1] = True
    Return $GUI_RUNDEFMSG
EndFunc

Func _KeyProc($nCode, $wParam, $lParam)
    Local $tKEYHOOKS, $keyCode
    $tKEYHOOKS = DllStructCreate($tagKBDLLHOOKSTRUCT, $lParam)
    If $nCode < 0 Then
        Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
    EndIf
    If WinActive($Form1) then
        If ($wParam = $WM_KEYDOWN) then
            Local $keyCode = DllStructGetData($tKEYHOOKS, "vkCode")
            If ($keyCode = 113) AND ($_AccelTableHelp[0][0] = 0) Then $_AccelTableHelp[0][0] = 1
        ElseIf ($wParam = $WM_KEYUP) then
            Local $keyCode = DllStructGetData($tKEYHOOKS, "vkCode")
            If ($keyCode = 113) AND ($_AccelTableHelp[0][0] = 2) Then $_AccelTableHelp[0][0] = 0
        EndIf
    EndIf
    Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
EndFunc

Func _Cleanup()
    _WinAPI_UnhookWindowsHookEx($hHook)
    DllCallbackFree($hStub_KeyProc)
EndFunc

edit: code optimization

Edited by dragan

Share this post


Link to post
Share on other sites

dragan - thanks

i haven't gotten around to playing with this yet, but i will shortly


FUNCTIONS: WinDock (dock window to screen edge) | EditCtrl_ToggleLineWrap (line/word wrap for AU3 edit control) | SendEX (yet another alternative to Send( ) ) | Spell Checker (Hunspell wrapper) | SentenceCase (capitalize first letter of sentences)

CODE SNIPPITS: Dynamic tab width (set tab control width according to window width)

Share this post


Link to post
Share on other sites

how about this...

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

Local $Form1 = GUICreate("Form1", 280, 153, 586, 179)
Local $MenuItem1 = GUICtrlCreateMenu("MenuItem1")
Local $MenuItem2 = GUICtrlCreateMenuItem("MenuItem2"&@TAB&"F2", $MenuItem1)
Local $Form1_AccelTable[1][2] = [["{F2}", $MenuItem2]]
GUISetAccelerators($Form1_AccelTable)
GUISetState(@SW_SHOW)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $MenuItem2

            ConsoleWrite('in' & @LF)
            GUISetAccelerators('')
            Do
                Sleep(10)
            Until _IsPressed('71') = 0
            ConsoleWrite('out' & @LF)
            GUISetAccelerators($Form1_AccelTable)

    EndSwitch
WEnd

FUNCTIONS: WinDock (dock window to screen edge) | EditCtrl_ToggleLineWrap (line/word wrap for AU3 edit control) | SendEX (yet another alternative to Send( ) ) | Spell Checker (Hunspell wrapper) | SentenceCase (capitalize first letter of sentences)

CODE SNIPPITS: Dynamic tab width (set tab control width according to window width)

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