Jump to content
bobbyab9987

How to temporarily disable all hotkeysets?

Recommended Posts

After a long time using AutoIt to automate tasks on my PC, my work performance has increased noticeably.

However, now that my script has grown quite big, I have a new problem: Each time I add a new hotkeyset, I have to search the whole script for possible conflicting hotkeys and temporarily disable those hotkeys.

Let's look at the example below:

Say I have function do_task_1() like this:

Func do_task_1()

    ; Unset the HotKey to prevent hotkey recursion
    HotKeySet($task_1_hotkey)

    ; do task 1 here (call a bunch of send() functions)

    ; And now reset the HotKey
    HotKeySet($task_1_hotkey, "do_task_1")
    
EndFunc

Now if I add another function, let's say do_task_2(), like this:

Func do_task_2()

    ; Unset the HotKey
    HotKeySet($task_2_hotkey) ; prevent hotkey recursion

    ; do task 2 here

    ; And now reset the HotKey
    HotKeySet($task_2_hotkey, "do_task_2")
    
EndFunc

And if, for some random reasons, $task_2_hotkey is used inside do_task_1()'s body, then inside do_task_1() body, I have to temporarily disable do_task_2() like this:

Func do_task_1()

    ; Unset the HotKeys to prevent hotkey recursion
    HotKeySet($task_1_hotkey) 
    HotKeySet($task_2_hotkey)

    ; do task 1 here (call a bunch of send() functions)
    ; one of them is: send($task_2_hotkey)

    ; And now reset the HotKeys
    HotKeySet($task_1_hotkey, "do_task_1")
    HotKeySet($task_2_hotkey, "do_task_2")
    
EndFunc

Over time, the more HotKeySets I add, the more frequent I have to check and temporarily disable conflicting hotkeys like above. In fact I already had hotkeysets inside whose bodies I have to temporarily disable 3-4 other hotkeysets. This is both inelegant and time consuming.

So I think it would be very nice if there is some way to disable / enable all other hotkeys in just one command like this:

Func do_task_1()

    disableAllHotkeys()

    ; do task 1 here

    enableAllHotkeys()
    
EndFunc

Does such a built-in method exist in AutoIt? If not, then is there any concise method to tackle this problem (other than manually checking and disabling like I did above)?

Thank you.

Share this post


Link to post
Share on other sites

@faustf good joke! You must be a fan of Tolkien.


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites

bobbyab9987,

Perhaps you could use an array to store the various HotKeys in use and then use a function to Enable/Disable them in a loop every time you find the need. This should give you the idea:

; Declare array to hold HotKeys
Global $aHotKeys[3][2]

; Now set your hotkeys

$aHotKeys[0][0] = "!+a"   ; Keys
$aHotKeys[0][1] = "_HK_0" ; Function
HotKeySet($aHotKeys[0][0], $aHotKeys[0][1])

$aHotKeys[1][0] = "!+b"
$aHotKeys[1][1] = "_HK_1"
HotKeySet($aHotKeys[1][0], $aHotKeys[1][1])

$aHotKeys[2][0] = "!+c"
$aHotKeys[2][1] = "_HK_2"
HotKeySet($aHotKeys[2][0], $aHotKeys[2][1])

HotKeySet("{ESC}", "_Exit")

While 1
    Sleep(10)
WEnd

Func _Exit()
    Exit
EndFunc

Func _HK_0()

    _DisableHK()
    Send("HotKey A actioned" & @CRLF)
    ; Deliberately send another hotkey
    Send("!+b")
    _EnableHK()

EndFunc

Func _HK_1()

    _DisableHK()
    Send("HotKey B actioned" & @CRLF)
    ; Deliberately send another hotkey
    Send("!+c")
    _EnableHK()

EndFunc

Func _HK_2()

    _DisableHK()
    Send("HotKey C actioned" & @CRLF)
    ; Deliberately send another hotkey
    Send("!+a")
    _EnableHK()

EndFunc

Func _DisableHK()
    For $i = 0 To UBound($aHotKeys) - 1
        HotKeySet($aHotKeys[$i][0])
    Next
EndFunc

Func _EnableHK()
    For $i = 0 To UBound($aHotKeys) - 1
        HotKeySet($aHotKeys[$i][0], $aHotKeys[$i][1])
    Next
EndFunc

You can see that only the initial HotKey is honoured - if you Send another HotKey combination during the function, nothing happens.

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
Posted (edited)

@jchdyeaaa  who is not fan of Tolkien???

@Musashi somthing like this

#include <MsgBoxConstants.au3>

; Press Esc to terminate script, Pause/Break to "pause"

Global $g_bPaused = False

HotKeySet("+!o", "_ON") ; Shift-Alt-d
HotKeySet("+!p", "_off") ; Shift-Alt-d

