Раз создали, значит надо решать.
Основной элемент есть в моём коде, если захотите добавить, ещё и не получится, обсудим тут (извините, не стал заморачиваться более чем с одним (не считая уведомлений)).
CoordMode, Mouse
Menu, Tray, NoStandard
Menu, Tray, Add, Exit, ExitScript
HKeys:=[], IsKey:=False
bmd1=
(Join
0000ffff000000000000ffff000000000000
ffff000000000000ffff000000000000ffff
)
bmd2=
(Join
00ffffff0000000000ffffff0000000000ff
ffff0000000000ffffff0000000000ffffff
)
hpatbr1:=CreatePBrush(bmd1), hpatbr2:=CreatePBrush(bmd2)
#LButton::
If WinExist("ahk_id"GUIhWnd) Or WinExist("ahk_id"hMsg)
Return
If !IsSeek
For Key, Value In HKeys
Hotkey, % Value.key1, HKeyLabel, Off
If IsSeek
SetTimer, Settings, -75
SetTimer, ChaseCursor, % (IsSeek:=!IsSeek) ? 125:"Off"
Return
ChaseCursor:
MouseGetPos,,,, nCtrl, 1
MouseGetPos,,,, hCtrl, 2
WinGetPos, X, Y, W, H, % "ahk_id"hCtrl
CreateRgn(X, Y, W, H, hpatbr1, 6)
If hCtrlPassed<>hCtrl
Gosub, Redraw
hCtrlPassed:=hCtrl
Return
Settings:
Gui, +AlwaysOnTop -Caption +Border +ToolWindow HwndGUIhWnd
Gui, Add, Hotkey, vHKey x4 y4 w118 h20
Gui, Add, Button, x76 y27 w45 h20, Set
If % Counter>=1
{
Gui, Add, Checkbox, x6 y27 w70 h20 vIsChecked, Delete all
Gui, Add, ListView, x4 y57 w118 h100
, % " hotkey"(Counter>1 ? "s":"")
. " ("Counter ") | hCtrl | nCtrl "
For Key, Value In HKeys
{
SetFormat, Integer, H
Value_value1:=Value.value1
SetFormat, Integer, D
LV_Add("", Value.key1, Value_value1, Value.value2)
}
Gui, Show, w127 h164
}
Else Gui, Show, w127 h53
CreateRgn(X, Y, W, H, hpatbr1)
CoordMode, Mouse, Relative
ControlGetPos, CX, CY, CW, CH, Button1, % "ahk_id"GUIhWnd
MouseMove, CX+CW//2, CY+CH//2, 0
CoordMode, Mouse
Return
ButtonSet:
Gui, Submit
Gui, Destroy
SetTimer, Redraw, -0
If !HKey Or IsChecked
{
SetTimer, % "EditMsg"(IsChecked ? "":"2"), -50
MsgBox, % 2622 . (IsChecked ? 08:12)
,, % IsChecked ? "Deleted":"Hotkey is not set"
. ", try again?", % IsChecked ? 1:0
IfMsgBox, Yes
Goto, Settings
Else Goto, Continue
}
For Key, Value In HKeys
If IsDuplicate:=(Value.key1=HKey And Value.value1=hCtrl)
{
SetTimer, EditMsg, -50
MsgBox, 262160,, % "Duplicate`n("HKey ")", 1
Goto, Continue
}
For Key, Value In HKeys
If % Value.key1=HKey Or Value.value1=hCtrl
{
IsKey:=(Value.key1=HKey) ? True:False
SetTimer, % "EditMsg"(IsKey ? "":"2"), -50
MsgBox, % 26221 . (IsKey ? 1:2)
,, % "This "(IsKey ? "hotkey ("HKey ")":"control")
. " already used"(IsKey ? ", choose resolve below":"")
. "`n"(IsKey ? "":"set this hotkey ("HKey ") too?")
IfMsgBox, No
Goto, Continue
IfMsgBox, Yes
{
For Key, Value In HKeys
If % Value.key1=HKey
HKeys.Remove(Key)
Break
}
IfMsgBox, Cancel
{
For Key, Value In HKeys
If % Value.key1=HKey
HKeys.Remove(Key)
Goto, Continue
}
}
HKeys.Insert( New Data(HKey, hCtrl, nCtrl))
Continue:
For Key, Value In HKeys
{
Counter:=A_Index
Hotkey, % Value.key1, HKeyLabel, On
}
Return
HKeyLabel:
SetTimer, Redraw, -250
For Key, Value In HKeys
If Value.key1=A_ThisHotkey
{
WinGetPos, X, Y, W, H, % "ahk_id"Value.value1
Break
}
MouseClick,, X+W//2, Y+H//2,, 0
CreateRgn(X, Y, W, H, hpatbr2)
KeyWait, % A_ThisHotkey
Return
EditMsg:
If IsChecked Or IsDuplicate
{
Control, Hide,, Button1, A
If IsChecked
HKeys:=[], Counter:=IsChecked:=False
IsDuplicate:=False
WinMove, A,, A_ScreenWidth//2-(150//2)
, A_ScreenHeight//2-(90//2), 150, 90
}
Else
{
ControlSetText, Button1, Reassign, A
ControlSetText, Button2, Cancel, A
ControlSetText, Button3, Delete, A
}
EditMsg2:
WinSet, Style, -0xC00000, % "ahk_id"hMsg:=WinActive("A")
Return
Redraw:
DllCall("RedrawWindow", "UInt", 0
, "UInt", 0
, "UInt", hRgn
, "UInt", 0x787)
DllCall("DeleteObject", "UInt", hRgn)
Return
ExitScript:
DllCall("DeleteObject", "UInt", hpatbr1)
DllCall("DeleteObject", "UInt", hpatbr2)
ExitApp
CreatePBrush(bmd)
{
VarSetCapacity(Buffer, nSize:=StrLen(bmd)//2, 0)
Loop, % nSize
NumPut("0x"SubStr(bmd, 2*A_Index-1, 2)
, Buffer, A_Index-1, "UChar")
hBm:=DllCall("CreateBitmap", "UInt", 3
, "UInt", 3
, "UInt", 1
, "UInt", 32
, "UInt", &Buffer)
Return, DllCall("CreatePatternBrush", "UInt", hBm)
DllCall("DeleteObject", "UInt", hBm)
}
CreateRgn(xpos, ypos, width, height, pbrush, mixmode=13)
{
global hRgn
hDC:=DllCall("GetDC", "UInt", 0)
DllCall("SetROP2", "UInt", hDC, "Int", mixmode)
hRgn:=DllCall("CreateRectRgn", "Int", xpos
, "Int", ypos
, "Int", xpos+width
, "Int", ypos+height)
DllCall("FrameRgn", "UInt", hDC
, "UInt", hRgn
, "UInt", pbrush
, "UInt", 6
, "UInt", 6)
DllCall("ReleaseDC", "UInt", 0
, "UInt", hDC)
}
Class Data
{
__New(key1, value1, value2)
{
This.key1:=key1, This.value1:=value1, This.value2:=value2
}
}