It also allows you to keep a log of all hotkeys. Live, within the script as it is running, and to a text file. You could have an OnExit function that outputs hotkey data to an ini file when the script exits, giving you usage data on hotkeys: first/last/total usage.
The script also allows you to get extended information for current and past hotkeys, far more than what is currently available in the 'A_' variables.
This is a prototype, in future, I might change some of the variable/object names to make them more convenient. I think now that I would want to use the name 'AX_' variables/objects, for something that I would want to be an 'A_' variable/object, but for which I don't want to call it that, in order to not cause confusion with standard 'A_' variables.
Here is some potential logic intended to make sure that hotkeys are always applied to the correct window:
Code: Select all
;e.g. AX_HotkeyCount is 50, when the 50th hotkey is pressed
;e.g. AX_HotkeyHWnd[50] would be the hWnd that matched the window criteria when the 50th hotkey was triggered
MyLabel:
if !(vMyLabelHKCount = "")
return
vMyLabelHKCount := AX_HotkeyCount
hWnd := WinExist("A")
if (hWnd = AX_HotkeyHWnd[vMyLabelHKCount])
MsgBox, % "OK to proceed"
else
MsgBox, % "do nothing"
vMyLabelHKCount := ""
return
full script:
Code: Select all
;==================================================
;jee log hotkeys.ahk by jeeswg
;[first released: 2017-03-23][updated: N/A]
;log hotkeys to a text file
;get extended information about hotkeys
;potentially prevent interacting with the wrong window
;uses 'Hotkey, If, % FunctionObject'
;see:
;Hotkey
;https://autohotkey.com/docs/commands/Hotkey.htm
;==================================================
#SingleInstance force
ListLines, Off
#KeyHistory 0
Menu, Tray, Click, 1
#NoEnv
AutoTrim, Off
#UseHook
SplitPath, A_ScriptName,,,, vScriptNameNoExt
Menu, Tray, Tip, % vScriptNameNoExt
;==================================================
DetectHiddenWindows, On
;'vJee'/'oJee' are the equivalent of AutoHotkey's 'A_'
global oJeeHotkey, vJeeHotkeyCount, vJeeHotkeyHWnd, vJeeHotkeyDelim, vJeePathHotkeyLog
vJeePathHotkeyLog := A_Desktop "\z jee log hotkeys list.txt"
vJeeHotkeyDelim := "|"
vList = ;continuation section
(
q|MyFunc|ahk_class Notepad
q|MyFunc|ahk_class WordPadClass
q|MyFunc|ahk_exe iexplore.exe
q|MyFunc|A
w|MyLabel|ahk_class Notepad
w|MyLabel|ahk_class WordPadClass
w|MyLabel|ahk_exe iexplore.exe
w|MyLabel|A
)
Loop, Parse, vList, `n
{
vHotkeyCriteria := A_LoopField
oHotkeyCriteria := StrSplit(vHotkeyCriteria, vJeeHotkeyDelim)
vHotkey := oHotkeyCriteria[1]
vHotkeyLabel := oHotkeyCriteria[2]
fn := Func("JEE_HotkeyHandler").Bind(vHotkeyCriteria)
Hotkey, If, % fn
Hotkey, % vHotkey, % vHotkeyLabel
}
return
;==================================================
JEE_HotkeyHandler(vHotkeyCriteria, vHotkey)
{
return JEE_HotkeyHandler2(vHotkeyCriteria, vHotkey)
}
JEE_HotkeyHandler2(vHotkeyCriteria, vHotkey)
{
static
oHotkeyCriteria := StrSplit(vHotkeyCriteria, vJeeHotkeyDelim)
if !(hWnd := WinActive(oHotkeyCriteria[3]))
return 0
if !oJeeHotkey
oJeeHotkey := {}
DllCall("kernel32\GetSystemTimeAsFileTime", Int64P,vIntervalsUTC)
DllCall("kernel32\FileTimeToLocalFileTime", Int64P,vIntervalsUTC, Int64P,vIntervalsLocal)
vDateUTC := 1601
vDateUTC += % Floor(vIntervalsUTC/10000000), Seconds
vDateLocal := 1601
vDateLocal += % Floor(vIntervalsLocal/10000000), Seconds
WinGetClass, vWinClass, % "ahk_id " hWnd
WinGet, vPName, ProcessName, % "ahk_id " hWnd
vCount++
vJeeHotkeyCount := vCount
vJeeHotkeyHWnd := hWnd
oJeeHotkey[vCount, "HWnd"] := hWnd
oJeeHotkey[vCount, "Criteria"] := vHotkeyCriteria
oJeeHotkey[vCount, "Hotkey"] := vHotkey
oJeeHotkey[vCount, "HK"] := vHotkey
oJeeHotkey[vCount, "Label"] := oHotkeyCriteria[2]
oJeeHotkey[vCount, "WinCriteria"] := oHotkeyCriteria[3]
oJeeHotkey[vCount, "WC"] := oHotkeyCriteria[3]
oJeeHotkey[vCount, "HKWC"] := oHotkeyCriteria[1] "|" oHotkeyCriteria[3]
oJeeHotkey[vCount, "Time"] := vDateLocal
oJeeHotkey[vCount, "TimeUTC"] := vDateUTC
oJeeHotkey[vCount, "MSec"] := Floor(vIntervalsLocal/10000)
oJeeHotkey[vCount, "MSecUTC"] := Floor(vIntervalsUTC/10000)
vOutput := vDateLocal "`t" vHotkeyCriteria "`t" vPName "`t" vWinClass "`r`n"
FileAppend, % vOutput, % "*" vJeePathHotkeyLog, UTF-8
return 1
}
;==================================================
;to try and ensure that we interact with the window
;that was active when the hotkey was triggered,
;and to ensure that that window has the required window criteria:
;we create a unique variable in each function/label,
;that records how many hotkeys have been triggered so far,
;we then get data for the nth hotkey when required
;e.g. 'HKWC' (hotkey and window criteria)
;if (oJeeHotkey[vMyFuncHC].HKWC = "q|ahk_class Notepad")
; WinClose, % "ahk_id " oJeeHotkey[vMyFuncHC].HWnd
;if (oJeeHotkey[vMyFuncHC].HK = "q")
; WinClose, % "ahk_id " oJeeHotkey[vMyFuncHC].HWnd
;if (oJeeHotkey[vMyFuncHC].WC = "ahk_class Notepad")
; WinClose, % "ahk_id " oJeeHotkey[vMyFuncHC].HWnd
MyFunc()
{
vMyFuncHC := vJeeHotkeyCount
MsgBox, % JEE_HotkeyInfo(A_ThisFunc)
}
MyLabel:
vMyLabelHC := vJeeHotkeyCount
MsgBox, % JEE_HotkeyInfo(A_ThisLabel)
return
;==================================================
JEE_HotkeyInfo(vLabel)
{
static
vCount := vJeeHotkeyCount
WinGetClass, vWinClass, % "ahk_id " oJeeHotkey[vCount].HWnd
WinGet, vPName, ProcessName, % "ahk_id " oJeeHotkey[vCount].HWnd
WinGet, vPID, PID, % "ahk_id " oJeeHotkey[vCount].HWnd
vOutput := ""
if !(oJeeHotkey[vCount].Hotkey = A_ThisHotkey)
vOutput .= "[warning: hotkey mismatch: " oJeeHotkey[vCount] " " A_ThisHotkey "]`r`n"
if !(oJeeHotkey[vCount].Label = vLabel)
vOutput .= "[warning: label mismatch: " oJeeHotkey[vCount].Label " " vLabel "]`r`n"
vOutput .= "==============================`r`n"
vOutput .= "criteria (hotkey): " oJeeHotkey[vCount].Hotkey "`r`n"
vOutput .= "criteria (label): " oJeeHotkey[vCount].Label "`r`n"
vOutput .= "criteria (window): " oJeeHotkey[vCount].WinCriteria "`r`n"
vOutput .= "class: " vWinClass "`r`n"
vOutput .= "process: " vPName "`r`n"
vOutput .= "hWnd: " oJeeHotkey[vCount].HWnd "`r`n"
vOutput .= "PID: " vPID "`r`n"
vOutput .= "time (local): " oJeeHotkey[vCount].Time "`r`n"
vOutput .= "time (UTC): " oJeeHotkey[vCount].TimeUTC "`r`n"
vOutput .= "system time (local): " oJeeHotkey[vCount].MSec "`r`n"
vOutput .= "system time (UTC): " oJeeHotkey[vCount].MSecUTC "`r`n"
vOutput .= "=============================="
return vOutput
}
;==================================================
Code: Select all
vHotkey1 := "q"
vHotkeyLabel1 := "MyFunc"
vHotkey2 := "w"
vHotkeyLabel2 := "MyLabel"
fn := Func("JEE_HotkeyHandler").Bind(vArg)
Hotkey, If, % fn
Hotkey, % vHotkey1, % vHotkeyLabel1
Hotkey, % vHotkey2, % vHotkeyLabel2
Hotkey, % "e", % "MyFunc"
Hotkey, r, MyLabel
return
;==================================================
JEE_HotkeyHandler(vArg, vHotkey)
{
return JEE_HotkeyHandler2(vArg, vHotkey)
}
JEE_HotkeyHandler2(vArg, vHotkey)
{
;if MyCriteria
return 1
;else
return 0
}
MyFunc()
{
MsgBox, % A_ThisFunc " " A_ThisHotkey
}
MyLabel:
MsgBox, % A_ThisLabel " " A_ThisHotkey
return