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