1 /*
2 * PROJECT: input.dll
3 * FILE: dll/cpl/input/settings_page.c
4 * PURPOSE: input.dll
5 * PROGRAMMERS: Dmitry Chapyshev (dmitry@reactos.org)
6 * Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
7 */
8
9 #include "input.h"
10 #include "layout_list.h"
11 #include "locale_list.h"
12 #include "input_list.h"
13
14 static INT s_nAliveLeafCount = 0;
15 static INT s_nRootCount = 0;
16 static INT s_iKeyboardImage = -1;
17 static INT s_iDotImage = -1;
18
19 static HICON
CreateLayoutIcon(LANGID LangID)20 CreateLayoutIcon(LANGID LangID)
21 {
22 WCHAR szBuf[4];
23 HDC hdcScreen, hdc;
24 HBITMAP hbmColor, hbmMono, hBmpOld;
25 HFONT hFont, hFontOld;
26 LOGFONTW lf;
27 RECT rect;
28 ICONINFO IconInfo;
29 HICON hIcon;
30 INT cxIcon = GetSystemMetrics(SM_CXSMICON);
31 INT cyIcon = GetSystemMetrics(SM_CYSMICON);
32
33 /* Getting "EN", "FR", etc. from English, French, ... */
34 if (GetLocaleInfoW(LangID,
35 LOCALE_SABBREVLANGNAME | LOCALE_NOUSEROVERRIDE,
36 szBuf,
37 ARRAYSIZE(szBuf)) == 0)
38 {
39 szBuf[0] = szBuf[1] = L'?';
40 }
41 szBuf[2] = UNICODE_NULL; /* Truncate the identifier to two characters: "ENG" --> "EN" etc. */
42
43 /* Create hdc, hbmColor and hbmMono */
44 hdcScreen = GetDC(NULL);
45 hdc = CreateCompatibleDC(hdcScreen);
46 hbmColor = CreateCompatibleBitmap(hdcScreen, cxIcon, cyIcon);
47 ReleaseDC(NULL, hdcScreen);
48 hbmMono = CreateBitmap(cxIcon, cyIcon, 1, 1, NULL);
49
50 /* Checking NULL */
51 if (!hdc || !hbmColor || !hbmMono)
52 {
53 if (hbmMono)
54 DeleteObject(hbmMono);
55 if (hbmColor)
56 DeleteObject(hbmColor);
57 if (hdc)
58 DeleteDC(hdc);
59 return NULL;
60 }
61
62 /* Create a font */
63 hFont = NULL;
64 if (SystemParametersInfoW(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0))
65 {
66 /* Override the current size with something manageable */
67 lf.lfHeight = -11;
68 lf.lfWidth = 0;
69 hFont = CreateFontIndirectW(&lf);
70 }
71 if (!hFont)
72 hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
73
74 SetRect(&rect, 0, 0, cxIcon, cyIcon);
75
76 /* Draw hbmColor */
77 hBmpOld = SelectObject(hdc, hbmColor);
78 SetDCBrushColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
79 FillRect(hdc, &rect, (HBRUSH)GetStockObject(DC_BRUSH));
80 hFontOld = SelectObject(hdc, hFont);
81 SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
82 SetBkMode(hdc, TRANSPARENT);
83 DrawTextW(hdc, szBuf, 2, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
84 SelectObject(hdc, hFontOld);
85
86 /* Fill hbmMono with black */
87 SelectObject(hdc, hbmMono);
88 PatBlt(hdc, 0, 0, cxIcon, cyIcon, BLACKNESS);
89 SelectObject(hdc, hBmpOld);
90
91 /* Create an icon from hbmColor and hbmMono */
92 IconInfo.fIcon = TRUE;
93 IconInfo.xHotspot = IconInfo.yHotspot = 0;
94 IconInfo.hbmColor = hbmColor;
95 IconInfo.hbmMask = hbmMono;
96 hIcon = CreateIconIndirect(&IconInfo);
97
98 /* Clean up */
99 DeleteObject(hFont);
100 DeleteObject(hbmMono);
101 DeleteObject(hbmColor);
102 DeleteDC(hdc);
103
104 return hIcon;
105 }
106
InitDefaultLangComboBox(HWND hwndCombo)107 static VOID InitDefaultLangComboBox(HWND hwndCombo)
108 {
109 WCHAR szText[256];
110 INPUT_LIST_NODE *pNode;
111 INT iIndex, nCount, iDefault = (INT)SendMessageW(hwndCombo, CB_GETCURSEL, 0, 0);
112
113 SendMessageW(hwndCombo, CB_RESETCONTENT, 0, 0);
114
115 for (pNode = InputList_GetFirst(); pNode != NULL; pNode = pNode->pNext)
116 {
117 if (pNode->wFlags & INPUT_LIST_NODE_FLAG_DELETED)
118 continue;
119
120 StringCchPrintfW(szText, _countof(szText), L"%s - %s",
121 pNode->pLocale->pszName, pNode->pLayout->pszName);
122 iIndex = (INT)SendMessageW(hwndCombo, CB_ADDSTRING, 0, (LPARAM)szText);
123 SendMessageW(hwndCombo, CB_SETITEMDATA, iIndex, (LPARAM)pNode);
124
125 if (pNode->wFlags & INPUT_LIST_NODE_FLAG_DEFAULT)
126 iDefault = iIndex;
127 }
128
129 nCount = (INT)SendMessageW(hwndCombo, CB_GETCOUNT, 0, 0);
130 if (iDefault >= nCount)
131 SendMessageW(hwndCombo, CB_SETCURSEL, nCount - 1, 0);
132 else
133 SendMessageW(hwndCombo, CB_SETCURSEL, iDefault, 0);
134 }
135
136 static VOID
SetControlsState(HWND hwndDlg)137 SetControlsState(HWND hwndDlg)
138 {
139 HWND hwndList = GetDlgItem(hwndDlg, IDC_KEYLAYOUT_LIST);
140 HWND hwndCombo = GetDlgItem(hwndDlg, IDC_DEFAULT_LANGUAGE);
141 BOOL bIsLeaf, bCanRemove, bCanProp;
142 HTREEITEM hSelected = TreeView_GetSelection(hwndList);
143 TV_ITEM item = { TVIF_PARAM | TVIF_HANDLE };
144 item.hItem = hSelected;
145
146 bIsLeaf = (hSelected && TreeView_GetItem(hwndList, &item) && HIWORD(item.lParam));
147
148 bCanRemove = (bIsLeaf && (s_nAliveLeafCount > 1)) || (s_nRootCount > 1);
149 bCanProp = bIsLeaf;
150
151 EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE_BUTTON), bCanRemove);
152 EnableWindow(GetDlgItem(hwndDlg, IDC_PROP_BUTTON), bCanProp);
153
154 InitDefaultLangComboBox(hwndCombo);
155 }
156
157 static BOOL CALLBACK
EnumResNameProc(HMODULE hModule,LPCWSTR lpszType,LPWSTR lpszName,LONG_PTR lParam)158 EnumResNameProc(HMODULE hModule, LPCWSTR lpszType, LPWSTR lpszName, LONG_PTR lParam)
159 {
160 HICON* phIconSm = (HICON*)lParam;
161 if (*phIconSm)
162 return FALSE;
163
164 *phIconSm = (HICON)LoadImageW(hModule, lpszName, IMAGE_ICON,
165 GetSystemMetrics(SM_CXSMICON),
166 GetSystemMetrics(SM_CYSMICON),
167 0);
168 return TRUE;
169 }
170
LoadIMEIcon(LPCTSTR pszImeFile)171 static HICON LoadIMEIcon(LPCTSTR pszImeFile)
172 {
173 WCHAR szSysDir[MAX_PATH], szPath[MAX_PATH];
174 HINSTANCE hImeInst;
175 HICON hIconSm = NULL;
176
177 GetSystemDirectoryW(szSysDir, _countof(szSysDir));
178 StringCchPrintfW(szPath, _countof(szPath), L"%s\\%s", szSysDir, pszImeFile);
179
180 hImeInst = LoadLibraryExW(szPath, NULL, DONT_RESOLVE_DLL_REFERENCES);
181 if (hImeInst == NULL)
182 return NULL;
183
184 EnumResourceNamesW(hImeInst, RT_GROUP_ICON, EnumResNameProc, (LPARAM)&hIconSm);
185 FreeLibrary(hImeInst);
186
187 return hIconSm;
188 }
189
FindLanguageInList(HWND hwndList,LPCTSTR pszLangName)190 static HTREEITEM FindLanguageInList(HWND hwndList, LPCTSTR pszLangName)
191 {
192 TV_ITEM item;
193 TCHAR szText[128];
194 HTREEITEM hItem;
195
196 hItem = TreeView_GetRoot(hwndList);
197 while (hItem)
198 {
199 szText[0] = 0;
200 item.mask = TVIF_TEXT | TVIF_HANDLE;
201 item.pszText = szText;
202 item.cchTextMax = _countof(szText);
203 item.hItem = hItem;
204 TreeView_GetItem(hwndList, &item);
205 if (_wcsicmp(szText, pszLangName) == 0)
206 return hItem;
207
208 hItem = TreeView_GetNextSibling(hwndList, hItem);
209 }
210
211 return NULL;
212 }
213
214 static VOID
AddToInputListView(HWND hwndList,INPUT_LIST_NODE * pInputNode)215 AddToInputListView(HWND hwndList, INPUT_LIST_NODE *pInputNode)
216 {
217 TV_ITEM item;
218 TV_INSERTSTRUCT insert;
219 HIMAGELIST hImageList = TreeView_GetImageList(hwndList, TVSIL_NORMAL);
220 WCHAR szKeyboard[64];
221 HTREEITEM hItem;
222 BOOL bBold = !!(pInputNode->wFlags & INPUT_LIST_NODE_FLAG_DEFAULT);
223
224 hItem = FindLanguageInList(hwndList, pInputNode->pLocale->pszName);
225 if (hItem == NULL)
226 {
227 // Language icon
228 INT LangImageIndex = -1;
229 HICON hLangIcon = CreateLayoutIcon(LOWORD(pInputNode->pLocale->dwId));
230 if (hLangIcon)
231 {
232 LangImageIndex = ImageList_AddIcon(hImageList, hLangIcon);
233 DestroyIcon(hLangIcon);
234 }
235
236 // Language
237 ZeroMemory(&item, sizeof(item));
238 item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_PARAM | TVIF_SELECTEDIMAGE | TVIF_STATE;
239 item.pszText = pInputNode->pLocale->pszName;
240 item.iImage = LangImageIndex;
241 item.iSelectedImage = LangImageIndex;
242 item.lParam = LOWORD(pInputNode->pLocale->dwId); // HIWORD(item.lParam) == 0
243 if (bBold)
244 {
245 item.state = item.stateMask = TVIS_BOLD;
246 }
247 insert.hParent = TVI_ROOT;
248 insert.hInsertAfter = TVI_LAST;
249 insert.item = item;
250 hItem = TreeView_InsertItem(hwndList, &insert);
251
252 // The type of input method (currently keyboard only)
253 LoadStringW(hApplet, IDS_KEYBOARD, szKeyboard, _countof(szKeyboard));
254 ZeroMemory(&item, sizeof(item));
255 item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_PARAM | TVIF_SELECTEDIMAGE;
256 item.pszText = szKeyboard;
257 item.iImage = s_iKeyboardImage;
258 item.iSelectedImage = s_iKeyboardImage;
259 item.lParam = 0; // HIWORD(item.lParam) == 0
260 insert.hParent = hItem;
261 insert.hInsertAfter = TVI_LAST;
262 insert.item = item;
263 hItem = TreeView_InsertItem(hwndList, &insert);
264 }
265 else
266 {
267 // Language
268 ZeroMemory(&item, sizeof(item));
269 item.mask = TVIF_STATE | TVIF_HANDLE;
270 item.hItem = hItem;
271 item.stateMask = TVIS_BOLD;
272 if (TreeView_GetItem(hwndList, &item) && bBold && !(item.state & TVIS_BOLD))
273 {
274 // Make the item bold
275 item.mask = TVIF_STATE | TVIF_HANDLE;
276 item.hItem = hItem;
277 item.state = item.stateMask = TVIS_BOLD;
278 TreeView_SetItem(hwndList, &item);
279 }
280
281 // The type of input method (currently keyboard only)
282 hItem = TreeView_GetChild(hwndList, hItem);
283 }
284
285 // Input method
286 if (hItem)
287 {
288 INT ImeImageIndex = s_iDotImage;
289 if (IS_IME_HKL(pInputNode->hkl) && pInputNode->pLayout->pszImeFile) // IME?
290 {
291 HICON hImeIcon = LoadIMEIcon(pInputNode->pLayout->pszImeFile);
292 if (hImeIcon)
293 {
294 ImeImageIndex = ImageList_AddIcon(hImageList, hImeIcon);
295 DestroyIcon(hImeIcon);
296 }
297 }
298
299 ZeroMemory(&item, sizeof(item));
300 item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_PARAM | TVIF_SELECTEDIMAGE | TVIF_STATE;
301 item.pszText = pInputNode->pLayout->pszName;
302 item.iImage = ImeImageIndex;
303 item.iSelectedImage = ImeImageIndex;
304 item.lParam = (LPARAM)pInputNode; // HIWORD(item.lParam) != 0
305 if (bBold)
306 {
307 item.state = item.stateMask = TVIS_BOLD; // Make the item bold
308 }
309 insert.hParent = hItem;
310 insert.hInsertAfter = TVI_LAST;
311 insert.item = item;
312 hItem = TreeView_InsertItem(hwndList, &insert);
313 }
314 }
315
ExpandTreeItem(HWND hwndTree,HTREEITEM hItem)316 static VOID ExpandTreeItem(HWND hwndTree, HTREEITEM hItem)
317 {
318 TreeView_Expand(hwndTree, hItem, TVE_EXPAND);
319 hItem = TreeView_GetChild(hwndTree, hItem);
320 while (hItem)
321 {
322 ExpandTreeItem(hwndTree, hItem);
323 hItem = TreeView_GetNextSibling(hwndTree, hItem);
324 }
325 }
326
327 static VOID
UpdateInputListView(HWND hwndList)328 UpdateInputListView(HWND hwndList)
329 {
330 INPUT_LIST_NODE *pNode;
331 HIMAGELIST hImageList = TreeView_GetImageList(hwndList, TVSIL_NORMAL);
332 HTREEITEM hItem;
333 HICON hKeyboardIcon, hDotIcon;
334
335 ImageList_RemoveAll(hImageList);
336 TreeView_DeleteAllItems(hwndList);
337
338 // Add keyboard icon
339 s_iKeyboardImage = -1;
340 hKeyboardIcon = (HICON)LoadImageW(hApplet, MAKEINTRESOURCEW(IDI_KEYBOARD), IMAGE_ICON,
341 GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
342 0);
343 if (hKeyboardIcon)
344 {
345 s_iKeyboardImage = ImageList_AddIcon(hImageList, hKeyboardIcon);
346 DestroyIcon(hKeyboardIcon);
347 }
348
349 // Add dot icon
350 s_iDotImage = -1;
351 hDotIcon = (HICON)LoadImageW(hApplet, MAKEINTRESOURCEW(IDI_DOT), IMAGE_ICON,
352 GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
353 0);
354 if (hDotIcon)
355 {
356 s_iDotImage = ImageList_AddIcon(hImageList, hDotIcon);
357 DestroyIcon(hDotIcon);
358 }
359
360 InputList_Sort();
361
362 s_nAliveLeafCount = InputList_GetAliveCount();
363
364 // Add items to the list
365 for (pNode = InputList_GetFirst(); pNode; pNode = pNode->pNext)
366 {
367 if (pNode->wFlags & INPUT_LIST_NODE_FLAG_DELETED)
368 continue;
369
370 AddToInputListView(hwndList, pNode);
371 }
372
373 // Expand all (with counting s_nRootCount)
374 s_nRootCount = 0;
375 hItem = TreeView_GetRoot(hwndList);
376 while (hItem)
377 {
378 ++s_nRootCount;
379 ExpandTreeItem(hwndList, hItem);
380 hItem = TreeView_GetNextSibling(hwndList, hItem);
381 }
382
383 // Redraw
384 InvalidateRect(hwndList, NULL, TRUE);
385 }
386
387 static VOID
OnInitSettingsPage(HWND hwndDlg)388 OnInitSettingsPage(HWND hwndDlg)
389 {
390 HWND hwndInputList = GetDlgItem(hwndDlg, IDC_KEYLAYOUT_LIST);
391 HIMAGELIST hLayoutImageList, hOldImageList;
392
393 LayoutList_Create();
394 LocaleList_Create();
395 InputList_Create();
396
397 EnableWindow(GetDlgItem(hwndDlg, IDC_LANGUAGE_BAR), FALSE);
398
399 hLayoutImageList = ImageList_Create(GetSystemMetrics(SM_CXSMICON),
400 GetSystemMetrics(SM_CYSMICON),
401 ILC_COLOR8 | ILC_MASK, 0, 0);
402 if (hLayoutImageList != NULL)
403 {
404 hOldImageList = TreeView_SetImageList(hwndInputList, hLayoutImageList, TVSIL_NORMAL);
405 ImageList_Destroy(hOldImageList);
406 }
407
408 UpdateInputListView(hwndInputList);
409
410 SetControlsState(hwndDlg);
411 }
412
413
414 static VOID
OnDestroySettingsPage(HWND hwndDlg)415 OnDestroySettingsPage(HWND hwndDlg)
416 {
417 LayoutList_Destroy();
418 LocaleList_Destroy();
419 InputList_Destroy();
420 }
421
422
423 VOID
OnCommandSettingsPage(HWND hwndDlg,WPARAM wParam)424 OnCommandSettingsPage(HWND hwndDlg, WPARAM wParam)
425 {
426 switch (LOWORD(wParam))
427 {
428 case IDC_ADD_BUTTON:
429 {
430 if (DialogBoxW(hApplet,
431 MAKEINTRESOURCEW(IDD_ADD),
432 hwndDlg,
433 AddDialogProc) == IDOK)
434 {
435 UpdateInputListView(GetDlgItem(hwndDlg, IDC_KEYLAYOUT_LIST));
436 SetControlsState(hwndDlg);
437 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
438 }
439 }
440 break;
441
442 case IDC_REMOVE_BUTTON:
443 {
444 HWND hwndList = GetDlgItem(hwndDlg, IDC_KEYLAYOUT_LIST);
445 if (hwndList)
446 {
447 HTREEITEM hItem = TreeView_GetSelection(hwndList);
448 TV_ITEM item = { TVIF_HANDLE | TVIF_PARAM };
449 item.hItem = hItem;
450
451 if (hItem && TreeView_GetItem(hwndList, &item))
452 {
453 if (item.lParam == 0) // Branch? (currently branch is keyboard only)
454 {
455 // Get root of branch
456 item.hItem = TreeView_GetParent(hwndList, hItem);
457 TreeView_GetItem(hwndList, &item);
458 }
459
460 if (HIWORD(item.lParam)) // Leaf?
461 {
462 if (InputList_Remove((INPUT_LIST_NODE*)item.lParam))
463 g_bRebootNeeded = TRUE;
464 }
465 else // Root?
466 {
467 if (InputList_RemoveByLang(LOWORD(item.lParam)))
468 g_bRebootNeeded = TRUE;
469 }
470
471 UpdateInputListView(hwndList);
472 SetControlsState(hwndDlg);
473 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
474 }
475 }
476 }
477 break;
478
479 case IDC_PROP_BUTTON:
480 {
481 HWND hwndList = GetDlgItem(hwndDlg, IDC_KEYLAYOUT_LIST);
482 if (hwndList)
483 {
484 HTREEITEM hItem = TreeView_GetSelection(hwndList);
485 TV_ITEM item = { TVIF_HANDLE | TVIF_PARAM };
486 item.hItem = hItem;
487
488 if (hItem && TreeView_GetItem(hwndList, &item) && HIWORD(item.lParam))
489 {
490 if (DialogBoxParamW(hApplet,
491 MAKEINTRESOURCEW(IDD_INPUT_LANG_PROP),
492 hwndDlg,
493 EditDialogProc,
494 item.lParam) == IDOK)
495 {
496 UpdateInputListView(hwndList);
497 SetControlsState(hwndDlg);
498 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
499 }
500 }
501 }
502 }
503 break;
504
505 case IDC_KEY_SET_BTN:
506 {
507 DialogBoxW(hApplet,
508 MAKEINTRESOURCEW(IDD_KEYSETTINGS),
509 hwndDlg,
510 KeySettingsDialogProc);
511 }
512 break;
513
514 case IDC_LANGUAGE_BAR:
515 {
516 // FIXME
517 break;
518 }
519
520 case IDC_DEFAULT_LANGUAGE:
521 {
522 if (HIWORD(wParam) == CBN_SELENDOK)
523 {
524 HWND hwndList = GetDlgItem(hwndDlg, IDC_KEYLAYOUT_LIST);
525 HWND hwndCombo = GetDlgItem(hwndDlg, IDC_DEFAULT_LANGUAGE);
526 INT iSelected = (INT)SendMessageW(hwndCombo, CB_GETCURSEL, 0, 0);
527 if (iSelected != CB_ERR)
528 {
529 LPARAM lParam = SendMessageW(hwndCombo, CB_GETITEMDATA, iSelected, 0);
530 if (lParam)
531 {
532 INPUT_LIST_NODE* pNode = (INPUT_LIST_NODE*)lParam;
533 if (!(pNode->wFlags & INPUT_LIST_NODE_FLAG_DEFAULT))
534 {
535 g_bRebootNeeded = TRUE;
536 InputList_SetDefault(pNode);
537 UpdateInputListView(hwndList);
538 SetControlsState(hwndDlg);
539 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
540 }
541 }
542 }
543 }
544 }
545 }
546 }
547
EnableProcessPrivileges(LPCWSTR lpPrivilegeName,BOOL bEnable)548 BOOL EnableProcessPrivileges(LPCWSTR lpPrivilegeName, BOOL bEnable)
549 {
550 HANDLE hToken;
551 LUID luid;
552 TOKEN_PRIVILEGES tokenPrivileges;
553 BOOL Ret;
554
555 Ret = OpenProcessToken(GetCurrentProcess(),
556 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
557 &hToken);
558 if (!Ret)
559 return Ret; // failure
560
561 Ret = LookupPrivilegeValueW(NULL, lpPrivilegeName, &luid);
562 if (Ret)
563 {
564 tokenPrivileges.PrivilegeCount = 1;
565 tokenPrivileges.Privileges[0].Luid = luid;
566 tokenPrivileges.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0;
567
568 Ret = AdjustTokenPrivileges(hToken, FALSE, &tokenPrivileges, 0, 0, 0);
569 }
570
571 CloseHandle(hToken);
572 return Ret;
573 }
574
575 static INT_PTR
OnNotifySettingsPage(HWND hwndDlg,LPARAM lParam)576 OnNotifySettingsPage(HWND hwndDlg, LPARAM lParam)
577 {
578 LPNMHDR header = (LPNMHDR)lParam;
579
580 switch (header->code)
581 {
582 case TVN_SELCHANGED:
583 {
584 SetControlsState(hwndDlg);
585 break;
586 }
587
588 case TVN_ITEMEXPANDING:
589 {
590 // FIXME: Prevent collapse (COMCTL32 is buggy)
591 // https://bugs.winehq.org/show_bug.cgi?id=53727
592 NM_TREEVIEW* pTreeView = (NM_TREEVIEW*)lParam;
593 if ((pTreeView->action & TVE_TOGGLE) == TVE_COLLAPSE)
594 {
595 SetWindowLongPtrW(hwndDlg, DWLP_MSGRESULT, TRUE);
596 return TRUE;
597 }
598 break;
599 }
600
601 case PSN_APPLY:
602 {
603 /* Write Input Methods list to registry */
604 g_bRebootNeeded |= InputList_Process();
605 break;
606 }
607 }
608
609 return 0;
610 }
611
612 INT_PTR CALLBACK
SettingsPageProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)613 SettingsPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
614 {
615 switch (uMsg)
616 {
617 case WM_INITDIALOG:
618 OnInitSettingsPage(hwndDlg);
619 return TRUE;
620
621 case WM_DESTROY:
622 OnDestroySettingsPage(hwndDlg);
623 break;
624
625 case WM_COMMAND:
626 OnCommandSettingsPage(hwndDlg, wParam);
627 break;
628
629 case WM_NOTIFY:
630 return OnNotifySettingsPage(hwndDlg, lParam);
631 }
632
633 return FALSE;
634 }
635