display icons in tray notification area

svn path=/trunk/; revision=5725
This commit is contained in:
Martin Fuchs 2003-08-21 19:24:30 +00:00
parent afbf3c66b6
commit 61076e4c18
5 changed files with 161 additions and 54 deletions

View file

@ -26,9 +26,6 @@
// //
#include <list>
#define CLASSNAME_STARTMENU _T("ReactosStartmenuClass") #define CLASSNAME_STARTMENU _T("ReactosStartmenuClass")
#define TITLE_STARTMENU _T("Start Menu") #define TITLE_STARTMENU _T("Start Menu")

View file

@ -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), 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)); SmallIcon(IDI_STARTMENU));
ClientRect clnt(_hwnd);
// create task bar // create task bar
_hwndTaskBar = Window::Create(WINDOW_CREATOR(TaskBar), 0, _hwndTaskBar = Window::Create(WINDOW_CREATOR(TaskBar), 0,
BtnWindowClass(CLASSNAME_TASKBAR), TITLE_TASKBAR, WS_CHILD|WS_VISIBLE, 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<TaskBar*>(Window::get_window(_hwndTaskBar)); TaskBar* taskbar = static_cast<TaskBar*>(Window::get_window(_hwndTaskBar));
taskbar->_desktop_bar = this; taskbar->_desktop_bar = this;
// create tray notification area // create tray notification area
_hwndNotify = Window::Create(WINDOW_CREATOR(NotifyArea), WS_EX_STATICEDGE, _hwndNotify = Window::Create(WINDOW_CREATOR(NotifyArea), WS_EX_STATICEDGE,
BtnWindowClass(CLASSNAME_TRAYNOTIFY), TITLE_TRAYNOTIFY, WS_CHILD|WS_VISIBLE, BtnWindowClass(CLASSNAME_TRAYNOTIFY,CS_DBLCLKS), TITLE_TRAYNOTIFY, WS_CHILD|WS_VISIBLE,
TASKBAR_LEFT, 0, ClientRect(_hwnd).right-TASKBAR_LEFT, TASKBAR_HEIGHT, _hwnd); clnt.right-NOTIFYAREA_WIDTH, 1, NOTIFYAREA_WIDTH, clnt.bottom-2, _hwnd);
NotifyArea* notify_area = static_cast<NotifyArea*>(Window::get_window(_hwndNotify)); NotifyArea* notify_area = static_cast<NotifyArea*>(Window::get_window(_hwndNotify));
notify_area->_desktop_bar = this; 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); MoveWindow(_hwndTaskBar, TASKBAR_LEFT, 0, clnt.right-TASKBAR_LEFT-NOTIFYAREA_WIDTH, cy, TRUE);
if (_hwndNotify) 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;} break;}
case WM_CLOSE: case WM_CLOSE:
@ -231,7 +233,7 @@ void DesktopBar::CloseStartMenu()
struct TrayNotifyCDS { struct TrayNotifyCDS {
DWORD cookie; DWORD cookie;
DWORD notify_code; DWORD notify_code;
DWORD offset; NOTIFYICONDATA nicon_data;
}; };
LRESULT DesktopBar::ProcessCopyData(COPYDATASTRUCT* pcd) LRESULT DesktopBar::ProcessCopyData(COPYDATASTRUCT* pcd)
@ -239,12 +241,11 @@ LRESULT DesktopBar::ProcessCopyData(COPYDATASTRUCT* pcd)
// Is this a tray notification message? // Is this a tray notification message?
if (pcd->dwData == 1) { if (pcd->dwData == 1) {
TrayNotifyCDS* ptr = (TrayNotifyCDS*) pcd->lpData; TrayNotifyCDS* ptr = (TrayNotifyCDS*) pcd->lpData;
NOTIFYICONDATA* pnid = (NOTIFYICONDATA*) (LPBYTE(pcd->lpData)+ptr->offset);
NotifyArea* notify_area = static_cast<NotifyArea*>(Window::get_window(_hwndNotify)); NotifyArea* notify_area = static_cast<NotifyArea*>(Window::get_window(_hwndNotify));
if (notify_area) if (notify_area)
return notify_area->ProcessTrayNotification(ptr->notify_code, pnid); return notify_area->ProcessTrayNotification(ptr->notify_code, &ptr->nicon_data);
} }
return 0; 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) NotifyArea::NotifyArea(HWND hwnd)
: super(hwnd) : super(hwnd)
{ {
_desktop_bar = NULL; _desktop_bar = NULL;
} _next_idx = 0;
NotifyArea::~NotifyArea()
{
}
LRESULT NotifyArea::Init(LPCREATESTRUCT pcs)
{
if (super::Init(pcs))
return 1;
return 0;
} }
LRESULT NotifyArea::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) LRESULT NotifyArea::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
{ {
/*@@
switch(nmsg) { switch(nmsg) {
case WM_PAINT:
Paint();
break;
default: default:
return super::WndProc(nmsg, wparam, lparam); return super::WndProc(nmsg, wparam, lparam);
} }
*/return super::WndProc(nmsg, wparam, lparam);
return 0; return 0;
} }
int NotifyArea::Command(int id, int code)
{
return super::Command(id, code);
}
LRESULT NotifyArea::ProcessTrayNotification(int notify_code, NOTIFYICONDATA* pnid) LRESULT NotifyArea::ProcessTrayNotification(int notify_code, NOTIFYICONDATA* pnid)
{ {
NotifyIconMap::iterator found = _icon_map.find(pnid);
switch(notify_code) { switch(notify_code) {
case NIM_ADD: case NIM_ADD:
break; case NIM_MODIFY: {
NotifyInfo& entry = _icon_map[pnid] = pnid;
case NIM_MODIFY: // a new entry?
break; if (entry._idx == -1)
entry._idx = ++_next_idx;
Refresh();
break;}
case NIM_DELETE: case NIM_DELETE:
if (found != _icon_map.end()) {
_icon_map.erase(found);
Refresh();
}
break; break;
#if NOTIFYICON_VERSION>=3 // currently (as of 21.08.2003) missing in MinGW headers #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; 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;
}
}
}

View file

@ -34,7 +34,7 @@
#define TASKBAR_LEFT 70 #define TASKBAR_LEFT 70
//#define TASKBAR_AT_TOP //#define TASKBAR_AT_TOP
#define NOTIFYAREA_WIDTH 100 #define NOTIFYAREA_WIDTH 244
#define CLASSNAME_EXPLORERBAR _T("Shell_TrayWnd") #define CLASSNAME_EXPLORERBAR _T("Shell_TrayWnd")
@ -150,12 +150,35 @@ protected:
}; };
struct NotifyIconIndex { struct NotifyIconIndex
HWND hWnd; {
UINT uID; NotifyIconIndex(NOTIFYICONDATA* pnid);
// sort operator
friend bool operator<(const NotifyIconIndex& a, const NotifyIconIndex& b)
{return a._hWnd<b._hWnd || (a._hWnd==b._hWnd && a._uID<b._uID);}
HWND _hWnd;
UINT _uID;
}; };
typedef map<NotifyIconIndex, int> NotifyIconMap; struct NotifyInfo
{
NotifyInfo();
// sort operator
friend bool operator<(const NotifyInfo& a, const NotifyInfo& b)
{return a._idx<b._idx;}
NotifyInfo& operator=(NOTIFYICONDATA* pnid);
int _idx; // display index
HICON _hIcon;
DWORD _dwState;
};
typedef map<NotifyIconIndex, NotifyInfo> NotifyIconMap;
typedef set<NotifyInfo> NotifyIconSet;
/// tray notification area aka "tray" /// tray notification area aka "tray"
@ -164,16 +187,18 @@ struct NotifyArea : public Window
typedef Window super; typedef Window super;
NotifyArea(HWND hwnd); NotifyArea(HWND hwnd);
~NotifyArea();
DesktopBar* _desktop_bar; DesktopBar* _desktop_bar;
LRESULT ProcessTrayNotification(int notify_code, NOTIFYICONDATA* pnid); LRESULT ProcessTrayNotification(int notify_code, NOTIFYICONDATA* pnid);
protected: protected:
NotifyIconMap _icon_map; NotifyIconMap _icon_map;
NotifyIconSet _sorted_icons;
int _next_idx;
LRESULT Init(LPCREATESTRUCT pcs);
LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam); LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
int Command(int id, int code);
void Refresh();
void Paint();
}; };

View file

@ -88,6 +88,8 @@ struct CommonControlInit
}; };
/// wait cursor
struct WaitCursor struct WaitCursor
{ {
WaitCursor() WaitCursor()
@ -105,6 +107,8 @@ protected:
}; };
// window utilities
struct ClientRect : public RECT struct ClientRect : public RECT
{ {
ClientRect(HWND hwnd) ClientRect(HWND hwnd)
@ -121,7 +125,7 @@ struct WindowRect : public RECT
} }
}; };
struct Point: public POINT struct Point : public POINT
{ {
Point(LONG x_, LONG y_) 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 struct TextColor
{ {
TextColor(HDC hdc, COLORREF color) TextColor(HDC hdc, COLORREF color)
@ -175,18 +213,6 @@ protected:
}; };
struct FullScreenParameters {
FullScreenParameters()
: _mode(FALSE)
{
}
BOOL _mode;
RECT _orgPos;
BOOL _wasZoomed;
};
struct String struct String
#ifdef UNICODE #ifdef UNICODE
: public wstring : public wstring

View file

@ -28,6 +28,7 @@
#include <map> #include <map>
#include <set> #include <set>
#include <list>
typedef set<HWND> WindowSet; typedef set<HWND> WindowSet;