1 /*
2 * PROJECT: ReactOS
3 * LICENSE: GPL - See COPYING in the top level directory
4 * PURPOSE: Keyboard layout testapp
5 * COPYRIGHT: Copyright 2007 Saveliy Tretiakov
6 */
7
8 #define UNICODE
9 #include<wchar.h>
10 #include <windows.h>
11 #include "resource.h"
12
13
14
15 INT_PTR CALLBACK MainDialogProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam);
16
17
18 HINSTANCE hInst;
19 HWND hMainDlg;
20
21
22 typedef struct {
23 WNDPROC OrigProc;
24 WCHAR WndName[25];
25 } WND_DATA;
26
ThreadProc(LPVOID lpParam)27 DWORD WINAPI ThreadProc(LPVOID lpParam)
28 {
29 DialogBoxParam(hInst,
30 MAKEINTRESOURCE(IDD_MAINDIALOG),
31 NULL,
32 MainDialogProc,
33 (LPARAM)NULL);
34
35 return 0;
36 }
37
WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)38 INT WINAPI WinMain(HINSTANCE hInstance,
39 HINSTANCE hPrevInstance,
40 LPSTR lpCmdLine,
41 int nCmdShow)
42 {
43 hInst = hInstance;
44
45 ThreadProc(0);
46
47 return 0;
48 }
49
GetKlList(HKL ** list)50 int GetKlList(HKL **list)
51 {
52 HKL *ret;
53 int n;
54
55 n = GetKeyboardLayoutList(0, NULL);
56 ret = HeapAlloc(GetProcessHeap(), 0, sizeof(HKL)*n);
57 GetKeyboardLayoutList(n, ret);
58 *list = ret;
59 return n;
60 }
61
FreeKlList(HKL * list)62 void FreeKlList(HKL *list)
63 {
64 HeapFree(GetProcessHeap(), 0, list);
65 }
66
UpdateData(HWND hDlg)67 void UpdateData(HWND hDlg)
68 {
69 WCHAR buf[KL_NAMELENGTH];
70 WCHAR buf2[512];
71
72 HWND hList;
73 HKL *klList, hKl;
74 int n, i,j;
75
76 GetKeyboardLayoutName(buf);
77 swprintf(buf2, L"Active: %s (%x)", buf, GetKeyboardLayout(0));
78 SetWindowText(GetDlgItem(hDlg, IDC_ACTIVE), buf2);
79
80 hList = GetDlgItem(hDlg, IDC_LIST);
81 SendMessage(hList, LB_RESETCONTENT, 0, 0);
82
83 n = GetKlList(&klList);
84 hKl = GetKeyboardLayout(0);
85 for(i = 0; i < n; i++)
86 {
87 swprintf(buf, L"%x", klList[i] );
88 j = SendMessage(hList, LB_ADDSTRING, 0, (LPARAM) buf);
89 SendMessage(hList, LB_SETITEMDATA, j, (LPARAM) klList[i]);
90 if(klList[i] == hKl) SendMessage(hList, LB_SETCURSEL, j, 0);
91 }
92
93 FreeKlList(klList);
94 }
95
FormatMsg(WCHAR * format,...)96 void FormatMsg(WCHAR *format, ...)
97 {
98 WCHAR buf[255];
99 va_list argptr;
100 va_start(argptr, format);
101 _vsnwprintf(buf, sizeof(buf)-1, format, argptr);
102 MessageBox(0, buf, L"msg", 0);
103 va_end(argptr);
104 }
105
FormatBox(HWND hWnd,DWORD Flags,WCHAR * Caption,WCHAR * Format,...)106 void FormatBox(HWND hWnd, DWORD Flags, WCHAR *Caption, WCHAR *Format, ...)
107 {
108 WCHAR buf[255];
109 va_list argptr;
110 va_start(argptr, Format);
111 _vsnwprintf(buf, sizeof(buf)-1, Format, argptr);
112 MessageBox(hWnd, buf, Caption, Flags);
113 va_end(argptr);
114 }
115
WndSubclassProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)116 LRESULT CALLBACK WndSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
117 {
118 WND_DATA *data = (WND_DATA*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
119
120 if(uMsg == WM_INPUTLANGCHANGE)
121 {
122 FormatMsg(L"%s: WM_INPUTLANGCHANGE lParam=%x wParam=%x\n", data->WndName, lParam, wParam);
123 UpdateData(hMainDlg);
124 //Pass message to defwindowproc
125 }
126 else if(uMsg == WM_INPUTLANGCHANGEREQUEST)
127 {
128 FormatMsg(L"%s: WM_INPUTLANGCHANGEREQUEST lParam=%x wParam=%x\n", data->WndName, lParam, wParam);
129 UpdateData(hMainDlg);
130 //Pass message to defwindowproc
131 }
132
133 return CallWindowProc(data->OrigProc, hwnd, uMsg, wParam, lParam);
134 }
135
SubclassWnd(HWND hWnd,WCHAR * Name)136 void SubclassWnd(HWND hWnd, WCHAR* Name)
137 {
138 WND_DATA *data = HeapAlloc(GetProcessHeap(), 0, sizeof(WND_DATA));
139 data->OrigProc = (WNDPROC)SetWindowLongPtr( hWnd, GWLP_WNDPROC, (LONG_PTR)WndSubclassProc);
140 wcsncpy(data->WndName, Name, 25);
141 SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)data);
142 }
143
GetActivateFlags(HWND hDlg)144 DWORD GetActivateFlags(HWND hDlg)
145 {
146 DWORD ret = 0;
147
148 if(IsDlgButtonChecked(hDlg, IDC_KLF_REORDER))
149 ret |= KLF_REORDER;
150
151 if(IsDlgButtonChecked(hDlg, IDC_KLF_RESET))
152 ret |= KLF_RESET;
153
154 if(IsDlgButtonChecked(hDlg, IDC_KLF_SHIFTLOCK))
155 ret |= KLF_SHIFTLOCK;
156
157 if(IsDlgButtonChecked(hDlg, IDC_KLF_SETFORPROCESS))
158 ret |= KLF_SETFORPROCESS;
159
160 return ret;
161 }
162
GetLoadFlags(HWND hDlg)163 DWORD GetLoadFlags(HWND hDlg)
164 {
165 DWORD ret = 0;
166
167 if(IsDlgButtonChecked(hDlg, IDL_KLF_ACTIVATE))
168 ret |= KLF_ACTIVATE;
169
170 if(IsDlgButtonChecked(hDlg, IDL_KLF_NOTELLSHELL))
171 ret |= KLF_NOTELLSHELL;
172
173 if(IsDlgButtonChecked(hDlg, IDL_KLF_REORDER))
174 ret |= KLF_REORDER;
175
176 if(IsDlgButtonChecked(hDlg, IDL_KLF_REPLACELANG))
177 ret |= KLF_REPLACELANG;
178
179 if(IsDlgButtonChecked(hDlg, IDL_KLF_SUBSTITUTE_OK))
180 ret |= KLF_SUBSTITUTE_OK;
181
182 if(IsDlgButtonChecked(hDlg, IDL_KLF_SETFORPROCESS))
183 ret |= KLF_SETFORPROCESS;
184
185 return ret;
186 }
187
GetDelayMilliseconds(HWND hDlg)188 UINT GetDelayMilliseconds(HWND hDlg)
189 {
190 WCHAR Buf[255];
191 UINT ret;
192
193 GetWindowText(GetDlgItem(hDlg, IDC_DELAY), Buf, sizeof(Buf));
194
195 swscanf(Buf, L"%d", &ret);
196
197 return ret*1000;
198 }
199
GetSelectedLayout(HWND hDlg)200 HKL GetSelectedLayout(HWND hDlg)
201 {
202 int n;
203 HWND hList;
204 hList = GetDlgItem(hDlg, IDC_LIST);
205 if((n = SendMessage(hList, LB_GETCURSEL, 0, 0)) != LB_ERR)
206 return (HKL) SendMessage(hList, LB_GETITEMDATA, n, 0);
207 else return INVALID_HANDLE_VALUE;
208 }
209
GetActivateHandle(HWND hDlg)210 HKL GetActivateHandle(HWND hDlg)
211 {
212 if(IsDlgButtonChecked(hDlg, IDC_FROMLIST))
213 return GetSelectedLayout(hDlg);
214 else if(IsDlgButtonChecked(hDlg, IDC_HKL_NEXT))
215 return (HKL)HKL_NEXT;
216
217 return (HKL)HKL_PREV;
218 }
219
MainDialogProc(HWND hDlg,UINT Msg,WPARAM wParam,LPARAM lParam)220 INT_PTR CALLBACK MainDialogProc(HWND hDlg,
221 UINT Msg,
222 WPARAM wParam,
223 LPARAM lParam)
224 {
225 HKL hKl;
226
227 switch (Msg)
228 {
229 case WM_INITDIALOG:
230 {
231 WCHAR Buf[255];
232 UpdateData(hDlg);
233 hMainDlg = hDlg;
234
235 SubclassWnd(GetDlgItem(hDlg, IDC_LIST), L"List");
236 SubclassWnd(GetDlgItem(hDlg, IDC_EDIT1), L"Edit1");
237 SubclassWnd(GetDlgItem(hDlg, IDC_KLID), L"Klid");
238 SubclassWnd(GetDlgItem(hDlg, ID_CANCEL), L"CancelB");
239 SubclassWnd(GetDlgItem(hDlg, IDC_ACTIVATE), L"ActivateB");
240 SubclassWnd(GetDlgItem(hDlg, IDC_REFRESH), L"RefreshB");
241 SubclassWnd(GetDlgItem(hDlg, IDC_UNLOAD), L"UnloadB");
242 SubclassWnd(GetDlgItem(hDlg, IDC_LOAD), L"LoadB");
243
244 CheckRadioButton(hDlg, IDC_FROMLIST, IDC_FROMEDIT, IDC_FROMLIST);
245 SetWindowText(GetDlgItem(hDlg, IDC_KLID), L"00000419");
246
247 swprintf(Buf, L"Current thread id: %d", GetCurrentThreadId());
248 SetWindowText(GetDlgItem(hDlg, IDC_CURTHREAD), Buf);
249
250 SetWindowText(GetDlgItem(hDlg, IDC_DELAY), L"0");
251
252 return 0;
253 } /* WM_INITDIALOG */
254
255 case WM_COMMAND:
256 {
257 switch(LOWORD(wParam))
258 {
259 case ID_CANCEL:
260 {
261 EndDialog(hDlg, ERROR_CANCELLED);
262 break;
263 }
264
265 case IDC_ACTIVATE:
266 {
267 if((hKl = GetActivateHandle(hDlg)) != INVALID_HANDLE_VALUE)
268 {
269 Sleep(GetDelayMilliseconds(hDlg));
270 if(!(hKl = ActivateKeyboardLayout(hKl, GetActivateFlags(hDlg))))
271 FormatBox(hDlg, MB_ICONERROR, L"Error",
272 L"ActivateKeyboardLayout() failed. %d", GetLastError());
273 else UpdateData(hDlg);
274 //FormatBox(hDlg, 0, L"Activated", L"Prev - %x, err - %d.", hKl,
275 // GetLastError());
276 }
277 else MessageBox(hDlg, L"No item selected", L"Error", MB_ICONERROR);
278 break;
279 }
280
281 case IDC_UNLOAD:
282 {
283 if((hKl = GetSelectedLayout(hDlg)) != INVALID_HANDLE_VALUE)
284 {
285 Sleep(GetDelayMilliseconds(hDlg));
286 if(!UnloadKeyboardLayout(hKl))
287 FormatBox(hDlg, MB_ICONERROR, L"Error",
288 L"UnloadKeyboardLayout() failed. %d",
289 GetLastError());
290 else UpdateData(hDlg);
291 }
292 else MessageBox(hDlg, L"No item selected", L"Error", MB_ICONERROR);
293 break;
294 }
295
296 case IDC_LOAD:
297 {
298 WCHAR buf[255];
299 GetWindowText(GetDlgItem(hDlg, IDC_KLID), buf, sizeof(buf));
300 Sleep(GetDelayMilliseconds(hDlg));
301 if(!LoadKeyboardLayout(buf, GetLoadFlags(hDlg)))
302 FormatBox(hDlg, MB_ICONERROR, L"Error",
303 L"LoadKeyboardLayout() failed. %d",
304 GetLastError());
305 else UpdateData(hDlg);
306 break;
307 }
308
309 case IDC_REFRESH:
310 {
311 UpdateData(hDlg);
312 break;
313 }
314
315 case IDC_NEWTHREAD:
316 {
317 if(!CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL))
318 {
319 FormatBox(hDlg, MB_ICONERROR, L"Error!",
320 L"Can not create thread (%d).", GetLastError());
321 }
322 }
323
324 case IDC_LIST:
325 {
326 if(HIWORD(wParam) == LBN_SELCHANGE)
327 {
328 WCHAR buf[25];
329 if((hKl = GetSelectedLayout(hDlg)) != NULL)
330 {
331 swprintf(buf, L"%x", hKl);
332 SetWindowText(GetDlgItem(hDlg, IDC_HANDLE), buf);
333 }
334 }
335 break;
336 }
337 }
338
339 return TRUE;
340 } /* WM_COMMAND */
341
342 case WM_INPUTLANGCHANGE:
343 {
344 FormatMsg(L"dlg WM_INPUTLANGCHANGE lParam=%x wParam=%x\n", lParam, wParam);
345 return FALSE;
346 }
347
348 case WM_INPUTLANGCHANGEREQUEST:
349 {
350 FormatMsg(L"dlg WM_INPUTLANGCHANGEREQUEST lParam=%x wParam=%x\n", lParam, wParam);
351 UpdateData(hDlg);
352 return FALSE;
353 }
354
355 case WM_CLOSE:
356 {
357 EndDialog(hDlg, ERROR_CANCELLED);
358 return TRUE;
359 } /* WM_CLOSE */
360
361 default:
362 return FALSE;
363 }
364 }
365
366