Leaked source code of windows server 2003
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.

487 lines
16 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: access.c
  3. *
  4. * Copyright (c) 1997, Microsoft Corporation
  5. *
  6. * Accessibility notification dialogs
  7. *
  8. * History:
  9. * 02-01-97 Fritz Sands Created
  10. \***************************************************************************/
  11. #include <stdio.h>
  12. #include <wtypes.h>
  13. #include "dialogs.h"
  14. #include <winuserp.h>
  15. #include <oleacc.h>
  16. #pragma hdrstop
  17. /*
  18. * Notification Dialog Stuff
  19. */
  20. extern HINSTANCE g_hInstance;
  21. #define cchBuf 1024 // plenty of room for title
  22. #define cchTitle 128
  23. typedef struct tagACCESSINFO {
  24. UINT Feature;
  25. UINT TitleID;
  26. HANDLE hDesk;
  27. WCHAR wcTitle[cchTitle];
  28. } ACCESSINFO, *PACCESSINFO;
  29. #define NOTIF_KEY __TEXT("Control Panel\\Accessibility")
  30. #define NOTIFY_VALUE __TEXT("Warning Sounds")
  31. #define HOTKEYCODE 100
  32. #define ID_STICKYKEYNAME NOTIF_KEY __TEXT("\\StickyKeys")
  33. #define ID_TOGGLEKEYS NOTIF_KEY __TEXT("\\ToggleKeys")
  34. #define ID_HIGHCONTROST NOTIF_KEY __TEXT("\\HighContrast")
  35. #define ID_MOUSEKEYS NOTIF_KEY __TEXT("\\MouseKeys")
  36. #define ID_SERIALKEYS NOTIF_KEY __TEXT("\\SerialKeys")
  37. /***************************************************************************
  38. * *
  39. * ConfirmHandler_InitDialog *
  40. * *
  41. * Input: hWnd = dialog window handle *
  42. * uiTitle = resource ID of dialog box title *
  43. * uiTitle+1 through uiTitle+n = resource ID of dialog box text *
  44. * Output: Returns TRUE on success, FALSE on failure. *
  45. * *
  46. ***************************************************************************/
  47. BOOL ConfirmHandler_InitDialog(HWND hWnd, HDESK hDesk, UINT uiTitle, WCHAR *pszTitle) {
  48. RECT rc; // Current window size
  49. WCHAR *pszBuf;
  50. WCHAR *pszNext;
  51. int cchBufLeft;
  52. int cchHelpText;
  53. int fSuccess = 0;
  54. WCHAR szDesktop[MAX_PATH];
  55. DWORD Len1 = MAX_PATH;
  56. BOOL b;
  57. szDesktop[0] = 0;
  58. b = GetUserObjectInformation(hDesk, UOI_NAME, szDesktop, MAX_PATH, &Len1);
  59. SetWindowText(hWnd, pszTitle); // Init title bar
  60. pszBuf = (WCHAR *)LocalAlloc(LMEM_FIXED, cchBuf * sizeof (WCHAR));
  61. if (!pszBuf) goto Exit;
  62. pszNext = pszBuf; cchBufLeft = cchBuf;
  63. while (cchHelpText = LoadString(g_hInstance, ++uiTitle, pszNext, cchBufLeft)) {
  64. pszNext += cchHelpText;
  65. cchBufLeft -= cchHelpText;
  66. }
  67. SetDlgItemText(hWnd, ID_HELPTEXT, pszBuf); // Init help text
  68. if (b && (0 == wcscmp(szDesktop,L"Winlogon"))) {
  69. EnableWindow(GetDlgItem(hWnd, IDHELP), FALSE);
  70. }
  71. // Make us a topmost window and center ourselves.
  72. GetWindowRect(hWnd, &rc); // Get size of dialog
  73. // Center dialog and make it topmost
  74. SetWindowPos(hWnd,
  75. HWND_TOPMOST,
  76. (GetSystemMetrics(SM_CXFULLSCREEN)/2) - (rc.right - rc.left)/2,
  77. (GetSystemMetrics(SM_CYFULLSCREEN)/2) - (rc.bottom - rc.top)/2,
  78. 0,0, SWP_NOSIZE );
  79. // Make sure we're active!
  80. // Lets try setting this to be the foreground window.
  81. // SetForegroundWindow(hWnd);
  82. // SetForgroundWindow will not work because we are not the forground task. So use accSelect
  83. if ( hWnd )
  84. {
  85. IAccessible *pAcc = NULL;
  86. VARIANT varChild;
  87. varChild.vt = VT_I4;
  88. varChild.lVal = 0;
  89. if ( AccessibleObjectFromWindow( hWnd, OBJID_CLIENT, &IID_IAccessible, (void**)&pAcc ) == S_OK )
  90. {
  91. if ( pAcc )
  92. pAcc->lpVtbl->accSelect( pAcc, SELFLAG_TAKEFOCUS, varChild );
  93. }
  94. }
  95. fSuccess = 1;
  96. LocalFree((HLOCAL)pszBuf);
  97. Exit:
  98. return fSuccess;
  99. }
  100. /***************************************************************************
  101. * *
  102. * *
  103. * ConfirmHandler *
  104. * *
  105. * Input: Std Window messages *
  106. * Output: IDOK if success, IDCANCEL if we should abort *
  107. * *
  108. * *
  109. * Put up the main dialog to tell the user what is happening and to get *
  110. * permission to continue. *
  111. ***************************************************************************/
  112. INT_PTR CALLBACK ConfirmHandler(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  113. {
  114. WCHAR buf[100];
  115. WCHAR szRundll[] = L"rundll32.exe";
  116. WCHAR szDesktop[MAX_PATH];
  117. DWORD Len1, Len2;
  118. PACCESSINFO pAccessInfo;
  119. PROCESS_INFORMATION ProcessInfo;
  120. STARTUPINFO si;
  121. GetStartupInfo(&si);
  122. switch(message) {
  123. case WM_INITDIALOG:
  124. SetWindowLongPtr(hWnd, DWLP_USER, lParam);
  125. pAccessInfo = (PACCESSINFO)lParam;
  126. return ConfirmHandler_InitDialog(hWnd, pAccessInfo->hDesk, pAccessInfo->TitleID, pAccessInfo->wcTitle);
  127. case WM_COMMAND:
  128. pAccessInfo = (PACCESSINFO)GetWindowLongPtr(hWnd, DWLP_USER);
  129. switch (LOWORD(wParam)) {
  130. case IDOK:
  131. case IDCANCEL:
  132. EndDialog(hWnd, LOWORD(wParam));
  133. return TRUE;
  134. case IDHELP:
  135. // IDHELP (Settings... really) dismisses dialog with no changes
  136. EndDialog(hWnd, IDCANCEL);
  137. //
  138. // Spawn the correct help
  139. //
  140. lstrcpy(buf,L" Shell32.dll,Control_RunDLL access.cpl,,");
  141. switch (pAccessInfo->Feature) {
  142. case ACCESS_STICKYKEYS:
  143. case ACCESS_FILTERKEYS:
  144. case ACCESS_TOGGLEKEYS:
  145. default:
  146. lstrcat(buf,L"1");
  147. break;
  148. case ACCESS_MOUSEKEYS:
  149. lstrcat(buf,L"4");
  150. break;
  151. case ACCESS_HIGHCONTRAST:
  152. lstrcat(buf,L"3");
  153. break;
  154. }
  155. CreateProcess( szRundll, buf, NULL, NULL, FALSE, 0, NULL, NULL, &si, &ProcessInfo );
  156. return TRUE;
  157. break;
  158. default:
  159. return FALSE;
  160. }
  161. break;
  162. default:
  163. // fall thru rather than return FALSE to keep compiler happy
  164. break;
  165. }
  166. return FALSE;
  167. }
  168. DWORD MakeAccessDlg(PACCESSINFO pAccessInfo) {
  169. DWORD iRet = 0;
  170. HDESK hDeskOld;
  171. hDeskOld = GetThreadDesktop(GetCurrentThreadId());
  172. if (hDeskOld == NULL) return 0;
  173. pAccessInfo->hDesk = OpenInputDesktop(0, FALSE, MAXIMUM_ALLOWED);
  174. if (pAccessInfo->hDesk == NULL) return 0;
  175. if (LoadString(g_hInstance, pAccessInfo->TitleID, pAccessInfo->wcTitle, cchTitle)) {
  176. SetThreadDesktop(pAccessInfo->hDesk);
  177. if (!FindWindowEx(GetDesktopWindow(), NULL, (LPCTSTR)0x8002, pAccessInfo->wcTitle)) {
  178. iRet = (DWORD)DialogBoxParam(g_hInstance, MAKEINTRESOURCE(DLG_CONFIRM), NULL, ConfirmHandler, (LPARAM)pAccessInfo);
  179. }
  180. SetThreadDesktop(hDeskOld);
  181. }
  182. CloseDesktop(pAccessInfo->hDesk);
  183. return iRet;
  184. }
  185. /***************************************************************************
  186. * *
  187. * The thread opens the input desktopn, connects to it, and calls the *
  188. * notification dialog for the accessibility feature. *
  189. * *
  190. ***************************************************************************/
  191. DWORD WINAPI StickyKeysNotification(BOOL fNotifReq) {
  192. DWORD iRet = IDCANCEL ;
  193. ACCESSINFO AccessInfo;
  194. STICKYKEYS sticky;
  195. DWORD dwS;
  196. BOOL b;
  197. AccessInfo.Feature = ACCESS_STICKYKEYS;
  198. AccessInfo.TitleID = ID_STICKY_TITLE;
  199. if ( fNotifReq )
  200. {
  201. iRet = MakeAccessDlg(&AccessInfo);
  202. }
  203. else
  204. iRet = IDOK;
  205. if (iRet)
  206. {
  207. sticky.cbSize = sizeof sticky;
  208. b = SystemParametersInfo(SPI_GETSTICKYKEYS, sizeof sticky, &sticky, 0);
  209. dwS= sticky.dwFlags;
  210. if (iRet & HOTKEYCODE) {
  211. sticky.dwFlags &= ~SKF_HOTKEYACTIVE;
  212. b = SystemParametersInfo(SPI_SETSTICKYKEYS, sizeof sticky, &sticky, SPIF_UPDATEINIFILE);
  213. iRet &= ~HOTKEYCODE;
  214. }
  215. if (iRet == IDOK) {
  216. sticky.dwFlags |= SKF_STICKYKEYSON;
  217. }
  218. if (dwS != sticky.dwFlags) {
  219. b = SystemParametersInfo(SPI_SETSTICKYKEYS, sizeof sticky, &sticky, 0);
  220. SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETSTICKYKEYS, FALSE,
  221. SMTO_ABORTIFHUNG, 5000, NULL);
  222. }
  223. iRet = 1;
  224. }
  225. return iRet;
  226. }
  227. /***************************************************************************
  228. * *
  229. * The thread opens the input desktopn, connects to it, and calls the *
  230. * notification dialog for the accessibility feature. *
  231. * *
  232. ***************************************************************************/
  233. DWORD WINAPI FilterKeysNotification(BOOL fNotifReq) {
  234. DWORD iRet = IDCANCEL ;
  235. ACCESSINFO AccessInfo;
  236. FILTERKEYS filter;
  237. DWORD dwF;
  238. BOOL b;
  239. AccessInfo.Feature = ACCESS_FILTERKEYS;
  240. AccessInfo.TitleID = ID_FILTER_TITLE;
  241. if ( fNotifReq )
  242. {
  243. iRet = MakeAccessDlg(&AccessInfo);
  244. }
  245. else
  246. iRet = IDOK;
  247. if (iRet) {
  248. filter.cbSize = sizeof filter;
  249. b = SystemParametersInfo(SPI_GETFILTERKEYS, sizeof filter, &filter, 0);
  250. dwF = filter.dwFlags;
  251. if (iRet & HOTKEYCODE) {
  252. filter.dwFlags &= ~FKF_HOTKEYACTIVE;
  253. b = SystemParametersInfo(SPI_SETFILTERKEYS, sizeof filter, &filter, SPIF_UPDATEINIFILE);
  254. iRet &= ~HOTKEYCODE;
  255. }
  256. if (iRet == IDOK) {
  257. filter.dwFlags |= FKF_FILTERKEYSON;
  258. }
  259. if (dwF !=filter.dwFlags) {
  260. b = SystemParametersInfo(SPI_SETFILTERKEYS, sizeof filter, &filter, 0);
  261. // Broadcast a message. Being extra safe not to turn on filter keys
  262. // during logon. Send message to notify all specially systray: a-anilk
  263. SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETFILTERKEYS, FALSE,
  264. SMTO_ABORTIFHUNG, 5000, NULL);
  265. }
  266. iRet = 1;
  267. }
  268. return iRet;
  269. }
  270. /***************************************************************************
  271. * *
  272. * The thread opens the input desktopn, connects to it, and calls the *
  273. * notification dialog for the accessibility feature. *
  274. * *
  275. ***************************************************************************/
  276. DWORD WINAPI ToggleKeysNotification(BOOL fNotifReq) {
  277. DWORD iRet = IDCANCEL;
  278. ACCESSINFO AccessInfo;
  279. TOGGLEKEYS toggle;
  280. DWORD dwT;
  281. BOOL b;
  282. toggle.cbSize = sizeof toggle;
  283. AccessInfo.Feature = ACCESS_TOGGLEKEYS;
  284. AccessInfo.TitleID = ID_TOGGLE_TITLE;
  285. if ( fNotifReq )
  286. {
  287. iRet = MakeAccessDlg(&AccessInfo);
  288. }
  289. else
  290. iRet = IDOK;
  291. if (iRet) {
  292. toggle.cbSize = sizeof toggle;
  293. b = SystemParametersInfo(SPI_GETTOGGLEKEYS, sizeof toggle, &toggle, 0);
  294. dwT = toggle.dwFlags;
  295. if (iRet & HOTKEYCODE) {
  296. toggle.dwFlags &= ~TKF_HOTKEYACTIVE;
  297. b = SystemParametersInfo(SPI_SETTOGGLEKEYS, sizeof toggle, &toggle, SPIF_UPDATEINIFILE);
  298. iRet &= ~HOTKEYCODE;
  299. }
  300. if (iRet == IDOK) {
  301. toggle.dwFlags |= TKF_TOGGLEKEYSON;
  302. }
  303. if (toggle.dwFlags != dwT) {
  304. b = SystemParametersInfo(SPI_SETTOGGLEKEYS, sizeof toggle, &toggle, 0);
  305. // Not required to send message, As it currently has no indicators...
  306. }
  307. iRet = 1;
  308. }
  309. return iRet;
  310. }
  311. /***************************************************************************
  312. * *
  313. * The thread opens the input desktopn, connects to it, and calls the *
  314. * notification dialog for the accessibility feature. *
  315. * *
  316. ***************************************************************************/
  317. DWORD WINAPI MouseKeysNotification(BOOL fNotifReq) {
  318. DWORD iRet = IDCANCEL;
  319. ACCESSINFO AccessInfo;
  320. MOUSEKEYS mouse;
  321. DWORD dwM;
  322. BOOL b;
  323. AccessInfo.Feature = ACCESS_MOUSEKEYS;
  324. AccessInfo.TitleID = ID_MOUSE_TITLE;
  325. if ( fNotifReq )
  326. {
  327. iRet = MakeAccessDlg(&AccessInfo);
  328. }
  329. else
  330. iRet = IDOK;
  331. if (iRet) {
  332. mouse.cbSize = sizeof mouse;
  333. b = SystemParametersInfo(SPI_GETMOUSEKEYS, sizeof mouse, &mouse, 0);
  334. dwM = mouse.dwFlags;
  335. if (iRet & HOTKEYCODE) {
  336. mouse.dwFlags &= ~MKF_HOTKEYACTIVE;
  337. b = SystemParametersInfo(SPI_SETMOUSEKEYS, sizeof mouse, &mouse, SPIF_UPDATEINIFILE);
  338. iRet &= ~HOTKEYCODE;
  339. }
  340. if (iRet == IDOK) {
  341. mouse.dwFlags |= MKF_MOUSEKEYSON;
  342. }
  343. if (mouse.dwFlags != dwM) {
  344. b = SystemParametersInfo(SPI_SETMOUSEKEYS, sizeof mouse, &mouse, 0);
  345. SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETMOUSEKEYS, FALSE,
  346. SMTO_ABORTIFHUNG, 5000, NULL);
  347. }
  348. iRet = 1;
  349. }
  350. return iRet;
  351. }
  352. /***************************************************************************
  353. * *
  354. * The thread opens the input desktopn, connects to it, and calls the *
  355. * notification dialog for the accessibility feature. *
  356. * *
  357. ***************************************************************************/
  358. DWORD WINAPI HighContNotification(BOOL fNotifReq)
  359. {
  360. DWORD iRet = IDCANCEL ;
  361. ACCESSINFO AccessInfo;
  362. HIGHCONTRAST hc;
  363. DWORD dwH;
  364. BOOL b;
  365. AccessInfo.Feature = ACCESS_HIGHCONTRAST;
  366. AccessInfo.TitleID = ID_HC_TITLE;
  367. if ( fNotifReq )
  368. {
  369. iRet = MakeAccessDlg(&AccessInfo);
  370. }
  371. else
  372. iRet = IDOK;
  373. if (iRet) {
  374. hc.cbSize = sizeof hc;
  375. b = SystemParametersInfo(SPI_GETHIGHCONTRAST, sizeof hc, &hc, 0);
  376. dwH = hc.dwFlags;
  377. if (iRet & HOTKEYCODE) {
  378. hc.dwFlags &= ~HCF_HOTKEYACTIVE;
  379. b = SystemParametersInfo(SPI_SETHIGHCONTRAST, sizeof hc, &hc, SPIF_UPDATEINIFILE);
  380. iRet &= ~HOTKEYCODE;
  381. }
  382. if (iRet == IDOK) {
  383. hc.dwFlags |= HCF_HIGHCONTRASTON;
  384. }
  385. if (hc.dwFlags != dwH) {
  386. b = SystemParametersInfo(SPI_SETHIGHCONTRAST, sizeof hc, &hc, 0);
  387. SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETHIGHCONTRAST, FALSE,
  388. SMTO_ABORTIFHUNG, 5000, NULL);
  389. }
  390. iRet = 1;
  391. }
  392. return iRet;
  393. }