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.

343 lines
9.3 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // File: tray.cpp
  4. //
  5. // Description:
  6. //
  7. // Copyright (c) 2000 Microsoft Corp.
  8. //
  9. //////////////////////////////////////////////////////////////////////////////
  10. // App Includes
  11. #include "precomp.h"
  12. #include "main.h"
  13. #include "resource.h"
  14. ///////////////////////////
  15. // GVAR_LOCAL
  16. //
  17. // Global Variable
  18. //
  19. static struct GVAR_LOCAL
  20. {
  21. HINSTANCE hInstance;
  22. HMENU hMenu;
  23. } GVAR_LOCAL =
  24. {
  25. NULL,
  26. NULL
  27. };
  28. ////////////////////////// Function Prototypes ////////////////////////////////
  29. static HRESULT AddTaskBarIcon(HWND hwnd,
  30. UINT uiIconID,
  31. UINT uiCallBackMsg,
  32. ULONG ulStrID);
  33. static HRESULT ModifyTaskBarIcon(HWND hwnd,
  34. UINT uiNewIconID,
  35. ULONG ulStrID);
  36. static HRESULT DeleteTaskBarIcon(HWND hwnd);
  37. //////////////////////////////////////////////////////////////////////
  38. // Tray::Init
  39. //
  40. HRESULT Tray::Init(HINSTANCE hInstance,
  41. HWND hwndDlg,
  42. UINT uiWindowsUserMsgId)
  43. {
  44. HRESULT hr = S_OK;
  45. GVAR_LOCAL.hInstance = hInstance;
  46. // delete the taskbar notification area icon.
  47. DeleteTaskBarIcon(hwndDlg);
  48. // Place the icon in the taskbar notification area.
  49. AddTaskBarIcon(hwndDlg,
  50. IDI_MONITOR,
  51. uiWindowsUserMsgId,
  52. 0);
  53. // load our popup menu
  54. GVAR_LOCAL.hMenu = ::LoadMenu(GVAR_LOCAL.hInstance,
  55. MAKEINTRESOURCE(IDM_TRAY_POPUP_MENU));
  56. return hr;
  57. }
  58. //////////////////////////////////////////////////////////////////////
  59. // Tray::Term
  60. //
  61. // Desc:
  62. //
  63. HRESULT Tray::Term(HWND hwndDlg)
  64. {
  65. HRESULT hr = S_OK;
  66. // unload the popup menu
  67. ::DestroyMenu(GVAR_LOCAL.hMenu);
  68. GVAR_LOCAL.hMenu = NULL;
  69. // delete the tray icon.
  70. DeleteTaskBarIcon(hwndDlg);
  71. return hr;
  72. }
  73. //////////////////////////////////////////////////////////////////
  74. // Tray::PopupMenu
  75. //
  76. //
  77. HRESULT Tray::PopupMenu(HWND hwndOwner)
  78. {
  79. HRESULT hr = S_OK;
  80. POINT pt = {0}; // stores mouse click
  81. HMENU hmenuTrackPopup = NULL; // pop-up menu
  82. // needed to correct a bug with TrackPopupMenu in Win32
  83. SetForegroundWindow(hwndOwner);
  84. // TrackPopupMenu cannot display the top-level menu, so get
  85. // the handle of the first pop-up menu.
  86. hmenuTrackPopup = GetSubMenu(GVAR_LOCAL.hMenu, 0);
  87. GetCursorPos(&pt);
  88. // Display the floating pop-up menu. Track the left mouse
  89. // button on the assumption that this function is called
  90. // during WM_CONTEXTMENU processing.
  91. TrackPopupMenu(hmenuTrackPopup,
  92. TPM_RIGHTALIGN | TPM_LEFTBUTTON,
  93. pt.x,
  94. pt.y,
  95. 0,
  96. hwndOwner,
  97. NULL);
  98. // needed to correct a bug with TrackPopupMenu in Win32
  99. PostMessage(hwndOwner, WM_USER, 0, 0);
  100. return S_OK;
  101. }
  102. //////////////////////////////////////////////////////////////////////
  103. // AddTaskBarIcon
  104. //
  105. // Desc: Adds an icon to the task bar.
  106. //
  107. // Params: - hwnd, handle of main window.
  108. // - uiID, id of icon.
  109. // - uiCallBackMsg, WM_USER message to send to hwnd when
  110. // event occurs on icon.
  111. // - ulStrID, string table text of tool tip to display for
  112. // this icon.
  113. //
  114. static HRESULT AddTaskBarIcon(HWND hwnd,
  115. UINT uiIconID,
  116. UINT uiCallBackMsg,
  117. ULONG ulStrID)
  118. {
  119. HRESULT hr = S_OK;
  120. BOOL bRes;
  121. NOTIFYICONDATA tnid;
  122. HICON hIconHandle = NULL;
  123. TCHAR szToolTip[255 + 1] = {0};
  124. if (ulStrID != 0)
  125. {
  126. ::LoadString(GVAR_LOCAL.hInstance,
  127. ulStrID,
  128. szToolTip,
  129. sizeof(szToolTip) / sizeof(TCHAR));
  130. }
  131. if (SUCCEEDED(hr))
  132. {
  133. // load the specified icon.
  134. hIconHandle = (HICON) ::LoadImage(GVAR_LOCAL.hInstance,
  135. MAKEINTRESOURCE(uiIconID),
  136. IMAGE_ICON,
  137. 16,
  138. 16,
  139. LR_DEFAULTCOLOR);
  140. if (hIconHandle == NULL)
  141. {
  142. hr = E_FAIL;
  143. DBG_ERR(("AddTaskBarIcon, failed ot load icon, hr = 0x%08lx",
  144. hr));
  145. }
  146. }
  147. if (SUCCEEDED(hr))
  148. {
  149. // add the icon to the notification tray
  150. tnid.cbSize = sizeof(NOTIFYICONDATA);
  151. tnid.hWnd = hwnd;
  152. tnid.uID = MSPRJCTR_TASKBAR_ID;
  153. tnid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
  154. tnid.uCallbackMessage = uiCallBackMsg;
  155. tnid.hIcon = hIconHandle;
  156. if (szToolTip[0] != '\0')
  157. {
  158. _tcsncpy(tnid.szTip, szToolTip, sizeof(tnid.szTip) / sizeof(TCHAR));
  159. }
  160. else
  161. {
  162. tnid.szTip[0] = '\0';
  163. }
  164. bRes = Shell_NotifyIcon(NIM_ADD, &tnid);
  165. if (!bRes)
  166. {
  167. hr = E_FAIL;
  168. DBG_ERR(("Failed to set TaskBar Icon, hr = 0x%08lx",
  169. hr));
  170. }
  171. }
  172. if (hIconHandle)
  173. {
  174. // destroy the icon
  175. DestroyIcon(hIconHandle);
  176. }
  177. return hr;
  178. }
  179. //////////////////////////////////////////////////////////////////////
  180. // ModifyTaskBarIcon
  181. //
  182. // Desc: Modifies a taskbar icon/tooltip (or both) to a new
  183. // one. Note, if ulStrID is 0, then the tool tip is NOT
  184. // modified. If uiNewIconID is 0, then the icon is not
  185. // modified. If both are 0, then actually nothing changes.
  186. //
  187. //
  188. // Params: - hwnd, handle of main window.
  189. // - uiNewIconID, resource ID of icon to display.
  190. // - ulStrID, string resource ID of string to use for tooltip.
  191. // Note your string will be prefixed with "InterLYNX - "
  192. //
  193. static HRESULT ModifyTaskBarIcon(HWND hwnd,
  194. UINT uiNewIconID,
  195. ULONG ulStrID)
  196. {
  197. HRESULT hr = S_OK;
  198. BOOL bRes = TRUE;
  199. NOTIFYICONDATA tnid = {0};
  200. HICON hIconHandle = NULL;
  201. TCHAR szToolTip[255 + 1] = {0};
  202. BOOL bContinue = TRUE;
  203. if ((uiNewIconID == 0) && (ulStrID == 0))
  204. {
  205. bContinue = FALSE;
  206. }
  207. else
  208. {
  209. bContinue = TRUE;
  210. }
  211. if (bContinue)
  212. {
  213. // if we are instructed to modify the tool tip.
  214. if (ulStrID != 0)
  215. {
  216. ::LoadString(GVAR_LOCAL.hInstance,
  217. ulStrID,
  218. szToolTip,
  219. sizeof(szToolTip) / sizeof(TCHAR));
  220. }
  221. // if a new icon was specified.
  222. if (uiNewIconID != 0)
  223. {
  224. // load the specified icon.
  225. hIconHandle = (HICON) ::LoadImage(GVAR_LOCAL.hInstance,
  226. MAKEINTRESOURCE(uiNewIconID),
  227. IMAGE_ICON,
  228. 16,
  229. 16,
  230. LR_DEFAULTCOLOR);
  231. }
  232. // add the icon to the notification tray
  233. tnid.cbSize = sizeof(NOTIFYICONDATA);
  234. tnid.hWnd = hwnd;
  235. tnid.uID = MSPRJCTR_TASKBAR_ID;
  236. tnid.uFlags = 0;
  237. tnid.hIcon = 0;
  238. if (ulStrID != 0)
  239. {
  240. _tcsncpy(tnid.szTip, szToolTip, sizeof(tnid.szTip) / sizeof(TCHAR));
  241. tnid.uFlags = tnid.uFlags | NIF_TIP;
  242. }
  243. if (uiNewIconID != 0)
  244. {
  245. tnid.hIcon = hIconHandle;
  246. tnid.uFlags = tnid.uFlags | NIF_ICON;
  247. }
  248. bRes = Shell_NotifyIcon(NIM_MODIFY, &tnid);
  249. if (!bRes)
  250. {
  251. hr = E_FAIL;
  252. DBG_ERR(("Failed to modify taskbar icon, hr = 0x%08lx",
  253. hr));
  254. }
  255. }
  256. if (hIconHandle)
  257. {
  258. // destroy the icon
  259. DestroyIcon(hIconHandle);
  260. }
  261. return hr;
  262. }
  263. //////////////////////////////////////////////////////////////////////
  264. // DeleteTaskBarIcon
  265. //
  266. // Desc: Deletes a taskbar icon
  267. //
  268. //
  269. // Params: - hwnd, handle of main window.
  270. // - uiID, id of icon.
  271. //
  272. static HRESULT DeleteTaskBarIcon(HWND hwnd)
  273. {
  274. HRESULT hr = S_OK;
  275. BOOL bRes = TRUE;
  276. NOTIFYICONDATA tnid = {0};
  277. HICON hIconHandle = NULL;
  278. if (SUCCEEDED(hr))
  279. {
  280. tnid.cbSize = sizeof(NOTIFYICONDATA);
  281. tnid.hWnd = hwnd;
  282. tnid.uID = MSPRJCTR_TASKBAR_ID;
  283. bRes = Shell_NotifyIcon(NIM_DELETE, &tnid);
  284. // this is not such a big deal.
  285. if (!bRes)
  286. {
  287. hr = E_FAIL;
  288. }
  289. }
  290. return hr;
  291. }