Недавно, в не первый раз, появилась задача создать довольно большой массив из кнопок, и их меток с разными префиксами. На основе "Блок функций для разработчика" из шапки (которую привёл в порядок) сделал скрипт для создания разных массивов по нажатию кнопок (Hook), вручную (Add), и автоматически из буфера обмена (Clipboard), добавляя каждую строку как ключ. Также в массиве можно учитывать количество ключей в строке (Items).
; http://forum.script-coding.com/viewtopic.php?pid=83250#p83250
#NoTrayIcon
#SingleInstance Force
#NoEnv
SetBatchLines, -1
ListLines, Off
Menu, Tray, Icon, Shell32.dll, 71
Global Hotkey_TargetFunc := "Write", Hotkey_Hook := 0, Man_Hook, hGui, CountItem := 1
Patterns := [ ["Standart delimiter", "|", "Arr := """, "|""``n" A_Tab ". """, "Key", ""]
, ["Standart delimiter (no expression)", "|", "Arr = ", , "Key"]
, [" "]
, ["Hotkey labels", "::``n" A_Tab "``n" A_Tab "Return``n``n", "", "", "Key", ""]
, ["Send `%pref`%`{`%hotkey`%`}", "", "Send, ", "", "Key", "", "{", "}"]
, ["Send array", "", "Arr := `[", "``n" A_Tab "`, ", "Key", "", "{", "}""`, ", """"]
, [" "]
, ["Simple", """, """, "Arr := `[""", """``n" A_Tab "`, """, "Key", ""]
, ["Simple (no quotes)", ", ", "Arr := [", "``n" A_Tab "`, ", "Key", ""]
, ["Simple (in simple array)", ", ", "Arr := [", "``n" A_Tab "`, ", "[""key1"", ""key2"", ""key3""]", ""]
, [" "]
, ["Associative", """: ""`%Value`%""`, """, "Arr := {""", """: ""`%Value`%""``n" A_Tab "`, """, "Key", "Value"]
, ["Associative (no quotes)", ": `%Value`%`, ", "Arr := {", ": `%Value`%``n" A_Tab "`, ", "Key", "Value"]
, ["Associative (value simple array)", """: `%Value`%`, """, "Arr := {""", """: `%Value`%``n" A_Tab "`, """
, "Key", "[""key1"", ""key2"", ""key3""]"]
, ["Associative (value simple array no quotes)", ": `%Value`%`, ", "Arr := {", ": `%Value`%``n" A_Tab "`, ", "Key", "[key1, key2, key3]"] ]
/*
, ["Name", Delimiter, OpenArr, RowDelimiter, "Key", "Value", HK1Delimiter, HK2Delimiter, PrefKey]
*/
For k, v in Patterns
Delimiters .= v[1] "|"
Gui, Margin, 10, 10
Gui, +AlwaysOnTop +HWNDhGui -DPIScale +ReSize
Gui, Color, E3C47A
Gui, Font, , Verdana
A_ScreenDPI != 120 ? (xo1:=25, xo2:=16, xo3:=21, wres := 591) : (xo1:=16, xo2:=xo3:=15, wres := 582)
Gui, Add, DDL, xm gControlGet vModificators w222, Modificators||Left & Right Modificators
Gui, Add, Text, x+%xo1%, OpenArr:
Gui, Add, Edit, x+15 vOpenArr w270 WantTab
Gui, Add, Text, xm, Delimiter:
Gui, Add, Edit, x95 yp w500 vDelimiter gControlGet WantTab
Gui, Add, DDL, x95 y+2 vDDLPattern +AltSubmit gPattern w500, % RTrim(Delimiters, "|")
Gui, Add, Text, xm y+6, Row`nDelimiter:
Gui, Add, Edit, x95 yp+6 vRowDelimiter w330 gControlGet WantTab
Gui, Add, Text, x+%xo2%, Items:
Gui, Add, Text, x+15 w66 h26 +0x201 Border
Gui, Add, UpDown, Range0-100 vRowLen gControlGet Wrap Horz 16 Border, 2
GuiControl, Move, RowLen, h26 w52
Gui, Add, Text, xm, Pref Key:
Gui, Add, Edit, x95 yp vPrefKey w229 gControlGet WantTab
Gui, Add, Text, x+%xo3%, `%Value`%
Gui, Add, Edit, x+15 yp vValue w179 gControlGet WantTab
Gui, Add, Text, xm, Key:
Gui, Add, Edit, x95 yp vKey w400 gControlGet WantTab
Gui, Add, Button, x+15 w85 gFrom_Clip vFrom_Clip, Clipboard
Gui, Add, Button, xm+40 vBut_Add w85 gAdd, Add
Gui, Add, Button, x+15 vBut_Hook wp gHook, Hook
Gui, Add, Button, x+125 vBut_Copy wp gCopy, Copy
Gui, Add, Button, x+15 vBut_Clean wp gClean, Clean
Gui, Add, Edit, xm r14 WantTab -Wrap +HScroll vResult hwndhResult w%wres%
GuiControlGet, PosResult, Pos, Result
OnExit, GuiClose
OnMessage(0x6, "WM_ACTIVATE")
DllCall("RegisterShellHookWindow", "UInt", A_ScriptHwnd)
OnMessage(DllCall("RegisterWindowMessage", "str", "SHELLHOOK"), "ShellProc")
SetWinEventHook(0x8005, 0x8005, 0, RegisterCallback("Focus", "F"),0,0,0) ; EVENT_OBJECT_FOCUS := 0x8005
Gui, Show
Gui, +MinSize
GuiControl, Choose, DDLPattern, |1
Gui, Submit, NoHide
Hotkey_Control(1)
GuiControl, Focus, Static1
Return
Pattern:
GuiControlGet DDLPattern
GuiControl, , Delimiter, % Patterns[DDLPattern, 2]
GuiControl, , OpenArr, % Patterns[DDLPattern, 3]
GuiControl, , RowDelimiter, % Patterns[DDLPattern, 4]
GuiControl, , Key, % Patterns[DDLPattern, 5]
GuiControl, , Value, % Patterns[DDLPattern, 6]
HK1Delimiter := Patterns[DDLPattern, 7]
HK2Delimiter := Patterns[DDLPattern, 8]
GuiControl, , PrefKey, % Patterns[DDLPattern, 9]
; GuiControl, Focus, Delimiter
Return
ControlGet:
GuiControlGet %A_GuiControl%
If A_GuiControl = Delimiter
StringReplace, Delimiter, Delimiter, ``n, `n, 1
Return
From_Clip:
TempClipboard := Clipboard
Gui, +Disabled -AlwaysOnTop
Loop, parse, TempClipboard, `n, `r
Write({"Addkey":A_LoopField, "Add":1}*)
Gui, -Disabled +AlwaysOnTop
Gui, Show
Return
Add:
Write({"Addkey":Key, "Add":1}*)
Return
Hook:
Hotkey_Hook := !Hotkey_Hook, Man_Hook := Hotkey_Hook ? 1 : 0
GuiControl, , But_Hook, % Hotkey_Hook ? "UnHook" : "Hook"
GuiControl, Disable%Hotkey_Hook%, But_Add
GuiControl, Disable%Hotkey_Hook%, From_Clip
Return
Copy:
GuiControlGet, Result
Clipboard := Result
Return
Clean:
GuiControl, , Result,
CountItem := 1, PrHK := ""
Return
ShellProc(nCode, wParam) {
If (nCode = 4)
{
If (wParam = hGui)
Man_Hook ? Hotkey_Hook := 1 : 0
Else If Hotkey_Hook
Hotkey_Reset()
}
}
WM_ACTIVATE(wp) {
If (wp & 0xFFFF)
Man_Hook ? Hotkey_Hook := 1 : 0
Else If (wp & 0xFFFF = 0 && Hotkey_Hook)
Hotkey_Reset()
}
Focus(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime) {
If (Hotkey_Hook && DllCall("GetParent", "UInt", hwnd) = hGui)
{
WinGetClass, Class, ahk_id %hwnd%
If Class = Edit
GoSub Hook
}
}
SetWinEventHook(eventMin, eventMax, hmodWinEventProc, lpfnWinEventProc, idProcess, idThread, dwFlags) {
Return DllCall("SetWinEventHook" , "UInt", eventMin, "UInt", eventMax, "Ptr", hmodWinEventProc
, "Ptr", lpfnWinEventProc, "UInt", idProcess, "UInt", idThread, "UInt", dwFlags, "Ptr")
}
#If WinActive("ahk_id" hGui) && IsEdit(ClassNN)
Enter:: Control, EditPaste, ``n, %ClassNN%, ahk_id %hGui%
#If
IsEdit(byref ClassNN) {
ControlGetFocus, ClassNN, A
Return ClassNN ~= "^Edit[^7]" ? 1 : 0
}
GuiSize:
If A_EventInfo != 1
WinMove, ahk_id %hResult%, , PosResultX, PosResultY, A_GuiWidth-26, A_GuiHeight-PosResultY-10
Return
GuiClose:
GuiEscape:
Hotkey_Control(0)
DllCall("DeregisterShellHookWindow", "UInt", A_ScriptHwnd)
ExitApp
; _________________________________________________ Write _________________________________________________
Write(K*) {
Local Prefix, Hotkey, _Delimiter, Mods, KeyName, LR
If !K.Add
{
LR := Modificators = "Modificators" ? "" : "LR"
Mods := K[LR "Mods"], Prefix := K[LR "Pref"]
Hotkey := K.HK, KeyName := K.Name
GuiControl, , Key, % Mods KeyName
If (PrHK = Prefix Hotkey || Hotkey = "")
Return
PrHK := Prefix Hotkey
GuiControl, , Key, % PrHK " // " Mods KeyName
}
GuiControlGet Result
Result := SubStr(Result, StrLen(OpenArr)+1)
GuiControlGet OpenArr
If (RowLen && ++CountItem > RowLen && RowDelimiter != "")
{
CountItem := 1
StringReplace, _Delimiter, RowDelimiter, ``n, `n, 1
StringReplace, _Delimiter, _Delimiter, `%Value`%, %Value%, 1
}
Else
StringReplace, _Delimiter, Delimiter, `%Value`%, %Value%, 1
GuiControl, -Redraw, Result
GuiControl, , Result, % OpenArr Result PrefKey Prefix HK1Delimiter Hotkey HK2Delimiter K.Addkey _Delimiter
SetTimer, GoLastLine, -10
}
GoLastLine:
SendMessage, 0x0E, , , , ahk_id %hResult% ; WM_GETTEXTLENGTH
PostMessage, 0x00B1, Errorlevel, Errorlevel, , ahk_id %hResult% ; EM_SETSEL
PostMessage, 0xB7,,,, ahk_id %hResult% ; EM_SCROLLCARET
GuiControl, +Redraw, Result
Return
; _________________________________________________ Hotkey Func _________________________________________________
Hotkey_Control(State) {
Static IsStart
If (!IsStart)
Hotkey_ExtKeyInit(), IsStart := 1
Hotkey_WindowsHookEx(State)
}
Hotkey_Main(VKCode, SCCode, StateMod = 0, IsMod = 0, OnlyMods = 0) {
Static K:={}, ModsOnly, Prefix := {"Alt":"!","Ctrl":"^","Shift":"+","Win":"#"}
, LRPrefix := {"LAlt":"<!","LCtrl":"<^","LShift":"<+","LWin":"<#"
,"RAlt":">!","RCtrl":">^","RShift":">+","RWin":">#"}
, VkMouse := {"MButton":"vk4","WheelDown":"vk9E","WheelUp":"vk9F","WheelRight":"vk9D"
,"WheelLeft":"vk9C","XButton1":"vk5","XButton2":"vk6"}
, Symbols := "|vkBA|vkBB|vkBC|vkBD|vkBE|vkBF|vkC0|vkDB|vkDC|vkDD|vkDE|vk41|vk42|"
. "vk43|vk44|vk45|vk46|vk47|vk48|vk49|vk4A|vk4B|vk4C|vk4D|vk4E|"
. "vk4F|vk50|vk51|vk52|vk53|vk54|vk55|vk56|vk57|vk58|vk59|vk5A|"
If (OnlyMods)
{
If !ModsOnly
Return 0
ModsOnly := 0, K.MCtrl := K.MAlt := K.MShift := K.MWin := K.Mods := ""
K.PCtrl := K.PAlt := K.PShift := K.PWin := K.Pref := ""
K.PLCtrl := K.PLAlt := K.PLShift := K.PLWin := K.LRPref := ""
K.PRCtrl := K.PRAlt := K.PRShift := K.PRWin := ""
K.MLCtrl := K.MLAlt := K.MLShift := K.MLWin := K.LRMods := ""
K.MRCtrl := K.MRAlt := K.MRShift := K.MRWin := ""
%Hotkey_TargetFunc%(K*)
Return 0
}
If (StateMod = "Down")
{
If (K["M" IsMod] != "")
Return 1
sIsMod := SubStr(IsMod, 2)
K["M" sIsMod] := sIsMod "+", K["P" sIsMod] := Prefix[sIsMod]
K["M" IsMod] := IsMod "+", K["P" IsMod] := LRPrefix[IsMod]
}
Else If (StateMod = "Up")
{
sIsMod := SubStr(IsMod, 2)
K["M" IsMod] := K["P" IsMod] := ""
If (K["ML" sIsMod] = "" && K["MR" sIsMod] = "")
K["M" sIsMod] := K["P" sIsMod] := ""
If (K.HK != "")
return 1
}
K.VK := VKCode, K.SC := SCCode
K.Mods := K.MCtrl K.MAlt K.MShift K.MWin
K.LRMods := K.MLCtrl K.MRCtrl K.MLAlt K.MRAlt K.MLShift K.MRShift K.MLWin K.MRWin
K.TK := GetKeyName(VKCode SCCode), K.TK := K.TK = "" ? VKCode SCCode : K.TK
(IsMod) ? (K.HK := K.Pref := K.LRPref := K.Name := "", ModsOnly := K.Mods = "" ? 0 : 1)
: (K.HK := InStr(Symbols, "|" VKCode "|") ? VKCode : K.TK
, K.Name := K.HK = "vkBF" ? "/" : K.TK
, K.Pref := K.PCtrl K.PAlt K.PShift K.PWin
, K.LRPref := K.PLCtrl K.PRCtrl K.PLAlt K.PRAlt K.PLShift K.PRShift K.PLWin K.PRWin
, ModsOnly := 0)
%Hotkey_TargetFunc%(K*)
Return 1
Hotkey_PressName:
K.Mods := K.MCtrl K.MAlt K.MShift K.MWin
K.LRMods := K.MLCtrl K.MRCtrl K.MLAlt K.MRAlt K.MLShift K.MRShift K.MLWin K.MRWin
K.Pref := K.PCtrl K.PAlt K.PShift K.PWin
K.LRPref := K.PLCtrl K.PRCtrl K.PLAlt K.PRAlt K.PLShift K.PRShift K.PLWin K.PRWin
K.HK := K.Name := K.TK := A_ThisHotkey, ModsOnly := 0, K.SC := ""
K.VK := !InStr(A_ThisHotkey, "Joy") ? VkMouse[A_ThisHotkey] : ""
%Hotkey_TargetFunc%(K*)
Return 1
}
Hotkey_ExtKeyInit() {
MouseKey := "MButton|WheelDown|WheelUp|WheelRight|WheelLeft|XButton1|XButton2"
#If Hotkey_Hook
#If
Hotkey, If, Hotkey_Hook
Loop, Parse, MouseKey, |
Hotkey, %A_LoopField%, Hotkey_PressName, P3 UseErrorLevel
Loop 128
Hotkey % Ceil(A_Index/32) "Joy" Mod(A_Index-1,32)+1, Hotkey_PressName, P3 UseErrorLevel
Hotkey, If
}
Hotkey_Reset() {
Return Hotkey_Hook := 0, Hotkey_Main("", "", "", "", 1)
}
Hotkey_LowLevelKeyboardProc(nCode, wParam, lParam) {
Static Mods := {"vkA4":"LAlt","vkA5":"RAlt","vkA2":"LCtrl","vkA3":"RCtrl"
,"vkA0":"LShift","vkA1":"RShift","vk5B":"LWin","vk5C":"RWin"}, SaveFormat
If !Hotkey_Hook
Return DllCall("CallNextHookEx", "Ptr", 0, "Int", nCode, "UInt", wParam, "UInt", lParam)
SaveFormat := A_FormatInteger
SetFormat, IntegerFast, H
VKCode := "vk" SubStr(NumGet(lParam+0, 0, "UInt"), 3)
sc := NumGet(lParam+0, 8, "UInt") & 1, sc := sc << 8 | NumGet(lParam+0, 4, "UInt")
SCCode := "sc" SubStr(sc, 3), IsMod := Mods[VKCode]
SetFormat, IntegerFast, %SaveFormat%
If (wParam = 0x100 || wParam = 0x104) ; WM_KEYDOWN := 0x100, WM_SYSKEYDOWN := 0x104
IsMod ? Hotkey_Main(VKCode, SCCode, "Down", IsMod) : Hotkey_Main(VKCode, SCCode)
Else If ((wParam = 0x101 || wParam = 0x105) && VKCode != "vk5D") ; WM_KEYUP := 0x101, WM_SYSKEYUP := 0x105, AppsKey = "vk5D"
nCode := -1, IsMod ? Hotkey_Main(VKCode, SCCode, "Up", IsMod) : ""
Return nCode < 0 ? DllCall("CallNextHookEx", "Ptr", 0, "Int", nCode, "UInt", wParam, "UInt", lParam) : 1
}
Hotkey_WindowsHookEx(State) {
Static Hook
If State
Hook := DllCall("SetWindowsHookEx" . (A_IsUnicode ? "W" : "A")
, "Int", 13 ; WH_KEYBOARD_LL
, "Ptr", RegisterCallback("Hotkey_LowLevelKeyboardProc", "Fast")
, "Ptr", DllCall("GetModuleHandle", "UInt", 0, "Ptr")
, "UInt", 0, "Ptr")
Else
DllCall("UnhookWindowsHookEx" , "Ptr", Hook), Hook := "", Hotkey_Reset()
}