From 61076e4c188ba400f0c2d250f2065f412d444077 Mon Sep 17 00:00:00 2001 From: Martin Fuchs Date: Thu, 21 Aug 2003 19:24:30 +0000 Subject: [PATCH] display icons in tray notification area svn path=/trunk/; revision=5725 --- .../system/explorer/taskbar/startmenu.h | 3 - .../system/explorer/taskbar/taskbar.cpp | 116 +++++++++++++----- .../subsys/system/explorer/taskbar/taskbar.h | 43 +++++-- .../subsys/system/explorer/utility/utility.h | 52 ++++++-- .../subsys/system/explorer/utility/window.h | 1 + 5 files changed, 161 insertions(+), 54 deletions(-) diff --git a/reactos/subsys/system/explorer/taskbar/startmenu.h b/reactos/subsys/system/explorer/taskbar/startmenu.h index e24089baea3..3539ee2dc22 100644 --- a/reactos/subsys/system/explorer/taskbar/startmenu.h +++ b/reactos/subsys/system/explorer/taskbar/startmenu.h @@ -26,9 +26,6 @@ // -#include - - #define CLASSNAME_STARTMENU _T("ReactosStartmenuClass") #define TITLE_STARTMENU _T("Start Menu") diff --git a/reactos/subsys/system/explorer/taskbar/taskbar.cpp b/reactos/subsys/system/explorer/taskbar/taskbar.cpp index c1c72c36a28..44a0476ff10 100644 --- a/reactos/subsys/system/explorer/taskbar/taskbar.cpp +++ b/reactos/subsys/system/explorer/taskbar/taskbar.cpp @@ -79,18 +79,20 @@ LRESULT DesktopBar::Init(LPCREATESTRUCT pcs) new PictureButton(Button(_hwnd, ResString(IDS_START), 2, 2, STARTBUTTON_WIDTH, TASKBAR_HEIGHT-8, IDC_START, WS_VISIBLE|WS_CHILD|BS_OWNERDRAW), SmallIcon(IDI_STARTMENU)); + ClientRect clnt(_hwnd); + // create task bar _hwndTaskBar = Window::Create(WINDOW_CREATOR(TaskBar), 0, BtnWindowClass(CLASSNAME_TASKBAR), TITLE_TASKBAR, WS_CHILD|WS_VISIBLE, - TASKBAR_LEFT, 0, ClientRect(_hwnd).right-TASKBAR_LEFT, TASKBAR_HEIGHT, _hwnd); + TASKBAR_LEFT, 0, clnt.right-TASKBAR_LEFT, TASKBAR_HEIGHT, _hwnd); TaskBar* taskbar = static_cast(Window::get_window(_hwndTaskBar)); taskbar->_desktop_bar = this; // create tray notification area _hwndNotify = Window::Create(WINDOW_CREATOR(NotifyArea), WS_EX_STATICEDGE, - BtnWindowClass(CLASSNAME_TRAYNOTIFY), TITLE_TRAYNOTIFY, WS_CHILD|WS_VISIBLE, - TASKBAR_LEFT, 0, ClientRect(_hwnd).right-TASKBAR_LEFT, TASKBAR_HEIGHT, _hwnd); + BtnWindowClass(CLASSNAME_TRAYNOTIFY,CS_DBLCLKS), TITLE_TRAYNOTIFY, WS_CHILD|WS_VISIBLE, + clnt.right-NOTIFYAREA_WIDTH, 1, NOTIFYAREA_WIDTH, clnt.bottom-2, _hwnd); NotifyArea* notify_area = static_cast(Window::get_window(_hwndNotify)); notify_area->_desktop_bar = this; @@ -164,7 +166,7 @@ LRESULT DesktopBar::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) MoveWindow(_hwndTaskBar, TASKBAR_LEFT, 0, clnt.right-TASKBAR_LEFT-NOTIFYAREA_WIDTH, cy, TRUE); if (_hwndNotify) - MoveWindow(_hwndNotify, clnt.right-NOTIFYAREA_WIDTH, 0, NOTIFYAREA_WIDTH, cy, TRUE); + MoveWindow(_hwndNotify, clnt.right-NOTIFYAREA_WIDTH, 1, NOTIFYAREA_WIDTH, cy-2, TRUE); break;} case WM_CLOSE: @@ -231,7 +233,7 @@ void DesktopBar::CloseStartMenu() struct TrayNotifyCDS { DWORD cookie; DWORD notify_code; - DWORD offset; + NOTIFYICONDATA nicon_data; }; LRESULT DesktopBar::ProcessCopyData(COPYDATASTRUCT* pcd) @@ -239,12 +241,11 @@ LRESULT DesktopBar::ProcessCopyData(COPYDATASTRUCT* pcd) // Is this a tray notification message? if (pcd->dwData == 1) { TrayNotifyCDS* ptr = (TrayNotifyCDS*) pcd->lpData; - NOTIFYICONDATA* pnid = (NOTIFYICONDATA*) (LPBYTE(pcd->lpData)+ptr->offset); NotifyArea* notify_area = static_cast(Window::get_window(_hwndNotify)); if (notify_area) - return notify_area->ProcessTrayNotification(ptr->notify_code, pnid); + return notify_area->ProcessTrayNotification(ptr->notify_code, &ptr->nicon_data); } return 0; @@ -554,51 +555,77 @@ TaskBarMap::iterator TaskBarMap::find_id(int id) } +NotifyIconIndex::NotifyIconIndex(NOTIFYICONDATA* pnid) +{ + _hWnd = pnid->hWnd; + + // special case for windows task manager icons + _uID = (int)pnid->uID>=0? pnid->uID: 0; +} + + +NotifyInfo::NotifyInfo() +{ + _idx = -1; + _hIcon = 0; + _dwState = 0; +} + +NotifyInfo& NotifyInfo::operator=(NOTIFYICONDATA* pnid) +{ + if (pnid->uFlags & NIF_ICON) + _hIcon = pnid->hIcon; + +#ifdef NIF_STATE // currently (as of 21.08.2003) missing in MinGW headers + if (pnid->uFlags & NIF_STATE) + _dwState = (_dwState&~pnid->dwStateMask) | (pnid->dwState&pnid->dwStateMask); +#endif + + return *this; +} + + NotifyArea::NotifyArea(HWND hwnd) : super(hwnd) { _desktop_bar = NULL; -} - -NotifyArea::~NotifyArea() -{ -} - -LRESULT NotifyArea::Init(LPCREATESTRUCT pcs) -{ - if (super::Init(pcs)) - return 1; - - return 0; + _next_idx = 0; } LRESULT NotifyArea::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) { -/*@@ switch(nmsg) { + case WM_PAINT: + Paint(); + break; + default: return super::WndProc(nmsg, wparam, lparam); } -*/return super::WndProc(nmsg, wparam, lparam); return 0; } -int NotifyArea::Command(int id, int code) -{ - return super::Command(id, code); -} - LRESULT NotifyArea::ProcessTrayNotification(int notify_code, NOTIFYICONDATA* pnid) { + NotifyIconMap::iterator found = _icon_map.find(pnid); + switch(notify_code) { case NIM_ADD: - break; + case NIM_MODIFY: { + NotifyInfo& entry = _icon_map[pnid] = pnid; - case NIM_MODIFY: - break; + // a new entry? + if (entry._idx == -1) + entry._idx = ++_next_idx; + Refresh(); + break;} case NIM_DELETE: + if (found != _icon_map.end()) { + _icon_map.erase(found); + Refresh(); + } break; #if NOTIFYICON_VERSION>=3 // currently (as of 21.08.2003) missing in MinGW headers @@ -612,3 +639,34 @@ LRESULT NotifyArea::ProcessTrayNotification(int notify_code, NOTIFYICONDATA* pni return 0; } + +void NotifyArea::Refresh() +{ + _sorted_icons.clear(); + + // sort icon infos by display index + for(NotifyIconMap::const_iterator it=_icon_map.begin(); it!=_icon_map.end(); ++it) + _sorted_icons.insert(it->second); + + InvalidateRect(_hwnd, NULL, TRUE); // refresh icon display + UpdateWindow(_hwnd); +} + +void NotifyArea::Paint() +{ + PaintCanvas canvas(_hwnd); + + // draw icons + int x = 2; + int y = 2; + + for(NotifyIconSet::const_iterator it=_sorted_icons.begin(); it!=_sorted_icons.end(); ++it) { +#ifdef NIF_STATE // currently (as of 21.08.2003) missing in MinGW headers + if (!(it->_dwState & NIS_HIDDEN)) +#endif + { + DrawIconEx(canvas, x, y, it->_hIcon, 16, 16, 0, 0, DI_NORMAL); + x += 20; + } + } +} diff --git a/reactos/subsys/system/explorer/taskbar/taskbar.h b/reactos/subsys/system/explorer/taskbar/taskbar.h index f91f6cb6f45..46cbf569d68 100644 --- a/reactos/subsys/system/explorer/taskbar/taskbar.h +++ b/reactos/subsys/system/explorer/taskbar/taskbar.h @@ -34,7 +34,7 @@ #define TASKBAR_LEFT 70 //#define TASKBAR_AT_TOP -#define NOTIFYAREA_WIDTH 100 +#define NOTIFYAREA_WIDTH 244 #define CLASSNAME_EXPLORERBAR _T("Shell_TrayWnd") @@ -150,12 +150,35 @@ protected: }; -struct NotifyIconIndex { - HWND hWnd; - UINT uID; +struct NotifyIconIndex +{ + NotifyIconIndex(NOTIFYICONDATA* pnid); + + // sort operator + friend bool operator<(const NotifyIconIndex& a, const NotifyIconIndex& b) + {return a._hWnd NotifyIconMap; +struct NotifyInfo +{ + NotifyInfo(); + + // sort operator + friend bool operator<(const NotifyInfo& a, const NotifyInfo& b) + {return a._idx NotifyIconMap; +typedef set NotifyIconSet; /// tray notification area aka "tray" @@ -164,16 +187,18 @@ struct NotifyArea : public Window typedef Window super; NotifyArea(HWND hwnd); - ~NotifyArea(); DesktopBar* _desktop_bar; - LRESULT ProcessTrayNotification(int notify_code, NOTIFYICONDATA* pnid); + LRESULT ProcessTrayNotification(int notify_code, NOTIFYICONDATA* pnid); protected: NotifyIconMap _icon_map; + NotifyIconSet _sorted_icons; + int _next_idx; - LRESULT Init(LPCREATESTRUCT pcs); LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam); - int Command(int id, int code); + + void Refresh(); + void Paint(); }; diff --git a/reactos/subsys/system/explorer/utility/utility.h b/reactos/subsys/system/explorer/utility/utility.h index 4e459f8b867..86784d8d15b 100644 --- a/reactos/subsys/system/explorer/utility/utility.h +++ b/reactos/subsys/system/explorer/utility/utility.h @@ -88,6 +88,8 @@ struct CommonControlInit }; + /// wait cursor + struct WaitCursor { WaitCursor() @@ -105,6 +107,8 @@ protected: }; + // window utilities + struct ClientRect : public RECT { ClientRect(HWND hwnd) @@ -121,7 +125,7 @@ struct WindowRect : public RECT } }; -struct Point: public POINT +struct Point : public POINT { Point(LONG x_, LONG y_) { @@ -138,6 +142,40 @@ struct Point: public POINT }; +struct FullScreenParameters +{ + FullScreenParameters() + : _mode(FALSE) + { + } + + BOOL _mode; + RECT _orgPos; + BOOL _wasZoomed; +}; + + + // drawing utilities + +struct PaintCanvas : public PAINTSTRUCT +{ + PaintCanvas(HWND hwnd) + : _hwnd(hwnd) + { + BeginPaint(hwnd, this); + } + + PaintCanvas() + { + EndPaint(_hwnd, this); + } + + operator HDC() const {return hdc;} + +protected: + HWND _hwnd; +}; + struct TextColor { TextColor(HDC hdc, COLORREF color) @@ -175,18 +213,6 @@ protected: }; -struct FullScreenParameters { - FullScreenParameters() - : _mode(FALSE) - { - } - - BOOL _mode; - RECT _orgPos; - BOOL _wasZoomed; -}; - - struct String #ifdef UNICODE : public wstring diff --git a/reactos/subsys/system/explorer/utility/window.h b/reactos/subsys/system/explorer/utility/window.h index ca11ff10bdd..2784cebfdf5 100644 --- a/reactos/subsys/system/explorer/utility/window.h +++ b/reactos/subsys/system/explorer/utility/window.h @@ -28,6 +28,7 @@ #include #include +#include typedef set WindowSet;