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 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 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 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 62 void FreeKlList(HKL *list) 63 { 64 HeapFree(GetProcessHeap(), 0, list); 65 } 66 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 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 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 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 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 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 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 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 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 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 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