| 163 | //A Tray Icon Application class that handles Context Menus. |
| 164 | |
| 165 | class CMenuTrayIcon : public CTrayIcon { |
| 166 | public: |
| 167 | CMenuTrayIcon() : DoubleClicked(false) {} |
| 168 | CMenuTrayIcon(LPCTSTR szTip, HICON hIcon, UINT Menu=0, UINT Default=0, BOOL ByPos=FALSE) : DoubleClicked(false) {Create(szTip, hIcon, Menu, Default, ByPos);} |
| 169 | void Create(LPCTSTR szTip, HICON hIcon, UINT Menu=0, UINT Default=0, BOOL ByPos=FALSE) { |
| 170 | CTrayIcon::Create(szTip, hIcon, Menu); |
| 171 | SetMenuDefaultItem(Default, ByPos); |
| 172 | } |
| 173 | virtual ~CMenuTrayIcon() {} |
| 174 | |
| 175 | // Attributes |
| 176 | protected: |
| 177 | UINT DefaultMenuItemID; |
| 178 | BOOL DefaultMenuItemByPos; |
| 179 | bool DoubleClicked; |
| 180 | |
| 181 | // Operations |
| 182 | public: |
| 183 | bool SetMenuDefaultItem(UINT MenuItemID, BOOL ByPos) { |
| 184 | if((DefaultMenuItemID==MenuItemID) && (DefaultMenuItemByPos==ByPos)) return TRUE; |
| 185 | DefaultMenuItemID =MenuItemID; |
| 186 | DefaultMenuItemByPos=ByPos; |
| 187 | CMenu Menu, *pSubMenu; |
| 188 | if(!Menu.LoadMenu(NID.uID) |
| 189 | || !(pSubMenu=Menu.GetSubMenu(0))) return false; |
| 190 | ::SetMenuDefaultItem(pSubMenu->m_hMenu, DefaultMenuItemID, DefaultMenuItemByPos); |
| 191 | return true; |
| 192 | } |
| 193 | |
| 194 | // Overrides |
| 195 | virtual LRESULT WindowProc(UINT Message, WPARAM wParam, LPARAM lParam) { |
| 196 | if(Message==NID.uCallbackMessage |
| 197 | && wParam==NID.uID) { |
| 198 | CMenu Menu, *pSubMenu; |
| 199 | CWnd* pMainWnd=AfxGetMainWnd(); |
| 200 | switch(LOWORD(lParam)) { |
| 201 | case WM_RBUTTONUP: { // Clicking with right button brings up a context Menu |
| 202 | if(!Menu.LoadMenu(NID.uID) |
| 203 | || !(pSubMenu=Menu.GetSubMenu(0))) return false; |
| 204 | // Make chosen Menu item the default (bold font) |
| 205 | ::SetMenuDefaultItem(pSubMenu->m_hMenu, DefaultMenuItemID, DefaultMenuItemByPos); |
| 206 | // Display and track the popup Menu |
| 207 | CPoint Mouse; |
| 208 | GetCursorPos(&Mouse); |
| 209 | pMainWnd->SetForegroundWindow(); // See MSDN Knowledge Base article "PRB: Menus for Notification Icons Don't Work Correctly" |
| 210 | pSubMenu->TrackPopupMenu(TPM_LEFTALIGN, Mouse.x, Mouse.y, pMainWnd, 0); |
| 211 | pMainWnd->PostMessage(WM_NULL, 0, 0); // See MSDN Knowledge Base article "PRB: Menus for Notification Icons Don't Work Correctly" |
| 212 | Menu.DestroyMenu(); |
| 213 | return true; |
| 214 | } |
| 215 | case WM_LBUTTONDBLCLK: return DoubleClicked=true; // double click received, do the default Menu item |
| 216 | case WM_LBUTTONUP: { |
| 217 | if(DoubleClicked) { // Make sure that if the default deletes the icon, that the next icon doesn't get our WM_LBUTTONUP notification (some icons use it). |
| 218 | DoubleClicked=false; |
| 219 | pMainWnd->SetForegroundWindow(); |
| 220 | UINT uItem; |
| 221 | if(DefaultMenuItemByPos) { |
| 222 | if(!Menu.LoadMenu(NID.uID) |
nothing calls this directly
no outgoing calls
no test coverage detected