From 942ea1645e335fb6fdbdd709cbd29d588dcd2860 Mon Sep 17 00:00:00 2001 From: Martin Fuchs Date: Fri, 22 Aug 2003 12:41:24 +0000 Subject: [PATCH] Implemented tray notification callback messages svn path=/trunk/; revision=5747 --- .../system/explorer/desktop/desktop.cpp | 7 +- reactos/subsys/system/explorer/globals.h | 2 - .../system/explorer/taskbar/desktopbar.cpp | 2 + .../system/explorer/taskbar/startmenu.cpp | 16 +-- .../system/explorer/taskbar/traynotify.cpp | 100 ++++++++++++++---- .../system/explorer/taskbar/traynotify.h | 10 +- 6 files changed, 99 insertions(+), 38 deletions(-) diff --git a/reactos/subsys/system/explorer/desktop/desktop.cpp b/reactos/subsys/system/explorer/desktop/desktop.cpp index 44cbc9aa1a6..3fc0cefabc0 100644 --- a/reactos/subsys/system/explorer/desktop/desktop.cpp +++ b/reactos/subsys/system/explorer/desktop/desktop.cpp @@ -32,9 +32,6 @@ #include "../explorer_intres.h" -UINT PM_DESKTOP_GOT_FOCUS = RegisterWindowMessage(WINMSG_DESKTOP_GOT_FOCUS); - - static BOOL (WINAPI*SetShellWindow)(HWND); static BOOL (WINAPI*SetShellWindowEx)(HWND, HWND); @@ -212,9 +209,9 @@ LRESULT DesktopWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) break; case WM_SETFOCUS: - // notify Startmenu of focus change + // close startup menu and other popup menus like on the tray notification icons if (wparam) - SendMessage((HWND)wparam, PM_DESKTOP_GOT_FOCUS, 0, 0); + SendMessage((HWND)wparam, WM_CANCELMODE, 0, 0); goto def; case WM_GETISHELLBROWSER: diff --git a/reactos/subsys/system/explorer/globals.h b/reactos/subsys/system/explorer/globals.h index 4675041c090..47217f6ae1d 100644 --- a/reactos/subsys/system/explorer/globals.h +++ b/reactos/subsys/system/explorer/globals.h @@ -38,8 +38,6 @@ extern struct ExplorerGlobals bool _desktop_mode; } g_Globals; -extern UINT PM_DESKTOP_GOT_FOCUS; - struct ResString : public String { diff --git a/reactos/subsys/system/explorer/taskbar/desktopbar.cpp b/reactos/subsys/system/explorer/taskbar/desktopbar.cpp index 283b1af6b33..9569b511778 100644 --- a/reactos/subsys/system/explorer/taskbar/desktopbar.cpp +++ b/reactos/subsys/system/explorer/taskbar/desktopbar.cpp @@ -244,6 +244,8 @@ LRESULT DesktopBar::ProcessCopyData(COPYDATASTRUCT* pcd) if (pcd->dwData == 1) { TrayNotifyCDS* ptr = (TrayNotifyCDS*) pcd->lpData; + //TODO: process the differnt versions of the NOTIFYICONDATA structure (look at cbSize to decide which one) + NotifyArea* notify_area = static_cast(Window::get_window(_hwndNotify)); if (notify_area) diff --git a/reactos/subsys/system/explorer/taskbar/startmenu.cpp b/reactos/subsys/system/explorer/taskbar/startmenu.cpp index a4206917119..7e46ea48096 100644 --- a/reactos/subsys/system/explorer/taskbar/startmenu.cpp +++ b/reactos/subsys/system/explorer/taskbar/startmenu.cpp @@ -202,13 +202,7 @@ LRESULT StartMenu::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) _submenu = 0; break; - default: - if (nmsg == PM_DESKTOP_GOT_FOCUS) { - CloseStartMenu(); - return 0; - } - - def: + default: def: return super::WndProc(nmsg, wparam, lparam); } @@ -467,11 +461,11 @@ LRESULT StartMenuButton::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) PostParent(PM_STARTENTRY_FOCUSED, _hasSubmenu, (LPARAM)_hwnd); goto def; - default: - if (nmsg == PM_DESKTOP_GOT_FOCUS) - return SendParent(nmsg, wparam, lparam); + case WM_CANCELMODE: + // route WM_CANCELMODE to the startmenu window + return SendParent(nmsg, wparam, lparam); - def: + default: def: return super::WndProc(nmsg, wparam, lparam); } diff --git a/reactos/subsys/system/explorer/taskbar/traynotify.cpp b/reactos/subsys/system/explorer/taskbar/traynotify.cpp index f911900e32b..cf78b379069 100644 --- a/reactos/subsys/system/explorer/taskbar/traynotify.cpp +++ b/reactos/subsys/system/explorer/taskbar/traynotify.cpp @@ -37,9 +37,17 @@ NotifyIconIndex::NotifyIconIndex(NOTIFYICONDATA* pnid) { _hWnd = pnid->hWnd; + _uID = pnid->uID; - // special case for windows task manager icons - _uID = (int)pnid->uID>=0? pnid->uID: 0; + // special handling for windows task manager + if ((int)_uID < 0) + _uID = 0; +} + +NotifyIconIndex::NotifyIconIndex() +{ + _hWnd = 0; + _uID = 0; } @@ -48,10 +56,17 @@ NotifyInfo::NotifyInfo() _idx = -1; _hIcon = 0; _dwState = 0; + _uCallbackMessage = 0; } NotifyInfo& NotifyInfo::operator=(NOTIFYICONDATA* pnid) { + _hWnd = pnid->hWnd; + _uID = pnid->uID; + + if (pnid->uFlags & NIF_MESSAGE) + _uCallbackMessage = pnid->uCallbackMessage; + if (pnid->uFlags & NIF_ICON) _hIcon = pnid->hIcon; @@ -94,7 +109,23 @@ LRESULT NotifyArea::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) break; default: - return super::WndProc(nmsg, wparam, lparam); + if (nmsg>=WM_MOUSEFIRST && nmsg<=WM_MOUSELAST) { + NotifyIconSet::iterator found = IconHitTest(Point(lparam)); + + if (found != _sorted_icons.end()) { + NotifyInfo& entry = const_cast(*found); // Why does GCC 3.3 need this additional const_cast ?! + + // Notify the message the the owner if it's still alive + if (IsWindow(entry._hWnd)) //TODO: We could check this regularly for all icons by using WM_TIMER to prevent for hanging icons + PostMessage(entry._hWnd, entry._uCallbackMessage, entry._uID, nmsg); + else { + // delete icons without owner window + if (_icon_map.erase(entry)) + Refresh(); + } + } + } else + return super::WndProc(nmsg, wparam, lparam); } return 0; @@ -102,26 +133,27 @@ LRESULT NotifyArea::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) LRESULT NotifyArea::ProcessTrayNotification(int notify_code, NOTIFYICONDATA* pnid) { - NotifyIconMap::iterator found = _icon_map.find(pnid); - switch(notify_code) { case NIM_ADD: - case NIM_MODIFY: { - NotifyInfo& entry = _icon_map[pnid] = pnid; + case NIM_MODIFY: + if ((int)pnid->uID >= 0) { + NotifyInfo& entry = _icon_map[pnid] = pnid; - // a new entry? - if (entry._idx == -1) - entry._idx = ++_next_idx; - Refresh(); - break;} + // a new entry? + if (entry._idx == -1) + entry._idx = ++_next_idx; - case NIM_DELETE: - if (found != _icon_map.end()) { - _icon_map.erase(found); + Refresh(); + } else { Refresh(); } break; + case NIM_DELETE: + if (_icon_map.erase(pnid)) + Refresh(); + break; + #if NOTIFYICON_VERSION>=3 // currently (as of 21.08.2003) missing in MinGW headers case NIM_SETFOCUS: break; @@ -154,18 +186,50 @@ void NotifyArea::Paint() int x = 2; int y = 2; - for(NotifyIconSet::const_iterator it=_sorted_icons.begin(); it!=_sorted_icons.end(); ++it) { + for(NotifyIconSet::const_iterator it=_sorted_icons.begin(); it!=_sorted_icons.end(); ++it) + { + const NotifyInfo& entry = *it; + #ifdef NIF_STATE // currently (as of 21.08.2003) missing in MinGW headers - if (!(it->_dwState & NIS_HIDDEN)) + if (!(entry._dwState & NIS_HIDDEN)) #endif { - DrawIconEx(canvas, x, y, it->_hIcon, 16, 16, 0, 0, DI_NORMAL); + DrawIconEx(canvas, x, y, entry._hIcon, 16, 16, 0, 0, DI_NORMAL); x += 20; } } } + /// search for a icon at a given client coordinate position +NotifyIconSet::iterator NotifyArea::IconHitTest(const POINT& pos) +{ + if (pos.y<2 || pos.y>=2+16) + return _sorted_icons.end(); + + NotifyIconSet::iterator it = _sorted_icons.begin(); + + int x = 2; + + for(; it!=_sorted_icons.end(); ++it) + { + NotifyInfo& entry = const_cast(*it); // Why does GCC 3.3 need this additional const_cast ?! + +#ifdef NIF_STATE // currently (as of 21.08.2003) missing in MinGW headers + if (!(entry._dwState & NIS_HIDDEN)) +#endif + { + if (pos.x>=x && pos.x NotifyIconMap; @@ -89,6 +93,8 @@ protected: void Refresh(); void Paint(); + + NotifyIconSet::iterator IconHitTest(const POINT& pos); };