Implemented tray notification callback messages

svn path=/trunk/; revision=5747
This commit is contained in:
Martin Fuchs
2003-08-22 12:41:24 +00:00
parent da38f35c6c
commit 942ea1645e
6 changed files with 99 additions and 38 deletions
@@ -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:
-2
View File
@@ -38,8 +38,6 @@ extern struct ExplorerGlobals
bool _desktop_mode;
} g_Globals;
extern UINT PM_DESKTOP_GOT_FOCUS;
struct ResString : public String
{
@@ -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<NotifyArea*>(Window::get_window(_hwndNotify));
if (notify_area)
@@ -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);
}
@@ -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<NotifyInfo&>(*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<NotifyInfo&>(*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<x+16)
break;
x += 20;
}
}
return it;
}
ClockWindow::ClockWindow(HWND hwnd)
: super(hwnd)
{
@@ -45,21 +45,25 @@ struct NotifyIconIndex
HWND _hWnd;
UINT _uID;
protected:
NotifyIconIndex();
};
struct NotifyInfo
struct NotifyInfo : public NotifyIconIndex
{
NotifyInfo();
// sort operator
friend bool operator<(const NotifyInfo& a, const NotifyInfo& b)
{return a._idx<b._idx;}
{return a._idx < b._idx;}
NotifyInfo& operator=(NOTIFYICONDATA* pnid);
int _idx; // display index
HICON _hIcon;
DWORD _dwState;
UINT _uCallbackMessage;
};
typedef map<NotifyIconIndex, NotifyInfo> NotifyIconMap;
@@ -89,6 +93,8 @@ protected:
void Refresh();
void Paint();
NotifyIconSet::iterator IconHitTest(const POINT& pos);
};