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