xref: /reactos/base/shell/explorer/trayntfy.cpp (revision 70d7009a)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  * ReactOS Explorer
3c2c66affSColin Finck  *
4c2c66affSColin Finck  * Copyright 2006 - 2007 Thomas Weidenmueller <w3seek@reactos.org>
5d66c6890Sgedmurphy  * Copyright 2018 Ged Murphy <gedmurphy@reactos.org>
6c2c66affSColin Finck  *
7c2c66affSColin Finck  * This library is free software; you can redistribute it and/or
8c2c66affSColin Finck  * modify it under the terms of the GNU Lesser General Public
9c2c66affSColin Finck  * License as published by the Free Software Foundation; either
10c2c66affSColin Finck  * version 2.1 of the License, or (at your option) any later version.
11c2c66affSColin Finck  *
12c2c66affSColin Finck  * This library is distributed in the hope that it will be useful,
13c2c66affSColin Finck  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14c2c66affSColin Finck  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15c2c66affSColin Finck  * Lesser General Public License for more details.
16c2c66affSColin Finck  *
17c2c66affSColin Finck  * You should have received a copy of the GNU Lesser General Public
18c2c66affSColin Finck  * License along with this library; if not, write to the Free Software
19c2c66affSColin Finck  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20c2c66affSColin Finck  */
21c2c66affSColin Finck 
22c2c66affSColin Finck #include "precomp.h"
23*70d7009aSEthan Rodensky #include <commoncontrols.h>
24c2c66affSColin Finck 
25a7ddabccSHermès Bélusca-Maïto static const WCHAR szTrayNotifyWndClass[] = L"TrayNotifyWnd";
26c2c66affSColin Finck 
27d11e7af5SGiannis Adamopoulos #define TRAY_NOTIFY_WND_SPACING_X   1
28c2c66affSColin Finck #define TRAY_NOTIFY_WND_SPACING_Y   1
29*70d7009aSEthan Rodensky #define CLOCK_TEXT_HACK             4
30*70d7009aSEthan Rodensky 
31*70d7009aSEthan Rodensky /*
32*70d7009aSEthan Rodensky  * TrayNotifyWnd
33*70d7009aSEthan Rodensky  */
34c2c66affSColin Finck 
35c2c66affSColin Finck class CTrayNotifyWnd :
36455bce68SGiannis Adamopoulos     public CComCoClass<CTrayNotifyWnd>,
37c2c66affSColin Finck     public CComObjectRootEx<CComMultiThreadModelNoCS>,
38455bce68SGiannis Adamopoulos     public CWindowImpl < CTrayNotifyWnd, CWindow, CControlWinTraits >,
39455bce68SGiannis Adamopoulos     public IOleWindow
40c2c66affSColin Finck {
41455bce68SGiannis Adamopoulos     CComPtr<IUnknown> m_clock;
42*70d7009aSEthan Rodensky     CTrayShowDesktopButton m_ShowDesktopButton;
43455bce68SGiannis Adamopoulos     CComPtr<IUnknown> m_pager;
44455bce68SGiannis Adamopoulos 
45455bce68SGiannis Adamopoulos     HWND m_hwndClock;
46*70d7009aSEthan Rodensky     HWND m_hwndShowDesktop;
47455bce68SGiannis Adamopoulos     HWND m_hwndPager;
48c2c66affSColin Finck 
49c2c66affSColin Finck     HTHEME TrayTheme;
50*70d7009aSEthan Rodensky     SIZE trayClockMinSize;
51*70d7009aSEthan Rodensky     SIZE trayShowDesktopSize;
52*70d7009aSEthan Rodensky     SIZE trayNotifySize;
53c2c66affSColin Finck     MARGINS ContentMargin;
542ed535daSGiannis Adamopoulos     BOOL IsHorizontal;
55c2c66affSColin Finck 
56c2c66affSColin Finck public:
CTrayNotifyWnd()57c2c66affSColin Finck     CTrayNotifyWnd() :
58455bce68SGiannis Adamopoulos         m_hwndClock(NULL),
59455bce68SGiannis Adamopoulos         m_hwndPager(NULL),
60c2c66affSColin Finck         TrayTheme(NULL),
612ed535daSGiannis Adamopoulos         IsHorizontal(FALSE)
62c2c66affSColin Finck     {
63*70d7009aSEthan Rodensky         ZeroMemory(&trayClockMinSize, sizeof(trayClockMinSize));
64*70d7009aSEthan Rodensky         ZeroMemory(&trayShowDesktopSize, sizeof(trayShowDesktopSize));
65*70d7009aSEthan Rodensky         ZeroMemory(&trayNotifySize, sizeof(trayNotifySize));
66c2c66affSColin Finck         ZeroMemory(&ContentMargin, sizeof(ContentMargin));
67c2c66affSColin Finck     }
~CTrayNotifyWnd()68*70d7009aSEthan Rodensky     ~CTrayNotifyWnd() { }
69c2c66affSColin Finck 
OnThemeChanged()70c2c66affSColin Finck     LRESULT OnThemeChanged()
71c2c66affSColin Finck     {
72c2c66affSColin Finck         if (TrayTheme)
73c2c66affSColin Finck             CloseThemeData(TrayTheme);
74c2c66affSColin Finck 
75c2c66affSColin Finck         if (IsThemeActive())
76c2c66affSColin Finck             TrayTheme = OpenThemeData(m_hWnd, L"TrayNotify");
77c2c66affSColin Finck         else
78c2c66affSColin Finck             TrayTheme = NULL;
79c2c66affSColin Finck 
80c2c66affSColin Finck         if (TrayTheme)
81c2c66affSColin Finck         {
82c2c66affSColin Finck             SetWindowExStyle(m_hWnd, WS_EX_STATICEDGE, 0);
83c2c66affSColin Finck 
84c2c66affSColin Finck             GetThemeMargins(TrayTheme,
85c2c66affSColin Finck                 NULL,
86c2c66affSColin Finck                 TNP_BACKGROUND,
87c2c66affSColin Finck                 0,
88c2c66affSColin Finck                 TMT_CONTENTMARGINS,
89c2c66affSColin Finck                 NULL,
90c2c66affSColin Finck                 &ContentMargin);
91c2c66affSColin Finck         }
92c2c66affSColin Finck         else
93c2c66affSColin Finck         {
94c2c66affSColin Finck             SetWindowExStyle(m_hWnd, WS_EX_STATICEDGE, WS_EX_STATICEDGE);
95c2c66affSColin Finck 
96c2c66affSColin Finck             ContentMargin.cxLeftWidth = 2;
97c2c66affSColin Finck             ContentMargin.cxRightWidth = 2;
98c2c66affSColin Finck             ContentMargin.cyTopHeight = 2;
99c2c66affSColin Finck             ContentMargin.cyBottomHeight = 2;
100c2c66affSColin Finck         }
101c2c66affSColin Finck 
102c2c66affSColin Finck         return TRUE;
103c2c66affSColin Finck     }
104c2c66affSColin Finck 
OnThemeChanged(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)105c2c66affSColin Finck     LRESULT OnThemeChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
106c2c66affSColin Finck     {
107c2c66affSColin Finck         return OnThemeChanged();
108c2c66affSColin Finck     }
109c2c66affSColin Finck 
OnCreate(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)110c2c66affSColin Finck     LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
111c2c66affSColin Finck     {
112455bce68SGiannis Adamopoulos         HRESULT hr;
113c2c66affSColin Finck 
114455bce68SGiannis Adamopoulos         hr = CTrayClockWnd_CreateInstance(m_hWnd, IID_PPV_ARG(IUnknown, &m_clock));
115455bce68SGiannis Adamopoulos         if (FAILED_UNEXPECTEDLY(hr))
116455bce68SGiannis Adamopoulos             return FALSE;
117455bce68SGiannis Adamopoulos 
118455bce68SGiannis Adamopoulos         hr = IUnknown_GetWindow(m_clock, &m_hwndClock);
119455bce68SGiannis Adamopoulos         if (FAILED_UNEXPECTEDLY(hr))
120455bce68SGiannis Adamopoulos             return FALSE;
121455bce68SGiannis Adamopoulos 
122455bce68SGiannis Adamopoulos         hr = CSysPagerWnd_CreateInstance(m_hWnd, IID_PPV_ARG(IUnknown, &m_pager));
123455bce68SGiannis Adamopoulos         if (FAILED_UNEXPECTEDLY(hr))
124455bce68SGiannis Adamopoulos             return FALSE;
125455bce68SGiannis Adamopoulos 
126455bce68SGiannis Adamopoulos         hr = IUnknown_GetWindow(m_pager, &m_hwndPager);
127455bce68SGiannis Adamopoulos         if (FAILED_UNEXPECTEDLY(hr))
128455bce68SGiannis Adamopoulos             return FALSE;
129c2c66affSColin Finck 
130*70d7009aSEthan Rodensky         /* Create the 'Show Desktop' button */
131*70d7009aSEthan Rodensky         m_ShowDesktopButton.DoCreate(m_hWnd);
132*70d7009aSEthan Rodensky         m_hwndShowDesktop = m_ShowDesktopButton.m_hWnd;
133*70d7009aSEthan Rodensky 
134c2c66affSColin Finck         return TRUE;
135c2c66affSColin Finck     }
136c2c66affSColin Finck 
GetMinimumSize(IN OUT PSIZE pSize)137c2c66affSColin Finck     BOOL GetMinimumSize(IN OUT PSIZE pSize)
138c2c66affSColin Finck     {
139*70d7009aSEthan Rodensky         SIZE clockSize = { 0, 0 };
140*70d7009aSEthan Rodensky         SIZE traySize = { 0, 0 };
141*70d7009aSEthan Rodensky         SIZE showDesktopSize = { 0, 0 };
142c2c66affSColin Finck 
1432ed535daSGiannis Adamopoulos         if (!g_TaskbarSettings.sr.HideClock)
144c2c66affSColin Finck         {
145c2c66affSColin Finck             if (IsHorizontal)
146c2c66affSColin Finck             {
147*70d7009aSEthan Rodensky                 clockSize.cy = pSize->cy;
148*70d7009aSEthan Rodensky                 if (clockSize.cy <= 0)
149c2c66affSColin Finck                     goto NoClock;
150c2c66affSColin Finck             }
151c2c66affSColin Finck             else
152c2c66affSColin Finck             {
153*70d7009aSEthan Rodensky                 clockSize.cx = pSize->cx;
154*70d7009aSEthan Rodensky                 if (clockSize.cx <= 0)
155c2c66affSColin Finck                     goto NoClock;
156c2c66affSColin Finck             }
157c2c66affSColin Finck 
158*70d7009aSEthan Rodensky             ::SendMessage(m_hwndClock, TNWM_GETMINIMUMSIZE, (WPARAM) IsHorizontal, (LPARAM) &clockSize);
159c2c66affSColin Finck 
160*70d7009aSEthan Rodensky             trayClockMinSize = clockSize;
161c2c66affSColin Finck         }
162c2c66affSColin Finck         else
163c2c66affSColin Finck         NoClock:
164*70d7009aSEthan Rodensky         trayClockMinSize = clockSize;
165c2c66affSColin Finck 
166c2c66affSColin Finck         if (IsHorizontal)
167c2c66affSColin Finck         {
168*70d7009aSEthan Rodensky             traySize.cy = pSize->cy - 2 * TRAY_NOTIFY_WND_SPACING_Y;
169c2c66affSColin Finck         }
170c2c66affSColin Finck         else
171c2c66affSColin Finck         {
172*70d7009aSEthan Rodensky             traySize.cx = pSize->cx - 2 * TRAY_NOTIFY_WND_SPACING_X;
173c2c66affSColin Finck         }
174c2c66affSColin Finck 
175*70d7009aSEthan Rodensky         ::SendMessage(m_hwndPager, TNWM_GETMINIMUMSIZE, (WPARAM) IsHorizontal, (LPARAM) &traySize);
176c2c66affSColin Finck 
177*70d7009aSEthan Rodensky         trayNotifySize = traySize;
178*70d7009aSEthan Rodensky 
179*70d7009aSEthan Rodensky         INT showDesktopButtonExtent = 0;
180*70d7009aSEthan Rodensky         if (g_TaskbarSettings.bShowDesktopButton)
181*70d7009aSEthan Rodensky         {
182*70d7009aSEthan Rodensky             showDesktopButtonExtent = m_ShowDesktopButton.WidthOrHeight();
183*70d7009aSEthan Rodensky             if (IsHorizontal)
184*70d7009aSEthan Rodensky             {
185*70d7009aSEthan Rodensky                 showDesktopSize.cx = showDesktopButtonExtent;
186*70d7009aSEthan Rodensky                 showDesktopSize.cy = pSize->cy;
187*70d7009aSEthan Rodensky             }
188*70d7009aSEthan Rodensky             else
189*70d7009aSEthan Rodensky             {
190*70d7009aSEthan Rodensky                 showDesktopSize.cx = pSize->cx;
191*70d7009aSEthan Rodensky                 showDesktopSize.cy = showDesktopButtonExtent;
192*70d7009aSEthan Rodensky             }
193*70d7009aSEthan Rodensky         }
194*70d7009aSEthan Rodensky         trayShowDesktopSize = showDesktopSize;
195c2c66affSColin Finck 
196c2c66affSColin Finck         if (IsHorizontal)
197c2c66affSColin Finck         {
198c2c66affSColin Finck             pSize->cx = 2 * TRAY_NOTIFY_WND_SPACING_X;
199c2c66affSColin Finck 
2002ed535daSGiannis Adamopoulos             if (!g_TaskbarSettings.sr.HideClock)
201*70d7009aSEthan Rodensky                 pSize->cx += TRAY_NOTIFY_WND_SPACING_X + trayClockMinSize.cx;
202c2c66affSColin Finck 
203*70d7009aSEthan Rodensky             if (g_TaskbarSettings.bShowDesktopButton)
204*70d7009aSEthan Rodensky                 pSize->cx += showDesktopButtonExtent;
205*70d7009aSEthan Rodensky 
206*70d7009aSEthan Rodensky             pSize->cx += traySize.cx;
20785d7dd4fSGiannis Adamopoulos             pSize->cx += ContentMargin.cxLeftWidth + ContentMargin.cxRightWidth;
208c2c66affSColin Finck         }
209c2c66affSColin Finck         else
210c2c66affSColin Finck         {
211c2c66affSColin Finck             pSize->cy = 2 * TRAY_NOTIFY_WND_SPACING_Y;
212c2c66affSColin Finck 
2132ed535daSGiannis Adamopoulos             if (!g_TaskbarSettings.sr.HideClock)
214*70d7009aSEthan Rodensky                 pSize->cy += TRAY_NOTIFY_WND_SPACING_Y + trayClockMinSize.cy;
215c2c66affSColin Finck 
216*70d7009aSEthan Rodensky             if (g_TaskbarSettings.bShowDesktopButton)
217*70d7009aSEthan Rodensky                 pSize->cy += showDesktopButtonExtent;
218*70d7009aSEthan Rodensky 
219*70d7009aSEthan Rodensky             pSize->cy += traySize.cy;
220c2c66affSColin Finck             pSize->cy += ContentMargin.cyTopHeight + ContentMargin.cyBottomHeight;
22185d7dd4fSGiannis Adamopoulos         }
222c2c66affSColin Finck 
223c2c66affSColin Finck         return TRUE;
224c2c66affSColin Finck     }
225c2c66affSColin Finck 
Size(IN OUT SIZE * pszClient)226*70d7009aSEthan Rodensky     VOID Size(IN OUT SIZE *pszClient)
227c2c66affSColin Finck     {
228*70d7009aSEthan Rodensky         RECT rcClient = {0, 0, pszClient->cx, pszClient->cy};
229*70d7009aSEthan Rodensky         AlignControls(&rcClient);
230*70d7009aSEthan Rodensky         pszClient->cx = rcClient.right - rcClient.left;
231*70d7009aSEthan Rodensky         pszClient->cy = rcClient.bottom - rcClient.top;
232*70d7009aSEthan Rodensky     }
233c2c66affSColin Finck 
AlignControls(IN CONST PRECT prcClient OPTIONAL)234*70d7009aSEthan Rodensky     VOID AlignControls(IN CONST PRECT prcClient OPTIONAL)
235*70d7009aSEthan Rodensky     {
236*70d7009aSEthan Rodensky         RECT rcClient;
237*70d7009aSEthan Rodensky         if (prcClient != NULL)
238*70d7009aSEthan Rodensky             rcClient = *prcClient;
239*70d7009aSEthan Rodensky         else
240*70d7009aSEthan Rodensky             GetClientRect(&rcClient);
241*70d7009aSEthan Rodensky 
242*70d7009aSEthan Rodensky         rcClient.left += ContentMargin.cxLeftWidth;
243*70d7009aSEthan Rodensky         rcClient.top += ContentMargin.cyTopHeight;
244*70d7009aSEthan Rodensky         rcClient.right -= ContentMargin.cxRightWidth;
245*70d7009aSEthan Rodensky         rcClient.bottom -= ContentMargin.cyBottomHeight;
246*70d7009aSEthan Rodensky 
247*70d7009aSEthan Rodensky         CONST UINT swpFlags = SWP_DRAWFRAME | SWP_NOCOPYBITS | SWP_NOZORDER;
248*70d7009aSEthan Rodensky 
249*70d7009aSEthan Rodensky         if (g_TaskbarSettings.bShowDesktopButton)
250*70d7009aSEthan Rodensky         {
251*70d7009aSEthan Rodensky             POINT ptShowDesktop =
252*70d7009aSEthan Rodensky             {
253*70d7009aSEthan Rodensky                 rcClient.left,
254*70d7009aSEthan Rodensky                 rcClient.top
255*70d7009aSEthan Rodensky             };
256*70d7009aSEthan Rodensky             SIZE showDesktopSize =
257*70d7009aSEthan Rodensky             {
258*70d7009aSEthan Rodensky                 rcClient.right - rcClient.left,
259*70d7009aSEthan Rodensky                 rcClient.bottom - rcClient.top
260*70d7009aSEthan Rodensky             };
261*70d7009aSEthan Rodensky 
262*70d7009aSEthan Rodensky             INT cxyShowDesktop = m_ShowDesktopButton.WidthOrHeight();
263c2c66affSColin Finck             if (IsHorizontal)
264c2c66affSColin Finck             {
265*70d7009aSEthan Rodensky                 if (!TrayTheme)
266*70d7009aSEthan Rodensky                 {
267*70d7009aSEthan Rodensky                     ptShowDesktop.y -= ContentMargin.cyTopHeight;
268*70d7009aSEthan Rodensky                     showDesktopSize.cy += ContentMargin.cyTopHeight + ContentMargin.cyBottomHeight;
269*70d7009aSEthan Rodensky                 }
270*70d7009aSEthan Rodensky 
271*70d7009aSEthan Rodensky                 rcClient.right -= (cxyShowDesktop - ContentMargin.cxRightWidth);
272*70d7009aSEthan Rodensky 
273*70d7009aSEthan Rodensky                 ptShowDesktop.x = rcClient.right;
274*70d7009aSEthan Rodensky                 showDesktopSize.cx = cxyShowDesktop;
275*70d7009aSEthan Rodensky 
276*70d7009aSEthan Rodensky                 // HACK: Clock has layout problems - remove this once addressed.
277*70d7009aSEthan Rodensky                 rcClient.right -= CLOCK_TEXT_HACK;
278c2c66affSColin Finck             }
279c2c66affSColin Finck             else
280c2c66affSColin Finck             {
281*70d7009aSEthan Rodensky                 if (!TrayTheme)
282*70d7009aSEthan Rodensky                 {
283*70d7009aSEthan Rodensky                     ptShowDesktop.x -= ContentMargin.cxLeftWidth;
284*70d7009aSEthan Rodensky                     showDesktopSize.cx += ContentMargin.cxLeftWidth + ContentMargin.cxRightWidth;
285*70d7009aSEthan Rodensky                 }
286*70d7009aSEthan Rodensky 
287*70d7009aSEthan Rodensky                 rcClient.bottom -= (cxyShowDesktop - ContentMargin.cyBottomHeight);
288*70d7009aSEthan Rodensky 
289*70d7009aSEthan Rodensky                 ptShowDesktop.y = rcClient.bottom;
290*70d7009aSEthan Rodensky                 showDesktopSize.cy = cxyShowDesktop;
291*70d7009aSEthan Rodensky 
292*70d7009aSEthan Rodensky                 // HACK: Clock has layout problems - remove this once addressed.
293*70d7009aSEthan Rodensky                 rcClient.bottom -= CLOCK_TEXT_HACK;
294*70d7009aSEthan Rodensky             }
295*70d7009aSEthan Rodensky 
296*70d7009aSEthan Rodensky             /* Resize and reposition the button */
297*70d7009aSEthan Rodensky             ::SetWindowPos(m_hwndShowDesktop,
298*70d7009aSEthan Rodensky                 NULL,
299*70d7009aSEthan Rodensky                 ptShowDesktop.x,
300*70d7009aSEthan Rodensky                 ptShowDesktop.y,
301*70d7009aSEthan Rodensky                 showDesktopSize.cx,
302*70d7009aSEthan Rodensky                 showDesktopSize.cy,
303*70d7009aSEthan Rodensky                 swpFlags);
304*70d7009aSEthan Rodensky         }
305*70d7009aSEthan Rodensky 
306*70d7009aSEthan Rodensky         if (!g_TaskbarSettings.sr.HideClock)
307*70d7009aSEthan Rodensky         {
308*70d7009aSEthan Rodensky             POINT ptClock = { rcClient.left, rcClient.top };
309*70d7009aSEthan Rodensky             SIZE clockSize = { rcClient.right - rcClient.left, rcClient.bottom - rcClient.top };
310*70d7009aSEthan Rodensky 
311*70d7009aSEthan Rodensky             if (IsHorizontal)
312*70d7009aSEthan Rodensky             {
313*70d7009aSEthan Rodensky                 rcClient.right -= trayClockMinSize.cx;
314*70d7009aSEthan Rodensky 
315*70d7009aSEthan Rodensky                 ptClock.x = rcClient.right;
316*70d7009aSEthan Rodensky                 clockSize.cx = trayClockMinSize.cx;
317*70d7009aSEthan Rodensky             }
318*70d7009aSEthan Rodensky             else
319*70d7009aSEthan Rodensky             {
320*70d7009aSEthan Rodensky                 rcClient.bottom -= trayClockMinSize.cy;
321*70d7009aSEthan Rodensky 
322*70d7009aSEthan Rodensky                 ptClock.y = rcClient.bottom;
323*70d7009aSEthan Rodensky                 clockSize.cy = trayClockMinSize.cy;
324c2c66affSColin Finck             }
325c2c66affSColin Finck 
326455bce68SGiannis Adamopoulos             ::SetWindowPos(m_hwndClock,
327c2c66affSColin Finck                 NULL,
328c2c66affSColin Finck                 ptClock.x,
329c2c66affSColin Finck                 ptClock.y,
330*70d7009aSEthan Rodensky                 clockSize.cx,
331*70d7009aSEthan Rodensky                 clockSize.cy,
332*70d7009aSEthan Rodensky                 swpFlags);
333488477d1SGiannis Adamopoulos         }
334c2c66affSColin Finck 
335c2c66affSColin Finck         POINT ptPager;
336c2c66affSColin Finck         if (IsHorizontal)
337c2c66affSColin Finck         {
338c2c66affSColin Finck             ptPager.x = ContentMargin.cxLeftWidth;
339*70d7009aSEthan Rodensky             ptPager.y = ((rcClient.bottom - rcClient.top) - trayNotifySize.cy) / 2;
340*70d7009aSEthan Rodensky             if (g_TaskbarSettings.UseCompactTrayIcons())
341*70d7009aSEthan Rodensky                 ptPager.y += ContentMargin.cyTopHeight;
342c2c66affSColin Finck         }
343c2c66affSColin Finck         else
344c2c66affSColin Finck         {
345*70d7009aSEthan Rodensky             ptPager.x = ((rcClient.right - rcClient.left) - trayNotifySize.cx) / 2;
346*70d7009aSEthan Rodensky             if (g_TaskbarSettings.UseCompactTrayIcons())
347*70d7009aSEthan Rodensky                 ptPager.x += ContentMargin.cxLeftWidth;
348c2c66affSColin Finck             ptPager.y = ContentMargin.cyTopHeight;
349c2c66affSColin Finck         }
350c2c66affSColin Finck 
351455bce68SGiannis Adamopoulos         ::SetWindowPos(m_hwndPager,
352c2c66affSColin Finck             NULL,
353c2c66affSColin Finck             ptPager.x,
354c2c66affSColin Finck             ptPager.y,
355*70d7009aSEthan Rodensky             trayNotifySize.cx,
356*70d7009aSEthan Rodensky             trayNotifySize.cy,
357*70d7009aSEthan Rodensky             swpFlags);
358*70d7009aSEthan Rodensky 
359*70d7009aSEthan Rodensky         if (prcClient != NULL)
360*70d7009aSEthan Rodensky         {
361*70d7009aSEthan Rodensky             prcClient->left = rcClient.left - ContentMargin.cxLeftWidth;
362*70d7009aSEthan Rodensky             prcClient->top = rcClient.top - ContentMargin.cyTopHeight;
363*70d7009aSEthan Rodensky             prcClient->right = rcClient.right + ContentMargin.cxRightWidth;
364*70d7009aSEthan Rodensky             prcClient->bottom = rcClient.bottom + ContentMargin.cyBottomHeight;
365*70d7009aSEthan Rodensky         }
366c2c66affSColin Finck     }
367c2c66affSColin Finck 
OnEraseBackground(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)368c2c66affSColin Finck     LRESULT OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
369c2c66affSColin Finck     {
370c2c66affSColin Finck         HDC hdc = (HDC) wParam;
371c2c66affSColin Finck 
372c2c66affSColin Finck         if (!TrayTheme)
373c2c66affSColin Finck         {
374c2c66affSColin Finck             bHandled = FALSE;
375c2c66affSColin Finck             return 0;
376c2c66affSColin Finck         }
377c2c66affSColin Finck 
3787f35908aSGiannis Adamopoulos         RECT rect;
3797f35908aSGiannis Adamopoulos         GetClientRect(&rect);
3807f35908aSGiannis Adamopoulos         if (IsThemeBackgroundPartiallyTransparent(TrayTheme, TNP_BACKGROUND, 0))
3817f35908aSGiannis Adamopoulos             DrawThemeParentBackground(m_hWnd, hdc, &rect);
382c2c66affSColin Finck 
3837f35908aSGiannis Adamopoulos         DrawThemeBackground(TrayTheme, hdc, TNP_BACKGROUND, 0, &rect, 0);
384c2c66affSColin Finck 
385c2c66affSColin Finck         return TRUE;
386c2c66affSColin Finck     }
387c2c66affSColin Finck 
OnGetMinimumSize(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)388c2c66affSColin Finck     LRESULT OnGetMinimumSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
389c2c66affSColin Finck     {
390c2c66affSColin Finck         BOOL Horizontal = (BOOL) wParam;
391c2c66affSColin Finck 
392c2c66affSColin Finck         if (Horizontal != IsHorizontal)
393c2c66affSColin Finck             IsHorizontal = Horizontal;
394*70d7009aSEthan Rodensky 
395*70d7009aSEthan Rodensky         SetWindowTheme(m_hWnd,
396*70d7009aSEthan Rodensky                        IsHorizontal ? L"TrayNotifyHoriz" : L"TrayNotifyVert",
397*70d7009aSEthan Rodensky                        NULL);
398*70d7009aSEthan Rodensky         m_ShowDesktopButton.m_bHorizontal = Horizontal;
399c2c66affSColin Finck 
400c2c66affSColin Finck         return (LRESULT)GetMinimumSize((PSIZE)lParam);
401c2c66affSColin Finck     }
402c2c66affSColin Finck 
OnGetShowDesktopButton(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)403*70d7009aSEthan Rodensky     LRESULT OnGetShowDesktopButton(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
404*70d7009aSEthan Rodensky     {
405*70d7009aSEthan Rodensky         if (wParam == NULL)
406*70d7009aSEthan Rodensky             return 0;
407*70d7009aSEthan Rodensky 
408*70d7009aSEthan Rodensky         CTrayShowDesktopButton** ptr = (CTrayShowDesktopButton**)wParam;
409*70d7009aSEthan Rodensky         if (!m_ShowDesktopButton)
410*70d7009aSEthan Rodensky         {
411*70d7009aSEthan Rodensky             *ptr = NULL;
412*70d7009aSEthan Rodensky             return 0;
413*70d7009aSEthan Rodensky         }
414*70d7009aSEthan Rodensky 
415*70d7009aSEthan Rodensky         *ptr = &m_ShowDesktopButton;
416*70d7009aSEthan Rodensky         bHandled = TRUE;
417*70d7009aSEthan Rodensky         return 0;
418*70d7009aSEthan Rodensky     }
419*70d7009aSEthan Rodensky 
OnSize(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)420c2c66affSColin Finck     LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
421c2c66affSColin Finck     {
422*70d7009aSEthan Rodensky         SIZE clientSize;
423c2c66affSColin Finck 
424*70d7009aSEthan Rodensky         clientSize.cx = LOWORD(lParam);
425*70d7009aSEthan Rodensky         clientSize.cy = HIWORD(lParam);
426c2c66affSColin Finck 
427*70d7009aSEthan Rodensky         Size(&clientSize);
428c2c66affSColin Finck 
429c2c66affSColin Finck         return TRUE;
430c2c66affSColin Finck     }
431c2c66affSColin Finck 
OnNcHitTest(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)432c2c66affSColin Finck     LRESULT OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
433c2c66affSColin Finck     {
434*70d7009aSEthan Rodensky         POINT pt;
435*70d7009aSEthan Rodensky         pt.x = GET_X_LPARAM(lParam);
436*70d7009aSEthan Rodensky         pt.y = GET_Y_LPARAM(lParam);
437*70d7009aSEthan Rodensky 
438*70d7009aSEthan Rodensky         if (m_ShowDesktopButton && m_ShowDesktopButton.PtInButton(&pt))
439*70d7009aSEthan Rodensky             return HTCLIENT;
440*70d7009aSEthan Rodensky 
441c2c66affSColin Finck         return HTTRANSPARENT;
442c2c66affSColin Finck     }
443c2c66affSColin Finck 
OnMouseMove(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)444*70d7009aSEthan Rodensky     LRESULT OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
445*70d7009aSEthan Rodensky     {
446*70d7009aSEthan Rodensky         POINT pt;
447*70d7009aSEthan Rodensky         ::GetCursorPos(&pt);
448*70d7009aSEthan Rodensky 
449*70d7009aSEthan Rodensky         if (m_ShowDesktopButton && m_ShowDesktopButton.PtInButton(&pt))
450*70d7009aSEthan Rodensky             m_ShowDesktopButton.StartHovering();
451*70d7009aSEthan Rodensky 
452*70d7009aSEthan Rodensky         return TRUE;
453*70d7009aSEthan Rodensky     }
454*70d7009aSEthan Rodensky 
OnCtxMenu(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)455c2c66affSColin Finck     LRESULT OnCtxMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
456c2c66affSColin Finck     {
457c2c66affSColin Finck         bHandled = TRUE;
4583fee5d0eSBrock Mammen 
4593fee5d0eSBrock Mammen         if (reinterpret_cast<HWND>(wParam) == m_hwndClock)
4603fee5d0eSBrock Mammen             return GetParent().SendMessage(uMsg, wParam, lParam);
4613fee5d0eSBrock Mammen         else
462c2c66affSColin Finck             return 0;
463c2c66affSColin Finck     }
464c2c66affSColin Finck 
OnClockMessage(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)4657f35908aSGiannis Adamopoulos     LRESULT OnClockMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
466c2c66affSColin Finck     {
467455bce68SGiannis Adamopoulos         return SendMessageW(m_hwndClock, uMsg, wParam, lParam);
468c2c66affSColin Finck     }
4697f35908aSGiannis Adamopoulos 
OnTaskbarSettingsChanged(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)470*70d7009aSEthan Rodensky     LRESULT OnTaskbarSettingsChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
471*70d7009aSEthan Rodensky     {
472*70d7009aSEthan Rodensky         TaskbarSettings* newSettings = (TaskbarSettings*)lParam;
473*70d7009aSEthan Rodensky 
474*70d7009aSEthan Rodensky         /* Toggle show desktop button */
475*70d7009aSEthan Rodensky         if (newSettings->bShowDesktopButton != g_TaskbarSettings.bShowDesktopButton)
476*70d7009aSEthan Rodensky         {
477*70d7009aSEthan Rodensky             g_TaskbarSettings.bShowDesktopButton = newSettings->bShowDesktopButton;
478*70d7009aSEthan Rodensky             ::ShowWindow(m_hwndShowDesktop, g_TaskbarSettings.bShowDesktopButton ? SW_SHOW : SW_HIDE);
479*70d7009aSEthan Rodensky 
480*70d7009aSEthan Rodensky             /* Ask the parent to resize */
481*70d7009aSEthan Rodensky             NMHDR nmh = {m_hWnd, 0, NTNWM_REALIGN};
482*70d7009aSEthan Rodensky             SendMessage(WM_NOTIFY, 0, (LPARAM) &nmh);
483*70d7009aSEthan Rodensky         }
484*70d7009aSEthan Rodensky 
485*70d7009aSEthan Rodensky         return OnClockMessage(uMsg, wParam, lParam, bHandled);
486*70d7009aSEthan Rodensky     }
487*70d7009aSEthan Rodensky 
OnPagerMessage(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)4887f35908aSGiannis Adamopoulos     LRESULT OnPagerMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
4897f35908aSGiannis Adamopoulos     {
490455bce68SGiannis Adamopoulos         return SendMessageW(m_hwndPager, uMsg, wParam, lParam);
4917f35908aSGiannis Adamopoulos     }
4927f35908aSGiannis Adamopoulos 
OnRealign(INT uCode,LPNMHDR hdr,BOOL & bHandled)4937f35908aSGiannis Adamopoulos     LRESULT OnRealign(INT uCode, LPNMHDR hdr, BOOL& bHandled)
4947f35908aSGiannis Adamopoulos     {
4957f35908aSGiannis Adamopoulos         hdr->hwndFrom = m_hWnd;
4967f35908aSGiannis Adamopoulos         return GetParent().SendMessage(WM_NOTIFY, 0, (LPARAM)hdr);
497c2c66affSColin Finck     }
498c2c66affSColin Finck 
GetWindow(HWND * phwnd)499455bce68SGiannis Adamopoulos     HRESULT WINAPI GetWindow(HWND* phwnd)
500455bce68SGiannis Adamopoulos     {
501455bce68SGiannis Adamopoulos         if (!phwnd)
502455bce68SGiannis Adamopoulos             return E_INVALIDARG;
503455bce68SGiannis Adamopoulos         *phwnd = m_hWnd;
504455bce68SGiannis Adamopoulos         return S_OK;
505455bce68SGiannis Adamopoulos     }
506455bce68SGiannis Adamopoulos 
ContextSensitiveHelp(BOOL fEnterMode)507455bce68SGiannis Adamopoulos     HRESULT WINAPI ContextSensitiveHelp(BOOL fEnterMode)
508455bce68SGiannis Adamopoulos     {
509455bce68SGiannis Adamopoulos         return E_NOTIMPL;
510455bce68SGiannis Adamopoulos     }
511455bce68SGiannis Adamopoulos 
Initialize(IN HWND hwndParent)512*70d7009aSEthan Rodensky     HRESULT Initialize(IN HWND hwndParent)
513*70d7009aSEthan Rodensky     {
514*70d7009aSEthan Rodensky         const DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
515*70d7009aSEthan Rodensky         Create(hwndParent, 0, NULL, dwStyle, WS_EX_STATICEDGE);
516*70d7009aSEthan Rodensky         return m_hWnd ? S_OK : E_FAIL;
517*70d7009aSEthan Rodensky     }
518*70d7009aSEthan Rodensky 
519455bce68SGiannis Adamopoulos     DECLARE_NOT_AGGREGATABLE(CTrayNotifyWnd)
520455bce68SGiannis Adamopoulos 
521455bce68SGiannis Adamopoulos     DECLARE_PROTECT_FINAL_CONSTRUCT()
522455bce68SGiannis Adamopoulos     BEGIN_COM_MAP(CTrayNotifyWnd)
523455bce68SGiannis Adamopoulos         COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
524455bce68SGiannis Adamopoulos     END_COM_MAP()
525455bce68SGiannis Adamopoulos 
526c2c66affSColin Finck     DECLARE_WND_CLASS_EX(szTrayNotifyWndClass, CS_DBLCLKS, COLOR_3DFACE)
527c2c66affSColin Finck 
528c2c66affSColin Finck     BEGIN_MSG_MAP(CTrayNotifyWnd)
529c2c66affSColin Finck         MESSAGE_HANDLER(WM_CREATE, OnCreate)
530c2c66affSColin Finck         MESSAGE_HANDLER(WM_THEMECHANGED, OnThemeChanged)
531c2c66affSColin Finck         MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
532c2c66affSColin Finck         MESSAGE_HANDLER(WM_SIZE, OnSize)
533c2c66affSColin Finck         MESSAGE_HANDLER(WM_NCHITTEST, OnNcHitTest)
534*70d7009aSEthan Rodensky         MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
535*70d7009aSEthan Rodensky         MESSAGE_HANDLER(WM_NCMOUSEMOVE, OnMouseMove)
5363fee5d0eSBrock Mammen         MESSAGE_HANDLER(WM_CONTEXTMENU, OnCtxMenu)
5377f35908aSGiannis Adamopoulos         MESSAGE_HANDLER(WM_NCLBUTTONDBLCLK, OnClockMessage)
5387f35908aSGiannis Adamopoulos         MESSAGE_HANDLER(WM_SETFONT, OnClockMessage)
5397f35908aSGiannis Adamopoulos         MESSAGE_HANDLER(WM_SETTINGCHANGE, OnPagerMessage)
5407f35908aSGiannis Adamopoulos         MESSAGE_HANDLER(WM_COPYDATA, OnPagerMessage)
541*70d7009aSEthan Rodensky         MESSAGE_HANDLER(TWM_SETTINGSCHANGED, OnTaskbarSettingsChanged)
5427f35908aSGiannis Adamopoulos         NOTIFY_CODE_HANDLER(NTNWM_REALIGN, OnRealign)
543c2c66affSColin Finck         MESSAGE_HANDLER(TNWM_GETMINIMUMSIZE, OnGetMinimumSize)
544*70d7009aSEthan Rodensky         MESSAGE_HANDLER(TNWM_GETSHOWDESKTOPBUTTON, OnGetShowDesktopButton)
545c2c66affSColin Finck     END_MSG_MAP()
546c2c66affSColin Finck };
547c2c66affSColin Finck 
CTrayNotifyWnd_CreateInstance(HWND hwndParent,REFIID riid,void ** ppv)548455bce68SGiannis Adamopoulos HRESULT CTrayNotifyWnd_CreateInstance(HWND hwndParent, REFIID riid, void **ppv)
549c2c66affSColin Finck {
550455bce68SGiannis Adamopoulos     return ShellObjectCreatorInit<CTrayNotifyWnd>(hwndParent, riid, ppv);
551c2c66affSColin Finck }
552