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