static UINT WINAPI WatcherThread(_In_opt_ LPVOID lpParam);
};
+class CNotifyToolbar;
+
class CBalloonQueue
{
public:
CAtlList<Info> m_queue;
- CToolbar<InternalIconData> * m_toolbar;
+ CNotifyToolbar * m_toolbar;
InternalIconData * m_current;
bool m_currentClosed;
public:
CBalloonQueue();
- void Init(HWND hwndParent, CToolbar<InternalIconData> * toolbar, CTooltips * balloons);
+ void Init(HWND hwndParent, CNotifyToolbar * toolbar, CTooltips * balloons);
void Deinit();
bool OnTimer(int timerId);
int IndexOf(InternalIconData * pdata);
void SetTimer(int length);
void Show(Info& info);
- void Close(IN OUT InternalIconData * notifyItem);
+ void Close(IN OUT InternalIconData * notifyItem, IN UINT uReason);
};
class CNotifyToolbar :
BOOL UpdateButton(IN CONST NOTIFYICONDATA *iconData);
BOOL RemoveButton(IN CONST NOTIFYICONDATA *iconData);
VOID ResizeImagelist();
+ bool SendNotifyCallback(InternalIconData* notifyItem, UINT uMsg);
private:
VOID SendMouseEvent(IN WORD wIndex, IN UINT uMsg, IN WPARAM wParam);
IconWatcherData *Icon = new IconWatcherData(iconData);
Icon->hProcess = hProcess;
- Icon->ProcessId;
+ Icon->ProcessId = ProcessId;
bool Added = false;
EnterCriticalSection(&m_ListLock);
ASSERT(Size <= MAXIMUM_WAIT_OBJECTS);
if (WatchList)
- delete WatchList;
+ delete[] WatchList;
WatchList = new HANDLE[Size];
WatchList[0] = This->m_WakeUpEvent;
}
if (WatchList)
- delete WatchList;
+ delete[] WatchList;
return 0;
}
{
}
-void CBalloonQueue::Init(HWND hwndParent, CToolbar<InternalIconData> * toolbar, CTooltips * balloons)
+void CBalloonQueue::Init(HWND hwndParent, CNotifyToolbar * toolbar, CTooltips * balloons)
{
m_hwndParent = hwndParent;
m_toolbar = toolbar;
if (m_current && !m_currentClosed)
{
- Close(m_current);
+ Close(m_current, NIN_BALLOONTIMEOUT);
}
else
{
}
else
{
- Close(notifyItem);
+ Close(notifyItem, NIN_BALLOONHIDE);
}
}
void CBalloonQueue::RemoveInfo(InternalIconData * notifyItem)
{
- Close(notifyItem);
+ Close(notifyItem, NIN_BALLOONHIDE);
POSITION position = m_queue.GetHeadPosition();
while(position != NULL)
void CBalloonQueue::CloseCurrent()
{
if (m_current != NULL)
- Close(m_current);
+ {
+ Close(m_current, NIN_BALLOONTIMEOUT);
+ }
}
int CBalloonQueue::IndexOf(InternalIconData * pdata)
if (timeout > MaxTimeout) timeout = MaxTimeout;
SetTimer(timeout);
+
+ m_toolbar->SendNotifyCallback(m_current, NIN_BALLOONSHOW);
}
-void CBalloonQueue::Close(IN OUT InternalIconData * notifyItem)
+void CBalloonQueue::Close(IN OUT InternalIconData * notifyItem, IN UINT uReason)
{
TRACE("HideBalloonTip called\n");
if (m_current == notifyItem && !m_currentClosed)
{
+ m_toolbar->SendNotifyCallback(m_current, uReason);
+
// Prevent Re-entry
m_currentClosed = true;
m_tooltips->TrackDeactivate();
BOOL CNotifyToolbar::AddButton(_In_ CONST NOTIFYICONDATA *iconData)
{
- TBBUTTON tbBtn;
+ TBBUTTON tbBtn = { 0 };
InternalIconData * notifyItem;
WCHAR text[] = L"";
SetButtonSize(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON));
}
-VOID CNotifyToolbar::SendMouseEvent(IN WORD wIndex, IN UINT uMsg, IN WPARAM wParam)
+bool CNotifyToolbar::SendNotifyCallback(InternalIconData* notifyItem, UINT uMsg)
{
- static LPCWSTR eventNames [] = {
- L"WM_MOUSEMOVE",
- L"WM_LBUTTONDOWN",
- L"WM_LBUTTONUP",
- L"WM_LBUTTONDBLCLK",
- L"WM_RBUTTONDOWN",
- L"WM_RBUTTONUP",
- L"WM_RBUTTONDBLCLK",
- L"WM_MBUTTONDOWN",
- L"WM_MBUTTONUP",
- L"WM_MBUTTONDBLCLK",
- L"WM_MOUSEWHEEL",
- L"WM_XBUTTONDOWN",
- L"WM_XBUTTONUP",
- L"WM_XBUTTONDBLCLK"
- };
-
- InternalIconData * notifyItem = GetItemData(wIndex);
-
if (!::IsWindow(notifyItem->hWnd))
{
// We detect and destroy icons with invalid handles only on mouse move over systray, same as MS does.
NMHDR nmh = {GetParent(), 0, NTNWM_REALIGN};
GetParent().SendMessage(WM_NOTIFY, 0, (LPARAM) &nmh);
- return;
- }
-
- if (uMsg >= WM_MOUSEFIRST && uMsg <= WM_MOUSELAST)
- {
- TRACE("Sending message %S from button %d to %p (msg=%x, w=%x, l=%x)...\n",
- eventNames[uMsg - WM_MOUSEFIRST], wIndex,
- notifyItem->hWnd, notifyItem->uCallbackMessage, notifyItem->uID, uMsg);
+ return true;
}
DWORD pid;
(uMsg >= WM_MOUSEFIRST && uMsg <= WM_MOUSELAST))
{
::PostMessage(notifyItem->hWnd,
- notifyItem->uCallbackMessage,
- notifyItem->uID,
- uMsg);
+ notifyItem->uCallbackMessage,
+ notifyItem->uID,
+ uMsg);
}
else
{
notifyItem->uID,
uMsg);
}
+ return false;
+}
+
+VOID CNotifyToolbar::SendMouseEvent(IN WORD wIndex, IN UINT uMsg, IN WPARAM wParam)
+{
+ static LPCWSTR eventNames [] = {
+ L"WM_MOUSEMOVE",
+ L"WM_LBUTTONDOWN",
+ L"WM_LBUTTONUP",
+ L"WM_LBUTTONDBLCLK",
+ L"WM_RBUTTONDOWN",
+ L"WM_RBUTTONUP",
+ L"WM_RBUTTONDBLCLK",
+ L"WM_MBUTTONDOWN",
+ L"WM_MBUTTONUP",
+ L"WM_MBUTTONDBLCLK",
+ L"WM_MOUSEWHEEL",
+ L"WM_XBUTTONDOWN",
+ L"WM_XBUTTONUP",
+ L"WM_XBUTTONDBLCLK"
+ };
+
+ InternalIconData * notifyItem = GetItemData(wIndex);
+
+ if (uMsg >= WM_MOUSEFIRST && uMsg <= WM_MOUSELAST)
+ {
+ TRACE("Sending message %S from button %d to %p (msg=%x, w=%x, l=%x)...\n",
+ eventNames[uMsg - WM_MOUSEFIRST], wIndex,
+ notifyItem->hWnd, notifyItem->uCallbackMessage, notifyItem->uID, uMsg);
+ }
+
+ SendNotifyCallback(notifyItem, uMsg);
}
LRESULT CNotifyToolbar::OnMouseEvent(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
const WCHAR szSysPagerWndClass[] = L"SysPager";
CSysPagerWnd::CSysPagerWnd() {}
+
CSysPagerWnd::~CSysPagerWnd() {}
LRESULT CSysPagerWnd::OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
(void)AddIconToWatcher(iconData);
}
break;
+
case NIM_MODIFY:
ret = Toolbar.UpdateButton(iconData);
break;
+
case NIM_DELETE:
ret = Toolbar.RemoveButton(iconData);
if (ret == TRUE)
(void)RemoveIconFromWatcher(iconData);
}
break;
+
case NIM_SETFOCUS:
Toolbar.SetFocus();
ret = TRUE;
+ break;
+
case NIM_SETVERSION:
ret = Toolbar.SwitchVersion(iconData);
+ break;
+
default:
TRACE("NotifyIcon received with unknown code %d.\n", dwMessage);
return FALSE;