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