While 1
    Sleep(100)
WEnd

Func TogglePause()
    $g_bPaused = Not $g_bPaused
    While $g_bPaused
        Sleep(100)
        ToolTip('Script is "Paused"', 0, 0)
    WEnd
    ToolTip("")
EndFunc   ;==>TogglePause

Func Terminate()
    Exit
EndFunc   ;==>Terminate

Func ShowMessage()
    MsgBox($MB_SYSTEMMODAL, "", "This is a message.")
EndFunc   ;==>ShowMessage

Func _ON()

HotKeySet("{PAUSE}", "TogglePause")
HotKeySet("{ESC}", "Terminate")
HotKeySet("+!d", "ShowMessage") ; Shift-Alt-d

EndFunc


Func _off()
    HotKeySet("+!d")
EndFunc

i thinked

Edited by faustf

Share this post


Link to post
Share on other sites

If the OP is a hotkey fan, one hotkey to rule them all is not incompatible with Melba's array way  :think:

Share this post


Link to post
Share on other sites

Rather than unsetting & re-setting all the hot keys could you just set a flag to ignore the others?

 

Func hotkey_busy($bBusy)
    static $bIsBusy = False
    If $bBusy and $bIsBusy Then Return True
    $bIsBusy = $bBusy
    Return False
EndFunc

Func do_task_1()

    If hotkey_busy(True) Then Return

    ; do task 1 here (call a bunch of send() functions)

    hotkey_busy(False)
    
EndFunc

Func do_task_2()

    If hotkey_busy(True) Then Return

    ; do task 2 here

    hotkey_busy(False)
    
EndFunc

 

Share this post


Link to post
Share on other sites
8 hours ago, bobbyab9987 said:

Each time I add a new hotkeyset, I have to search the whole script

$aHotKeys[0][0] = "!+a"   ; Keys
$aHotKeys[0][1] = "_HK_0" ; Function

$aHotKeys[1][0] = "!+b"
$aHotKeys[1][1] = "_HK_1"

$aHotKeys[2][0] = "!+c"
$aHotKeys[2][1] = "_HK_2"

... ...

For $n = 0 To UBound($aHotKeys) -1
    HotKeySet($aHotKeys[$n][0], $aHotKeys[$n][1])
Next

...so is easy to find

Share this post


Link to post
Share on other sites

Bilgus,

There could be a problem with your approach as I believe the HotKey combination itself will be eaten by the active function and so never be sent to the underlying app, which was the whole reason for disabling the other Hotkeys.

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
Posted (edited)
Global Enum $iHKEx_HotKey, $iHKEx_Func, $iHKEx_Params, _
    $iHKEx_Total
Global $aHKEx_Data[1][$iHKEx_Total]

_HotKeySetEx('{ESC}', '_Escape', 'Exit?')
_HotKeySetEx('{ENTER}', '_OK', 'OK')

If MsgBox(36, @ScriptName, 'Unset all?') = 6 Then
    _HotKeySetEx()
    MsgBox(64, @ScriptName, 'Please check your hot keys...')
    Exit
EndIf

While 1
    Sleep(10)
WEnd

Func _OK($vData)
    MsgBox(64, @ScriptName, $vData)
EndFunc

Func _Escape($vData)
    If MsgBox(52, @ScriptName, $vData) = 6 Then
        Exit
    EndIf
EndFunc

;============ HotKeyEx UDF ============

Func _HotKeySetEx($sHotKey = '', $sFunc = '', $vParam = '')
    ;Unset hotkey
    If $sFunc = '' Or $sHotKey = '' Then
        Local $aTmp[1][$iHKEx_Total]
        
        ;Unset all
        If $sHotKey = '' Then
            For $i = 1 To $aHKEx_Data[0][0]
                HotKeySet($aHKEx_Data[$i][$iHKEx_HotKey])
            Next
            
            $aHKEx_Data = $aTmp
            Return 1
        EndIf
        
        ReDim $aTmp[$aHKEx_Data[0][0]][$iHKEx_Total]
        
        For $i = 1 To $aHKEx_Data[0][0]
            If $aHKEx_Data[$i][$iHKEx_HotKey] = $sHotKey Then
                HotKeySet($aHKEx_Data[$i][$iHKEx_HotKey])
            Else
                $aTmp[0][0] += 1
                $aTmp[$aTmp[0][0]][$iHKEx_HotKey] = $aHKEx_Data[$i][$iHKEx_HotKey]
                $aTmp[$aTmp[0][0]][$iHKEx_Func] = $aHKEx_Data[$i][$iHKEx_Func]
                $aTmp[$aTmp[0][0]][$iHKEx_Params] = $aHKEx_Data[$i][$iHKEx_Params]
            EndIf
        Next
        
        $aHKEx_Data = $aTmp
        Return 1
    EndIf
    
    $aHKEx_Data[0][0] += 1
    ReDim $aHKEx_Data[$aHKEx_Data[0][0] + 1][$iHKEx_Total]
    
    $aHKEx_Data[$aHKEx_Data[0][0]][$iHKEx_HotKey] = $sHotKey
    $aHKEx_Data[$aHKEx_Data[0][0]][$iHKEx_Func] = $sFunc
    $aHKEx_Data[$aHKEx_Data[0][0]][$iHKEx_Params] = $vParam
    
    Return HotKeySet($sHotKey, '__HKEx_Handler')
