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 15 static HICON 16 CreateLayoutIcon(LPWSTR szLayout, BOOL bIsDefault) 17 { 18 INT width = GetSystemMetrics(SM_CXSMICON) * 2; 19 INT height = GetSystemMetrics(SM_CYSMICON); 20 HDC hdc; 21 HDC hdcsrc; 22 HBITMAP hBitmap; 23 HICON hIcon = NULL; 24 25 hdcsrc = GetDC(NULL); 26 hdc = CreateCompatibleDC(hdcsrc); 27 hBitmap = CreateCompatibleBitmap(hdcsrc, width, height); 28 29 ReleaseDC(NULL, hdcsrc); 30 31 if (hdc && hBitmap) 32 { 33 HBITMAP hBmpNew; 34 35 hBmpNew = CreateBitmap(width, height, 1, 1, NULL); 36 if (hBmpNew) 37 { 38 LOGFONTW lf; 39 40 if (SystemParametersInfoW(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0)) 41 { 42 ICONINFO IconInfo; 43 HFONT hFont; 44 45 hFont = CreateFontIndirectW(&lf); 46 47 if (hFont != NULL) 48 { 49 HBITMAP hBmpOld; 50 51 hBmpOld = SelectObject(hdc, hBitmap); 52 53 if (hBmpOld != NULL) 54 { 55 RECT rect; 56 57 SetRect(&rect, 0, 0, width / 2, height); 58 59 if (bIsDefault != FALSE) 60 { 61 SetBkColor(hdc, GetSysColor(COLOR_WINDOW)); 62 SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT)); 63 64 ExtTextOutW(hdc, rect.left, rect.top, ETO_OPAQUE, &rect, L"", 0, NULL); 65 66 SelectObject(hdc, hFont); 67 DrawTextW(hdc, L"\x2022", 1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER); 68 } 69 else 70 { 71 FillRect(hdc, &rect, GetSysColorBrush(COLOR_WINDOW)); 72 } 73 74 SetRect(&rect, width / 2, 0, width, height); 75 76 SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT)); 77 SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT)); 78 79 ExtTextOutW(hdc, rect.left, rect.top, ETO_OPAQUE, &rect, L"", 0, NULL); 80 81 SelectObject(hdc, hFont); 82 DrawTextW(hdc, szLayout, 2, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER); 83 84 SelectObject(hdc, hBmpNew); 85 86 PatBlt(hdc, 0, 0, width, height, BLACKNESS); 87 88 SelectObject(hdc, hBmpOld); 89 90 IconInfo.hbmColor = hBitmap; 91 IconInfo.hbmMask = hBmpNew; 92 IconInfo.fIcon = TRUE; 93 94 hIcon = CreateIconIndirect(&IconInfo); 95 96 DeleteObject(hBmpOld); 97 } 98 99 DeleteObject(hFont); 100 } 101 } 102 103 DeleteObject(hBmpNew); 104 } 105 } 106 107 DeleteDC(hdc); 108 DeleteObject(hBitmap); 109 110 return hIcon; 111 } 112 113 114 static VOID 115 SetControlsState(HWND hwndDlg, BOOL bIsEnabled) 116 { 117 EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE_BUTTON), bIsEnabled); 118 EnableWindow(GetDlgItem(hwndDlg, IDC_PROP_BUTTON), bIsEnabled); 119 EnableWindow(GetDlgItem(hwndDlg, IDC_SET_DEFAULT), bIsEnabled); 120 } 121 122 123 static VOID 124 AddToInputListView(HWND hwndList, INPUT_LIST_NODE *pInputNode) 125 { 126 INT ItemIndex = -1; 127 INT ImageIndex = -1; 128 LV_ITEM item; 129 HIMAGELIST hImageList; 130 131 hImageList = ListView_GetImageList(hwndList, LVSIL_SMALL); 132 133 if (hImageList != NULL) 134 { 135 HICON hLayoutIcon; 136 137 hLayoutIcon = CreateLayoutIcon(pInputNode->pszIndicator, 138 (pInputNode->wFlags & INPUT_LIST_NODE_FLAG_DEFAULT)); 139 140 if (hLayoutIcon != NULL) 141 { 142 ImageIndex = ImageList_AddIcon(hImageList, hLayoutIcon); 143 DestroyIcon(hLayoutIcon); 144 } 145 } 146 147 ZeroMemory(&item, sizeof(item)); 148 149 item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; 150 item.pszText = pInputNode->pLocale->pszName; 151 item.iItem = ListView_GetItemCount(hwndList) + 1; 152 item.lParam = (LPARAM)pInputNode; 153 item.iImage = ImageIndex; 154 155 ItemIndex = ListView_InsertItem(hwndList, &item); 156 157 ListView_SetItemText(hwndList, ItemIndex, 1, pInputNode->pLayout->pszName); 158 } 159 160 161 static VOID 162 UpdateInputListView(HWND hwndList) 163 { 164 INPUT_LIST_NODE *pCurrentInputNode; 165 HIMAGELIST hImageList; 166 167 hImageList = ListView_GetImageList(hwndList, LVSIL_SMALL); 168 if (hImageList != NULL) 169 { 170 ImageList_RemoveAll(hImageList); 171 } 172 173 ListView_DeleteAllItems(hwndList); 174 175 for (pCurrentInputNode = InputList_GetFirst(); 176 pCurrentInputNode != NULL; 177 pCurrentInputNode = pCurrentInputNode->pNext) 178 { 179 if (!(pCurrentInputNode->wFlags & INPUT_LIST_NODE_FLAG_DELETED)) 180 { 181 AddToInputListView(hwndList, pCurrentInputNode); 182 } 183 } 184 } 185 186 187 static VOID 188 OnInitSettingsPage(HWND hwndDlg) 189 { 190 HWND hwndInputList; 191 192 LayoutList_Create(); 193 LocaleList_Create(); 194 InputList_Create(); 195 196 hwndInputList = GetDlgItem(hwndDlg, IDC_KEYLAYOUT_LIST); 197 198 if (hwndInputList != NULL) 199 { 200 WCHAR szBuffer[MAX_STR_LEN]; 201 HIMAGELIST hLayoutImageList; 202 LV_COLUMN column; 203 204 ListView_SetExtendedListViewStyle(hwndInputList, LVS_EX_FULLROWSELECT); 205 206 ZeroMemory(&column, sizeof(column)); 207 208 column.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM; 209 210 LoadStringW(hApplet, IDS_LANGUAGE, szBuffer, ARRAYSIZE(szBuffer)); 211 column.fmt = LVCFMT_LEFT; 212 column.iSubItem = 0; 213 column.pszText = szBuffer; 214 column.cx = 175; 215 ListView_InsertColumn(hwndInputList, 0, &column); 216 217 LoadStringW(hApplet, IDS_LAYOUT, szBuffer, ARRAYSIZE(szBuffer)); 218 column.fmt = LVCFMT_RIGHT; 219 column.cx = 155; 220 column.iSubItem = 1; 221 column.pszText = szBuffer; 222 ListView_InsertColumn(hwndInputList, 1, &column); 223 224 hLayoutImageList = ImageList_Create(GetSystemMetrics(SM_CXSMICON) * 2, 225 GetSystemMetrics(SM_CYSMICON), 226 ILC_COLOR8 | ILC_MASK, 0, 0); 227 if (hLayoutImageList != NULL) 228 { 229 ListView_SetImageList(hwndInputList, hLayoutImageList, LVSIL_SMALL); 230 } 231 232 UpdateInputListView(hwndInputList); 233 } 234 235 SetControlsState(hwndDlg, FALSE); 236 } 237 238 239 static VOID 240 OnDestroySettingsPage(HWND hwndDlg) 241 { 242 HIMAGELIST hImageList; 243 244 LayoutList_Destroy(); 245 LocaleList_Destroy(); 246 InputList_Destroy(); 247 248 hImageList = ListView_GetImageList(GetDlgItem(hwndDlg, IDC_KEYLAYOUT_LIST), 249 LVSIL_SMALL); 250 if (hImageList != NULL) 251 { 252 ImageList_Destroy(hImageList); 253 } 254 } 255 256 257 VOID 258 OnCommandSettingsPage(HWND hwndDlg, WPARAM wParam) 259 { 260 switch (LOWORD(wParam)) 261 { 262 case IDC_ADD_BUTTON: 263 { 264 if (DialogBoxW(hApplet, 265 MAKEINTRESOURCEW(IDD_ADD), 266 hwndDlg, 267 AddDialogProc) == IDOK) 268 { 269 UpdateInputListView(GetDlgItem(hwndDlg, IDC_KEYLAYOUT_LIST)); 270 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 271 } 272 } 273 break; 274 275 case IDC_REMOVE_BUTTON: 276 { 277 HWND hwndList; 278 279 hwndList = GetDlgItem(hwndDlg, IDC_KEYLAYOUT_LIST); 280 281 if (hwndList != NULL) 282 { 283 LVITEM item = { 0 }; 284 285 item.mask = LVIF_PARAM; 286 item.iItem = ListView_GetNextItem(hwndList, -1, LVNI_SELECTED); 287 288 if (ListView_GetItem(hwndList, &item) != FALSE) 289 { 290 InputList_Remove((INPUT_LIST_NODE*) item.lParam); 291 UpdateInputListView(hwndList); 292 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 293 } 294 } 295 } 296 break; 297 298 case IDC_PROP_BUTTON: 299 { 300 HWND hwndList; 301 302 hwndList = GetDlgItem(hwndDlg, IDC_KEYLAYOUT_LIST); 303 304 if (hwndList != NULL) 305 { 306 LVITEM item = { 0 }; 307 308 item.mask = LVIF_PARAM; 309 item.iItem = ListView_GetNextItem(hwndList, -1, LVNI_SELECTED); 310 311 if (ListView_GetItem(hwndList, &item) != FALSE) 312 { 313 if (DialogBoxParamW(hApplet, 314 MAKEINTRESOURCEW(IDD_INPUT_LANG_PROP), 315 hwndDlg, 316 EditDialogProc, 317 item.lParam) == IDOK) 318 { 319 UpdateInputListView(hwndList); 320 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 321 } 322 } 323 } 324 } 325 break; 326 327 case IDC_SET_DEFAULT: 328 { 329 HWND hwndList; 330 331 hwndList = GetDlgItem(hwndDlg, IDC_KEYLAYOUT_LIST); 332 333 if (hwndList != NULL) 334 { 335 LVITEM item = { 0 }; 336 337 item.mask = LVIF_PARAM; 338 item.iItem = ListView_GetNextItem(hwndList, -1, LVNI_SELECTED); 339 340 if (ListView_GetItem(hwndList, &item) != FALSE) 341 { 342 InputList_SetDefault((INPUT_LIST_NODE*) item.lParam); 343 UpdateInputListView(hwndList); 344 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 345 } 346 } 347 } 348 break; 349 350 case IDC_KEY_SET_BTN: 351 { 352 DialogBoxW(hApplet, 353 MAKEINTRESOURCEW(IDD_KEYSETTINGS), 354 hwndDlg, 355 KeySettingsDialogProc); 356 } 357 break; 358 } 359 } 360 361 BOOL EnableProcessPrivileges(LPCWSTR lpPrivilegeName, BOOL bEnable) 362 { 363 HANDLE hToken; 364 LUID luid; 365 TOKEN_PRIVILEGES tokenPrivileges; 366 BOOL Ret; 367 368 Ret = OpenProcessToken(GetCurrentProcess(), 369 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, 370 &hToken); 371 if (!Ret) 372 return Ret; // failure 373 374 Ret = LookupPrivilegeValueW(NULL, lpPrivilegeName, &luid); 375 if (Ret) 376 { 377 tokenPrivileges.PrivilegeCount = 1; 378 tokenPrivileges.Privileges[0].Luid = luid; 379 tokenPrivileges.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0; 380 381 Ret = AdjustTokenPrivileges(hToken, FALSE, &tokenPrivileges, 0, 0, 0); 382 } 383 384 CloseHandle(hToken); 385 return Ret; 386 } 387 388 static VOID 389 OnNotifySettingsPage(HWND hwndDlg, LPARAM lParam) 390 { 391 LPNMHDR header; 392 393 header = (LPNMHDR)lParam; 394 395 switch (header->code) 396 { 397 case NM_CLICK: 398 { 399 if (header->idFrom == IDC_KEYLAYOUT_LIST) 400 { 401 INT iSelected = ListView_GetNextItem(header->hwndFrom, -1, LVNI_SELECTED); 402 403 if (iSelected != -1) 404 { 405 LVITEM item = { 0 }; 406 407 SetControlsState(hwndDlg, TRUE); 408 409 item.mask = LVIF_PARAM; 410 item.iItem = iSelected; 411 412 if (ListView_GetItem(header->hwndFrom, &item) != FALSE) 413 { 414 INPUT_LIST_NODE *pInput; 415 416 pInput = (INPUT_LIST_NODE*) item.lParam; 417 418 if (pInput != NULL && pInput->wFlags & INPUT_LIST_NODE_FLAG_DEFAULT) 419 { 420 EnableWindow(GetDlgItem(hwndDlg, IDC_SET_DEFAULT), FALSE); 421 } 422 } 423 } 424 else 425 { 426 SetControlsState(hwndDlg, FALSE); 427 } 428 } 429 } 430 break; 431 432 case PSN_APPLY: 433 { 434 /* Write Input Methods list to registry */ 435 if (InputList_Process()) 436 { 437 /* Needs reboot */ 438 WCHAR szNeedsReboot[128], szLanguage[64]; 439 LoadStringW(hApplet, IDS_REBOOT_NOW, szNeedsReboot, _countof(szNeedsReboot)); 440 LoadStringW(hApplet, IDS_LANGUAGE, szLanguage, _countof(szLanguage)); 441 442 if (MessageBoxW(hwndDlg, szNeedsReboot, szLanguage, 443 MB_ICONINFORMATION | MB_YESNOCANCEL) == IDYES) 444 { 445 EnableProcessPrivileges(SE_SHUTDOWN_NAME, TRUE); 446 ExitWindowsEx(EWX_REBOOT | EWX_FORCE, 0); 447 } 448 } 449 } 450 break; 451 } 452 } 453 454 455 INT_PTR CALLBACK 456 SettingsPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 457 { 458 switch (uMsg) 459 { 460 case WM_INITDIALOG: 461 OnInitSettingsPage(hwndDlg); 462 break; 463 464 case WM_DESTROY: 465 OnDestroySettingsPage(hwndDlg); 466 break; 467 468 case WM_COMMAND: 469 OnCommandSettingsPage(hwndDlg, wParam); 470 break; 471 472 case WM_NOTIFY: 473 OnNotifySettingsPage(hwndDlg, lParam); 474 break; 475 } 476 477 return FALSE; 478 } 479