[EXPLORER] Split up the notification area into a few more manageable pieces.
[reactos.git] / base / shell / explorer / syspager.h
1 #pragma once
2
3 struct InternalIconData : NOTIFYICONDATA
4 {
5 // Must keep a separate copy since the original is unioned with uTimeout.
6 UINT uVersionCopy;
7 };
8
9 struct IconWatcherData
10 {
11 HANDLE hProcess;
12 DWORD ProcessId;
13 NOTIFYICONDATA IconData;
14
15 IconWatcherData(NOTIFYICONDATA *iconData) :
16 hProcess(NULL), ProcessId(0)
17 {
18 IconData.cbSize = sizeof(NOTIFYICONDATA);
19 IconData.hWnd = iconData->hWnd;
20 IconData.uID = iconData->uID;
21 IconData.guidItem = iconData->guidItem;
22 }
23
24 ~IconWatcherData()
25 {
26 if (hProcess)
27 {
28 CloseHandle(hProcess);
29 }
30 }
31 };
32
33 class CIconWatcher
34 {
35 CAtlList<IconWatcherData *> m_WatcherList;
36 CRITICAL_SECTION m_ListLock;
37 HANDLE m_hWatcherThread;
38 HANDLE m_WakeUpEvent;
39 HWND m_hwndSysTray;
40 bool m_Loop;
41
42 public:
43 CIconWatcher();
44
45 virtual ~CIconWatcher();
46
47 bool Initialize(_In_ HWND hWndParent);
48 void Uninitialize();
49
50 bool AddIconToWatcher(_In_ NOTIFYICONDATA *iconData);
51 bool RemoveIconFromWatcher(_In_ NOTIFYICONDATA *iconData);
52
53 IconWatcherData* GetListEntry(_In_opt_ NOTIFYICONDATA *iconData, _In_opt_ HANDLE hProcess, _In_ bool Remove);
54
55 private:
56
57 static UINT WINAPI WatcherThread(_In_opt_ LPVOID lpParam);
58 };
59
60 class CBalloonQueue
61 {
62 public:
63 static const int TimerInterval = 2000;
64 static const int BalloonsTimerId = 1;
65 static const int MinTimeout = 10000;
66 static const int MaxTimeout = 30000;
67 static const int CooldownBetweenBalloons = 2000;
68
69 private:
70 struct Info
71 {
72 InternalIconData * pSource;
73 WCHAR szInfo[256];
74 WCHAR szInfoTitle[64];
75 WPARAM uIcon;
76 UINT uTimeout;
77
78 Info(InternalIconData * source)
79 {
80 pSource = source;
81 StrNCpy(szInfo, source->szInfo, _countof(szInfo));
82 StrNCpy(szInfoTitle, source->szInfoTitle, _countof(szInfoTitle));
83 uIcon = source->dwInfoFlags & NIIF_ICON_MASK;
84 if (source->dwInfoFlags == NIIF_USER)
85 uIcon = reinterpret_cast<WPARAM>(source->hIcon);
86 uTimeout = source->uTimeout;
87 }
88 };
89
90 HWND m_hwndParent;
91
92 CTooltips * m_tooltips;
93
94 CAtlList<Info> m_queue;
95
96 CToolbar<InternalIconData> * m_toolbar;
97
98 InternalIconData * m_current;
99 bool m_currentClosed;
100
101 int m_timer;
102
103 public:
104 CBalloonQueue();
105
106 void Init(HWND hwndParent, CToolbar<InternalIconData> * toolbar, CTooltips * balloons);
107 void Deinit();
108
109 bool OnTimer(int timerId);
110 void UpdateInfo(InternalIconData * notifyItem);
111 void RemoveInfo(InternalIconData * notifyItem);
112 void CloseCurrent();
113
114 private:
115
116 int IndexOf(InternalIconData * pdata);
117 void SetTimer(int length);
118 void Show(Info& info);
119 void Close(IN OUT InternalIconData * notifyItem);
120 };
121
122 class CNotifyToolbar :
123 public CWindowImplBaseT< CToolbar<InternalIconData>, CControlWinTraits >
124 {
125 HIMAGELIST m_ImageList;
126 int m_VisibleButtonCount;
127
128 CBalloonQueue * m_BalloonQueue;
129
130 public:
131 CNotifyToolbar();
132 virtual ~CNotifyToolbar();
133
134 int GetVisibleButtonCount();
135 int FindItem(IN HWND hWnd, IN UINT uID, InternalIconData ** pdata);
136 int FindExistingSharedIcon(HICON handle);
137 BOOL AddButton(IN CONST NOTIFYICONDATA *iconData);
138 BOOL SwitchVersion(IN CONST NOTIFYICONDATA *iconData);
139 BOOL UpdateButton(IN CONST NOTIFYICONDATA *iconData);
140 BOOL RemoveButton(IN CONST NOTIFYICONDATA *iconData);
141 VOID ResizeImagelist();
142
143 private:
144 VOID SendMouseEvent(IN WORD wIndex, IN UINT uMsg, IN WPARAM wParam);
145 LRESULT OnMouseEvent(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
146 LRESULT OnTooltipShow(INT uCode, LPNMHDR hdr, BOOL& bHandled);
147
148 public:
149 BEGIN_MSG_MAP(CNotifyToolbar)
150 MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseEvent)
151 NOTIFY_CODE_HANDLER(TTN_SHOW, OnTooltipShow)
152 END_MSG_MAP()
153
154 void Initialize(HWND hWndParent, CBalloonQueue * queue);
155 };
156
157 extern const WCHAR szSysPagerWndClass[];
158
159 class CSysPagerWnd :
160 public CComObjectRootEx<CComMultiThreadModelNoCS>,
161 public CWindowImpl < CSysPagerWnd, CWindow, CControlWinTraits >,
162 public CIconWatcher
163 {
164 CNotifyToolbar Toolbar;
165 CTooltips m_Balloons;
166 CBalloonQueue m_BalloonQueue;
167
168 public:
169 CSysPagerWnd();
170 virtual ~CSysPagerWnd();
171
172 LRESULT DrawBackground(HDC hdc);
173 LRESULT OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
174 LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
175 LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
176 LRESULT OnGetInfoTip(INT uCode, LPNMHDR hdr, BOOL& bHandled);
177 LRESULT OnCustomDraw(INT uCode, LPNMHDR hdr, BOOL& bHandled);
178 LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
179 LRESULT OnCtxMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
180 LRESULT OnBalloonPop(UINT uCode, LPNMHDR hdr, BOOL& bHandled);
181 LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
182
183 public:
184 BOOL NotifyIconCmd(WPARAM wParam, LPARAM lParam);
185 void GetSize(IN BOOL IsHorizontal, IN PSIZE size);
186 void ResizeImagelist();
187
188 DECLARE_WND_CLASS_EX(szSysPagerWndClass, CS_DBLCLKS, COLOR_3DFACE)
189
190 BEGIN_MSG_MAP(CSysPagerWnd)
191 MESSAGE_HANDLER(WM_CREATE, OnCreate)
192 MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
193 MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
194 MESSAGE_HANDLER(WM_SIZE, OnSize)
195 MESSAGE_HANDLER(WM_CONTEXTMENU, OnCtxMenu)
196 MESSAGE_HANDLER(WM_TIMER, OnTimer)
197 NOTIFY_CODE_HANDLER(TTN_POP, OnBalloonPop)
198 NOTIFY_CODE_HANDLER(TBN_GETINFOTIPW, OnGetInfoTip)
199 NOTIFY_CODE_HANDLER(NM_CUSTOMDRAW, OnCustomDraw)
200 END_MSG_MAP()
201
202 HWND _Init(IN HWND hWndParent, IN BOOL bVisible);
203 };