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