1 /* 2 * PROJECT: ReactOS Accessibility Control Panel 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: dll/cpl/access/display.c 5 * PURPOSE: Display-related accessibility settings 6 * COPYRIGHT: Copyright 2004 Johannes Anderwald (johannes.anderwald@reactos.org) 7 * Copyright 2007 Eric Kohl 8 */ 9 10 #include "access.h" 11 12 #include <wingdi.h> 13 14 #define ID_BLINK_TIMER 346 15 16 static VOID 17 UpdateCaretBlinkTimeReg( 18 _In_ UINT uCaretBlinkTime) 19 { 20 HKEY hKey; 21 WCHAR szBuffer[12]; 22 23 if (RegOpenKeyExW(HKEY_CURRENT_USER, 24 L"Control Panel\\Desktop", 25 0, KEY_SET_VALUE, 26 &hKey) != ERROR_SUCCESS) 27 { 28 return; 29 } 30 31 wsprintf(szBuffer, L"%d", uCaretBlinkTime); 32 33 RegSetValueExW(hKey, L"CursorBlinkRate", 34 0, REG_SZ, 35 (CONST BYTE*)szBuffer, 36 (wcslen(szBuffer) + 1) * sizeof(WCHAR)); 37 38 RegCloseKey(hKey); 39 } 40 41 static VOID 42 FillColorSchemeComboBox(HWND hwnd) 43 { 44 TCHAR szValue[128]; 45 DWORD dwDisposition; 46 DWORD dwLength; 47 HKEY hKey; 48 LONG lError; 49 INT i; 50 51 lError = RegCreateKeyEx(HKEY_CURRENT_USER, 52 _T("Control Panel\\Appearance\\Schemes"), 53 0, 54 NULL, 55 REG_OPTION_NON_VOLATILE, 56 KEY_ENUMERATE_SUB_KEYS | KEY_EXECUTE | KEY_QUERY_VALUE, 57 NULL, 58 &hKey, 59 &dwDisposition); 60 if (lError != ERROR_SUCCESS) 61 return; 62 63 for (i = 0; ; i++) 64 { 65 dwLength = 128; 66 lError = RegEnumValue(hKey, 67 i, 68 szValue, 69 &dwLength, NULL, NULL, NULL, NULL); 70 if (lError == ERROR_NO_MORE_ITEMS) 71 break; 72 73 SendMessage(hwnd, 74 CB_ADDSTRING, 75 0, 76 (LPARAM)szValue); 77 } 78 79 RegCloseKey(hKey); 80 } 81 82 83 INT_PTR CALLBACK 84 HighContrastDlgProc(HWND hwndDlg, 85 UINT uMsg, 86 WPARAM wParam, 87 LPARAM lParam) 88 { 89 PGLOBAL_DATA pGlobalData; 90 91 pGlobalData = (PGLOBAL_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER); 92 93 switch (uMsg) 94 { 95 case WM_INITDIALOG: 96 pGlobalData = (PGLOBAL_DATA)lParam; 97 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pGlobalData); 98 99 CheckDlgButton(hwndDlg, 100 IDC_CONTRAST_ACTIVATE_CHECK, 101 pGlobalData->highContrast.dwFlags & HCF_HOTKEYACTIVE ? BST_CHECKED : BST_UNCHECKED); 102 103 FillColorSchemeComboBox(GetDlgItem(hwndDlg, IDC_CONTRAST_COMBO)); 104 105 SendDlgItemMessage(hwndDlg, 106 IDC_CONTRAST_COMBO, 107 CB_SELECTSTRING, 108 (WPARAM)-1, 109 (LPARAM)pGlobalData->highContrast.lpszDefaultScheme); 110 break; 111 112 case WM_COMMAND: 113 switch (LOWORD(wParam)) 114 { 115 case IDC_CONTRAST_ACTIVATE_CHECK: 116 pGlobalData->highContrast.dwFlags ^= HCF_HOTKEYACTIVE; 117 break; 118 119 case IDC_CONTRAST_COMBO: 120 if (HIWORD(wParam) == CBN_SELCHANGE) 121 { 122 INT nSel; 123 124 nSel = SendDlgItemMessage(hwndDlg, IDC_CONTRAST_COMBO, 125 CB_GETCURSEL, 0, 0); 126 SendDlgItemMessage(hwndDlg, IDC_CONTRAST_COMBO, 127 CB_GETLBTEXT, nSel, 128 (LPARAM)pGlobalData->highContrast.lpszDefaultScheme); 129 } 130 break; 131 132 case IDOK: 133 EndDialog(hwndDlg, TRUE); 134 break; 135 136 case IDCANCEL: 137 EndDialog(hwndDlg, FALSE); 138 break; 139 140 default: 141 break; 142 } 143 break; 144 } 145 146 return FALSE; 147 } 148 149 150 /* Property page dialog callback */ 151 INT_PTR CALLBACK 152 DisplayPageProc(HWND hwndDlg, 153 UINT uMsg, 154 WPARAM wParam, 155 LPARAM lParam) 156 { 157 PGLOBAL_DATA pGlobalData; 158 LPPSHNOTIFY lppsn; 159 INT i; 160 161 pGlobalData = (PGLOBAL_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER); 162 163 switch (uMsg) 164 { 165 case WM_INITDIALOG: 166 pGlobalData = (PGLOBAL_DATA)((LPPROPSHEETPAGE)lParam)->lParam; 167 if (pGlobalData == NULL) 168 return FALSE; 169 170 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pGlobalData); 171 172 pGlobalData->fShowCaret = TRUE; 173 GetWindowRect(GetDlgItem(hwndDlg, IDC_CURSOR_WIDTH_TEXT), &pGlobalData->rcCaret); 174 ScreenToClient(hwndDlg, (LPPOINT)&pGlobalData->rcCaret.left); 175 ScreenToClient(hwndDlg, (LPPOINT)&pGlobalData->rcCaret.right); 176 CopyRect(&pGlobalData->rcOldCaret, &pGlobalData->rcCaret); 177 178 pGlobalData->rcCaret.right = pGlobalData->rcCaret.left + pGlobalData->uCaretWidth; 179 180 /* Set the checkbox */ 181 CheckDlgButton(hwndDlg, 182 IDC_CONTRAST_BOX, 183 pGlobalData->highContrast.dwFlags & HCF_HIGHCONTRASTON ? BST_CHECKED : BST_UNCHECKED); 184 185 SendDlgItemMessage(hwndDlg, IDC_CURSOR_BLINK_TRACK, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(0, 10)); 186 SendDlgItemMessage(hwndDlg, IDC_CURSOR_BLINK_TRACK, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)(12 - (pGlobalData->uCaretBlinkTime / 100))); 187 188 SendDlgItemMessage(hwndDlg, IDC_CURSOR_WIDTH_TRACK, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(0, 19)); 189 SendDlgItemMessage(hwndDlg, IDC_CURSOR_WIDTH_TRACK, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)(pGlobalData->uCaretWidth - 1)); 190 191 /* Start the blink timer */ 192 pGlobalData->uCaretBlinkTime = pGlobalData->uCaretBlinkTime >= 1200 ? -1 : pGlobalData->uCaretBlinkTime; 193 if ((INT)pGlobalData->uCaretBlinkTime > 0) 194 { 195 SetTimer(hwndDlg, ID_BLINK_TIMER, pGlobalData->uCaretBlinkTime, NULL); 196 } 197 else 198 { 199 PostMessage(hwndDlg, WM_TIMER, ID_BLINK_TIMER, 0); 200 } 201 202 return TRUE; 203 204 case WM_COMMAND: 205 switch (LOWORD(wParam)) 206 { 207 case IDC_CONTRAST_BOX: 208 pGlobalData->highContrast.dwFlags ^= HCF_HIGHCONTRASTON; 209 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 210 break; 211 212 case IDC_CONTRAST_BUTTON: 213 if (DialogBoxParam(hApplet, 214 MAKEINTRESOURCE(IDD_CONTRASTOPTIONS), 215 hwndDlg, 216 HighContrastDlgProc, 217 (LPARAM)pGlobalData)) 218 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 219 break; 220 221 default: 222 break; 223 } 224 break; 225 226 case WM_HSCROLL: 227 switch (GetWindowLongPtr((HWND) lParam, GWL_ID)) 228 { 229 case IDC_CURSOR_BLINK_TRACK: 230 i = SendDlgItemMessage(hwndDlg, IDC_CURSOR_BLINK_TRACK, TBM_GETPOS, 0, 0); 231 pGlobalData->uCaretBlinkTime = (12 - (UINT)i) * 100; 232 KillTimer(hwndDlg, ID_BLINK_TIMER); 233 pGlobalData->uCaretBlinkTime = pGlobalData->uCaretBlinkTime >= 1200 ? -1 : pGlobalData->uCaretBlinkTime; 234 if ((INT)pGlobalData->uCaretBlinkTime > 0) 235 { 236 SetTimer(hwndDlg, ID_BLINK_TIMER, pGlobalData->uCaretBlinkTime, NULL); 237 } 238 else if (pGlobalData->fShowCaret) 239 { 240 SendMessage(hwndDlg, WM_TIMER, ID_BLINK_TIMER, 0); 241 } 242 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 243 break; 244 245 case IDC_CURSOR_WIDTH_TRACK: 246 i = SendDlgItemMessage(hwndDlg, IDC_CURSOR_WIDTH_TRACK, TBM_GETPOS, 0, 0); 247 pGlobalData->uCaretWidth = (UINT)i + 1; 248 pGlobalData->rcCaret.right = pGlobalData->rcCaret.left + pGlobalData->uCaretWidth; 249 if (pGlobalData->fShowCaret) 250 { 251 HDC hDC = GetDC(hwndDlg); 252 HBRUSH hBrush = GetSysColorBrush(COLOR_BTNTEXT); 253 FillRect(hDC, &pGlobalData->rcCaret, hBrush); 254 ReleaseDC(hwndDlg, hDC); 255 } 256 else 257 { 258 InvalidateRect(hwndDlg, &pGlobalData->rcOldCaret, TRUE); 259 } 260 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 261 break; 262 } 263 break; 264 265 case WM_TIMER: 266 if (wParam == ID_BLINK_TIMER) 267 { 268 if (pGlobalData->fShowCaret) 269 { 270 HDC hDC = GetDC(hwndDlg); 271 HBRUSH hBrush = GetSysColorBrush(COLOR_BTNTEXT); 272 FillRect(hDC, &pGlobalData->rcCaret, hBrush); 273 ReleaseDC(hwndDlg, hDC); 274 } 275 else 276 { 277 InvalidateRect(hwndDlg, &pGlobalData->rcOldCaret, TRUE); 278 } 279 280 pGlobalData->fShowCaret = !pGlobalData->fShowCaret; 281 } 282 break; 283 284 case WM_NOTIFY: 285 lppsn = (LPPSHNOTIFY)lParam; 286 if (lppsn->hdr.code == PSN_APPLY) 287 { 288 if (SetCaretBlinkTime(pGlobalData->uCaretBlinkTime)) 289 { 290 UpdateCaretBlinkTimeReg(pGlobalData->uCaretBlinkTime); 291 } 292 293 SystemParametersInfo(SPI_SETCARETWIDTH, 294 0, 295 IntToPtr(pGlobalData->uCaretWidth), 296 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE /*0*/); 297 SystemParametersInfo(SPI_SETHIGHCONTRAST, 298 sizeof(HIGHCONTRAST), 299 &pGlobalData->highContrast, 300 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE /*0*/); 301 return TRUE; 302 } 303 break; 304 305 case WM_DESTROY: 306 KillTimer(hwndDlg, ID_BLINK_TIMER); 307 break; 308 } 309 310 return FALSE; 311 } 312