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.

410 lines
12 KiB

  1. #include "stdafx.h"
  2. #include "systray.h"
  3. #include "winuserp.h"
  4. // These two lines must be commented out before checkin
  5. //#define DBG 1
  6. //#include "..\..\..\osshell\accessib\inc\w95trace.c"
  7. #define DBPRINTF 1 ? (void)0 : (void)
  8. STICKYKEYS sk;
  9. int skIconShown = -1; // either -1 or displacement of icon
  10. HICON skIcon;
  11. MOUSEKEYS mk;
  12. DWORD mkStatus;
  13. int mkIconShown = -1; // either -1 or equivalent to mkStatus
  14. HICON mkIcon;
  15. FILTERKEYS fk;
  16. HICON fkIcon;
  17. extern HINSTANCE g_hInstance;
  18. void StickyKeys_UpdateStatus(HWND hWnd, BOOL bShowIcon);
  19. void StickyKeys_UpdateIcon(HWND hWnd, DWORD message);
  20. void MouseKeys_UpdateStatus(HWND hWnd, BOOL bShowIcon);
  21. void MouseKeys_UpdateIcon(HWND hWnd, DWORD message);
  22. void FilterKeys_UpdateStatus(HWND hWnd, BOOL bShowIcon);
  23. void FilterKeys_UpdateIcon(HWND hWnd, DWORD message);
  24. void NormalizeIcon(HICON *phIcon);
  25. extern DWORD g_uiShellHook; //shell hook window message
  26. __inline void RegShellHook(HWND hWnd)
  27. {
  28. // Only register the shell hook if it isn't yet registered
  29. if (!g_uiShellHook) {
  30. g_uiShellHook = RegisterWindowMessage(L"SHELLHOOK");
  31. RegisterShellHookWindow(hWnd);
  32. DBPRINTF(TEXT("RegShellHook\r\n"));
  33. }
  34. }
  35. __inline void UnregShellHook(HWND hWnd)
  36. {
  37. // Only unregister the shell hook if neither sticky keys or mouse keys is on
  38. if (skIconShown == -1 && mkIconShown == -1) {
  39. g_uiShellHook = 0;
  40. DeregisterShellHookWindow(hWnd);
  41. DBPRINTF(TEXT("UnregShellHook\r\n"));
  42. }
  43. }
  44. BOOL StickyKeys_CheckEnable(HWND hWnd)
  45. {
  46. BOOL bEnable;
  47. sk.cbSize = sizeof(sk);
  48. SystemParametersInfo(
  49. SPI_GETSTICKYKEYS,
  50. sizeof(sk),
  51. &sk,
  52. 0);
  53. bEnable = sk.dwFlags & SKF_INDICATOR && sk.dwFlags & SKF_STICKYKEYSON;
  54. DBPRINTF(TEXT("StickyKeys_CheckEnable\r\n"));
  55. StickyKeys_UpdateStatus(hWnd, bEnable);
  56. return(bEnable);
  57. }
  58. void StickyKeys_UpdateStatus(HWND hWnd, BOOL bShowIcon) {
  59. if (bShowIcon != (skIconShown!= -1)) {
  60. if (bShowIcon) {
  61. StickyKeys_UpdateIcon(hWnd, NIM_ADD);
  62. RegShellHook(hWnd);
  63. } else {
  64. skIconShown = -1;
  65. UnregShellHook(hWnd);
  66. SysTray_NotifyIcon(hWnd, STWM_NOTIFYSTICKYKEYS, NIM_DELETE, NULL, NULL);
  67. if (skIcon) {
  68. DestroyIcon(skIcon);
  69. skIcon = NULL;
  70. }
  71. }
  72. }
  73. if (bShowIcon) {
  74. StickyKeys_UpdateIcon(hWnd, NIM_MODIFY);
  75. }
  76. }
  77. void StickyKeys_UpdateIcon(HWND hWnd, DWORD message)
  78. {
  79. LPTSTR lpsz;
  80. int iStickyOffset = 0;
  81. if (sk.dwFlags & SKF_LSHIFTLATCHED) iStickyOffset |= 1;
  82. if (sk.dwFlags & SKF_RSHIFTLATCHED) iStickyOffset |= 1;
  83. if (sk.dwFlags & SKF_LSHIFTLOCKED) iStickyOffset |= 1;
  84. if (sk.dwFlags & SKF_RSHIFTLOCKED) iStickyOffset |= 1;
  85. if (sk.dwFlags & SKF_LCTLLATCHED) iStickyOffset |= 2;
  86. if (sk.dwFlags & SKF_RCTLLATCHED) iStickyOffset |= 2;
  87. if (sk.dwFlags & SKF_LCTLLOCKED) iStickyOffset |= 2;
  88. if (sk.dwFlags & SKF_RCTLLOCKED) iStickyOffset |= 2;
  89. if (sk.dwFlags & SKF_LALTLATCHED) iStickyOffset |= 4;
  90. if (sk.dwFlags & SKF_RALTLATCHED) iStickyOffset |= 4;
  91. if (sk.dwFlags & SKF_LALTLOCKED) iStickyOffset |= 4;
  92. if (sk.dwFlags & SKF_RALTLOCKED) iStickyOffset |= 4;
  93. if (sk.dwFlags & SKF_LWINLATCHED) iStickyOffset |= 8;
  94. if (sk.dwFlags & SKF_RWINLATCHED) iStickyOffset |= 8;
  95. if (sk.dwFlags & SKF_LWINLOCKED) iStickyOffset |= 8;
  96. if (sk.dwFlags & SKF_RWINLOCKED) iStickyOffset |= 8;
  97. if ((!skIcon) || (iStickyOffset != skIconShown)) {
  98. if (skIcon) DestroyIcon(skIcon);
  99. skIcon = LoadImage(g_hInstance, MAKEINTRESOURCE(IDI_STK000 + iStickyOffset),
  100. IMAGE_ICON, 16, 16, 0);
  101. skIconShown = iStickyOffset;
  102. }
  103. lpsz = LoadDynamicString(IDS_STICKYKEYS);
  104. if (skIcon)
  105. {
  106. NormalizeIcon(&skIcon);
  107. SysTray_NotifyIcon(hWnd, STWM_NOTIFYSTICKYKEYS, message, skIcon, lpsz);
  108. }
  109. DeleteDynamicString(lpsz);
  110. }
  111. void StickyKeys_Notify(HWND hWnd, WPARAM wParam, LPARAM lParam)
  112. {
  113. switch (lParam)
  114. {
  115. case WM_LBUTTONDBLCLK:
  116. case WM_RBUTTONDBLCLK:
  117. WinExec("rundll32.exe Shell32.dll,Control_RunDLL access.cpl,,1",SW_SHOW);
  118. break;
  119. }
  120. }
  121. BOOL MouseKeys_CheckEnable(HWND hWnd)
  122. {
  123. BOOL bEnable;
  124. mk.cbSize = sizeof(mk);
  125. SystemParametersInfo(
  126. SPI_GETMOUSEKEYS,
  127. sizeof(mk),
  128. &mk,
  129. 0);
  130. bEnable = mk.dwFlags & MKF_INDICATOR && mk.dwFlags & MKF_MOUSEKEYSON;
  131. DBPRINTF(TEXT("MouseKeys_CheckEnable\r\n"));
  132. MouseKeys_UpdateStatus(hWnd, bEnable);
  133. return(bEnable);
  134. }
  135. void MouseKeys_UpdateStatus(HWND hWnd, BOOL bShowIcon) {
  136. if (bShowIcon != (mkIconShown!= -1)) {
  137. if (bShowIcon) {
  138. MouseKeys_UpdateIcon(hWnd, NIM_ADD);
  139. RegShellHook(hWnd);
  140. } else {
  141. mkIconShown = -1;
  142. UnregShellHook(hWnd);
  143. SysTray_NotifyIcon(hWnd, STWM_NOTIFYMOUSEKEYS, NIM_DELETE, NULL, NULL);
  144. if (mkIcon) {
  145. DestroyIcon(mkIcon);
  146. mkIcon = NULL;
  147. }
  148. }
  149. }
  150. if (bShowIcon) {
  151. MouseKeys_UpdateIcon(hWnd, NIM_MODIFY);
  152. }
  153. }
  154. int MouseIcon[] = {
  155. IDI_MKPASS, // 00 00 no buttons selected
  156. IDI_MKGT, // 00 01 left selected, up
  157. IDI_MKTG, // 00 10 right selected, up
  158. IDI_MKGG, // 00 11 both selected, up
  159. IDI_MKPASS, // 01 00 no buttons selected
  160. IDI_MKBT, // 01 01 left selected, and down
  161. IDI_MKTG, // 01 10 right selected, up
  162. IDI_MKBG, // 01 11 both selected, left down, right up
  163. IDI_MKPASS, // 10 00 no buttons selected
  164. IDI_MKGT, // 10 01 left selected, right down
  165. IDI_MKTB, // 10 10 right selected, down
  166. IDI_MKGB, // 10 11 both selected, right down
  167. IDI_MKPASS, // 11 00 no buttons selected
  168. IDI_MKBT, // 11 01 left selected, down
  169. IDI_MKTB, // 11 10 right selected, down
  170. IDI_MKBB}; // 11 11 both selected, down
  171. void MouseKeys_UpdateIcon(HWND hWnd, DWORD message)
  172. {
  173. LPTSTR lpsz;
  174. int iMouseIcon = 0;
  175. if (!(mk.dwFlags & MKF_MOUSEMODE)) iMouseIcon = IDI_MKPASS;
  176. else {
  177. /*
  178. * Set up iMouseIcon as an index into the table first
  179. */
  180. if (mk.dwFlags & MKF_LEFTBUTTONSEL) iMouseIcon |= 1;
  181. if (mk.dwFlags & MKF_RIGHTBUTTONSEL) iMouseIcon |= 2;
  182. if (mk.dwFlags & MKF_LEFTBUTTONDOWN) iMouseIcon |= 4;
  183. if (mk.dwFlags & MKF_RIGHTBUTTONDOWN) iMouseIcon |= 8;
  184. iMouseIcon = MouseIcon[iMouseIcon];
  185. }
  186. if ((!mkIcon) || (iMouseIcon != mkIconShown)) {
  187. if (mkIcon) DestroyIcon(mkIcon);
  188. mkIcon = LoadImage(g_hInstance, MAKEINTRESOURCE(iMouseIcon),
  189. IMAGE_ICON, 16, 16, 0);
  190. mkIconShown = iMouseIcon;
  191. }
  192. lpsz = LoadDynamicString(IDS_MOUSEKEYS);
  193. if (mkIcon)
  194. {
  195. NormalizeIcon(&mkIcon);
  196. SysTray_NotifyIcon(hWnd, STWM_NOTIFYMOUSEKEYS, message, mkIcon, lpsz);
  197. }
  198. DeleteDynamicString(lpsz);
  199. }
  200. void MouseKeys_Notify(HWND hWnd, WPARAM wParam, LPARAM lParam)
  201. {
  202. switch (lParam)
  203. {
  204. case WM_LBUTTONDBLCLK:
  205. case WM_RBUTTONDBLCLK:
  206. WinExec("rundll32.exe Shell32.dll,Control_RunDLL access.cpl,,4",SW_SHOW);
  207. break;
  208. }
  209. }
  210. BOOL FilterKeys_CheckEnable(HWND hWnd)
  211. {
  212. BOOL bEnable;
  213. fk.cbSize = sizeof(fk);
  214. SystemParametersInfo(
  215. SPI_GETFILTERKEYS,
  216. sizeof(fk),
  217. &fk,
  218. 0);
  219. bEnable = fk.dwFlags & FKF_INDICATOR && fk.dwFlags & FKF_FILTERKEYSON;
  220. DBPRINTF(TEXT("FilterKeys_CheckEnable\r\n"));
  221. FilterKeys_UpdateStatus(hWnd, bEnable);
  222. return(bEnable);
  223. }
  224. void FilterKeys_UpdateStatus(HWND hWnd, BOOL bShowIcon) {
  225. if (bShowIcon != (fkIcon!= NULL)) {
  226. if (bShowIcon) {
  227. FilterKeys_UpdateIcon(hWnd, NIM_ADD);
  228. } else {
  229. SysTray_NotifyIcon(hWnd, STWM_NOTIFYFILTERKEYS, NIM_DELETE, NULL, NULL);
  230. if (fkIcon) {
  231. DestroyIcon(fkIcon);
  232. fkIcon = NULL;
  233. }
  234. }
  235. }
  236. }
  237. void FilterKeys_UpdateIcon(HWND hWnd, DWORD message)
  238. {
  239. LPTSTR lpsz;
  240. if (!fkIcon) {
  241. fkIcon = LoadImage(g_hInstance, MAKEINTRESOURCE(IDI_FILTER),
  242. IMAGE_ICON, 16, 16, 0);
  243. }
  244. lpsz = LoadDynamicString(IDS_FILTERKEYS);
  245. if (fkIcon)
  246. {
  247. NormalizeIcon(&fkIcon);
  248. SysTray_NotifyIcon(hWnd, STWM_NOTIFYFILTERKEYS, message, fkIcon, lpsz);
  249. }
  250. DeleteDynamicString(lpsz);
  251. }
  252. void FilterKeys_Notify(HWND hWnd, WPARAM wParam, LPARAM lParam)
  253. {
  254. switch (lParam)
  255. {
  256. case WM_LBUTTONDBLCLK:
  257. case WM_RBUTTONDBLCLK:
  258. WinExec("rundll32.exe Shell32.dll,Control_RunDLL access.cpl,,1",SW_SHOW);
  259. break;
  260. }
  261. }
  262. //
  263. // This function takes the resource icon and changes the dark blue
  264. // pixels to the window text color (black in normal mode or white
  265. // in high contrast).
  266. //
  267. // If any part of the conversion fails, the normal icon is unchanged.
  268. // If the conversion is successful, the normal icon is destroyed and
  269. // replaced with the converted one.
  270. //
  271. void NormalizeIcon(HICON *phIcon)
  272. {
  273. BITMAP BmpInfo;
  274. ICONINFO IconInfo;
  275. HBITMAP hCopyBmp = NULL;
  276. HDC hdcCopyBmp = NULL;
  277. HDC hdcIconBmp = NULL;
  278. ICONINFO ic;
  279. HICON hNewIcon = NULL;
  280. int i, j;
  281. COLORREF clr = GetSysColor(COLOR_WINDOWTEXT);
  282. HGDIOBJ hObjTmp1, hObjTmp2;
  283. if (!GetIconInfo(*phIcon, &IconInfo))
  284. {
  285. DBPRINTF(TEXT("GetIconInfo failed\r\n"));
  286. goto Cleanup;
  287. }
  288. if (!GetObject(IconInfo.hbmColor, sizeof(BITMAP), &BmpInfo ))
  289. {
  290. DBPRINTF(TEXT("GetObject failed\r\n"));
  291. goto Cleanup;
  292. }
  293. hCopyBmp = CreateBitmap(BmpInfo.bmWidth,
  294. BmpInfo.bmHeight,
  295. BmpInfo.bmPlanes, // Planes
  296. BmpInfo.bmBitsPixel, // BitsPerPel
  297. NULL); // bits
  298. if (!hCopyBmp)
  299. {
  300. DBPRINTF(TEXT("CreateBitmap failed\r\n"));
  301. goto Cleanup;
  302. }
  303. hdcCopyBmp = CreateCompatibleDC(NULL);
  304. if (!hdcCopyBmp)
  305. {
  306. DBPRINTF(TEXT("CreateCompatibleDC 1 failed\r\n"));
  307. goto Cleanup;
  308. }
  309. hObjTmp1 = SelectObject(hdcCopyBmp, hCopyBmp);
  310. // Select Icon bitmap into a memoryDC so we can use it
  311. hdcIconBmp = CreateCompatibleDC(NULL);
  312. if (!hdcIconBmp)
  313. {
  314. DBPRINTF(TEXT("CreateCompatibleDC 2 failed\r\n"));
  315. SelectObject(hdcCopyBmp, hObjTmp1); // restore original bitmap
  316. goto Cleanup;
  317. }
  318. hObjTmp2 = SelectObject(hdcIconBmp, IconInfo.hbmColor);
  319. BitBlt( hdcCopyBmp,
  320. 0,
  321. 0,
  322. BmpInfo.bmWidth,
  323. BmpInfo.bmHeight,
  324. hdcIconBmp,
  325. 0,
  326. 0,
  327. SRCCOPY
  328. );
  329. ic.fIcon = TRUE; // This is an icon
  330. ic.xHotspot = 0;
  331. ic.yHotspot = 0;
  332. ic.hbmMask = IconInfo.hbmMask;
  333. for (i=0; i < BmpInfo.bmWidth; i++)
  334. for (j=0; j < BmpInfo.bmHeight; j++)
  335. {
  336. COLORREF pel_value = GetPixel(hdcCopyBmp, i, j);
  337. if (pel_value == (COLORREF) RGB(0,0,128)) // The color on icon resource is BLUE!!
  338. SetPixel(hdcCopyBmp, i, j, clr); // Window-Text icon
  339. }
  340. ic.hbmColor = hCopyBmp;
  341. hNewIcon = CreateIconIndirect(&ic);
  342. if (hNewIcon)
  343. {
  344. DestroyIcon(*phIcon);
  345. *phIcon = hNewIcon;
  346. SelectObject(hdcIconBmp, hObjTmp2); // restore original bitmap
  347. }
  348. Cleanup:
  349. if (hdcIconBmp)
  350. DeleteDC(hdcIconBmp);
  351. if (hdcCopyBmp)
  352. DeleteDC(hdcCopyBmp);
  353. if (hCopyBmp)
  354. DeleteObject(hCopyBmp);
  355. }