EndFunc

Func __HKEx_Handler()
    For $i = 1 To $aHKEx_Data[0][0]
        If $aHKEx_Data[$i][$iHKEx_HotKey] = @HotKeyPressed Then
            Call($aHKEx_Data[$i][$iHKEx_Func], $aHKEx_Data[$i][$iHKEx_Params])
            
            If @error = 0xDEAD And @extended = 0xBEEF Then
                Call($aHKEx_Data[$i][$iHKEx_Func])
            EndIf
        EndIf
    Next
EndFunc

 

Edited by MrCreatoR

 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize Program

AutoIt_Icon_small.pngUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF
 
AutoIt_Icon_small.pngExamples: 
ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo

Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Share this post


Link to post
Share on other sites

Hi guys, thank you very much for your suggestions.

Melba23's solution is good and is similar to my initial idea when I first thought about this problem, but I think it might affect performance when the array grows.

I don't understand faustf's and MrCreatoR's solutions.

I think the solution offered by Bilgus is very good since it's succinct and it's like an O(1) algorithm (i.e. no matter how many more hotkeysets I add, this solution's execution time does not escalate). Based on this solution, I have written another one (same idea as Bilgus, but easier to understand).

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

; ^ = Ctrl
; ! = Alt
; + = Shift

Global $task1hk = "1"
HotKeySet($task1hk, "doTask1")

Global $task2hk = "2"
HotKeySet($task2hk, "doTask2")

Global $isBusyFlag = False

While 1
   Sleep(100)
WEnd

Func doTask1()

    If ($isBusyFlag = True) Then
        sendStrayHotkey($task1hk, "doTask1")
        Return
    EndIf
    
    $isBusyFlag = True
    
    ; Unset the HotKey
    HotKeySet($task1hk) ; prevent hotkey recursion

    _SendEx("Task 1 is executing..." & @CRLF)
    _SendEx($task2hk)

    ; And now reset the HotKey
    HotKeySet($task1hk, "doTask1")
    
    $isBusyFlag = False
    
EndFunc

Func doTask2()

    If ($isBusyFlag = True) Then
        sendStrayHotkey($task2hk, "doTask2")
        Return
    EndIf
    
    $isBusyFlag = True

    ; Unset the HotKey
    HotKeySet($task2hk) ; prevent hotkey recursion
    
    _SendEx("Task 2 is executing..." & @CRLF)

    ; And now reset the HotKey
    HotKeySet($task2hk, "doTask2")
    
    $isBusyFlag = False
    
EndFunc

Func sendStrayHotkey($hk, $task)
    HotKeySet($hk)
    _SendEx($hk)
    HotKeySet($hk, $task)    
EndFunc

Func _SendEx($ss, $warn = "")

    Local $iT = TimerInit()

    While _IsPressed("10") Or _IsPressed("11") Or _IsPressed("12")
        If $warn <> "" And TimerDiff($iT) > 1000 Then
            MsgBox(262144, "Warning", $warn)
        EndIf
        Sleep(50)
    WEnd

    Send($ss)

EndFunc;==>_SendEx

I ran the test script above and it worked as expected: Command _SendEx($task2hk), which is issued inside doTask1()'s body, does not activate doTask2(), it just sends out the hotkey of doTask2() (which is what I actually want).

Share this post


Link to post
Share on other sites

...working with arrays can be overwhelming at first but it opens a world of possibilities. Try to play with arrays to get the hang of it. It'll be worth it.
As far as your code: if it works, it worked. If you found a solution you can get your head around, then is all good.
You can always revisit old code and update it with your newer style, as you become more proficient ;) 

Share this post


Link to post
Share on other sites
2 hours ago, bobbyab9987 said:

I don't understand faustf's and MrCreatoR's solutions.

This is the best time to start understanding this kind of solutions, it's not so complicated, and the usage is simple.

The idea is to set hotkeys and hold them in array, and when needed, unset it by the data in this array.


 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize Program

AutoIt_Icon_small.pngUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF
 
AutoIt_Icon_small.pngExamples: 
ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo

Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

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

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...