forked from Ixiko/AHK-libs-and-classes-collection
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCLASS_Layout.ahk
177 lines (166 loc) · 6.33 KB
/
CLASS_Layout.ahk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#Include *i FUNC_hexToDecimal.ahk
class Layout
{ ; функции управления раскладками клавиатуры
static SISO639LANGNAME := 0x0059 ; ISO abbreviated language name, eg "en"
static LOCALE_SENGLANGUAGE := 0x1001 ; Full language name, eg "English"
static WM_INPUTLANGCHANGEREQUEST := 0x0050
static INPUTLANGCHANGE_FORWARD := 0x0002
static INPUTLANGCHANGE_BACKWARD := 0x0004
;
static Layouts_List := Layout.Get_Layouts_List()
static Layouts_List_By_HKL := Layout.Get_Layouts_List_By_HKL()
;
static Switch_Layout_Combo := "{Blind}{Alt Down}{Shift Down}{Alt Up}{Shift Up}"
;
Get_Layouts_List()
{ ; функция создания базы данных для текущих раскладок
local
VarSetCapacity(List, A_PtrSize * 5)
Layouts_List_Size := DllCall("GetKeyboardLayoutList", Int, 5, Str, List)
Layouts_List := []
Loop, % Layouts_List_Size
{
Layout_HKL := NumGet(List, A_PtrSize * (A_Index - 1)) ; & 0xFFFF
Layout_KLID := This.Get_KLID(Layout_HKL)
Layout_Name := This.Language_Name(Layout_HKL, false)
Layout_Full_Name := This.Language_Name(Layout_HKL, true)
Layout_Display_Name := This.Display_Name(Layout_HKL)
Layouts_List[A_Index] := {}
Layouts_List[A_Index].HKL := Layout_HKL
Layouts_List[A_Index].KLID := Layout_KLID
Layouts_List[A_Index].Name := Layout_Name
Layouts_List[A_Index].Full_Name := Layout_Full_Name
Layouts_List[A_Index].Display_Name := Layout_Display_Name
}
return Layouts_List
}
Get_Layouts_List_By_HKL()
{ ; функция создания базы данных для текущих раскладок
local
VarSetCapacity(List, A_PtrSize * 5)
Layouts_List_Size := DllCall("GetKeyboardLayoutList", Int, 5, Str, List)
Layouts_List := {}
Loop, % Layouts_List_Size
{
Layout_HKL := NumGet(List, A_PtrSize * (A_Index - 1)) ; & 0xFFFF
Layout_KLID := This.Get_KLID(Layout_HKL)
Layout_Name := This.Language_Name(Layout_HKL, false)
Layout_Full_Name := This.Language_Name(Layout_HKL, true)
Layout_Display_Name := This.Display_Name(Layout_HKL)
Layouts_List[Layout_HKL] := {}
Layouts_List[Layout_HKL].HKL := Layout_HKL
Layouts_List[Layout_HKL].KLID := Layout_KLID
Layouts_List[Layout_HKL].Name := Layout_Name
Layouts_List[Layout_HKL].Full_Name := Layout_Full_Name
Layouts_List[Layout_HKL].Display_Name := Layout_Display_Name
}
return Layouts_List
}
Language_Name(HKL, Full_Name := false)
{ ; функция получения наименования (сокращенного "en" или полного "English") раскладки по ее "HKL"
local
LocID := HKL & 0xFFFF
LCType := Full_Name ? This.LOCALE_SENGLANGUAGE : This.SISO639LANGNAME
Size := DllCall("GetLocaleInfo", UInt, LocID, UInt, LCType, UInt, 0, UInt, 0) * 2
VarSetCapacity(localeSig, Size, 0)
DllCall("GetLocaleInfo", UInt, LocID, UInt, LCType, Str, localeSig, UInt, Size)
return localeSig
}
Display_Name(HKL)
{ ; функция получения названия ("Английская") раскладки по ее "HKL"
local
KLID := This.Get_KLID(HKL)
RegRead, Display_Name, % "HKEY_LOCAL_MACHINE", % "SYSTEM\CurrentControlSet\Control\Keyboard Layouts\" . KLID, % "Layout Display Name"
if (not Display_Name) {
return False
}
DllCall("Shlwapi.dll\SHLoadIndirectString", "Ptr", &Display_Name, "Ptr", &Display_Name, "UInt", outBufSize := 50, "UInt", 0)
if (not Display_Name) {
RegRead, Display_Name, % "HKEY_LOCAL_MACHINE", % "SYSTEM\CurrentControlSet\Control\Keyboard Layouts\" . KLID, % "Layout Text"
}
return Display_Name
}
Get_HKL(Window := "A")
{ ; функция получения названия "HKL" текущей раскладки
local
Window_ID := WinExist(Window)
WinGetClass, Window_Class
if (Window_Class == "ConsoleWindowClass") {
WinGet, Console_PID, PID
DllCall("AttachConsole", Ptr, Console_PID)
VarSetCapacity(Buff, 16)
DllCall("GetConsoleKeyboardLayoutName", Str, Buff)
DllCall("FreeConsole")
HKL := SubStr(Buff, -3)
HKL := HKL ? hexToDecimal(HKL . HKL) : 0 ; HKL := HKL ? "0x" . HKL : 0
}
else {
HKL := DllCall("GetKeyboardLayout", Ptr, DllCall("GetWindowThreadProcessId", Ptr, Window_ID, UInt, 0, Ptr), Ptr) ; & 0xFFFF
}
return HKL
}
Get_KLID(HKL)
{ ; функция получения названия "KLID" раскладки по ее "HKL"
local
Prior_HKL := DllCall("GetKeyboardLayout", "Ptr", DllCall("GetWindowThreadProcessId", "Ptr", 0, "UInt", 0, "Ptr"), "Ptr")
VarSetCapacity(KLID, 8 * (A_IsUnicode ? 2 : 1))
if !DllCall("ActivateKeyboardLayout", "Ptr", HKL, "UInt", 0) || !DllCall("GetKeyboardLayoutName", "Ptr", &KLID) || !DllCall("ActivateKeyboardLayout", "Ptr", Prior_HKL, "UInt", 0) {
return False
}
return StrGet(&KLID)
}
Next(Window := "A", BySend := false)
{ ; функция смены раскладки (вперед)
local
if BySend { ; с помощью команды Send
SendInput, % This.Switch_Layout_Combo
}
else { ; с помощью команды PostMessage
if (Window_ID := WinExist(Window)) {
PostMessage, % This.WM_INPUTLANGCHANGEREQUEST, % This.INPUTLANGCHANGE_FORWARD,,, ahk_id %Window_ID%
}
}
Sleep, 1
}
Change(HKL, Window := "A", BySend := false)
{ ; функция смены раскладки по "HKL"
local
if (Window_ID := WinExist(Window)) {
if BySend { ; с помощью команды Send
Loop, % This.Layouts_List.MaxIndex()
{
This_Layout_KLID := This.Get_KLID(This.Get_HKL("ahk_id " Window_ID))
Next_Layout_KLID := This.Get_KLID(HKL)
Sleep, 1
if (This_Layout_KLID == Next_Layout_KLID) {
Break
}
SendInput, % This.Switch_Layout_Combo
Sleep, 1
}
}
else { ; с помощью команды PostMessage
PostMessage, % This.WM_INPUTLANGCHANGEREQUEST,, % HKL,, ahk_id %Window_ID%
}
}
Sleep, 1
}
Get_Index(HKL)
{ ; функция получения порядкового номера раскладки по "HKL"
local
for Index, Layout in This.Layouts_List {
if (This.Get_KLID(Layout.HKL) = This.Get_KLID(HKL)) {
return Index
}
}
}
Get_Index_By_Name(Full_Name)
{ ; функция получения порядкового номера раскладки по полному имени ("English")
local
for Index, Layout in This.Layouts_List {
if (Layout.Full_Name = Full_Name) {
return Index
}
}
}
}