Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

401 lines
12 KiB

  1. /******************************************************************************
  2. Module name: Display.C
  3. Purpose: Display Dialog handler
  4. ******************************************************************************/
  5. #include "Access.h"
  6. #include "winuserp.h"
  7. static BOOL s_fBlink = TRUE;
  8. static RECT s_rCursor;
  9. //////////////////////////////////////////////////////////////////////////////
  10. /*******************************************************************
  11. * DESCRIPTION: High Contrast dialog handler
  12. *******************************************************************/
  13. VOID FillCustonSchemeBox (HWND hwndCB) {
  14. HKEY hkey;
  15. int i;
  16. DWORD dwDisposition;
  17. // Get the class name and the value count.
  18. if (RegCreateKeyEx(HKEY_CURRENT_USER, CONTROL_KEY, 0, __TEXT(""),
  19. REG_OPTION_NON_VOLATILE, KEY_ENUMERATE_SUB_KEYS | KEY_EXECUTE | KEY_QUERY_VALUE,
  20. NULL, &hkey, &dwDisposition) != ERROR_SUCCESS) return;
  21. // Enumerate the child keys.
  22. for (i = 0; ; i++) {
  23. DWORD cbValueName;
  24. TCHAR szValueName[MAX_SCHEME_NAME_SIZE];
  25. LONG l;
  26. cbValueName = MAX_SCHEME_NAME_SIZE;
  27. l = RegEnumValue(hkey, i, szValueName, &cbValueName, NULL, NULL, NULL, NULL);
  28. if (ERROR_NO_MORE_ITEMS == l) break;
  29. // Add each value to a combobox.
  30. if (lstrlen(szValueName) == 0) lstrcpy(szValueName, __TEXT("<NO NAME>"));
  31. ComboBox_AddString(hwndCB, ((szValueName[0] == 0) ? __TEXT("<NO NAME>") : szValueName));
  32. }
  33. RegCloseKey(hkey);
  34. }
  35. // ****************************************************************************
  36. // Main HC Dialog handler
  37. // ****************************************************************************
  38. INT_PTR WINAPI HighContrastDlg (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  39. HKEY hkey;
  40. HWND hwndCB = GetDlgItem(hwnd, IDC_HC_DEFAULTSCHEME);
  41. int i;
  42. DWORD dwDisposition;
  43. BOOL fProcessed = TRUE;
  44. switch (uMsg) {
  45. case WM_INITDIALOG:
  46. CheckDlgButton(hwnd, IDC_HC_HOTKEY, (g_hc.dwFlags & HCF_HOTKEYACTIVE) ? TRUE : FALSE);
  47. //
  48. // Put possible high contrast schemes in combo
  49. // box and show the current one
  50. //
  51. // ISSUE: If MUI is enabled then displaying the strings from the registry may
  52. // be incorrect. It should be in the language currently selected.
  53. FillCustonSchemeBox(hwndCB);
  54. // Set the proper selection in the combobox (handle case where it's not set yet)
  55. if (g_hc.lpszDefaultScheme[0] == 0)
  56. {
  57. if (!IsMUI_Enabled())
  58. {
  59. // get scheme name from resources if not MUI enabled
  60. LoadString(g_hinst, IDS_WHITEBLACK_SCHEME, g_hc.lpszDefaultScheme, 200);
  61. }
  62. else
  63. {
  64. // else set scheme name in english
  65. lstrcpy(g_hc.lpszDefaultScheme, IDSENG_WHITEBLACK_SCHEME);
  66. }
  67. }
  68. if (ComboBox_SelectString(hwndCB, -1, g_hc.lpszDefaultScheme) == CB_ERR) {
  69. // Not found, select the 1st one
  70. // TODO this is bad! When MUI enabled we will rarely find the correct scheme!
  71. ComboBox_SetCurSel(hwndCB, 0);
  72. }
  73. break;
  74. case WM_HELP: // F1
  75. WinHelp(((LPHELPINFO) lParam)->hItemHandle, __TEXT("access.hlp"), HELP_WM_HELP, (DWORD_PTR) (LPSTR) g_aIds);
  76. break;
  77. case WM_CONTEXTMENU: // right mouse click
  78. WinHelp((HWND) wParam, __TEXT("access.hlp"), HELP_CONTEXTMENU, (DWORD_PTR) (LPSTR) g_aIds);
  79. break;
  80. // Handle the generic commands
  81. case WM_COMMAND:
  82. switch (GET_WM_COMMAND_ID(wParam, lParam)) {
  83. case IDC_HC_HOTKEY:
  84. g_hc.dwFlags ^= HCF_HOTKEYACTIVE;
  85. break;
  86. case IDC_HC_DEFAULTSCHEME:
  87. if (GET_WM_COMMAND_CMD(wParam, lParam) == CBN_SELCHANGE) {
  88. // Get the current string into our variable
  89. i = ComboBox_GetCurSel(hwndCB);
  90. ComboBox_GetLBText(hwndCB, i, g_hc.lpszDefaultScheme);
  91. }
  92. break;
  93. case IDOK:
  94. // Save the current custom scheme to the registry.
  95. if (ERROR_SUCCESS == RegCreateKeyEx(
  96. HKEY_CURRENT_USER,
  97. HC_KEY,
  98. 0,
  99. __TEXT(""),
  100. REG_OPTION_NON_VOLATILE,
  101. KEY_EXECUTE | KEY_QUERY_VALUE | KEY_SET_VALUE,
  102. NULL,
  103. &hkey,
  104. &dwDisposition)) {
  105. TCHAR szCust[MAX_SCHEME_NAME_SIZE];
  106. i = ComboBox_GetCurSel(hwndCB);
  107. ComboBox_GetLBText(hwndCB, i, szCust);
  108. // Abandon "Last Custom Scheme" (never written correctly (#954))
  109. RegSetValueEx(hkey
  110. , CURR_HC_SCHEME
  111. , 0, REG_SZ
  112. , (PBYTE) szCust
  113. , lstrlen(szCust)*sizeof(TCHAR));
  114. }
  115. EndDialog(hwnd, IDOK);
  116. break;
  117. case IDCANCEL:
  118. EndDialog(hwnd, IDCANCEL);
  119. break;
  120. }
  121. break;
  122. default:
  123. fProcessed = FALSE; break;
  124. }
  125. return((INT_PTR) fProcessed);
  126. }
  127. void DrawCaret(HWND hwnd, BOOL fClearFirst)
  128. {
  129. HWND hwndCursor = GetDlgItem(hwnd, IDC_KCURSOR_BLINK);
  130. HDC hDC = GetDC(hwnd);
  131. if (hDC)
  132. {
  133. HBRUSH hBrush;
  134. if (fClearFirst)
  135. {
  136. hBrush = GetSysColorBrush(COLOR_MENU);
  137. if (hBrush)
  138. {
  139. RECT rect;
  140. GetWindowRect(hwndCursor, &rect);
  141. MapWindowPoints(HWND_DESKTOP, hwnd, (LPPOINT)&rect, 2);
  142. FillRect(hDC, &rect, hBrush);
  143. InvalidateRect(hwndCursor, &rect, TRUE);
  144. }
  145. }
  146. hBrush = GetSysColorBrush(COLOR_BTNTEXT);
  147. if (hBrush)
  148. {
  149. FillRect(hDC, &s_rCursor, hBrush);
  150. InvalidateRect(hwndCursor, &s_rCursor, TRUE);
  151. }
  152. ReleaseDC(hwnd,hDC);
  153. }
  154. }
  155. void OnTimer( HWND hwnd, WPARAM wParam, LPARAM lParam )
  156. {
  157. if (wParam == BLINK)
  158. {
  159. BOOL fNoBlinkRate = (g_cs.dwNewCaretBlinkRate == CURSORMAX)?TRUE:FALSE;
  160. if (s_fBlink || fNoBlinkRate)
  161. {
  162. DrawCaret(hwnd, fNoBlinkRate);
  163. }
  164. else
  165. {
  166. InvalidateRect(GetDlgItem(hwnd, IDC_KCURSOR_BLINK), NULL, TRUE);
  167. }
  168. if (fNoBlinkRate)
  169. KillTimer(hwnd, wParam);
  170. s_fBlink = !s_fBlink;
  171. }
  172. }
  173. void OnHScroll( HWND hwnd, WPARAM wParam, LPARAM lParam )
  174. {
  175. if ((HWND)lParam == GetDlgItem(hwnd, IDC_KCURSOR_RATE))
  176. {
  177. // blink rate setting
  178. int nCurrent = (int)SendMessage( (HWND)lParam, TBM_GETPOS, 0, 0L );
  179. g_cs.dwNewCaretBlinkRate = CURSORSUM - (nCurrent * 100);
  180. // reset the bink rate timer
  181. SetTimer(hwnd, BLINK, g_cs.dwNewCaretBlinkRate, NULL);
  182. if (g_cs.dwNewCaretBlinkRate == CURSORMAX) // draw the caret immediately; if we wait
  183. DrawCaret(hwnd, TRUE); // for the timer there is a visible delay
  184. SendMessage(GetParent(hwnd), PSM_CHANGED, (WPARAM)hwnd, 0);
  185. }
  186. else if ((HWND)lParam == GetDlgItem(hwnd, IDC_KCURSOR_WIDTH))
  187. {
  188. // cursor width setting
  189. g_cs.dwNewCaretWidth = (int)SendMessage( (HWND)lParam, TBM_GETPOS, 0, 0L );
  190. s_rCursor.right = s_rCursor.left + g_cs.dwNewCaretWidth;
  191. DrawCaret(hwnd, (g_cs.dwNewCaretBlinkRate == CURSORMAX));
  192. SendMessage(GetParent(hwnd), PSM_CHANGED, (WPARAM)hwnd, 0);
  193. }
  194. }
  195. void InitCursorCtls(HWND hwnd)
  196. {
  197. g_cs.dwNewCaretWidth = g_cs.dwCaretWidth;
  198. g_cs.dwNewCaretBlinkRate = g_cs.dwCaretBlinkRate;
  199. // Update the Caret UI
  200. SendMessage(GetDlgItem(hwnd, IDC_KCURSOR_WIDTH), TBM_SETRANGE, 0, MAKELONG(1, 20));
  201. SendMessage(GetDlgItem(hwnd, IDC_KCURSOR_WIDTH), TBM_SETPOS, TRUE, (LONG)g_cs.dwCaretWidth);
  202. SendMessage(GetDlgItem(hwnd, IDC_KCURSOR_RATE), TBM_SETRANGE, 0, MAKELONG(CURSORMIN / 100, CURSORMAX / 100));
  203. SendMessage(GetDlgItem(hwnd, IDC_KCURSOR_RATE), TBM_SETPOS, TRUE, (LONG)(CURSORSUM - g_cs.dwCaretBlinkRate) / 100);
  204. // Update Blink and caret size
  205. GetWindowRect(GetDlgItem(hwnd, IDC_KCURSOR_BLINK), &s_rCursor);
  206. MapWindowPoints(HWND_DESKTOP, hwnd, (LPPOINT)&s_rCursor, 2);
  207. s_rCursor.right = s_rCursor.left + g_cs.dwCaretWidth;
  208. }
  209. // *******************************************************************
  210. // DisplayDialog handler
  211. // *******************************************************************
  212. INT_PTR WINAPI DisplayDlg (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  213. HIGHCONTRAST hc;
  214. TCHAR szScheme[MAX_SCHEME_NAME_SIZE];
  215. BOOL fProcessed = TRUE;
  216. switch (uMsg) {
  217. case WM_INITDIALOG:
  218. CheckDlgButton(hwnd, IDC_HC_ENABLE,
  219. (g_hc.dwFlags & HCF_HIGHCONTRASTON) ? TRUE : FALSE);
  220. if (!(g_hc.dwFlags & HCF_AVAILABLE)) {
  221. EnableWindow(GetDlgItem(hwnd, IDC_HC_SETTINGS), FALSE);
  222. EnableWindow(GetDlgItem(hwnd,IDC_HC_ENABLE), FALSE);
  223. }
  224. InitCursorCtls(hwnd);
  225. break;
  226. case WM_TIMER:
  227. OnTimer(hwnd, wParam, lParam);
  228. break;
  229. case WM_HSCROLL:
  230. OnHScroll(hwnd, wParam, lParam);
  231. break;
  232. case WM_HELP:
  233. WinHelp(((LPHELPINFO) lParam)->hItemHandle, __TEXT("access.hlp"), HELP_WM_HELP, (DWORD_PTR) (LPSTR) g_aIds);
  234. break;
  235. case WM_CONTEXTMENU:
  236. WinHelp((HWND) wParam, __TEXT("access.hlp"), HELP_CONTEXTMENU, (DWORD_PTR) (LPSTR) g_aIds);
  237. break;
  238. // sliders don't get this message so pass it on
  239. case WM_SYSCOLORCHANGE:
  240. SendMessage(GetDlgItem(hwnd, IDC_KCURSOR_WIDTH), WM_SYSCOLORCHANGE, 0, 0);
  241. SendMessage(GetDlgItem(hwnd, IDC_KCURSOR_RATE), WM_SYSCOLORCHANGE, 0, 0);
  242. break;
  243. case WM_COMMAND:
  244. switch (GET_WM_COMMAND_ID(wParam, lParam)) {
  245. case IDC_HC_ENABLE:
  246. g_hc.dwFlags ^= HCF_HIGHCONTRASTON;
  247. SendMessage(GetParent(hwnd), PSM_CHANGED, (WPARAM) hwnd, 0);
  248. break;
  249. case IDC_HC_SETTINGS:
  250. {
  251. INT_PTR RetValue;
  252. hc = g_hc;
  253. lstrcpy(szScheme, g_hc.lpszDefaultScheme);
  254. RetValue = DialogBox(g_hinst, MAKEINTRESOURCE(IDD_HIGHCONSETTINGS), hwnd, HighContrastDlg);
  255. if ( RetValue == IDCANCEL)
  256. {
  257. g_hc = hc;
  258. lstrcpy(g_hc.lpszDefaultScheme, szScheme);
  259. }
  260. else
  261. {
  262. SendMessage(GetParent(hwnd), PSM_CHANGED, (WPARAM) hwnd, 0);
  263. }
  264. }
  265. break;
  266. }
  267. break;
  268. case WM_NOTIFY:
  269. switch (((NMHDR *)lParam)->code) {
  270. case PSN_APPLY: SetAccessibilitySettings(); break;
  271. case PSN_KILLACTIVE:
  272. KillTimer(hwnd, BLINK);
  273. g_cs.dwCaretBlinkRate = g_cs.dwNewCaretBlinkRate;
  274. g_cs.dwCaretWidth = g_cs.dwNewCaretWidth;
  275. break;
  276. case PSN_SETACTIVE:
  277. SetTimer(hwnd
  278. , BLINK
  279. , (g_cs.dwNewCaretBlinkRate < CURSORMAX)?g_cs.dwNewCaretBlinkRate:0
  280. , NULL);
  281. break;
  282. }
  283. break;
  284. default:
  285. fProcessed = FALSE;
  286. break;
  287. }
  288. return(fProcessed);
  289. }
  290. BOOL IsMUI_Enabled()
  291. {
  292. OSVERSIONINFO verinfo;
  293. LANGID rcLang;
  294. HMODULE hModule;
  295. pfnGetUserDefaultUILanguage gpfnGetUserDefaultUILanguage;
  296. pfnGetSystemDefaultUILanguage gpfnGetSystemDefaultUILanguage;
  297. static g_bPFNLoaded=FALSE;
  298. static g_bMUIStatus=FALSE;
  299. if(g_bPFNLoaded)
  300. return g_bMUIStatus;
  301. g_bPFNLoaded = TRUE;
  302. verinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  303. GetVersionEx( &verinfo) ;
  304. if (verinfo.dwMajorVersion == 5)
  305. {
  306. hModule = GetModuleHandle(TEXT("kernel32.dll"));
  307. if (hModule)
  308. {
  309. gpfnGetSystemDefaultUILanguage =
  310. (pfnGetSystemDefaultUILanguage)GetProcAddress(hModule,"GetSystemDefaultUILanguage");
  311. if (gpfnGetSystemDefaultUILanguage)
  312. {
  313. rcLang = (LANGID) gpfnGetSystemDefaultUILanguage();
  314. if (rcLang == 0x409 )
  315. {
  316. gpfnGetUserDefaultUILanguage =
  317. (pfnGetUserDefaultUILanguage)GetProcAddress(hModule,"GetUserDefaultUILanguage");
  318. if (gpfnGetUserDefaultUILanguage)
  319. {
  320. if (rcLang != (LANGID)gpfnGetUserDefaultUILanguage() )
  321. {
  322. g_bMUIStatus = TRUE;
  323. }
  324. }
  325. }
  326. }
  327. }
  328. }
  329. return g_bMUIStatus;
  330. }
  331. ///////////////////////////////// End of File /////////////////////////////////