[USB]
[reactos.git] / reactos / dll / cpl / input / settings.c
1 /*
2 *
3 * PROJECT: input.dll
4 * FILE: dll/win32/input/settings.c
5 * PURPOSE: input.dll
6 * PROGRAMMER: Dmitry Chapyshev (dmitry@reactos.org)
7 * Colin Finck
8 * Gregor Schneider
9 * UPDATE HISTORY:
10 * 06-09-2007 Created
11 */
12
13 #include "input.h"
14
15 static HWND MainDlgWnd;
16 // for SaveInputLang()
17 static INT OldLayoutNum;
18
19 typedef struct
20 {
21 LANGID LangId;
22 TCHAR LangName[MAX_PATH];
23 TCHAR LayoutName[MAX_PATH];
24 TCHAR ValName[CCH_ULONG_DEC + 1];
25 TCHAR IndName[MAX_PATH];
26 } LAYOUT_ITEM, *LPLAYOUT_ITEM;
27
28
29 static INT
30 IsLayoutSelected()
31 {
32 INT iIndex = (INT) SendMessage(GetDlgItem(MainDlgWnd, IDC_KEYLAYOUT_LIST),
33 LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
34
35 return iIndex;
36 }
37
38 BOOL
39 IsLayoutExists(LPTSTR szLayoutID, LPTSTR szLangID)
40 {
41 HKEY hKey, hSubKey;
42 TCHAR szPreload[CCH_LAYOUT_ID + 1], szLayoutNum[3 + 1],
43 szTmp[CCH_LAYOUT_ID + 1], szOldLangID[CCH_LAYOUT_ID + 1];
44 DWORD dwIndex = 0, dwType, dwSize;
45 BOOL IsLangExists = FALSE;
46 LANGID langid;
47
48 if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Preload"),
49 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
50 {
51 dwSize = sizeof(szLayoutNum);
52
53 while (RegEnumValue(hKey, dwIndex, szLayoutNum, &dwSize, NULL, &dwType, NULL, NULL) == ERROR_SUCCESS)
54 {
55 dwSize = sizeof(szPreload);
56 if (RegQueryValueEx(hKey, szLayoutNum, NULL, NULL, (LPBYTE)szPreload, &dwSize) != ERROR_SUCCESS)
57 {
58 RegCloseKey(hKey);
59 return FALSE;
60 }
61
62 langid = (LANGID)_tcstoul(szPreload, NULL, 16);
63 GetLocaleInfo(langid, LOCALE_ILANGUAGE, szTmp, sizeof(szTmp) / sizeof(TCHAR));
64 wsprintf(szOldLangID, _T("0000%s"), szTmp);
65
66 if (_tcscmp(szOldLangID, szLangID) == 0)
67 IsLangExists = TRUE;
68 else
69 IsLangExists = FALSE;
70
71 if (szPreload[0] == 'd')
72 {
73 if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Substitutes"),
74 0, KEY_QUERY_VALUE, &hSubKey) == ERROR_SUCCESS)
75 {
76 dwSize = sizeof(szTmp);
77 RegQueryValueEx(hSubKey, szPreload, NULL, NULL, (LPBYTE)szTmp, &dwSize);
78
79 if ((_tcscmp(szTmp, szLayoutID) == 0)&&(IsLangExists))
80 {
81 RegCloseKey(hSubKey);
82 RegCloseKey(hKey);
83 return TRUE;
84 }
85 }
86 }
87 else
88 {
89 if ((_tcscmp(szPreload, szLayoutID) == 0) && (IsLangExists))
90 {
91 RegCloseKey(hKey);
92 return TRUE;
93 }
94 }
95
96 IsLangExists = FALSE;
97 dwSize = sizeof(szLayoutNum);
98 dwIndex++;
99 }
100
101 RegCloseKey(hKey);
102 }
103
104 return FALSE;
105 }
106
107 static HICON
108 CreateLayoutIcon(LPTSTR szInd)
109 {
110 HDC hdc, hdcsrc;
111 HBITMAP hBitmap, hBmpNew, hBmpOld;
112 RECT rect;
113 HFONT hFont = NULL;
114 ICONINFO IconInfo;
115 HICON hIcon = NULL;
116
117 hdcsrc = GetDC(NULL);
118 hdc = CreateCompatibleDC(hdcsrc);
119 hBitmap = CreateCompatibleBitmap(hdcsrc, 16, 16);
120 ReleaseDC(NULL, hdcsrc);
121
122 if (hdc && hBitmap)
123 {
124 hBmpNew = CreateBitmap(16, 16, 1, 1, NULL);
125 if (hBmpNew)
126 {
127 hBmpOld = SelectObject(hdc, hBitmap);
128 rect.right = 16;
129 rect.left = 0;
130 rect.bottom = 16;
131 rect.top = 0;
132
133 SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
134 SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
135
136 ExtTextOut(hdc, rect.left, rect.top, ETO_OPAQUE, &rect, _T(""), 0, NULL);
137
138 hFont = CreateFont(-11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
139 OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
140 DEFAULT_QUALITY, FF_DONTCARE, _T("Tahoma"));
141
142 SelectObject(hdc, hFont);
143 DrawText(hdc, _tcsupr(szInd), 2, &rect, DT_SINGLELINE|DT_CENTER|DT_VCENTER);
144 SelectObject(hdc, hBmpNew);
145 PatBlt(hdc, 0, 0, 16, 16, BLACKNESS);
146 SelectObject(hdc, hBmpOld);
147
148 IconInfo.hbmColor = hBitmap;
149 IconInfo.hbmMask = hBmpNew;
150 IconInfo.fIcon = TRUE;
151
152 hIcon = CreateIconIndirect(&IconInfo);
153
154 DeleteObject(hBmpNew);
155 DeleteObject(hBmpOld);
156 DeleteObject(hFont);
157 }
158 }
159
160 DeleteDC(hdc);
161 DeleteObject(hBitmap);
162
163 return hIcon;
164 }
165
166 static BOOL
167 GetLayoutID(LPTSTR szLayoutNum, LPTSTR szLCID)
168 {
169 DWORD dwBufLen;
170 DWORD dwRes;
171 HKEY hKey;
172 TCHAR szTempLCID[CCH_LAYOUT_ID + 1];
173
174 // Get the Layout ID
175 if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Preload"), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
176 {
177 dwBufLen = sizeof(szTempLCID);
178 dwRes = RegQueryValueEx(hKey, szLayoutNum, NULL, NULL, (LPBYTE)szTempLCID, &dwBufLen);
179
180 if (dwRes != ERROR_SUCCESS)
181 {
182 RegCloseKey(hKey);
183 return FALSE;
184 }
185
186 RegCloseKey(hKey);
187 }
188
189 // Look for a substitude of this layout
190 if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Substitutes"), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
191 {
192 dwBufLen = sizeof(szTempLCID);
193
194 if (RegQueryValueEx(hKey, szTempLCID, NULL, NULL, (LPBYTE)szLCID, &dwBufLen) != ERROR_SUCCESS)
195 {
196 // No substitute found, then use the old LCID
197 lstrcpy(szLCID, szTempLCID);
198 }
199
200 RegCloseKey(hKey);
201 }
202 else
203 {
204 // Substitutes key couldn't be opened, so use the old LCID
205 lstrcpy(szLCID, szTempLCID);
206 }
207
208 return TRUE;
209 }
210
211 BOOL
212 GetLayoutName(LPCTSTR szLCID, LPTSTR szName)
213 {
214 HKEY hKey;
215 DWORD dwBufLen;
216 TCHAR szBuf[MAX_PATH], szDispName[MAX_PATH], szIndex[MAX_PATH], szPath[MAX_PATH];
217 HANDLE hLib;
218 unsigned i, j, k;
219
220 wsprintf(szBuf, _T("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\%s"), szLCID);
221
222 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR)szBuf, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
223 {
224 dwBufLen = sizeof(szBuf);
225
226 if (RegQueryValueEx(hKey, _T("Layout Display Name"), NULL, NULL, (LPBYTE)szDispName, &dwBufLen) == ERROR_SUCCESS)
227 {
228 if (szDispName[0] == '@')
229 {
230 for (i = 0; i < _tcslen(szDispName); i++)
231 {
232 if ((szDispName[i] == ',') && (szDispName[i + 1] == '-'))
233 {
234 for (j = i + 2, k = 0; j < _tcslen(szDispName)+1; j++, k++)
235 {
236 szIndex[k] = szDispName[j];
237 }
238 szDispName[i - 1] = '\0';
239 break;
240 }
241 else szDispName[i] = szDispName[i + 1];
242 }
243
244 if (ExpandEnvironmentStrings(szDispName, szPath, MAX_PATH))
245 {
246 hLib = LoadLibrary(szPath);
247 if (hLib)
248 {
249 if (LoadString(hLib, _ttoi(szIndex), szPath, sizeof(szPath) / sizeof(TCHAR)) != 0)
250 {
251 _tcscpy(szName, szPath);
252 RegCloseKey(hKey);
253 return TRUE;
254 }
255 FreeLibrary(hLib);
256 }
257 }
258 }
259 }
260
261 dwBufLen = sizeof(szBuf);
262
263 if (RegQueryValueEx(hKey, _T("Layout Text"), NULL, NULL, (LPBYTE)szName, &dwBufLen) == ERROR_SUCCESS)
264 {
265 RegCloseKey(hKey);
266 return TRUE;
267 }
268 }
269
270 return FALSE;
271 }
272
273 static VOID
274 AddListColumn(HWND hWnd)
275 {
276 LV_COLUMN column;
277 TCHAR szBuf[MAX_PATH];
278 HWND hList = GetDlgItem(hWnd, IDC_KEYLAYOUT_LIST);
279
280 ZeroMemory(&column, sizeof(LV_COLUMN));
281 column.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
282
283 column.fmt = LVCFMT_LEFT;
284 column.iSubItem = 0;
285 LoadString(hApplet, IDS_LANGUAGE, szBuf, sizeof(szBuf) / sizeof(TCHAR));
286 column.pszText = szBuf;
287 column.cx = 175;
288 (VOID) ListView_InsertColumn(hList, 0, &column);
289
290 column.fmt = LVCFMT_RIGHT;
291 column.cx = 155;
292 column.iSubItem = 1;
293 LoadString(hApplet, IDS_LAYOUT, szBuf, sizeof(szBuf) / sizeof(TCHAR));
294 column.pszText = szBuf;
295 (VOID) ListView_InsertColumn(hList, 1, &column);
296 }
297
298 static VOID
299 InitLangList(HWND hWnd, HIMAGELIST hImgList)
300 {
301 HKEY hKey, hSubKey;
302 TCHAR szBuf[MAX_PATH], szPreload[CCH_LAYOUT_ID + 1], szSub[CCH_LAYOUT_ID + 1];
303 LAYOUT_ITEM lItem;
304 DWORD dwIndex = 0, dwType, dwSize;
305 LV_ITEM item = {0};
306 HWND hList = GetDlgItem(hWnd, IDC_KEYLAYOUT_LIST);
307 INT i, imgIndex;
308
309 item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE;
310
311 if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Preload"),
312 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
313 {
314 dwSize = sizeof(lItem.ValName);
315
316 while (RegEnumValue(hKey, dwIndex, lItem.ValName, &dwSize, NULL, &dwType, NULL, NULL) == ERROR_SUCCESS)
317 {
318 dwSize = sizeof(szPreload);
319 RegQueryValueEx(hKey, lItem.ValName, NULL, NULL, (LPBYTE)szPreload, &dwSize);
320
321 lItem.LangId = (LANGID)_tcstoul(szPreload, NULL, 16);
322
323 GetLocaleInfo(lItem.LangId, LOCALE_SISO639LANGNAME, (LPTSTR)szBuf, sizeof(szBuf) / sizeof(TCHAR));
324 lstrcpy(lItem.IndName, _tcsupr(szBuf));
325 imgIndex = ImageList_AddIcon(hImgList, CreateLayoutIcon(lItem.IndName));
326
327 GetLocaleInfo(lItem.LangId, LOCALE_SLANGUAGE, (LPTSTR)szBuf, sizeof(szBuf) / sizeof(TCHAR));
328 lstrcpy(lItem.LangName, szBuf);
329
330 // Does this keyboard layout have a substitute?
331 // Then add the substitute instead of the Layout ID
332 if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Substitutes"),
333 0, KEY_QUERY_VALUE, &hSubKey) == ERROR_SUCCESS)
334 {
335 dwSize = sizeof(szSub);
336
337 if (RegQueryValueEx(hSubKey, szPreload, NULL, NULL, (LPBYTE)szSub, &dwSize) == ERROR_SUCCESS)
338 {
339 lstrcpy(szPreload, szSub);
340 }
341
342 RegCloseKey(hSubKey);
343 }
344
345 GetLayoutName(szPreload, lItem.LayoutName);
346
347 item.pszText = lItem.LangName;
348 item.iItem = (INT) dwIndex;
349 item.lParam = (LPARAM)_ttoi(lItem.ValName);
350 item.iImage = imgIndex;
351 i = ListView_InsertItem(hList, &item);
352
353 ListView_SetItemText(hList, i, 1, lItem.LayoutName);
354
355 dwIndex++;
356
357 if (lstrcmp(lItem.ValName, _T("1")) == 0)
358 {
359 (VOID) ListView_SetHotItem(hList, i);
360 }
361 }
362
363 RegCloseKey(hKey);
364 }
365 }
366
367 VOID
368 UpdateLayoutsList(VOID)
369 {
370 HIMAGELIST hImgList;
371
372 /* Clear the list */
373 (VOID) ListView_DeleteAllItems(GetDlgItem(MainDlgWnd, IDC_KEYLAYOUT_LIST));
374
375 /* Crate new list */
376 hImgList = ImageList_Create(16, 16, ILC_COLOR8 | ILC_MASK, 0, 1);
377 InitLangList(MainDlgWnd, hImgList);
378 hImgList = ListView_SetImageList(GetDlgItem(MainDlgWnd, IDC_KEYLAYOUT_LIST), hImgList, LVSIL_SMALL);
379
380 /* Destroy old image list */
381 if(hImgList)
382 (VOID) ImageList_Destroy(hImgList);
383 }
384
385 typedef struct _REG_KB_ENTRY_
386 {
387 TCHAR szLayoutID[3];
388 DWORD dwType;
389 TCHAR szData[CCH_LAYOUT_ID + 1];
390 DWORD dwDataSize;
391 } REG_KB_ENTRY;
392
393 /* Layouts were deleted so we have to order the existing ones */
394 static VOID
395 UpdateRegValueNames(HKEY hKey)
396 {
397 DWORD dwIndex = 0, dwGot = 0, dwLayoutSize;
398 DWORD dwSets = 5;
399 REG_KB_ENTRY* data = HeapAlloc(GetProcessHeap(), 0, dwSets * sizeof(REG_KB_ENTRY));
400
401 /* Get all existing entries and delete them */
402 dwLayoutSize = sizeof(data[0].szLayoutID);
403 while (RegEnumValue(hKey,
404 dwIndex,
405 data[dwGot].szLayoutID,
406 &dwLayoutSize,
407 NULL,
408 &data[dwGot].dwType,
409 (PBYTE)data[dwGot].szData,
410 &data[dwGot].dwDataSize) != ERROR_NO_MORE_ITEMS)
411 {
412 if (_tcslen(data[dwGot].szLayoutID) <= 2 && _tcslen(data[dwGot].szData) == CCH_LAYOUT_ID)
413 {
414 RegDeleteValue(hKey, data[dwGot].szLayoutID);
415 dwGot++;
416 if (dwGot == dwSets)
417 {
418 dwSets += 5;
419 data = HeapReAlloc(GetProcessHeap(), 0, data, dwSets * sizeof(REG_KB_ENTRY));
420 }
421 }
422 dwIndex++;
423 dwLayoutSize = sizeof(data[0].szLayoutID);
424 }
425
426 /* Set all entries with an updated value name */
427 for (dwIndex = 0; dwIndex < dwGot; dwIndex++)
428 {
429 TCHAR szNewLayoutID[3];
430
431 _stprintf(szNewLayoutID, TEXT("%u"), dwIndex + 1);
432 RegSetValueEx(hKey, szNewLayoutID, 0, data[dwIndex].dwType,
433 (PBYTE)data[dwIndex].szData, data[dwIndex].dwDataSize);
434 }
435 HeapFree(GetProcessHeap(), 0, data);
436 }
437
438 static VOID
439 DeleteLayout(VOID)
440 {
441 INT iIndex, LayoutNum;
442 LVITEM item;
443 HKEY hKey, hSubKey;
444 HWND hLayoutList = GetDlgItem(MainDlgWnd, IDC_KEYLAYOUT_LIST);
445 TCHAR szLayoutNum[3 + 1], szTitle[MAX_PATH],
446 szConf[MAX_PATH], szPreload[CCH_LAYOUT_ID + 1];
447 DWORD dwSize;
448
449 iIndex = (INT) SendMessage(hLayoutList, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
450
451 if (iIndex != -1)
452 {
453 LoadString(hApplet, IDS_REM_QUESTION, szConf, sizeof(szConf) / sizeof(TCHAR));
454 LoadString(hApplet, IDS_CONFIRMATION, szTitle, sizeof(szTitle) / sizeof(TCHAR));
455
456 if (MessageBox(MainDlgWnd, szConf, szTitle, MB_YESNO | MB_ICONQUESTION) == IDYES)
457 {
458 ZeroMemory(&item, sizeof(LVITEM));
459
460 item.mask = LVIF_PARAM;
461 item.iItem = iIndex;
462
463 (VOID) ListView_GetItem(hLayoutList, &item);
464 LayoutNum = (INT) item.lParam;
465
466 if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Preload"), 0,
467 KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
468 {
469 _ultot(LayoutNum, szLayoutNum, 10);
470
471 dwSize = sizeof(szPreload);
472 RegQueryValueEx(hKey, szLayoutNum, NULL, NULL, (LPBYTE)szPreload, &dwSize);
473
474 if (szPreload[0] == 'd')
475 {
476 if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Substitutes"), 0,
477 KEY_ALL_ACCESS, &hSubKey) == ERROR_SUCCESS)
478 {
479 if (RegDeleteValue(hSubKey, szPreload) != ERROR_SUCCESS)
480 {
481 RegCloseKey(hSubKey);
482 RegCloseKey(hKey);
483 return;
484 }
485 RegCloseKey(hSubKey);
486 }
487 }
488
489 if (RegDeleteValue(hKey, szLayoutNum) == ERROR_SUCCESS)
490 {
491 UpdateLayoutsList();
492 UpdateRegValueNames(hKey);
493 }
494 }
495 RegCloseKey(hKey);
496 }
497 }
498 }
499
500 static VOID
501 SetDefaultLayout()
502 {
503 HKL hKl;
504 TCHAR szLCID[CCH_LAYOUT_ID + 1], szLayoutNum[CCH_ULONG_DEC + 1];
505 LVITEM item;
506 INT LayoutNum;
507
508 if (IsLayoutSelected() != -1)
509 {
510 ZeroMemory(&item, sizeof(LVITEM));
511
512 item.mask = LVIF_PARAM;
513 item.iItem = IsLayoutSelected();
514
515 (VOID) ListView_GetItem(GetDlgItem(MainDlgWnd, IDC_KEYLAYOUT_LIST), &item);
516
517 LayoutNum = (INT) item.lParam;
518 _ultot(LayoutNum, szLayoutNum, 10);
519
520 if (GetLayoutID(szLayoutNum, szLCID))
521 {
522 hKl = LoadKeyboardLayout(szLCID, KLF_ACTIVATE);
523 SystemParametersInfo(SPI_SETDEFAULTINPUTLANG, 0, &hKl, SPIF_SENDWININICHANGE);
524 }
525 }
526 }
527
528 static VOID
529 SaveInputLang(HWND hDlg)
530 {
531 HKEY hKey, hSubKey;
532 TCHAR szLayoutID[CCH_LAYOUT_ID + 1], szLayoutNum[CCH_ULONG_DEC + 1],
533 szPreload[CCH_LAYOUT_ID + 1], LangID[CCH_LAYOUT_ID + 1], szMessage[MAX_PATH],
534 Lang[MAX_PATH], SubPath[MAX_PATH];
535 PTSTR pts;
536 INT iLayout;
537 DWORD dwSize;
538 LANGID langid;
539
540 iLayout = SendMessage(GetDlgItem(hDlg, IDC_KB_LAYOUT_IME_COMBO), CB_GETCURSEL, 0, 0);
541 if (iLayout == CB_ERR) return;
542
543 pts = (PTSTR) SendMessage(GetDlgItem(hDlg, IDC_KB_LAYOUT_IME_COMBO), CB_GETITEMDATA, iLayout, 0);
544
545 _ultot(OldLayoutNum, szLayoutNum, 10);
546 if (!GetLayoutID(szLayoutNum, szLayoutID)) return;
547
548 // If old layout = selected layout
549 if (_tcscmp(szLayoutID, pts) == 0) return;
550
551 if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Preload"), 0,
552 KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
553 {
554 dwSize = sizeof(szPreload);
555 if (RegQueryValueEx(hKey, szLayoutNum, NULL, NULL, (LPBYTE)szPreload, &dwSize) != ERROR_SUCCESS)
556 {
557 RegCloseKey(hKey);
558 return;
559 }
560
561 langid = (LANGID)_tcstoul(szPreload, NULL, 16);
562 GetLocaleInfo(langid, LOCALE_ILANGUAGE, Lang, sizeof(Lang) / sizeof(TCHAR));
563 wsprintf(LangID, _T("0000%s"), Lang);
564
565 if (IsLayoutExists(pts, LangID))
566 {
567 LoadString(hApplet, IDS_LAYOUT_EXISTS, szMessage, sizeof(szMessage) / sizeof(TCHAR));
568 MessageBox(hDlg, szMessage, NULL, MB_OK | MB_ICONINFORMATION);
569
570 RegCloseKey(hKey);
571 return;
572 }
573
574 if (szPreload[0] == 'd')
575 {
576 if (_tcscmp(LangID, pts) == 0)
577 {
578 if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Substitutes"), 0,
579 KEY_ALL_ACCESS, &hSubKey) == ERROR_SUCCESS)
580 {
581 if (RegDeleteValue(hSubKey, szPreload) != ERROR_SUCCESS)
582 {
583 RegCloseKey(hSubKey);
584 RegCloseKey(hKey);
585 return;
586 }
587 RegCloseKey(hSubKey);
588
589 RegSetValueEx(hKey, szLayoutNum, 0, REG_SZ, (LPBYTE)pts,
590 (DWORD)((CCH_LAYOUT_ID + 1) * sizeof(TCHAR)));
591 }
592 }
593 else
594 {
595 if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Substitutes"), 0,
596 KEY_ALL_ACCESS, &hSubKey) == ERROR_SUCCESS)
597 {
598 RegSetValueEx(hSubKey, szPreload, 0, REG_SZ, (LPBYTE)pts,
599 (DWORD)((CCH_LAYOUT_ID + 1) * sizeof(TCHAR)));
600
601 RegCloseKey(hSubKey);
602 }
603 }
604 }
605 else
606 {
607 if (_tcscmp(LangID, pts) == 0)
608 {
609 RegSetValueEx(hKey, szLayoutNum, 0, REG_SZ, (LPBYTE)pts,
610 (DWORD)((CCH_LAYOUT_ID + 1) * sizeof(TCHAR)));
611 }
612 else
613 {
614 if (RegCreateKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Substitutes"), 0, NULL,
615 REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,
616 NULL, &hSubKey, NULL) == ERROR_SUCCESS)
617 {
618 wsprintf(SubPath, _T("d%03d%s"), GetLayoutCount(Lang)-1, Lang);
619
620 RegSetValueEx(hSubKey, SubPath, 0, REG_SZ, (LPBYTE)pts,
621 (DWORD)((CCH_LAYOUT_ID + 1) * sizeof(TCHAR)));
622
623 RegSetValueEx(hKey, szLayoutNum, 0, REG_SZ, (LPBYTE)SubPath,
624 (DWORD)((CCH_LAYOUT_ID + 1) * sizeof(TCHAR)));
625
626 RegCloseKey(hSubKey);
627 }
628 }
629 }
630
631 RegCloseKey(hKey);
632 }
633 }
634
635 static VOID
636 InitInputLangPropDlg(HWND hDlg)
637 {
638 HKEY hKey, hSubKey;
639 LVITEM item;
640 INT LayoutNum;
641 TCHAR szLayoutNum[10 + 1], szPreload[CCH_LAYOUT_ID + 1],
642 szTmp[CCH_LAYOUT_ID + 1], szName[MAX_PATH];
643 DWORD dwSize;
644 LANGID langid;
645
646 ZeroMemory(&item, sizeof(LVITEM));
647
648 item.mask = LVIF_PARAM;
649 item.iItem = IsLayoutSelected();
650
651 (VOID) ListView_GetItem(GetDlgItem(MainDlgWnd, IDC_KEYLAYOUT_LIST), &item);
652 LayoutNum = (INT) item.lParam;
653 OldLayoutNum = LayoutNum;
654
655 if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Preload"), 0,
656 KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
657 {
658 _ultot(LayoutNum, szLayoutNum, 10);
659
660 dwSize = sizeof(szPreload);
661 RegQueryValueEx(hKey, szLayoutNum, NULL, NULL, (LPBYTE)szPreload, &dwSize);
662
663 langid = (LANGID)_tcstoul(szPreload, NULL, 16);
664 GetLocaleInfo(langid, LOCALE_SLANGUAGE, (LPTSTR)szName, sizeof(szName) / sizeof(TCHAR));
665 SetWindowText(GetDlgItem(hDlg, IDC_INPUT_LANG_STR), szName);
666
667 if (szPreload[0] == 'd')
668 {
669 if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Substitutes"), 0,
670 KEY_ALL_ACCESS, &hSubKey) == ERROR_SUCCESS)
671 {
672 if (RegQueryValueEx(hSubKey, szPreload, NULL, NULL, (LPBYTE)szTmp, &dwSize) != ERROR_SUCCESS)
673 {
674 RegCloseKey(hSubKey);
675 RegCloseKey(hKey);
676 return;
677 }
678 lstrcpy(szPreload, szTmp);
679 RegCloseKey(hSubKey);
680 }
681 }
682
683 if (GetLayoutName(szPreload, szName))
684 {
685 SendMessage(GetDlgItem(hDlg, IDC_KB_LAYOUT_IME_COMBO),
686 CB_SELECTSTRING, (WPARAM)-1, (LPARAM)szName);
687 }
688 }
689 RegCloseKey(hKey);
690 }
691
692 INT_PTR CALLBACK
693 InputLangPropDlgProc(HWND hDlg,
694 UINT message,
695 WPARAM wParam,
696 LPARAM lParam)
697 {
698 UNREFERENCED_PARAMETER(lParam);
699
700 switch (message)
701 {
702 case WM_INITDIALOG:
703 CreateKeyboardLayoutList(GetDlgItem(hDlg, IDC_KB_LAYOUT_IME_COMBO));
704 InitInputLangPropDlg(hDlg);
705 break;
706
707 case WM_COMMAND:
708 switch (LOWORD(wParam))
709 {
710 case IDOK:
711 SaveInputLang(hDlg);
712 UpdateLayoutsList();
713 EndDialog(hDlg,LOWORD(wParam));
714 break;
715
716 case IDCANCEL:
717 EndDialog(hDlg,LOWORD(wParam));
718 break;
719 }
720 break;
721 }
722
723 return FALSE;
724 }
725
726 /* Property page dialog callback */
727 INT_PTR CALLBACK
728 SettingPageProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
729 {
730 UNREFERENCED_PARAMETER(lParam);
731
732 switch (uMsg)
733 {
734 case WM_INITDIALOG:
735 {
736 HIMAGELIST hImgList;
737
738 MainDlgWnd = hwndDlg;
739 AddListColumn(hwndDlg);
740 (VOID) ListView_SetExtendedListViewStyle(GetDlgItem(MainDlgWnd, IDC_KEYLAYOUT_LIST),
741 LVS_EX_FULLROWSELECT);
742 hImgList = ImageList_Create(16, 16, ILC_COLOR8 | ILC_MASK, 0, 1);
743 InitLangList(hwndDlg, hImgList);
744 (VOID) ListView_SetImageList(GetDlgItem(MainDlgWnd, IDC_KEYLAYOUT_LIST), hImgList, LVSIL_SMALL);
745 }
746 break;
747 case WM_NOTIFY:
748 {
749 switch (LOWORD(wParam))
750 {
751
752 }
753 }
754 break;
755 case WM_COMMAND:
756 switch (LOWORD(wParam))
757 {
758 case IDC_REMOVE_BUTTON:
759 DeleteLayout();
760 break;
761
762 case IDC_KEY_SET_BTN:
763 DialogBox(hApplet,
764 MAKEINTRESOURCE(IDD_KEYSETTINGS),
765 hwndDlg,
766 KeySettingsDlgProc);
767 break;
768
769 case IDC_ADD_BUTTON:
770 DialogBox(hApplet,
771 MAKEINTRESOURCE(IDD_ADD),
772 hwndDlg,
773 AddDlgProc);
774 break;
775
776 case IDC_PROP_BUTTON:
777 if (IsLayoutSelected() != -1)
778 DialogBox(hApplet,
779 MAKEINTRESOURCE(IDD_INPUT_LANG_PROP),
780 hwndDlg,
781 InputLangPropDlgProc);
782 break;
783
784 case IDC_SET_DEFAULT:
785 SetDefaultLayout();
786 UpdateLayoutsList();
787 break;
788 }
789 break;
790 case WM_DESTROY:
791 break;
792 }
793
794 return FALSE;
795 }
796
797 /* EOF */