xref: /reactos/base/shell/explorer/traywnd.cpp (revision 17b0623c)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  * ReactOS Explorer
3c2c66affSColin Finck  *
4c2c66affSColin Finck  * Copyright 2006 - 2007 Thomas Weidenmueller <w3seek@reactos.org>
526efda4dSKatayama Hirofumi MZ  * Copyright 2018-2022 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
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"
23c2c66affSColin Finck #include <commoncontrols.h>
24c2c66affSColin Finck 
25c2c66affSColin Finck HRESULT TrayWindowCtxMenuCreator(ITrayWindow * TrayWnd, IN HWND hWndOwner, IContextMenu ** ppCtxMenu);
261c400705SKatayama Hirofumi MZ LRESULT appbar_message(COPYDATASTRUCT* cds);
27451a9c6fSKatayama Hirofumi MZ void appbar_notify_all(HMONITOR hMon, UINT uMsg, HWND hwndExclude, LPARAM lParam);
28c2c66affSColin Finck 
29c2c66affSColin Finck #define WM_APP_TRAYDESTROY  (WM_APP + 0x100)
30c2c66affSColin Finck 
31c2c66affSColin Finck #define TIMER_ID_AUTOHIDE 1
32c2c66affSColin Finck #define TIMER_ID_MOUSETRACK 2
33c2c66affSColin Finck #define MOUSETRACK_INTERVAL 100
34c2c66affSColin Finck #define AUTOHIDE_DELAY_HIDE 2000
35c2c66affSColin Finck #define AUTOHIDE_DELAY_SHOW 50
36c2c66affSColin Finck #define AUTOHIDE_INTERVAL_ANIMATING 10
37c2c66affSColin Finck 
38c2c66affSColin Finck #define AUTOHIDE_SPEED_SHOW 10
39c2c66affSColin Finck #define AUTOHIDE_SPEED_HIDE 1
40c2c66affSColin Finck 
41c2c66affSColin Finck #define AUTOHIDE_HIDDEN 0
42c2c66affSColin Finck #define AUTOHIDE_SHOWING 1
43c2c66affSColin Finck #define AUTOHIDE_SHOWN 2
44c2c66affSColin Finck #define AUTOHIDE_HIDING 3
45c2c66affSColin Finck 
46c2c66affSColin Finck #define IDHK_RUN 0x1f4
47c2c66affSColin Finck #define IDHK_MINIMIZE_ALL 0x1f5
48c2c66affSColin Finck #define IDHK_RESTORE_ALL 0x1f6
49c2c66affSColin Finck #define IDHK_HELP 0x1f7
50c2c66affSColin Finck #define IDHK_EXPLORE 0x1f8
51c2c66affSColin Finck #define IDHK_FIND 0x1f9
52c2c66affSColin Finck #define IDHK_FIND_COMPUTER 0x1fa
53c2c66affSColin Finck #define IDHK_NEXT_TASK 0x1fb
54c2c66affSColin Finck #define IDHK_PREV_TASK 0x1fc
55c2c66affSColin Finck #define IDHK_SYS_PROPERTIES 0x1fd
56c2c66affSColin Finck #define IDHK_DESKTOP 0x1fe
57c2c66affSColin Finck #define IDHK_PAGER 0x1ff
58c2c66affSColin Finck 
59c2c66affSColin Finck static const WCHAR szTrayWndClass[] = L"Shell_TrayWnd";
60c2c66affSColin Finck 
61be970d8dSTuur Martens enum { NONE, TILED, CASCADED } g_Arrangement = NONE;
62be970d8dSTuur Martens 
63be970d8dSTuur Martens struct WINDOWPOSBACKUPDATA
64be970d8dSTuur Martens {
65be970d8dSTuur Martens     HWND hwnd;
66be970d8dSTuur Martens     WINDOWPLACEMENT wplt;
67be970d8dSTuur Martens };
68be970d8dSTuur Martens CSimpleArray<WINDOWPOSBACKUPDATA> g_WindowPosBackup;
69be970d8dSTuur Martens 
70be970d8dSTuur Martens static BOOL CALLBACK BackupWindowsPosProc(HWND hwnd, LPARAM lParam)
71be970d8dSTuur Martens {
72be970d8dSTuur Martens     WINDOWPOSBACKUPDATA wposdata;
73be970d8dSTuur Martens     HWND hDesk = GetDesktopWindow();
74be970d8dSTuur Martens     if (IsWindowVisible(hwnd) && !IsIconic(hwnd) && (hwnd != hDesk))
75be970d8dSTuur Martens     {
76be970d8dSTuur Martens         wposdata.hwnd = hwnd;
77be970d8dSTuur Martens         wposdata.wplt.length = sizeof(wposdata.wplt);
78be970d8dSTuur Martens         GetWindowPlacement(hwnd, &(wposdata.wplt));
79be970d8dSTuur Martens         g_WindowPosBackup.Add(wposdata);
80be970d8dSTuur Martens     }
81be970d8dSTuur Martens 
82be970d8dSTuur Martens     return TRUE;
83be970d8dSTuur Martens }
84be970d8dSTuur Martens 
85be970d8dSTuur Martens VOID BackupWindowPos()
86be970d8dSTuur Martens {
87be970d8dSTuur Martens     EnumWindows(BackupWindowsPosProc, NULL);
88be970d8dSTuur Martens }
89be970d8dSTuur Martens 
90be970d8dSTuur Martens VOID RestoreWindowPos()
91be970d8dSTuur Martens {
92be970d8dSTuur Martens     g_Arrangement = NONE;
93be970d8dSTuur Martens 
94be970d8dSTuur Martens     for (INT i = g_WindowPosBackup.GetSize() - 1; i >= 0; --i)
95be970d8dSTuur Martens     {
96be970d8dSTuur Martens         SetWindowPlacement(g_WindowPosBackup[i].hwnd, &(g_WindowPosBackup[i].wplt));
97be970d8dSTuur Martens     }
98be970d8dSTuur Martens 
99be970d8dSTuur Martens     g_WindowPosBackup.RemoveAll();
100be970d8dSTuur Martens }
101be970d8dSTuur Martens 
10222ab8c81SKatayama Hirofumi MZ BOOL CanBeMinimized(HWND hwnd)
10322ab8c81SKatayama Hirofumi MZ {
10422ab8c81SKatayama Hirofumi MZ     if (::IsWindowVisible(hwnd) && !::IsIconic(hwnd) && ::IsWindowEnabled(hwnd))
10522ab8c81SKatayama Hirofumi MZ     {
10622ab8c81SKatayama Hirofumi MZ         if (::GetClassLongPtrW(hwnd, GCW_ATOM) == (ULONG_PTR)WC_DIALOG)
10722ab8c81SKatayama Hirofumi MZ             return TRUE;
10822ab8c81SKatayama Hirofumi MZ 
10922ab8c81SKatayama Hirofumi MZ         DWORD exstyle = (DWORD)::GetWindowLongPtrW(hwnd, GWL_EXSTYLE);
11022ab8c81SKatayama Hirofumi MZ         if (!(exstyle & WS_EX_TOPMOST))
11122ab8c81SKatayama Hirofumi MZ             return TRUE;
11222ab8c81SKatayama Hirofumi MZ     }
11322ab8c81SKatayama Hirofumi MZ     return FALSE;
11422ab8c81SKatayama Hirofumi MZ }
11522ab8c81SKatayama Hirofumi MZ 
11675b09f3fSKatayama Hirofumi MZ struct EFFECTIVE_INFO
11775b09f3fSKatayama Hirofumi MZ {
11875b09f3fSKatayama Hirofumi MZ     HWND hwndFound;
11975b09f3fSKatayama Hirofumi MZ     HWND hwndDesktop;
12075b09f3fSKatayama Hirofumi MZ     HWND hwndProgman;
12175b09f3fSKatayama Hirofumi MZ     HWND hTrayWnd;
12275b09f3fSKatayama Hirofumi MZ     BOOL bMustBeInMonitor;
12375b09f3fSKatayama Hirofumi MZ };
12475b09f3fSKatayama Hirofumi MZ 
12575b09f3fSKatayama Hirofumi MZ static BOOL CALLBACK
12675b09f3fSKatayama Hirofumi MZ FindEffectiveProc(HWND hwnd, LPARAM lParam)
12775b09f3fSKatayama Hirofumi MZ {
12875b09f3fSKatayama Hirofumi MZ     EFFECTIVE_INFO *pei = (EFFECTIVE_INFO *)lParam;
12975b09f3fSKatayama Hirofumi MZ 
13022ab8c81SKatayama Hirofumi MZ     if (!CanBeMinimized(hwnd))
13175b09f3fSKatayama Hirofumi MZ         return TRUE;    // continue
13275b09f3fSKatayama Hirofumi MZ 
13375b09f3fSKatayama Hirofumi MZ     if (pei->hTrayWnd == hwnd || pei->hwndDesktop == hwnd ||
13475b09f3fSKatayama Hirofumi MZ         pei->hwndProgman == hwnd)
13575b09f3fSKatayama Hirofumi MZ     {
13675b09f3fSKatayama Hirofumi MZ         return TRUE;    // continue
13775b09f3fSKatayama Hirofumi MZ     }
13875b09f3fSKatayama Hirofumi MZ 
13975b09f3fSKatayama Hirofumi MZ     if (pei->bMustBeInMonitor)
14075b09f3fSKatayama Hirofumi MZ     {
14175b09f3fSKatayama Hirofumi MZ         // is the window in the nearest monitor?
14275b09f3fSKatayama Hirofumi MZ         HMONITOR hMon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
14375b09f3fSKatayama Hirofumi MZ         if (hMon)
14475b09f3fSKatayama Hirofumi MZ         {
14575b09f3fSKatayama Hirofumi MZ             MONITORINFO info;
14675b09f3fSKatayama Hirofumi MZ             ZeroMemory(&info, sizeof(info));
14775b09f3fSKatayama Hirofumi MZ             info.cbSize = sizeof(info);
14875b09f3fSKatayama Hirofumi MZ             if (GetMonitorInfoW(hMon, &info))
14975b09f3fSKatayama Hirofumi MZ             {
15075b09f3fSKatayama Hirofumi MZ                 RECT rcWindow, rcMonitor, rcIntersect;
15175b09f3fSKatayama Hirofumi MZ                 rcMonitor = info.rcMonitor;
15275b09f3fSKatayama Hirofumi MZ 
15375b09f3fSKatayama Hirofumi MZ                 GetWindowRect(hwnd, &rcWindow);
15475b09f3fSKatayama Hirofumi MZ 
15575b09f3fSKatayama Hirofumi MZ                 if (!IntersectRect(&rcIntersect, &rcMonitor, &rcWindow))
15675b09f3fSKatayama Hirofumi MZ                     return TRUE;    // continue
15775b09f3fSKatayama Hirofumi MZ             }
15875b09f3fSKatayama Hirofumi MZ         }
15975b09f3fSKatayama Hirofumi MZ     }
16075b09f3fSKatayama Hirofumi MZ 
16175b09f3fSKatayama Hirofumi MZ     pei->hwndFound = hwnd;
16275b09f3fSKatayama Hirofumi MZ     return FALSE;   // stop if found
16375b09f3fSKatayama Hirofumi MZ }
16475b09f3fSKatayama Hirofumi MZ 
16575b09f3fSKatayama Hirofumi MZ static BOOL
16675b09f3fSKatayama Hirofumi MZ IsThereAnyEffectiveWindow(BOOL bMustBeInMonitor)
16775b09f3fSKatayama Hirofumi MZ {
16875b09f3fSKatayama Hirofumi MZ     EFFECTIVE_INFO ei;
16975b09f3fSKatayama Hirofumi MZ     ei.hwndFound = NULL;
17075b09f3fSKatayama Hirofumi MZ     ei.hwndDesktop = GetDesktopWindow();
17175b09f3fSKatayama Hirofumi MZ     ei.hTrayWnd = FindWindowW(L"Shell_TrayWnd", NULL);
17275b09f3fSKatayama Hirofumi MZ     ei.hwndProgman = FindWindowW(L"Progman", NULL);
17375b09f3fSKatayama Hirofumi MZ     ei.bMustBeInMonitor = bMustBeInMonitor;
17475b09f3fSKatayama Hirofumi MZ 
17575b09f3fSKatayama Hirofumi MZ     EnumWindows(FindEffectiveProc, (LPARAM)&ei);
17675b09f3fSKatayama Hirofumi MZ     return ei.hwndFound != NULL;
17775b09f3fSKatayama Hirofumi MZ }
17875b09f3fSKatayama Hirofumi MZ 
179e6bced7aSKatayama Hirofumi MZ /* Minimized window position info */
180e6bced7aSKatayama Hirofumi MZ struct MINWNDPOS
181e6bced7aSKatayama Hirofumi MZ {
182e6bced7aSKatayama Hirofumi MZ     HWND hwnd;
183e6bced7aSKatayama Hirofumi MZ     WINDOWPLACEMENT wndpl;
184e6bced7aSKatayama Hirofumi MZ };
185e6bced7aSKatayama Hirofumi MZ CSimpleArray<MINWNDPOS>  g_MinimizedAll;
18675b09f3fSKatayama Hirofumi MZ 
187c2c66affSColin Finck /*
188c2c66affSColin Finck  * ITrayWindow
189c2c66affSColin Finck  */
190c2c66affSColin Finck 
191c2c66affSColin Finck const GUID IID_IShellDesktopTray = { 0x213e2df9, 0x9a14, 0x4328, { 0x99, 0xb1, 0x69, 0x61, 0xf9, 0x14, 0x3c, 0xe9 } };
192c2c66affSColin Finck 
193c2c66affSColin Finck class CStartButton
194c2c66affSColin Finck     : public CWindowImpl<CStartButton>
195c2c66affSColin Finck {
196c2c66affSColin Finck     HIMAGELIST m_ImageList;
197c2c66affSColin Finck     SIZE       m_Size;
198c2c66affSColin Finck     HFONT      m_Font;
199c2c66affSColin Finck 
200c2c66affSColin Finck public:
201c2c66affSColin Finck     CStartButton()
202c2c66affSColin Finck         : m_ImageList(NULL),
203c2c66affSColin Finck           m_Font(NULL)
204c2c66affSColin Finck     {
205c2c66affSColin Finck         m_Size.cx = 0;
206c2c66affSColin Finck         m_Size.cy = 0;
207c2c66affSColin Finck     }
208c2c66affSColin Finck 
209c2c66affSColin Finck     virtual ~CStartButton()
210c2c66affSColin Finck     {
211c2c66affSColin Finck         if (m_ImageList != NULL)
212c2c66affSColin Finck             ImageList_Destroy(m_ImageList);
213c2c66affSColin Finck 
214c2c66affSColin Finck         if (m_Font != NULL)
215c2c66affSColin Finck             DeleteObject(m_Font);
216c2c66affSColin Finck     }
217c2c66affSColin Finck 
218c2c66affSColin Finck     SIZE GetSize()
219c2c66affSColin Finck     {
220c2c66affSColin Finck         return m_Size;
221c2c66affSColin Finck     }
222c2c66affSColin Finck 
223c2c66affSColin Finck     VOID UpdateSize()
224c2c66affSColin Finck     {
225c2c66affSColin Finck         SIZE Size = { 0, 0 };
226c2c66affSColin Finck 
227c2c66affSColin Finck         if (m_ImageList == NULL ||
228c2c66affSColin Finck             !SendMessageW(BCM_GETIDEALSIZE, 0, (LPARAM) &Size))
229c2c66affSColin Finck         {
230c2c66affSColin Finck             Size.cx = 2 * GetSystemMetrics(SM_CXEDGE) + GetSystemMetrics(SM_CYCAPTION) * 3;
231c2c66affSColin Finck         }
232c2c66affSColin Finck 
233c2c66affSColin Finck         Size.cy = max(Size.cy, GetSystemMetrics(SM_CYCAPTION));
234c2c66affSColin Finck 
235c2c66affSColin Finck         /* Save the size of the start button */
236c2c66affSColin Finck         m_Size = Size;
237c2c66affSColin Finck     }
238c2c66affSColin Finck 
239c2c66affSColin Finck     VOID UpdateFont()
240c2c66affSColin Finck     {
241c2c66affSColin Finck         /* Get the system fonts, we use the caption font, always bold, though. */
242c2c66affSColin Finck         NONCLIENTMETRICS ncm = {sizeof(ncm)};
243c2c66affSColin Finck         if (!SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, FALSE))
244c2c66affSColin Finck             return;
245c2c66affSColin Finck 
246c2c66affSColin Finck         if (m_Font)
247c2c66affSColin Finck             DeleteObject(m_Font);
248c2c66affSColin Finck 
249c2c66affSColin Finck         ncm.lfCaptionFont.lfWeight = FW_BOLD;
250c2c66affSColin Finck         m_Font = CreateFontIndirect(&ncm.lfCaptionFont);
251c2c66affSColin Finck 
252c2c66affSColin Finck         SetFont(m_Font, FALSE);
253c2c66affSColin Finck     }
254c2c66affSColin Finck 
255c2c66affSColin Finck     VOID Initialize()
256c2c66affSColin Finck     {
257d9589502SKatayama Hirofumi MZ         // HACK & FIXME: CORE-18016
258d9589502SKatayama Hirofumi MZ         HWND hWnd = m_hWnd;
259d9589502SKatayama Hirofumi MZ         m_hWnd = NULL;
260d9589502SKatayama Hirofumi MZ         SubclassWindow(hWnd);
2611952e5b7SMark Jansen 
262c2c66affSColin Finck         SetWindowTheme(m_hWnd, L"Start", NULL);
263c2c66affSColin Finck 
264c2c66affSColin Finck         m_ImageList = ImageList_LoadImageW(hExplorerInstance,
265c2c66affSColin Finck                                            MAKEINTRESOURCEW(IDB_START),
266c2c66affSColin Finck                                            0, 0, 0,
267c2c66affSColin Finck                                            IMAGE_BITMAP,
268c2c66affSColin Finck                                            LR_LOADTRANSPARENT | LR_CREATEDIBSECTION);
269c2c66affSColin Finck 
270c2c66affSColin Finck         BUTTON_IMAGELIST bil = {m_ImageList, {1,1,1,1}, BUTTON_IMAGELIST_ALIGN_LEFT};
271c2c66affSColin Finck         SendMessageW(BCM_SETIMAGELIST, 0, (LPARAM) &bil);
272c2c66affSColin Finck         UpdateSize();
273c2c66affSColin Finck     }
274c2c66affSColin Finck 
275c2c66affSColin Finck     HWND Create(HWND hwndParent)
276c2c66affSColin Finck     {
277c2c66affSColin Finck         WCHAR szStartCaption[32];
278c2c66affSColin Finck         if (!LoadStringW(hExplorerInstance,
279c2c66affSColin Finck                          IDS_START,
280c2c66affSColin Finck                          szStartCaption,
281c2c66affSColin Finck                          _countof(szStartCaption)))
282c2c66affSColin Finck         {
283c2c66affSColin Finck             wcscpy(szStartCaption, L"Start");
284c2c66affSColin Finck         }
285c2c66affSColin Finck 
286c2c66affSColin Finck         DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | BS_PUSHBUTTON | BS_LEFT | BS_VCENTER;
287c2c66affSColin Finck 
288d9589502SKatayama Hirofumi MZ         // HACK & FIXME: CORE-18016
289c2c66affSColin Finck         m_hWnd = CreateWindowEx(
290c2c66affSColin Finck             0,
291c2c66affSColin Finck             WC_BUTTON,
292c2c66affSColin Finck             szStartCaption,
293c2c66affSColin Finck             dwStyle,
294c2c66affSColin Finck             0, 0, 0, 0,
295c2c66affSColin Finck             hwndParent,
296c2c66affSColin Finck             (HMENU) IDC_STARTBTN,
297c2c66affSColin Finck             hExplorerInstance,
298c2c66affSColin Finck             NULL);
299c2c66affSColin Finck 
300c2c66affSColin Finck         if (m_hWnd)
301c2c66affSColin Finck             Initialize();
302c2c66affSColin Finck 
303c2c66affSColin Finck         return m_hWnd;
304c2c66affSColin Finck     }
305c2c66affSColin Finck 
306c2c66affSColin Finck     LRESULT OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
307c2c66affSColin Finck     {
308c2c66affSColin Finck         if (uMsg == WM_KEYUP && wParam != VK_SPACE)
309c2c66affSColin Finck             return 0;
310c2c66affSColin Finck 
311c2c66affSColin Finck         GetParent().PostMessage(TWM_OPENSTARTMENU);
312c2c66affSColin Finck         return 0;
313c2c66affSColin Finck     }
314c2c66affSColin Finck 
315c2c66affSColin Finck     BEGIN_MSG_MAP(CStartButton)
316c2c66affSColin Finck         MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
317c2c66affSColin Finck     END_MSG_MAP()
318c2c66affSColin Finck 
319c2c66affSColin Finck };
320c2c66affSColin Finck 
32126efda4dSKatayama Hirofumi MZ // This window class name is CONFIRMED on Win10 by WinHier.
32226efda4dSKatayama Hirofumi MZ static const WCHAR szTrayShowDesktopButton[] = L"TrayShowDesktopButtonWClass";
32326efda4dSKatayama Hirofumi MZ 
32426efda4dSKatayama Hirofumi MZ // The 'Show Desktop' button at edge of taskbar
32526efda4dSKatayama Hirofumi MZ class CTrayShowDesktopButton :
32626efda4dSKatayama Hirofumi MZ     public CWindowImpl<CTrayShowDesktopButton, CWindow, CControlWinTraits>
32726efda4dSKatayama Hirofumi MZ {
32826efda4dSKatayama Hirofumi MZ     LONG m_nClickedTime;
32926efda4dSKatayama Hirofumi MZ     BOOL m_bHovering;
33026efda4dSKatayama Hirofumi MZ     HTHEME m_hTheme;
33126efda4dSKatayama Hirofumi MZ 
33226efda4dSKatayama Hirofumi MZ public:
33326efda4dSKatayama Hirofumi MZ     DECLARE_WND_CLASS_EX(szTrayShowDesktopButton, CS_HREDRAW | CS_VREDRAW, COLOR_3DFACE)
33426efda4dSKatayama Hirofumi MZ 
33526efda4dSKatayama Hirofumi MZ     CTrayShowDesktopButton() : m_nClickedTime(0), m_bHovering(FALSE)
33626efda4dSKatayama Hirofumi MZ     {
33726efda4dSKatayama Hirofumi MZ     }
33826efda4dSKatayama Hirofumi MZ 
33926efda4dSKatayama Hirofumi MZ     INT WidthOrHeight() const
34026efda4dSKatayama Hirofumi MZ     {
34126efda4dSKatayama Hirofumi MZ #define SHOW_DESKTOP_MINIMUM_WIDTH 3
34226efda4dSKatayama Hirofumi MZ         INT cxy = 2 * ::GetSystemMetrics(SM_CXEDGE);
34326efda4dSKatayama Hirofumi MZ         return max(cxy, SHOW_DESKTOP_MINIMUM_WIDTH);
34426efda4dSKatayama Hirofumi MZ     }
34526efda4dSKatayama Hirofumi MZ 
34626efda4dSKatayama Hirofumi MZ     HRESULT DoCreate(HWND hwndParent)
34726efda4dSKatayama Hirofumi MZ     {
34826efda4dSKatayama Hirofumi MZ         DWORD style = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS;
34926efda4dSKatayama Hirofumi MZ         Create(hwndParent, NULL, NULL, style);
35026efda4dSKatayama Hirofumi MZ         if (!m_hWnd)
35126efda4dSKatayama Hirofumi MZ             return E_FAIL;
35226efda4dSKatayama Hirofumi MZ 
35326efda4dSKatayama Hirofumi MZ         ::SetWindowTheme(m_hWnd, L"TaskBar", NULL);
35426efda4dSKatayama Hirofumi MZ         return S_OK;
35526efda4dSKatayama Hirofumi MZ     }
35626efda4dSKatayama Hirofumi MZ 
35726efda4dSKatayama Hirofumi MZ     LRESULT OnClick(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
35826efda4dSKatayama Hirofumi MZ     {
35926efda4dSKatayama Hirofumi MZ         // The actual action can be delayed as an expected behaviour.
36026efda4dSKatayama Hirofumi MZ         // But a too late action is an unexpected behaviour.
36126efda4dSKatayama Hirofumi MZ         LONG nTime0 = m_nClickedTime;
36226efda4dSKatayama Hirofumi MZ         LONG nTime1 = ::GetMessageTime();
36326efda4dSKatayama Hirofumi MZ         if (nTime1 - nTime0 >= 600) // Ignore after 0.6 sec
36426efda4dSKatayama Hirofumi MZ             return 0;
36526efda4dSKatayama Hirofumi MZ 
36626efda4dSKatayama Hirofumi MZ         // Show/Hide Desktop
367ba2cead8SKatayama Hirofumi MZ         GetParent().SendMessage(WM_COMMAND, TRAYCMD_TOGGLE_DESKTOP, 0);
36826efda4dSKatayama Hirofumi MZ         return 0;
36926efda4dSKatayama Hirofumi MZ     }
37026efda4dSKatayama Hirofumi MZ 
37126efda4dSKatayama Hirofumi MZ #define TSDB_CLICK (WM_USER + 100)
37226efda4dSKatayama Hirofumi MZ 
37326efda4dSKatayama Hirofumi MZ     // This function is called from OnLButtonDown and parent.
37426efda4dSKatayama Hirofumi MZ     VOID Click()
37526efda4dSKatayama Hirofumi MZ     {
37626efda4dSKatayama Hirofumi MZ         // The actual action can be delayed as an expected behaviour.
37726efda4dSKatayama Hirofumi MZ         m_nClickedTime = ::GetMessageTime();
37826efda4dSKatayama Hirofumi MZ         PostMessage(TSDB_CLICK, 0, 0);
37926efda4dSKatayama Hirofumi MZ     }
38026efda4dSKatayama Hirofumi MZ 
381ba2cead8SKatayama Hirofumi MZ     LRESULT OnLButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
38226efda4dSKatayama Hirofumi MZ     {
38326efda4dSKatayama Hirofumi MZ         Click(); // Left-click
38426efda4dSKatayama Hirofumi MZ         return 0;
38526efda4dSKatayama Hirofumi MZ     }
38626efda4dSKatayama Hirofumi MZ 
38726efda4dSKatayama Hirofumi MZ     LRESULT OnSettingChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
38826efda4dSKatayama Hirofumi MZ     {
38926efda4dSKatayama Hirofumi MZ         if (m_hTheme)
39026efda4dSKatayama Hirofumi MZ             ::CloseThemeData(m_hTheme);
39126efda4dSKatayama Hirofumi MZ 
39226efda4dSKatayama Hirofumi MZ         m_hTheme = ::OpenThemeData(m_hWnd, L"TaskBar");
39326efda4dSKatayama Hirofumi MZ         InvalidateRect(NULL, TRUE);
39426efda4dSKatayama Hirofumi MZ         return 0;
39526efda4dSKatayama Hirofumi MZ     }
39626efda4dSKatayama Hirofumi MZ 
39726efda4dSKatayama Hirofumi MZ     // This function is called from OnPaint and parent.
39826efda4dSKatayama Hirofumi MZ     VOID OnDraw(HDC hdc, LPRECT prc);
39926efda4dSKatayama Hirofumi MZ 
40026efda4dSKatayama Hirofumi MZ     LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
40126efda4dSKatayama Hirofumi MZ     {
40226efda4dSKatayama Hirofumi MZ         RECT rc;
40326efda4dSKatayama Hirofumi MZ         GetClientRect(&rc);
40426efda4dSKatayama Hirofumi MZ 
40526efda4dSKatayama Hirofumi MZ         PAINTSTRUCT ps;
40626efda4dSKatayama Hirofumi MZ         HDC hdc = BeginPaint(&ps);
40726efda4dSKatayama Hirofumi MZ         OnDraw(hdc, &rc);
40826efda4dSKatayama Hirofumi MZ         EndPaint(&ps);
40926efda4dSKatayama Hirofumi MZ         return 0;
41026efda4dSKatayama Hirofumi MZ     }
41126efda4dSKatayama Hirofumi MZ 
41226efda4dSKatayama Hirofumi MZ     BOOL PtInButton(POINT pt)
41326efda4dSKatayama Hirofumi MZ     {
414ba2cead8SKatayama Hirofumi MZ         if (!IsWindow())
415ba2cead8SKatayama Hirofumi MZ             return FALSE;
41626efda4dSKatayama Hirofumi MZ         RECT rc;
41726efda4dSKatayama Hirofumi MZ         GetWindowRect(&rc);
41826efda4dSKatayama Hirofumi MZ         INT cxEdge = ::GetSystemMetrics(SM_CXEDGE), cyEdge = ::GetSystemMetrics(SM_CYEDGE);
41926efda4dSKatayama Hirofumi MZ         ::InflateRect(&rc, max(cxEdge, 1), max(cyEdge, 1));
42026efda4dSKatayama Hirofumi MZ         return ::PtInRect(&rc, pt);
42126efda4dSKatayama Hirofumi MZ     }
42226efda4dSKatayama Hirofumi MZ 
42326efda4dSKatayama Hirofumi MZ #define SHOW_DESKTOP_TIMER_ID 999
42426efda4dSKatayama Hirofumi MZ #define SHOW_DESKTOP_TIMER_INTERVAL 200
42526efda4dSKatayama Hirofumi MZ 
42626efda4dSKatayama Hirofumi MZ     VOID StartHovering()
42726efda4dSKatayama Hirofumi MZ     {
42826efda4dSKatayama Hirofumi MZ         if (m_bHovering)
42926efda4dSKatayama Hirofumi MZ             return;
43026efda4dSKatayama Hirofumi MZ 
43126efda4dSKatayama Hirofumi MZ         m_bHovering = TRUE;
43226efda4dSKatayama Hirofumi MZ         SetTimer(SHOW_DESKTOP_TIMER_ID, SHOW_DESKTOP_TIMER_INTERVAL, NULL);
43326efda4dSKatayama Hirofumi MZ         InvalidateRect(NULL, TRUE);
434ba2cead8SKatayama Hirofumi MZ         GetParent().PostMessage(WM_NCPAINT, 0, 0);
43526efda4dSKatayama Hirofumi MZ     }
43626efda4dSKatayama Hirofumi MZ 
43726efda4dSKatayama Hirofumi MZ     LRESULT OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
43826efda4dSKatayama Hirofumi MZ     {
43926efda4dSKatayama Hirofumi MZ         StartHovering();
44026efda4dSKatayama Hirofumi MZ         return 0;
44126efda4dSKatayama Hirofumi MZ     }
44226efda4dSKatayama Hirofumi MZ 
44326efda4dSKatayama Hirofumi MZ     LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
44426efda4dSKatayama Hirofumi MZ     {
44526efda4dSKatayama Hirofumi MZ         if (wParam != SHOW_DESKTOP_TIMER_ID || !m_bHovering)
44626efda4dSKatayama Hirofumi MZ             return 0;
44726efda4dSKatayama Hirofumi MZ 
44826efda4dSKatayama Hirofumi MZ         POINT pt;
44926efda4dSKatayama Hirofumi MZ         ::GetCursorPos(&pt);
45026efda4dSKatayama Hirofumi MZ         if (!PtInButton(pt)) // The end of hovering?
45126efda4dSKatayama Hirofumi MZ         {
45226efda4dSKatayama Hirofumi MZ             m_bHovering = FALSE;
45326efda4dSKatayama Hirofumi MZ             KillTimer(SHOW_DESKTOP_TIMER_ID);
45426efda4dSKatayama Hirofumi MZ             InvalidateRect(NULL, TRUE);
455ba2cead8SKatayama Hirofumi MZ             GetParent().PostMessage(WM_NCPAINT, 0, 0);
45626efda4dSKatayama Hirofumi MZ         }
45726efda4dSKatayama Hirofumi MZ 
45826efda4dSKatayama Hirofumi MZ         return 0;
45926efda4dSKatayama Hirofumi MZ     }
46026efda4dSKatayama Hirofumi MZ 
46126efda4dSKatayama Hirofumi MZ     LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
46226efda4dSKatayama Hirofumi MZ     {
46326efda4dSKatayama Hirofumi MZ         if (m_hTheme)
46426efda4dSKatayama Hirofumi MZ         {
46526efda4dSKatayama Hirofumi MZ             CloseThemeData(m_hTheme);
46626efda4dSKatayama Hirofumi MZ             m_hTheme = NULL;
46726efda4dSKatayama Hirofumi MZ         }
46826efda4dSKatayama Hirofumi MZ         return 0;
46926efda4dSKatayama Hirofumi MZ     }
47026efda4dSKatayama Hirofumi MZ 
47126efda4dSKatayama Hirofumi MZ     BEGIN_MSG_MAP(CTrayShowDesktopButton)
472ba2cead8SKatayama Hirofumi MZ         MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
47326efda4dSKatayama Hirofumi MZ         MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChanged)
47426efda4dSKatayama Hirofumi MZ         MESSAGE_HANDLER(WM_THEMECHANGED, OnSettingChanged)
47526efda4dSKatayama Hirofumi MZ         MESSAGE_HANDLER(WM_PAINT, OnPaint)
47626efda4dSKatayama Hirofumi MZ         MESSAGE_HANDLER(WM_TIMER, OnTimer)
47726efda4dSKatayama Hirofumi MZ         MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
47826efda4dSKatayama Hirofumi MZ         MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
47926efda4dSKatayama Hirofumi MZ         MESSAGE_HANDLER(TSDB_CLICK, OnClick)
48026efda4dSKatayama Hirofumi MZ     END_MSG_MAP()
48126efda4dSKatayama Hirofumi MZ };
48226efda4dSKatayama Hirofumi MZ 
48326efda4dSKatayama Hirofumi MZ VOID CTrayShowDesktopButton::OnDraw(HDC hdc, LPRECT prc)
48426efda4dSKatayama Hirofumi MZ {
48526efda4dSKatayama Hirofumi MZ     if (m_hTheme)
48626efda4dSKatayama Hirofumi MZ     {
48726efda4dSKatayama Hirofumi MZ         if (m_bHovering) // Draw a hot button
48826efda4dSKatayama Hirofumi MZ         {
48926efda4dSKatayama Hirofumi MZ             HTHEME hButtonTheme = ::OpenThemeData(m_hWnd, L"Button");
49026efda4dSKatayama Hirofumi MZ             ::DrawThemeBackground(hButtonTheme, hdc, BP_PUSHBUTTON, PBS_NORMAL, prc, prc);
49126efda4dSKatayama Hirofumi MZ             ::CloseThemeData(hButtonTheme);
49226efda4dSKatayama Hirofumi MZ         }
49326efda4dSKatayama Hirofumi MZ         else // Draw a taskbar background
49426efda4dSKatayama Hirofumi MZ         {
49526efda4dSKatayama Hirofumi MZ             ::DrawThemeBackground(m_hTheme, hdc, TBP_BACKGROUNDTOP, 0, prc, prc);
49626efda4dSKatayama Hirofumi MZ         }
49726efda4dSKatayama Hirofumi MZ     }
49826efda4dSKatayama Hirofumi MZ     else
49926efda4dSKatayama Hirofumi MZ     {
50026efda4dSKatayama Hirofumi MZ         RECT rc = *prc;
50126efda4dSKatayama Hirofumi MZ         if (m_bHovering) // Draw a hot button
50226efda4dSKatayama Hirofumi MZ         {
50326efda4dSKatayama Hirofumi MZ             ::DrawFrameControl(hdc, &rc, DFC_BUTTON, DFCS_BUTTONPUSH | DFCS_ADJUSTRECT);
50426efda4dSKatayama Hirofumi MZ             HBRUSH hbrHot = ::CreateSolidBrush(RGB(255, 255, 191));
50526efda4dSKatayama Hirofumi MZ             ::FillRect(hdc, &rc, hbrHot);
50626efda4dSKatayama Hirofumi MZ             ::DeleteObject(hbrHot);
50726efda4dSKatayama Hirofumi MZ         }
50826efda4dSKatayama Hirofumi MZ         else // Draw a flattish button
50926efda4dSKatayama Hirofumi MZ         {
51026efda4dSKatayama Hirofumi MZ             ::DrawFrameControl(hdc, &rc, DFC_BUTTON, DFCS_BUTTONPUSH);
51126efda4dSKatayama Hirofumi MZ             ::InflateRect(&rc, -1, -1);
51226efda4dSKatayama Hirofumi MZ             ::FillRect(hdc, &rc, ::GetSysColorBrush(COLOR_3DFACE));
51326efda4dSKatayama Hirofumi MZ         }
51426efda4dSKatayama Hirofumi MZ     }
51526efda4dSKatayama Hirofumi MZ }
51626efda4dSKatayama Hirofumi MZ 
517c2c66affSColin Finck class CTrayWindow :
518c2c66affSColin Finck     public CComCoClass<CTrayWindow>,
519c2c66affSColin Finck     public CComObjectRootEx<CComMultiThreadModelNoCS>,
520c2c66affSColin Finck     public CWindowImpl < CTrayWindow, CWindow, CControlWinTraits >,
521c2c66affSColin Finck     public ITrayWindow,
522c2c66affSColin Finck     public IShellDesktopTray,
523c2c66affSColin Finck     public IOleWindow,
524c2c66affSColin Finck     public IContextMenu
525c2c66affSColin Finck {
526c2c66affSColin Finck     CStartButton m_StartButton;
52726efda4dSKatayama Hirofumi MZ     CTrayShowDesktopButton m_ShowDesktopButton;
528c2c66affSColin Finck 
529c2c66affSColin Finck     CComPtr<IMenuBand>  m_StartMenuBand;
530c2c66affSColin Finck     CComPtr<IMenuPopup> m_StartMenuPopup;
531c2c66affSColin Finck 
532c2c66affSColin Finck     CComPtr<IDeskBand> m_TaskBand;
533c2c66affSColin Finck     CComPtr<IContextMenu> m_ContextMenu;
534c2c66affSColin Finck     HTHEME m_Theme;
535c2c66affSColin Finck 
536c2c66affSColin Finck     HFONT m_Font;
537c2c66affSColin Finck 
538c2c66affSColin Finck     HWND m_DesktopWnd;
539c2c66affSColin Finck     HWND m_Rebar;
540c2c66affSColin Finck     HWND m_TaskSwitch;
541c2c66affSColin Finck     HWND m_TrayNotify;
542c2c66affSColin Finck 
543455bce68SGiannis Adamopoulos     CComPtr<IUnknown> m_TrayNotifyInstance;
544c2c66affSColin Finck 
545c2c66affSColin Finck     DWORD    m_Position;
546c2c66affSColin Finck     HMONITOR m_Monitor;
547c2c66affSColin Finck     HMONITOR m_PreviousMonitor;
548c2c66affSColin Finck     DWORD    m_DraggingPosition;
549c2c66affSColin Finck     HMONITOR m_DraggingMonitor;
550c2c66affSColin Finck 
551c2c66affSColin Finck     RECT m_TrayRects[4];
552c2c66affSColin Finck     SIZE m_TraySize;
553c2c66affSColin Finck 
554c2c66affSColin Finck     HWND m_TrayPropertiesOwner;
555c2c66affSColin Finck     HWND m_RunFileDlgOwner;
556c2c66affSColin Finck 
557c2c66affSColin Finck     UINT m_AutoHideState;
558c2c66affSColin Finck     SIZE m_AutoHideOffset;
559c2c66affSColin Finck     TRACKMOUSEEVENT m_MouseTrackingInfo;
560c2c66affSColin Finck 
561c2c66affSColin Finck     HDPA m_ShellServices;
562c2c66affSColin Finck 
563c2c66affSColin Finck public:
564c2c66affSColin Finck     CComPtr<ITrayBandSite> m_TrayBandSite;
565c2c66affSColin Finck 
566c2c66affSColin Finck     union
567c2c66affSColin Finck     {
568c2c66affSColin Finck         DWORD Flags;
569c2c66affSColin Finck         struct
570c2c66affSColin Finck         {
571c2c66affSColin Finck             /* UI Status */
572c2c66affSColin Finck             DWORD InSizeMove : 1;
573c2c66affSColin Finck             DWORD IsDragging : 1;
574c2c66affSColin Finck             DWORD NewPosSize : 1;
575e6bced7aSKatayama Hirofumi MZ             DWORD IgnorePulse : 1;
576c2c66affSColin Finck         };
577c2c66affSColin Finck     };
578c2c66affSColin Finck 
579c2c66affSColin Finck public:
580c2c66affSColin Finck     CTrayWindow() :
581c2c66affSColin Finck         m_StartButton(),
58226efda4dSKatayama Hirofumi MZ         m_ShowDesktopButton(),
583c2c66affSColin Finck         m_Theme(NULL),
584c2c66affSColin Finck         m_Font(NULL),
585c2c66affSColin Finck         m_DesktopWnd(NULL),
586c2c66affSColin Finck         m_Rebar(NULL),
587c2c66affSColin Finck         m_TaskSwitch(NULL),
588c2c66affSColin Finck         m_TrayNotify(NULL),
589c2c66affSColin Finck         m_Position(0),
590c2c66affSColin Finck         m_Monitor(NULL),
591c2c66affSColin Finck         m_PreviousMonitor(NULL),
592c2c66affSColin Finck         m_DraggingPosition(0),
593c2c66affSColin Finck         m_DraggingMonitor(NULL),
594c2c66affSColin Finck         m_TrayPropertiesOwner(NULL),
595c2c66affSColin Finck         m_RunFileDlgOwner(NULL),
596c2c66affSColin Finck         m_AutoHideState(NULL),
597c2c66affSColin Finck         m_ShellServices(NULL),
598c2c66affSColin Finck         Flags(0)
599c2c66affSColin Finck     {
600c2c66affSColin Finck         ZeroMemory(&m_TrayRects, sizeof(m_TrayRects));
601c2c66affSColin Finck         ZeroMemory(&m_TraySize, sizeof(m_TraySize));
602c2c66affSColin Finck         ZeroMemory(&m_AutoHideOffset, sizeof(m_AutoHideOffset));
603c2c66affSColin Finck         ZeroMemory(&m_MouseTrackingInfo, sizeof(m_MouseTrackingInfo));
604e6bced7aSKatayama Hirofumi MZ         IgnorePulse = TRUE;
605c2c66affSColin Finck     }
606c2c66affSColin Finck 
607c2c66affSColin Finck     virtual ~CTrayWindow()
608c2c66affSColin Finck     {
609c2c66affSColin Finck         if (m_ShellServices != NULL)
610c2c66affSColin Finck         {
611c2c66affSColin Finck             ShutdownShellServices(m_ShellServices);
612c2c66affSColin Finck             m_ShellServices = NULL;
613c2c66affSColin Finck         }
614c2c66affSColin Finck 
615c2c66affSColin Finck         if (m_Font != NULL)
616c2c66affSColin Finck         {
617c2c66affSColin Finck             DeleteObject(m_Font);
618c2c66affSColin Finck             m_Font = NULL;
619c2c66affSColin Finck         }
620c2c66affSColin Finck 
621c2c66affSColin Finck         if (m_Theme)
622c2c66affSColin Finck         {
623c2c66affSColin Finck             CloseThemeData(m_Theme);
624c2c66affSColin Finck             m_Theme = NULL;
625c2c66affSColin Finck         }
626c2c66affSColin Finck 
627c2c66affSColin Finck         PostQuitMessage(0);
628c2c66affSColin Finck     }
629c2c66affSColin Finck 
630c2c66affSColin Finck 
631c2c66affSColin Finck 
632c2c66affSColin Finck 
633c2c66affSColin Finck 
634c2c66affSColin Finck     /**********************************************************
635c2c66affSColin Finck      *    ##### command handling #####
636c2c66affSColin Finck      */
637c2c66affSColin Finck 
638c2c66affSColin Finck     HRESULT ExecResourceCmd(int id)
639c2c66affSColin Finck     {
640c2c66affSColin Finck         WCHAR szCommand[256];
641c2c66affSColin Finck         WCHAR *pszParameters;
642c2c66affSColin Finck 
643c2c66affSColin Finck         if (!LoadStringW(hExplorerInstance,
644c2c66affSColin Finck                          id,
645c2c66affSColin Finck                          szCommand,
646c2c66affSColin Finck                          _countof(szCommand)))
647c2c66affSColin Finck         {
648c2c66affSColin Finck             return E_FAIL;
649c2c66affSColin Finck         }
650c2c66affSColin Finck 
651c2c66affSColin Finck         pszParameters = wcschr(szCommand, L'>');
652c2c66affSColin Finck         if (pszParameters)
653c2c66affSColin Finck         {
654c2c66affSColin Finck             *pszParameters = 0;
655c2c66affSColin Finck             pszParameters++;
656c2c66affSColin Finck         }
657c2c66affSColin Finck 
658c2c66affSColin Finck         ShellExecuteW(m_hWnd, NULL, szCommand, pszParameters, NULL, SW_SHOWNORMAL);
659c2c66affSColin Finck         return S_OK;
660c2c66affSColin Finck     }
661c2c66affSColin Finck 
662c2c66affSColin Finck     LRESULT DoExitWindows()
663c2c66affSColin Finck     {
664c62bccddSHermès Bélusca-Maïto         /* Display the ReactOS Shutdown Dialog */
665c2c66affSColin Finck         ExitWindowsDialog(m_hWnd);
666c62bccddSHermès Bélusca-Maïto 
667c62bccddSHermès Bélusca-Maïto         /*
668c62bccddSHermès Bélusca-Maïto          * If the user presses CTRL+ALT+SHIFT while exiting
669c62bccddSHermès Bélusca-Maïto          * the shutdown dialog, exit the shell cleanly.
670c62bccddSHermès Bélusca-Maïto          */
671c62bccddSHermès Bélusca-Maïto         if ((GetKeyState(VK_CONTROL) & 0x8000) &&
672c62bccddSHermès Bélusca-Maïto             (GetKeyState(VK_SHIFT)   & 0x8000) &&
673c62bccddSHermès Bélusca-Maïto             (GetKeyState(VK_MENU)    & 0x8000))
674c62bccddSHermès Bélusca-Maïto         {
675c62bccddSHermès Bélusca-Maïto             PostMessage(WM_QUIT, 0, 0);
676c62bccddSHermès Bélusca-Maïto         }
677c2c66affSColin Finck         return 0;
678c2c66affSColin Finck     }
679c2c66affSColin Finck 
680c2c66affSColin Finck     DWORD WINAPI RunFileDlgThread()
681c2c66affSColin Finck     {
682c2c66affSColin Finck         HWND hwnd;
683c2c66affSColin Finck         RECT posRect;
684c2c66affSColin Finck 
685c2c66affSColin Finck         m_StartButton.GetWindowRect(&posRect);
686c2c66affSColin Finck 
687c2c66affSColin Finck         hwnd = CreateWindowEx(0,
688c2c66affSColin Finck                               WC_STATIC,
689c2c66affSColin Finck                               NULL,
690c2c66affSColin Finck                               WS_OVERLAPPED | WS_DISABLED | WS_CLIPSIBLINGS | WS_BORDER | SS_LEFT,
691c2c66affSColin Finck                               posRect.left,
692c2c66affSColin Finck                               posRect.top,
693c2c66affSColin Finck                               posRect.right - posRect.left,
694c2c66affSColin Finck                               posRect.bottom - posRect.top,
695c2c66affSColin Finck                               NULL,
696c2c66affSColin Finck                               NULL,
697c2c66affSColin Finck                               NULL,
698c2c66affSColin Finck                               NULL);
699c2c66affSColin Finck 
700c2c66affSColin Finck         m_RunFileDlgOwner = hwnd;
701c2c66affSColin Finck 
702c84f3983SKatayama Hirofumi MZ         // build the default directory from two environment variables
703c84f3983SKatayama Hirofumi MZ         CStringW strDefaultDir, strHomePath;
704c84f3983SKatayama Hirofumi MZ         strDefaultDir.GetEnvironmentVariable(L"HOMEDRIVE");
705c84f3983SKatayama Hirofumi MZ         strHomePath.GetEnvironmentVariable(L"HOMEPATH");
706c84f3983SKatayama Hirofumi MZ         strDefaultDir += strHomePath;
707c84f3983SKatayama Hirofumi MZ 
708c84f3983SKatayama Hirofumi MZ         RunFileDlg(hwnd, NULL, (LPCWSTR)strDefaultDir, NULL, NULL, RFF_CALCDIRECTORY);
709c2c66affSColin Finck 
710c2c66affSColin Finck         m_RunFileDlgOwner = NULL;
711c2c66affSColin Finck         ::DestroyWindow(hwnd);
712c2c66affSColin Finck 
713c2c66affSColin Finck         return 0;
714c2c66affSColin Finck     }
715c2c66affSColin Finck 
716c2c66affSColin Finck     static DWORD WINAPI s_RunFileDlgThread(IN OUT PVOID pParam)
717c2c66affSColin Finck     {
718c2c66affSColin Finck         CTrayWindow * This = (CTrayWindow*) pParam;
719c2c66affSColin Finck         return This->RunFileDlgThread();
720c2c66affSColin Finck     }
721c2c66affSColin Finck 
722c2c66affSColin Finck     void DisplayRunFileDlg()
723c2c66affSColin Finck     {
724c2c66affSColin Finck         HWND hRunDlg;
725c2c66affSColin Finck         if (m_RunFileDlgOwner)
726c2c66affSColin Finck         {
727c2c66affSColin Finck             hRunDlg = ::GetLastActivePopup(m_RunFileDlgOwner);
728c2c66affSColin Finck             if (hRunDlg != NULL &&
729c2c66affSColin Finck                 hRunDlg != m_RunFileDlgOwner)
730c2c66affSColin Finck             {
731c2c66affSColin Finck                 SetForegroundWindow(hRunDlg);
732c2c66affSColin Finck                 return;
733c2c66affSColin Finck             }
734c2c66affSColin Finck         }
735c2c66affSColin Finck 
736c2c66affSColin Finck         CloseHandle(CreateThread(NULL, 0, s_RunFileDlgThread, this, 0, NULL));
737c2c66affSColin Finck     }
738c2c66affSColin Finck 
739c2c66affSColin Finck     DWORD WINAPI TrayPropertiesThread()
740c2c66affSColin Finck     {
741c2c66affSColin Finck         HWND hwnd;
742c2c66affSColin Finck         RECT posRect;
743c2c66affSColin Finck 
744c2c66affSColin Finck         m_StartButton.GetWindowRect(&posRect);
745c2c66affSColin Finck         hwnd = CreateWindowEx(0,
746c2c66affSColin Finck                               WC_STATIC,
747c2c66affSColin Finck                               NULL,
748c2c66affSColin Finck                               WS_OVERLAPPED | WS_DISABLED | WS_CLIPSIBLINGS | WS_BORDER | SS_LEFT,
749c2c66affSColin Finck                               posRect.left,
750c2c66affSColin Finck                               posRect.top,
751c2c66affSColin Finck                               posRect.right - posRect.left,
752c2c66affSColin Finck                               posRect.bottom - posRect.top,
753c2c66affSColin Finck                               NULL,
754c2c66affSColin Finck                               NULL,
755c2c66affSColin Finck                               NULL,
756c2c66affSColin Finck                               NULL);
757c2c66affSColin Finck 
758c2c66affSColin Finck         m_TrayPropertiesOwner = hwnd;
759c2c66affSColin Finck 
7602ed535daSGiannis Adamopoulos         DisplayTrayProperties(hwnd, m_hWnd);
761c2c66affSColin Finck 
762c2c66affSColin Finck         m_TrayPropertiesOwner = NULL;
763c2c66affSColin Finck         ::DestroyWindow(hwnd);
764c2c66affSColin Finck 
765c2c66affSColin Finck         return 0;
766c2c66affSColin Finck     }
767c2c66affSColin Finck 
768c2c66affSColin Finck     static DWORD WINAPI s_TrayPropertiesThread(IN OUT PVOID pParam)
769c2c66affSColin Finck     {
770c2c66affSColin Finck         CTrayWindow *This = (CTrayWindow*) pParam;
771c2c66affSColin Finck 
772c2c66affSColin Finck         return This->TrayPropertiesThread();
773c2c66affSColin Finck     }
774c2c66affSColin Finck 
775c2c66affSColin Finck     HWND STDMETHODCALLTYPE DisplayProperties()
776c2c66affSColin Finck     {
777c2c66affSColin Finck         HWND hTrayProp;
778c2c66affSColin Finck 
779c2c66affSColin Finck         if (m_TrayPropertiesOwner)
780c2c66affSColin Finck         {
781c2c66affSColin Finck             hTrayProp = ::GetLastActivePopup(m_TrayPropertiesOwner);
782c2c66affSColin Finck             if (hTrayProp != NULL &&
783c2c66affSColin Finck                 hTrayProp != m_TrayPropertiesOwner)
784c2c66affSColin Finck             {
785c2c66affSColin Finck                 SetForegroundWindow(hTrayProp);
786c2c66affSColin Finck                 return NULL;
787c2c66affSColin Finck             }
788c2c66affSColin Finck         }
789c2c66affSColin Finck 
790c2c66affSColin Finck         CloseHandle(CreateThread(NULL, 0, s_TrayPropertiesThread, this, 0, NULL));
791c2c66affSColin Finck         return NULL;
792c2c66affSColin Finck     }
793c2c66affSColin Finck 
794c2c66affSColin Finck     VOID OpenCommonStartMenuDirectory(IN HWND hWndOwner, IN LPCTSTR lpOperation)
795c2c66affSColin Finck     {
796c2c66affSColin Finck         WCHAR szDir[MAX_PATH];
797c2c66affSColin Finck 
798c2c66affSColin Finck         if (SHGetSpecialFolderPath(hWndOwner,
799c2c66affSColin Finck             szDir,
800c2c66affSColin Finck             CSIDL_COMMON_STARTMENU,
801c2c66affSColin Finck             FALSE))
802c2c66affSColin Finck         {
803c2c66affSColin Finck             ShellExecute(hWndOwner,
804c2c66affSColin Finck                          lpOperation,
805c2c66affSColin Finck                          szDir,
806c2c66affSColin Finck                          NULL,
807c2c66affSColin Finck                          NULL,
808c2c66affSColin Finck                          SW_SHOWNORMAL);
809c2c66affSColin Finck         }
810c2c66affSColin Finck     }
811c2c66affSColin Finck 
812c2c66affSColin Finck     VOID OpenTaskManager(IN HWND hWndOwner)
813c2c66affSColin Finck     {
814c2c66affSColin Finck         ShellExecute(hWndOwner,
815c2c66affSColin Finck                      TEXT("open"),
816c2c66affSColin Finck                      TEXT("taskmgr.exe"),
817c2c66affSColin Finck                      NULL,
818c2c66affSColin Finck                      NULL,
819c2c66affSColin Finck                      SW_SHOWNORMAL);
820c2c66affSColin Finck     }
821c2c66affSColin Finck 
82275b09f3fSKatayama Hirofumi MZ     VOID ToggleDesktop()
82375b09f3fSKatayama Hirofumi MZ     {
82475b09f3fSKatayama Hirofumi MZ         if (::IsThereAnyEffectiveWindow(TRUE))
82575b09f3fSKatayama Hirofumi MZ         {
82675b09f3fSKatayama Hirofumi MZ             ShowDesktop();
82775b09f3fSKatayama Hirofumi MZ         }
82875b09f3fSKatayama Hirofumi MZ         else
82975b09f3fSKatayama Hirofumi MZ         {
83075b09f3fSKatayama Hirofumi MZ             RestoreAll();
83175b09f3fSKatayama Hirofumi MZ         }
83275b09f3fSKatayama Hirofumi MZ     }
83375b09f3fSKatayama Hirofumi MZ 
834c2c66affSColin Finck     BOOL STDMETHODCALLTYPE ExecContextMenuCmd(IN UINT uiCmd)
835c2c66affSColin Finck     {
836c2c66affSColin Finck         switch (uiCmd)
837c2c66affSColin Finck         {
838c2c66affSColin Finck         case ID_SHELL_CMD_PROPERTIES:
839c2c66affSColin Finck             DisplayProperties();
840c2c66affSColin Finck             break;
841c2c66affSColin Finck 
842c2c66affSColin Finck         case ID_SHELL_CMD_OPEN_ALL_USERS:
843c2c66affSColin Finck             OpenCommonStartMenuDirectory(m_hWnd,
844c2c66affSColin Finck                                          TEXT("open"));
845c2c66affSColin Finck             break;
846c2c66affSColin Finck 
847c2c66affSColin Finck         case ID_SHELL_CMD_EXPLORE_ALL_USERS:
848c2c66affSColin Finck             OpenCommonStartMenuDirectory(m_hWnd,
849c2c66affSColin Finck                                          TEXT("explore"));
850c2c66affSColin Finck             break;
851c2c66affSColin Finck 
852c2c66affSColin Finck         case ID_LOCKTASKBAR:
8537fafeb63SCarl J. Bialorucki             HandleCommand(TRAYCMD_LOCK_TASKBAR);
854c2c66affSColin Finck             break;
855c2c66affSColin Finck 
856c2c66affSColin Finck         case ID_SHELL_CMD_OPEN_TASKMGR:
857c2c66affSColin Finck             OpenTaskManager(m_hWnd);
858c2c66affSColin Finck             break;
859c2c66affSColin Finck 
860c2c66affSColin Finck         case ID_SHELL_CMD_UNDO_ACTION:
861be970d8dSTuur Martens             RestoreWindowPos();
862c2c66affSColin Finck             break;
863c2c66affSColin Finck 
864c2c66affSColin Finck         case ID_SHELL_CMD_SHOW_DESKTOP:
86575b09f3fSKatayama Hirofumi MZ             ShowDesktop();
866c2c66affSColin Finck             break;
867c2c66affSColin Finck 
868c2c66affSColin Finck         case ID_SHELL_CMD_TILE_WND_H:
869451a9c6fSKatayama Hirofumi MZ             appbar_notify_all(NULL, ABN_WINDOWARRANGE, NULL, TRUE);
870be970d8dSTuur Martens             if (g_Arrangement == NONE)
871be970d8dSTuur Martens             {
872be970d8dSTuur Martens                 BackupWindowPos();
873be970d8dSTuur Martens             }
874c2c66affSColin Finck             TileWindows(NULL, MDITILE_HORIZONTAL, NULL, 0, NULL);
875451a9c6fSKatayama Hirofumi MZ             appbar_notify_all(NULL, ABN_WINDOWARRANGE, NULL, FALSE);
876be970d8dSTuur Martens             g_Arrangement = TILED;
877c2c66affSColin Finck             break;
878c2c66affSColin Finck 
879c2c66affSColin Finck         case ID_SHELL_CMD_TILE_WND_V:
880451a9c6fSKatayama Hirofumi MZ             appbar_notify_all(NULL, ABN_WINDOWARRANGE, NULL, TRUE);
881be970d8dSTuur Martens             if (g_Arrangement == NONE)
882be970d8dSTuur Martens             {
883be970d8dSTuur Martens                 BackupWindowPos();
884be970d8dSTuur Martens             }
885c2c66affSColin Finck             TileWindows(NULL, MDITILE_VERTICAL, NULL, 0, NULL);
886451a9c6fSKatayama Hirofumi MZ             appbar_notify_all(NULL, ABN_WINDOWARRANGE, NULL, FALSE);
887be970d8dSTuur Martens             g_Arrangement = TILED;
888c2c66affSColin Finck             break;
889c2c66affSColin Finck 
890c2c66affSColin Finck         case ID_SHELL_CMD_CASCADE_WND:
891451a9c6fSKatayama Hirofumi MZ             appbar_notify_all(NULL, ABN_WINDOWARRANGE, NULL, TRUE);
892be970d8dSTuur Martens             if (g_Arrangement == NONE)
893be970d8dSTuur Martens             {
894be970d8dSTuur Martens                 BackupWindowPos();
895be970d8dSTuur Martens             }
896c2c66affSColin Finck             CascadeWindows(NULL, MDITILE_SKIPDISABLED, NULL, 0, NULL);
897451a9c6fSKatayama Hirofumi MZ             appbar_notify_all(NULL, ABN_WINDOWARRANGE, NULL, FALSE);
898be970d8dSTuur Martens             g_Arrangement = CASCADED;
899c2c66affSColin Finck             break;
900c2c66affSColin Finck 
901c2c66affSColin Finck         case ID_SHELL_CMD_CUST_NOTIF:
902c2c66affSColin Finck             ShowCustomizeNotifyIcons(hExplorerInstance, m_hWnd);
903c2c66affSColin Finck             break;
904c2c66affSColin Finck 
905c2c66affSColin Finck         case ID_SHELL_CMD_ADJUST_DAT:
906c2c66affSColin Finck             //FIXME: Use SHRunControlPanel
907c2c66affSColin Finck             ShellExecuteW(m_hWnd, NULL, L"timedate.cpl", NULL, NULL, SW_NORMAL);
908c2c66affSColin Finck             break;
909c2c66affSColin Finck 
91075b09f3fSKatayama Hirofumi MZ         case ID_SHELL_CMD_RESTORE_ALL:
91175b09f3fSKatayama Hirofumi MZ             RestoreAll();
91275b09f3fSKatayama Hirofumi MZ             break;
91375b09f3fSKatayama Hirofumi MZ 
914c2c66affSColin Finck         default:
915c2c66affSColin Finck             TRACE("ITrayWindow::ExecContextMenuCmd(%u): Unhandled Command ID!\n", uiCmd);
916c2c66affSColin Finck             return FALSE;
917c2c66affSColin Finck         }
918c2c66affSColin Finck 
919c2c66affSColin Finck         return TRUE;
920c2c66affSColin Finck     }
921c2c66affSColin Finck 
922802a87dfSKatayama Hirofumi MZ     VOID HideStartMenu()
923802a87dfSKatayama Hirofumi MZ     {
924802a87dfSKatayama Hirofumi MZ         m_StartMenuPopup->OnSelect(MPOS_CANCELLEVEL);
925802a87dfSKatayama Hirofumi MZ     }
926802a87dfSKatayama Hirofumi MZ 
927c2c66affSColin Finck     LRESULT HandleHotKey(DWORD id)
928c2c66affSColin Finck     {
929c2c66affSColin Finck         switch (id)
930c2c66affSColin Finck         {
931c2c66affSColin Finck         case IDHK_RUN:
932802a87dfSKatayama Hirofumi MZ             HideStartMenu();
933c2c66affSColin Finck             DisplayRunFileDlg();
934c2c66affSColin Finck             break;
935c2c66affSColin Finck         case IDHK_HELP:
936c2c66affSColin Finck             ExecResourceCmd(IDS_HELP_COMMAND);
937c2c66affSColin Finck             break;
938c2c66affSColin Finck         case IDHK_EXPLORE:
939c2c66affSColin Finck             //FIXME: We don't support this yet:
940c2c66affSColin Finck             //ShellExecuteW(0, L"explore", NULL, NULL, NULL, 1);
9414b6d929bSGiannis Adamopoulos             ShellExecuteW(0, NULL, L"explorer.exe", L"/e ,", NULL, 1);
942c2c66affSColin Finck             break;
943c2c66affSColin Finck         case IDHK_FIND:
944c2c66affSColin Finck             SHFindFiles(NULL, NULL);
945c2c66affSColin Finck             break;
946c2c66affSColin Finck         case IDHK_FIND_COMPUTER:
947c2c66affSColin Finck             SHFindComputer(NULL, NULL);
948c2c66affSColin Finck             break;
949c2c66affSColin Finck         case IDHK_SYS_PROPERTIES:
950c2c66affSColin Finck             //FIXME: Use SHRunControlPanel
951c2c66affSColin Finck             ShellExecuteW(m_hWnd, NULL, L"sysdm.cpl", NULL, NULL, SW_NORMAL);
952c2c66affSColin Finck             break;
953c2c66affSColin Finck         case IDHK_NEXT_TASK:
954c2c66affSColin Finck             break;
955c2c66affSColin Finck         case IDHK_PREV_TASK:
956c2c66affSColin Finck             break;
957c2c66affSColin Finck         case IDHK_MINIMIZE_ALL:
95875b09f3fSKatayama Hirofumi MZ             MinimizeAll();
959c2c66affSColin Finck             break;
960c2c66affSColin Finck         case IDHK_RESTORE_ALL:
96175b09f3fSKatayama Hirofumi MZ             RestoreAll();
962c2c66affSColin Finck             break;
963c2c66affSColin Finck         case IDHK_DESKTOP:
96475b09f3fSKatayama Hirofumi MZ             ToggleDesktop();
965c2c66affSColin Finck             break;
966c2c66affSColin Finck         case IDHK_PAGER:
967c2c66affSColin Finck             break;
968c2c66affSColin Finck         }
969c2c66affSColin Finck 
970c2c66affSColin Finck         return 0;
971c2c66affSColin Finck     }
972c2c66affSColin Finck 
973c2c66affSColin Finck     LRESULT HandleCommand(UINT uCommand)
974c2c66affSColin Finck     {
975c2c66affSColin Finck         switch (uCommand)
976c2c66affSColin Finck         {
97775b09f3fSKatayama Hirofumi MZ             case TRAYCMD_STARTMENU:
97875b09f3fSKatayama Hirofumi MZ                 // TODO:
979c2c66affSColin Finck                 break;
98075b09f3fSKatayama Hirofumi MZ             case TRAYCMD_RUN_DIALOG:
981802a87dfSKatayama Hirofumi MZ                 HideStartMenu();
982c2c66affSColin Finck                 DisplayRunFileDlg();
983c2c66affSColin Finck                 break;
98475b09f3fSKatayama Hirofumi MZ             case TRAYCMD_LOGOFF_DIALOG:
985c2c66affSColin Finck                 LogoffWindowsDialog(m_hWnd); // FIXME: Maybe handle it in a similar way as DoExitWindows?
986c2c66affSColin Finck                 break;
98775b09f3fSKatayama Hirofumi MZ             case TRAYCMD_CASCADE:
98875b09f3fSKatayama Hirofumi MZ                 CascadeWindows(NULL, MDITILE_SKIPDISABLED, NULL, 0, NULL);
98975b09f3fSKatayama Hirofumi MZ                 break;
99075b09f3fSKatayama Hirofumi MZ             case TRAYCMD_TILE_H:
99175b09f3fSKatayama Hirofumi MZ                 TileWindows(NULL, MDITILE_HORIZONTAL, NULL, 0, NULL);
99275b09f3fSKatayama Hirofumi MZ                 break;
99375b09f3fSKatayama Hirofumi MZ             case TRAYCMD_TILE_V:
99475b09f3fSKatayama Hirofumi MZ                 TileWindows(NULL, MDITILE_VERTICAL, NULL, 0, NULL);
99575b09f3fSKatayama Hirofumi MZ                 break;
99675b09f3fSKatayama Hirofumi MZ             case TRAYCMD_TOGGLE_DESKTOP:
99775b09f3fSKatayama Hirofumi MZ                 ToggleDesktop();
99875b09f3fSKatayama Hirofumi MZ                 break;
99975b09f3fSKatayama Hirofumi MZ             case TRAYCMD_DATE_AND_TIME:
100075b09f3fSKatayama Hirofumi MZ                 ShellExecuteW(m_hWnd, NULL, L"timedate.cpl", NULL, NULL, SW_NORMAL);
100175b09f3fSKatayama Hirofumi MZ                 break;
100275b09f3fSKatayama Hirofumi MZ             case TRAYCMD_TASKBAR_PROPERTIES:
100375b09f3fSKatayama Hirofumi MZ                 DisplayProperties();
100475b09f3fSKatayama Hirofumi MZ                 break;
100575b09f3fSKatayama Hirofumi MZ             case TRAYCMD_MINIMIZE_ALL:
100675b09f3fSKatayama Hirofumi MZ                 MinimizeAll();
100775b09f3fSKatayama Hirofumi MZ                 break;
100875b09f3fSKatayama Hirofumi MZ             case TRAYCMD_RESTORE_ALL:
100975b09f3fSKatayama Hirofumi MZ                 RestoreAll();
101075b09f3fSKatayama Hirofumi MZ                 break;
101175b09f3fSKatayama Hirofumi MZ             case TRAYCMD_SHOW_DESKTOP:
101275b09f3fSKatayama Hirofumi MZ                 ShowDesktop();
101375b09f3fSKatayama Hirofumi MZ                 break;
101475b09f3fSKatayama Hirofumi MZ             case TRAYCMD_SHOW_TASK_MGR:
101575b09f3fSKatayama Hirofumi MZ                 OpenTaskManager(m_hWnd);
101675b09f3fSKatayama Hirofumi MZ                 break;
101775b09f3fSKatayama Hirofumi MZ             case TRAYCMD_CUSTOMIZE_TASKBAR:
101875b09f3fSKatayama Hirofumi MZ                 break;
101975b09f3fSKatayama Hirofumi MZ             case TRAYCMD_LOCK_TASKBAR:
102075b09f3fSKatayama Hirofumi MZ                 if (SHRestricted(REST_CLASSICSHELL) == 0)
102175b09f3fSKatayama Hirofumi MZ                 {
102275b09f3fSKatayama Hirofumi MZ                     Lock(!g_TaskbarSettings.bLock);
10237fafeb63SCarl J. Bialorucki                     g_TaskbarSettings.Save();
102475b09f3fSKatayama Hirofumi MZ                 }
102575b09f3fSKatayama Hirofumi MZ                 break;
102675b09f3fSKatayama Hirofumi MZ             case TRAYCMD_HELP_AND_SUPPORT:
102775b09f3fSKatayama Hirofumi MZ                 ExecResourceCmd(IDS_HELP_COMMAND);
102875b09f3fSKatayama Hirofumi MZ                 break;
102975b09f3fSKatayama Hirofumi MZ             case TRAYCMD_CONTROL_PANEL:
103075b09f3fSKatayama Hirofumi MZ                 // TODO:
103175b09f3fSKatayama Hirofumi MZ                 break;
103275b09f3fSKatayama Hirofumi MZ             case TRAYCMD_SHUTDOWN_DIALOG:
1033c2c66affSColin Finck                 DoExitWindows();
1034c2c66affSColin Finck                 break;
103575b09f3fSKatayama Hirofumi MZ             case TRAYCMD_PRINTERS_AND_FAXES:
103675b09f3fSKatayama Hirofumi MZ                 // TODO:
103775b09f3fSKatayama Hirofumi MZ                 break;
103875b09f3fSKatayama Hirofumi MZ             case TRAYCMD_LOCK_DESKTOP:
103975b09f3fSKatayama Hirofumi MZ                 // TODO:
104075b09f3fSKatayama Hirofumi MZ                 break;
104175b09f3fSKatayama Hirofumi MZ             case TRAYCMD_SWITCH_USER_DIALOG:
104275b09f3fSKatayama Hirofumi MZ                 // TODO:
104375b09f3fSKatayama Hirofumi MZ                 break;
10444d097cf8SBrock Mammen             case IDM_SEARCH:
104575b09f3fSKatayama Hirofumi MZ             case TRAYCMD_SEARCH_FILES:
104675b09f3fSKatayama Hirofumi MZ                 SHFindFiles(NULL, NULL);
104775b09f3fSKatayama Hirofumi MZ                 break;
104875b09f3fSKatayama Hirofumi MZ             case TRAYCMD_SEARCH_COMPUTERS:
104975b09f3fSKatayama Hirofumi MZ                 SHFindComputer(NULL, NULL);
105075b09f3fSKatayama Hirofumi MZ                 break;
105175b09f3fSKatayama Hirofumi MZ 
105275b09f3fSKatayama Hirofumi MZ             default:
105375b09f3fSKatayama Hirofumi MZ                 break;
1054c2c66affSColin Finck         }
1055c2c66affSColin Finck 
1056c2c66affSColin Finck         return FALSE;
1057c2c66affSColin Finck     }
1058c2c66affSColin Finck 
1059c2c66affSColin Finck 
1060c2c66affSColin Finck     UINT TrackMenu(
1061c2c66affSColin Finck         IN HMENU hMenu,
1062c2c66affSColin Finck         IN POINT *ppt OPTIONAL,
1063c2c66affSColin Finck         IN HWND hwndExclude OPTIONAL,
1064c2c66affSColin Finck         IN BOOL TrackUp,
1065c2c66affSColin Finck         IN BOOL IsContextMenu)
1066c2c66affSColin Finck     {
1067c2c66affSColin Finck         TPMPARAMS tmp, *ptmp = NULL;
1068c2c66affSColin Finck         POINT pt;
1069c2c66affSColin Finck         UINT cmdId;
1070c2c66affSColin Finck         UINT fuFlags;
1071c2c66affSColin Finck 
1072c2c66affSColin Finck         if (hwndExclude != NULL)
1073c2c66affSColin Finck         {
1074c2c66affSColin Finck             /* Get the client rectangle and map it to screen coordinates */
1075c2c66affSColin Finck             if (::GetClientRect(hwndExclude,
1076c2c66affSColin Finck                 &tmp.rcExclude) &&
1077c2c66affSColin Finck                 ::MapWindowPoints(hwndExclude,
1078c2c66affSColin Finck                 NULL,
1079c2c66affSColin Finck                 (LPPOINT) &tmp.rcExclude,
1080c2c66affSColin Finck                 2) != 0)
1081c2c66affSColin Finck             {
1082c2c66affSColin Finck                 ptmp = &tmp;
1083c2c66affSColin Finck             }
1084c2c66affSColin Finck         }
1085c2c66affSColin Finck 
1086c2c66affSColin Finck         if (ppt == NULL)
1087c2c66affSColin Finck         {
1088c2c66affSColin Finck             if (ptmp == NULL &&
1089c2c66affSColin Finck                 GetClientRect(&tmp.rcExclude) &&
1090c2c66affSColin Finck                 MapWindowPoints(
1091c2c66affSColin Finck                 NULL,
1092c2c66affSColin Finck                 (LPPOINT) &tmp.rcExclude,
1093c2c66affSColin Finck                 2) != 0)
1094c2c66affSColin Finck             {
1095c2c66affSColin Finck                 ptmp = &tmp;
1096c2c66affSColin Finck             }
1097c2c66affSColin Finck 
1098c2c66affSColin Finck             if (ptmp != NULL)
1099c2c66affSColin Finck             {
1100c2c66affSColin Finck                 /* NOTE: TrackPopupMenuEx will eventually align the track position
1101c2c66affSColin Finck                          for us, no need to take care of it here as long as the
1102c2c66affSColin Finck                          coordinates are somewhere within the exclusion rectangle */
1103c2c66affSColin Finck                 pt.x = ptmp->rcExclude.left;
1104c2c66affSColin Finck                 pt.y = ptmp->rcExclude.top;
1105c2c66affSColin Finck             }
1106c2c66affSColin Finck             else
1107c2c66affSColin Finck                 pt.x = pt.y = 0;
1108c2c66affSColin Finck         }
1109c2c66affSColin Finck         else
1110c2c66affSColin Finck             pt = *ppt;
1111c2c66affSColin Finck 
1112c2c66affSColin Finck         tmp.cbSize = sizeof(tmp);
1113c2c66affSColin Finck 
1114c2c66affSColin Finck         fuFlags = TPM_RETURNCMD | TPM_VERTICAL;
1115c2c66affSColin Finck         fuFlags |= (TrackUp ? TPM_BOTTOMALIGN : TPM_TOPALIGN);
1116c2c66affSColin Finck         if (IsContextMenu)
1117c2c66affSColin Finck             fuFlags |= TPM_RIGHTBUTTON;
1118c2c66affSColin Finck         else
1119c2c66affSColin Finck             fuFlags |= (TrackUp ? TPM_VERNEGANIMATION : TPM_VERPOSANIMATION);
1120c2c66affSColin Finck 
1121c2c66affSColin Finck         cmdId = TrackPopupMenuEx(hMenu,
1122c2c66affSColin Finck                                  fuFlags,
1123c2c66affSColin Finck                                  pt.x,
1124c2c66affSColin Finck                                  pt.y,
1125c2c66affSColin Finck                                  m_hWnd,
1126c2c66affSColin Finck                                  ptmp);
1127c2c66affSColin Finck 
1128c2c66affSColin Finck         return cmdId;
1129c2c66affSColin Finck     }
1130c2c66affSColin Finck 
1131c2c66affSColin Finck     HRESULT TrackCtxMenu(
1132c2c66affSColin Finck         IN IContextMenu * contextMenu,
1133c2c66affSColin Finck         IN POINT *ppt OPTIONAL,
1134c2c66affSColin Finck         IN HWND hwndExclude OPTIONAL,
1135c2c66affSColin Finck         IN BOOL TrackUp,
1136c2c66affSColin Finck         IN PVOID Context OPTIONAL)
1137c2c66affSColin Finck     {
113858825de8SKatayama Hirofumi MZ         POINT pt;
113958825de8SKatayama Hirofumi MZ         TPMPARAMS params;
114058825de8SKatayama Hirofumi MZ         RECT rc;
1141c2c66affSColin Finck         HRESULT hr;
1142c2c66affSColin Finck         UINT uCommand;
1143c2c66affSColin Finck         HMENU popup = CreatePopupMenu();
1144c2c66affSColin Finck 
1145c2c66affSColin Finck         if (popup == NULL)
1146c2c66affSColin Finck             return E_FAIL;
1147c2c66affSColin Finck 
114858825de8SKatayama Hirofumi MZ         if (ppt)
114958825de8SKatayama Hirofumi MZ         {
115058825de8SKatayama Hirofumi MZ             pt = *ppt;
115158825de8SKatayama Hirofumi MZ         }
115258825de8SKatayama Hirofumi MZ         else
115358825de8SKatayama Hirofumi MZ         {
115458825de8SKatayama Hirofumi MZ             ::GetWindowRect(m_hWnd, &rc);
115558825de8SKatayama Hirofumi MZ             pt.x = rc.left;
115658825de8SKatayama Hirofumi MZ             pt.y = rc.top;
115758825de8SKatayama Hirofumi MZ         }
115858825de8SKatayama Hirofumi MZ 
1159c2c66affSColin Finck         TRACE("Before Query\n");
1160c2c66affSColin Finck         hr = contextMenu->QueryContextMenu(popup, 0, 0, UINT_MAX, CMF_NORMAL);
1161c2c66affSColin Finck         if (FAILED_UNEXPECTEDLY(hr))
1162c2c66affSColin Finck         {
1163c2c66affSColin Finck             TRACE("Query failed\n");
1164c2c66affSColin Finck             DestroyMenu(popup);
1165c2c66affSColin Finck             return hr;
1166c2c66affSColin Finck         }
1167c2c66affSColin Finck 
1168c2c66affSColin Finck         TRACE("Before Tracking\n");
116958825de8SKatayama Hirofumi MZ         ::SetForegroundWindow(m_hWnd);
117058825de8SKatayama Hirofumi MZ         if (hwndExclude)
117158825de8SKatayama Hirofumi MZ         {
117258825de8SKatayama Hirofumi MZ             ::GetWindowRect(hwndExclude, &rc);
117358825de8SKatayama Hirofumi MZ             ZeroMemory(&params, sizeof(params));
117458825de8SKatayama Hirofumi MZ             params.cbSize = sizeof(params);
117558825de8SKatayama Hirofumi MZ             params.rcExclude = rc;
117658825de8SKatayama Hirofumi MZ             uCommand = ::TrackPopupMenuEx(popup, TPM_RETURNCMD, pt.x, pt.y, m_hWnd, &params);
117758825de8SKatayama Hirofumi MZ         }
117858825de8SKatayama Hirofumi MZ         else
117958825de8SKatayama Hirofumi MZ         {
118058825de8SKatayama Hirofumi MZ             uCommand = ::TrackPopupMenuEx(popup, TPM_RETURNCMD, pt.x, pt.y, m_hWnd, NULL);
118158825de8SKatayama Hirofumi MZ         }
118258825de8SKatayama Hirofumi MZ         ::PostMessage(m_hWnd, WM_NULL, 0, 0);
1183c2c66affSColin Finck 
1184c2c66affSColin Finck         if (uCommand != 0)
1185c2c66affSColin Finck         {
1186c2c66affSColin Finck             TRACE("Before InvokeCommand\n");
1187c2c66affSColin Finck             CMINVOKECOMMANDINFO cmi = { 0 };
1188c2c66affSColin Finck             cmi.cbSize = sizeof(cmi);
1189c2c66affSColin Finck             cmi.lpVerb = MAKEINTRESOURCEA(uCommand);
1190c2c66affSColin Finck             cmi.hwnd = m_hWnd;
1191c2c66affSColin Finck             hr = contextMenu->InvokeCommand(&cmi);
1192c2c66affSColin Finck         }
1193c2c66affSColin Finck         else
1194c2c66affSColin Finck         {
1195c2c66affSColin Finck             TRACE("TrackPopupMenu failed. Code=%d, LastError=%d\n", uCommand, GetLastError());
1196c2c66affSColin Finck             hr = S_FALSE;
1197c2c66affSColin Finck         }
1198c2c66affSColin Finck 
1199c2c66affSColin Finck         DestroyMenu(popup);
1200c2c66affSColin Finck         return hr;
1201c2c66affSColin Finck     }
1202c2c66affSColin Finck 
1203c2c66affSColin Finck 
1204c2c66affSColin Finck 
1205c2c66affSColin Finck 
1206c2c66affSColin Finck 
1207c2c66affSColin Finck     /**********************************************************
1208c2c66affSColin Finck      *    ##### moving and sizing handling #####
1209c2c66affSColin Finck      */
1210c2c66affSColin Finck 
1211c2c66affSColin Finck     void UpdateFonts()
1212c2c66affSColin Finck     {
1213c2c66affSColin Finck         /* There is nothing to do if themes are enabled */
1214c2c66affSColin Finck         if (m_Theme)
1215c2c66affSColin Finck             return;
1216c2c66affSColin Finck 
1217c2c66affSColin Finck         m_StartButton.UpdateFont();
1218c2c66affSColin Finck 
1219c2c66affSColin Finck         NONCLIENTMETRICS ncm = {sizeof(ncm)};
1220c2c66affSColin Finck         if (!SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, FALSE))
1221c2c66affSColin Finck         {
1222c2c66affSColin Finck             ERR("SPI_GETNONCLIENTMETRICS failed\n");
1223c2c66affSColin Finck             return;
1224c2c66affSColin Finck         }
1225c2c66affSColin Finck 
1226c2c66affSColin Finck         if (m_Font != NULL)
1227c2c66affSColin Finck             DeleteObject(m_Font);
1228c2c66affSColin Finck 
1229c2c66affSColin Finck         ncm.lfCaptionFont.lfWeight = FW_NORMAL;
1230c2c66affSColin Finck         m_Font = CreateFontIndirect(&ncm.lfCaptionFont);
1231c2c66affSColin Finck         if (!m_Font)
1232c2c66affSColin Finck         {
1233c2c66affSColin Finck             ERR("CreateFontIndirect failed\n");
1234c2c66affSColin Finck             return;
1235c2c66affSColin Finck         }
1236c2c66affSColin Finck 
1237c2c66affSColin Finck         SendMessage(m_Rebar, WM_SETFONT, (WPARAM) m_Font, TRUE);
1238c2c66affSColin Finck         SendMessage(m_TaskSwitch, WM_SETFONT, (WPARAM) m_Font, TRUE);
1239c2c66affSColin Finck         SendMessage(m_TrayNotify, WM_SETFONT, (WPARAM) m_Font, TRUE);
1240c2c66affSColin Finck     }
1241c2c66affSColin Finck 
1242c2c66affSColin Finck     HMONITOR GetScreenRectFromRect(
1243c2c66affSColin Finck         IN OUT RECT *pRect,
1244c2c66affSColin Finck         IN DWORD dwFlags)
1245c2c66affSColin Finck     {
1246c2c66affSColin Finck         MONITORINFO mi;
1247c2c66affSColin Finck         HMONITOR hMon;
1248c2c66affSColin Finck 
1249c2c66affSColin Finck         mi.cbSize = sizeof(mi);
1250c2c66affSColin Finck         hMon = MonitorFromRect(pRect, dwFlags);
1251c2c66affSColin Finck         if (hMon != NULL &&
1252c2c66affSColin Finck             GetMonitorInfo(hMon, &mi))
1253c2c66affSColin Finck         {
1254c2c66affSColin Finck             *pRect = mi.rcMonitor;
1255c2c66affSColin Finck         }
1256c2c66affSColin Finck         else
1257c2c66affSColin Finck         {
1258c2c66affSColin Finck             pRect->left = 0;
1259c2c66affSColin Finck             pRect->top = 0;
1260c2c66affSColin Finck             pRect->right = GetSystemMetrics(SM_CXSCREEN);
1261c2c66affSColin Finck             pRect->bottom = GetSystemMetrics(SM_CYSCREEN);
1262c2c66affSColin Finck 
1263c2c66affSColin Finck             hMon = NULL;
1264c2c66affSColin Finck         }
1265c2c66affSColin Finck 
1266c2c66affSColin Finck         return hMon;
1267c2c66affSColin Finck     }
1268c2c66affSColin Finck 
1269c2c66affSColin Finck     HMONITOR GetMonitorFromRect(
1270c2c66affSColin Finck         IN const RECT *pRect)
1271c2c66affSColin Finck     {
1272c2c66affSColin Finck         HMONITOR hMon;
1273c2c66affSColin Finck 
1274c2c66affSColin Finck         /* In case the monitor sizes or saved sizes differ a bit (probably
1275c2c66affSColin Finck            not a lot, only so the tray window overlaps into another monitor
1276c2c66affSColin Finck            now), minimize the risk that we determine a wrong monitor by
1277c2c66affSColin Finck            using the center point of the tray window if we can't determine
1278c2c66affSColin Finck            it using the rectangle. */
1279c2c66affSColin Finck         hMon = MonitorFromRect(pRect, MONITOR_DEFAULTTONULL);
1280c2c66affSColin Finck         if (hMon == NULL)
1281c2c66affSColin Finck         {
1282c2c66affSColin Finck             POINT pt;
1283c2c66affSColin Finck 
1284c2c66affSColin Finck             pt.x = pRect->left + ((pRect->right - pRect->left) / 2);
1285c2c66affSColin Finck             pt.y = pRect->top + ((pRect->bottom - pRect->top) / 2);
1286c2c66affSColin Finck 
1287c2c66affSColin Finck             /* be less error-prone, find the nearest monitor */
1288c2c66affSColin Finck             hMon = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST);
1289c2c66affSColin Finck         }
1290c2c66affSColin Finck 
1291c2c66affSColin Finck         return hMon;
1292c2c66affSColin Finck     }
1293c2c66affSColin Finck 
1294c2c66affSColin Finck     HMONITOR GetScreenRect(
1295c2c66affSColin Finck         IN HMONITOR hMonitor,
1296c2c66affSColin Finck         IN OUT RECT *pRect)
1297c2c66affSColin Finck     {
1298c2c66affSColin Finck         HMONITOR hMon = NULL;
1299c2c66affSColin Finck 
1300c2c66affSColin Finck         if (hMonitor != NULL)
1301c2c66affSColin Finck         {
1302c2c66affSColin Finck             MONITORINFO mi;
1303c2c66affSColin Finck 
1304c2c66affSColin Finck             mi.cbSize = sizeof(mi);
1305c2c66affSColin Finck             if (!GetMonitorInfo(hMonitor, &mi))
1306c2c66affSColin Finck             {
1307c2c66affSColin Finck                 /* Hm, the monitor is gone? Try to find a monitor where it
1308c2c66affSColin Finck                    could be located now */
1309c2c66affSColin Finck                 hMon = GetMonitorFromRect(pRect);
1310c2c66affSColin Finck                 if (hMon == NULL ||
1311c2c66affSColin Finck                     !GetMonitorInfo(hMon, &mi))
1312c2c66affSColin Finck                 {
1313c2c66affSColin Finck                     hMon = NULL;
1314c2c66affSColin Finck                     goto GetPrimaryRect;
1315c2c66affSColin Finck                 }
1316c2c66affSColin Finck             }
1317c2c66affSColin Finck 
1318c2c66affSColin Finck             *pRect = mi.rcMonitor;
1319c2c66affSColin Finck         }
1320c2c66affSColin Finck         else
1321c2c66affSColin Finck         {
1322c2c66affSColin Finck GetPrimaryRect:
1323c2c66affSColin Finck             pRect->left = 0;
1324c2c66affSColin Finck             pRect->top = 0;
1325c2c66affSColin Finck             pRect->right = GetSystemMetrics(SM_CXSCREEN);
1326c2c66affSColin Finck             pRect->bottom = GetSystemMetrics(SM_CYSCREEN);
1327c2c66affSColin Finck         }
1328c2c66affSColin Finck 
1329c2c66affSColin Finck         return hMon;
1330c2c66affSColin Finck     }
1331c2c66affSColin Finck 
1332c2c66affSColin Finck     VOID AdjustSizerRect(RECT *rc, DWORD pos)
1333c2c66affSColin Finck     {
1334c2c66affSColin Finck         int iSizerPart[4] = {TBP_SIZINGBARLEFT, TBP_SIZINGBARTOP, TBP_SIZINGBARRIGHT, TBP_SIZINGBARBOTTOM};
1335c2c66affSColin Finck         SIZE size;
1336c2c66affSColin Finck 
1337c2c66affSColin Finck         if (pos > ABE_BOTTOM)
1338c2c66affSColin Finck             pos = ABE_BOTTOM;
1339c2c66affSColin Finck 
1340c2c66affSColin Finck         HRESULT hr = GetThemePartSize(m_Theme, NULL, iSizerPart[pos], 0, NULL, TS_TRUE, &size);
1341c2c66affSColin Finck         if (FAILED_UNEXPECTEDLY(hr))
1342c2c66affSColin Finck             return;
1343c2c66affSColin Finck 
1344c2c66affSColin Finck         switch (pos)
1345c2c66affSColin Finck         {
1346c2c66affSColin Finck             case ABE_TOP:
1347c2c66affSColin Finck                 rc->bottom -= size.cy;
1348c2c66affSColin Finck                 break;
1349c2c66affSColin Finck             case ABE_BOTTOM:
1350c2c66affSColin Finck                 rc->top += size.cy;
1351c2c66affSColin Finck                 break;
1352c2c66affSColin Finck             case ABE_LEFT:
1353c2c66affSColin Finck                 rc->right -= size.cx;
1354c2c66affSColin Finck                 break;
1355c2c66affSColin Finck             case ABE_RIGHT:
1356c2c66affSColin Finck                 rc->left += size.cx;
1357c2c66affSColin Finck                 break;
1358c2c66affSColin Finck         }
1359c2c66affSColin Finck     }
1360c2c66affSColin Finck 
1361c2c66affSColin Finck     VOID MakeTrayRectWithSize(IN DWORD Position,
1362c2c66affSColin Finck                               IN const SIZE *pTraySize,
1363c2c66affSColin Finck                               IN OUT RECT *pRect)
1364c2c66affSColin Finck     {
1365c2c66affSColin Finck         switch (Position)
1366c2c66affSColin Finck         {
1367c2c66affSColin Finck         case ABE_LEFT:
1368c2c66affSColin Finck             pRect->right = pRect->left + pTraySize->cx;
1369c2c66affSColin Finck             break;
1370c2c66affSColin Finck 
1371c2c66affSColin Finck         case ABE_TOP:
1372c2c66affSColin Finck             pRect->bottom = pRect->top + pTraySize->cy;
1373c2c66affSColin Finck             break;
1374c2c66affSColin Finck 
1375c2c66affSColin Finck         case ABE_RIGHT:
1376c2c66affSColin Finck             pRect->left = pRect->right - pTraySize->cx;
1377c2c66affSColin Finck             break;
1378c2c66affSColin Finck 
1379c2c66affSColin Finck         case ABE_BOTTOM:
1380c2c66affSColin Finck         default:
1381c2c66affSColin Finck             pRect->top = pRect->bottom - pTraySize->cy;
1382c2c66affSColin Finck             break;
1383c2c66affSColin Finck         }
1384c2c66affSColin Finck     }
1385c2c66affSColin Finck 
1386c2c66affSColin Finck     VOID GetTrayRectFromScreenRect(IN DWORD Position,
1387c2c66affSColin Finck                                    IN const RECT *pScreen,
1388c2c66affSColin Finck                                    IN const SIZE *pTraySize OPTIONAL,
1389c2c66affSColin Finck                                    OUT RECT *pRect)
1390c2c66affSColin Finck     {
1391c2c66affSColin Finck         if (pTraySize == NULL)
1392c2c66affSColin Finck             pTraySize = &m_TraySize;
1393c2c66affSColin Finck 
1394c2c66affSColin Finck         *pRect = *pScreen;
1395c2c66affSColin Finck 
1396c2c66affSColin Finck         if(!m_Theme)
1397c2c66affSColin Finck         {
1398c2c66affSColin Finck             /* Move the border outside of the screen */
1399c2c66affSColin Finck             InflateRect(pRect,
1400c2c66affSColin Finck                         GetSystemMetrics(SM_CXEDGE),
1401c2c66affSColin Finck                         GetSystemMetrics(SM_CYEDGE));
1402c2c66affSColin Finck         }
1403c2c66affSColin Finck 
1404c2c66affSColin Finck         MakeTrayRectWithSize(Position, pTraySize, pRect);
1405c2c66affSColin Finck     }
1406c2c66affSColin Finck 
1407c2c66affSColin Finck     BOOL IsPosHorizontal()
1408c2c66affSColin Finck     {
1409c2c66affSColin Finck         return m_Position == ABE_TOP || m_Position == ABE_BOTTOM;
1410c2c66affSColin Finck     }
1411c2c66affSColin Finck 
1412c2c66affSColin Finck     HMONITOR CalculateValidSize(
1413c2c66affSColin Finck         IN DWORD Position,
1414c2c66affSColin Finck         IN OUT RECT *pRect)
1415c2c66affSColin Finck     {
1416c2c66affSColin Finck         RECT rcScreen;
1417c2c66affSColin Finck         //BOOL Horizontal;
1418c2c66affSColin Finck         HMONITOR hMon;
1419c2c66affSColin Finck         SIZE szMax, szWnd;
1420c2c66affSColin Finck 
1421c2c66affSColin Finck         //Horizontal = IsPosHorizontal();
1422c2c66affSColin Finck 
1423c2c66affSColin Finck         szWnd.cx = pRect->right - pRect->left;
1424c2c66affSColin Finck         szWnd.cy = pRect->bottom - pRect->top;
1425c2c66affSColin Finck 
1426c2c66affSColin Finck         rcScreen = *pRect;
1427c2c66affSColin Finck         hMon = GetScreenRectFromRect(
1428c2c66affSColin Finck             &rcScreen,
1429c2c66affSColin Finck             MONITOR_DEFAULTTONEAREST);
1430c2c66affSColin Finck 
1431c2c66affSColin Finck         /* Calculate the maximum size of the tray window and limit the window
1432c2c66affSColin Finck            size to half of the screen's size. */
1433c2c66affSColin Finck         szMax.cx = (rcScreen.right - rcScreen.left) / 2;
1434c2c66affSColin Finck         szMax.cy = (rcScreen.bottom - rcScreen.top) / 2;
1435c2c66affSColin Finck         if (szWnd.cx > szMax.cx)
1436c2c66affSColin Finck             szWnd.cx = szMax.cx;
1437c2c66affSColin Finck         if (szWnd.cy > szMax.cy)
1438c2c66affSColin Finck             szWnd.cy = szMax.cy;
1439c2c66affSColin Finck 
1440c2c66affSColin Finck         /* FIXME - calculate */
1441c2c66affSColin Finck 
1442c2c66affSColin Finck         GetTrayRectFromScreenRect(Position,
1443c2c66affSColin Finck                                   &rcScreen,
1444c2c66affSColin Finck                                   &szWnd,
1445c2c66affSColin Finck                                   pRect);
1446c2c66affSColin Finck 
1447c2c66affSColin Finck         return hMon;
1448c2c66affSColin Finck     }
1449c2c66affSColin Finck 
1450c2c66affSColin Finck #if 0
1451c2c66affSColin Finck     VOID
1452c2c66affSColin Finck         GetMinimumWindowSize(
1453c2c66affSColin Finck         OUT RECT *pRect)
1454c2c66affSColin Finck     {
1455c2c66affSColin Finck         RECT rcMin = {0};
1456c2c66affSColin Finck 
1457c2c66affSColin Finck         AdjustWindowRectEx(&rcMin,
1458c2c66affSColin Finck                            GetWindowLong(m_hWnd,
1459c2c66affSColin Finck                            GWL_STYLE),
1460c2c66affSColin Finck                            FALSE,
1461c2c66affSColin Finck                            GetWindowLong(m_hWnd,
1462c2c66affSColin Finck                            GWL_EXSTYLE));
1463c2c66affSColin Finck 
1464c2c66affSColin Finck         *pRect = rcMin;
1465c2c66affSColin Finck     }
1466c2c66affSColin Finck #endif
1467c2c66affSColin Finck 
1468c2c66affSColin Finck 
1469c2c66affSColin Finck     DWORD GetDraggingRectFromPt(
1470c2c66affSColin Finck         IN POINT pt,
1471c2c66affSColin Finck         OUT RECT *pRect,
1472c2c66affSColin Finck         OUT HMONITOR *phMonitor)
1473c2c66affSColin Finck     {
1474c2c66affSColin Finck         HMONITOR hMon, hMonNew;
1475c2c66affSColin Finck         DWORD PosH, PosV, Pos;
1476c2c66affSColin Finck         SIZE DeltaPt, ScreenOffset;
1477c2c66affSColin Finck         RECT rcScreen;
1478c2c66affSColin Finck 
1479c2c66affSColin Finck         rcScreen.left = 0;
1480c2c66affSColin Finck         rcScreen.top = 0;
1481c2c66affSColin Finck 
1482c2c66affSColin Finck         /* Determine the screen rectangle */
1483c2c66affSColin Finck         hMon = MonitorFromPoint(pt, MONITOR_DEFAULTTONULL);
1484c2c66affSColin Finck         if (hMon != NULL)
1485c2c66affSColin Finck         {
1486c2c66affSColin Finck             MONITORINFO mi;
1487c2c66affSColin Finck 
1488c2c66affSColin Finck             mi.cbSize = sizeof(mi);
1489c2c66affSColin Finck             if (!GetMonitorInfo(hMon, &mi))
1490c2c66affSColin Finck             {
1491c2c66affSColin Finck                 hMon = NULL;
1492c2c66affSColin Finck                 goto GetPrimaryScreenRect;
1493c2c66affSColin Finck             }
1494c2c66affSColin Finck 
1495c2c66affSColin Finck             /* make left top corner of the screen zero based to
1496c2c66affSColin Finck                make calculations easier */
1497c2c66affSColin Finck             pt.x -= mi.rcMonitor.left;
1498c2c66affSColin Finck             pt.y -= mi.rcMonitor.top;
1499c2c66affSColin Finck 
1500c2c66affSColin Finck             ScreenOffset.cx = mi.rcMonitor.left;
1501c2c66affSColin Finck             ScreenOffset.cy = mi.rcMonitor.top;
1502c2c66affSColin Finck             rcScreen.right = mi.rcMonitor.right - mi.rcMonitor.left;
1503c2c66affSColin Finck             rcScreen.bottom = mi.rcMonitor.bottom - mi.rcMonitor.top;
1504c2c66affSColin Finck         }
1505c2c66affSColin Finck         else
1506c2c66affSColin Finck         {
1507c2c66affSColin Finck GetPrimaryScreenRect:
1508c2c66affSColin Finck             ScreenOffset.cx = 0;
1509c2c66affSColin Finck             ScreenOffset.cy = 0;
1510c2c66affSColin Finck             rcScreen.right = GetSystemMetrics(SM_CXSCREEN);
1511c2c66affSColin Finck             rcScreen.bottom = GetSystemMetrics(SM_CYSCREEN);
1512c2c66affSColin Finck         }
1513c2c66affSColin Finck 
1514c2c66affSColin Finck         /* Calculate the nearest screen border */
1515c2c66affSColin Finck         if (pt.x < rcScreen.right / 2)
1516c2c66affSColin Finck         {
1517c2c66affSColin Finck             DeltaPt.cx = pt.x;
1518c2c66affSColin Finck             PosH = ABE_LEFT;
1519c2c66affSColin Finck         }
1520c2c66affSColin Finck         else
1521c2c66affSColin Finck         {
1522c2c66affSColin Finck             DeltaPt.cx = rcScreen.right - pt.x;
1523c2c66affSColin Finck             PosH = ABE_RIGHT;
1524c2c66affSColin Finck         }
1525c2c66affSColin Finck 
1526c2c66affSColin Finck         if (pt.y < rcScreen.bottom / 2)
1527c2c66affSColin Finck         {
1528c2c66affSColin Finck             DeltaPt.cy = pt.y;
1529c2c66affSColin Finck             PosV = ABE_TOP;
1530c2c66affSColin Finck         }
1531c2c66affSColin Finck         else
1532c2c66affSColin Finck         {
1533c2c66affSColin Finck             DeltaPt.cy = rcScreen.bottom - pt.y;
1534c2c66affSColin Finck             PosV = ABE_BOTTOM;
1535c2c66affSColin Finck         }
1536c2c66affSColin Finck 
1537c2c66affSColin Finck         Pos = (DeltaPt.cx * rcScreen.bottom < DeltaPt.cy * rcScreen.right) ? PosH : PosV;
1538c2c66affSColin Finck 
1539c2c66affSColin Finck         /* Fix the screen origin to be relative to the primary monitor again */
1540c2c66affSColin Finck         OffsetRect(&rcScreen,
1541c2c66affSColin Finck                    ScreenOffset.cx,
1542c2c66affSColin Finck                    ScreenOffset.cy);
1543c2c66affSColin Finck 
1544c2c66affSColin Finck         RECT rcPos = m_TrayRects[Pos];
1545c2c66affSColin Finck 
1546c2c66affSColin Finck         hMonNew = GetMonitorFromRect(&rcPos);
1547c2c66affSColin Finck         if (hMon != hMonNew)
1548c2c66affSColin Finck         {
1549c2c66affSColin Finck             SIZE szTray;
1550c2c66affSColin Finck 
1551c2c66affSColin Finck             /* Recalculate the rectangle, we're dragging to another monitor.
1552c2c66affSColin Finck                We don't need to recalculate the rect on single monitor systems. */
1553c2c66affSColin Finck             szTray.cx = rcPos.right - rcPos.left;
1554c2c66affSColin Finck             szTray.cy = rcPos.bottom - rcPos.top;
1555c2c66affSColin Finck 
1556c2c66affSColin Finck             GetTrayRectFromScreenRect(Pos, &rcScreen, &szTray, pRect);
1557c2c66affSColin Finck             hMon = hMonNew;
1558c2c66affSColin Finck         }
1559c2c66affSColin Finck         else
1560c2c66affSColin Finck         {
1561c2c66affSColin Finck             /* The user is dragging the tray window on the same monitor. We don't need
1562c2c66affSColin Finck                to recalculate the rectangle */
1563c2c66affSColin Finck             *pRect = rcPos;
1564c2c66affSColin Finck         }
1565c2c66affSColin Finck 
1566c2c66affSColin Finck         *phMonitor = hMon;
1567c2c66affSColin Finck 
1568c2c66affSColin Finck         return Pos;
1569c2c66affSColin Finck     }
1570c2c66affSColin Finck 
1571c2c66affSColin Finck     DWORD GetDraggingRectFromRect(
1572c2c66affSColin Finck         IN OUT RECT *pRect,
1573c2c66affSColin Finck         OUT HMONITOR *phMonitor)
1574c2c66affSColin Finck     {
1575c2c66affSColin Finck         POINT pt;
1576c2c66affSColin Finck 
1577c2c66affSColin Finck         /* Calculate the center of the rectangle. We call
1578c2c66affSColin Finck            GetDraggingRectFromPt to calculate a valid
1579c2c66affSColin Finck            dragging rectangle */
1580c2c66affSColin Finck         pt.x = pRect->left + ((pRect->right - pRect->left) / 2);
1581c2c66affSColin Finck         pt.y = pRect->top + ((pRect->bottom - pRect->top) / 2);
1582c2c66affSColin Finck 
1583c2c66affSColin Finck         return GetDraggingRectFromPt(
1584c2c66affSColin Finck             pt,
1585c2c66affSColin Finck             pRect,
1586c2c66affSColin Finck             phMonitor);
1587c2c66affSColin Finck     }
1588c2c66affSColin Finck 
1589c2c66affSColin Finck     VOID ChangingWinPos(IN OUT LPWINDOWPOS pwp)
1590c2c66affSColin Finck     {
1591c2c66affSColin Finck         RECT rcTray;
1592c2c66affSColin Finck 
1593c2c66affSColin Finck         if (IsDragging)
1594c2c66affSColin Finck         {
1595c2c66affSColin Finck             rcTray.left = pwp->x;
1596c2c66affSColin Finck             rcTray.top = pwp->y;
1597c2c66affSColin Finck             rcTray.right = rcTray.left + pwp->cx;
1598c2c66affSColin Finck             rcTray.bottom = rcTray.top + pwp->cy;
1599c2c66affSColin Finck 
1600c2c66affSColin Finck             if (!EqualRect(&rcTray,
1601c2c66affSColin Finck                 &m_TrayRects[m_DraggingPosition]))
1602c2c66affSColin Finck             {
1603c2c66affSColin Finck                 /* Recalculate the rectangle, the user dragged the tray
1604c2c66affSColin Finck                    window to another monitor or the window was somehow else
1605c2c66affSColin Finck                    moved or resized */
1606c2c66affSColin Finck                 m_DraggingPosition = GetDraggingRectFromRect(
1607c2c66affSColin Finck                     &rcTray,
1608c2c66affSColin Finck                     &m_DraggingMonitor);
1609c2c66affSColin Finck                 //m_TrayRects[DraggingPosition] = rcTray;
1610c2c66affSColin Finck             }
1611c2c66affSColin Finck 
1612c2c66affSColin Finck             //Monitor = CalculateValidSize(DraggingPosition,
1613c2c66affSColin Finck             //                             &rcTray);
1614c2c66affSColin Finck 
1615c2c66affSColin Finck             m_Monitor = m_DraggingMonitor;
1616c2c66affSColin Finck             m_Position = m_DraggingPosition;
16177fafeb63SCarl J. Bialorucki             g_TaskbarSettings.sr.Position = m_Position;
16187fafeb63SCarl J. Bialorucki             g_TaskbarSettings.Save();
1619c2c66affSColin Finck             IsDragging = FALSE;
1620c2c66affSColin Finck 
1621c2c66affSColin Finck             m_TrayRects[m_Position] = rcTray;
1622c2c66affSColin Finck             goto ChangePos;
1623c2c66affSColin Finck         }
1624c2c66affSColin Finck         else if (GetWindowRect(&rcTray))
1625c2c66affSColin Finck         {
1626c2c66affSColin Finck             if (InSizeMove)
1627c2c66affSColin Finck             {
1628c2c66affSColin Finck                 if (!(pwp->flags & SWP_NOMOVE))
1629c2c66affSColin Finck                 {
1630c2c66affSColin Finck                     rcTray.left = pwp->x;
1631c2c66affSColin Finck                     rcTray.top = pwp->y;
1632c2c66affSColin Finck                 }
1633c2c66affSColin Finck 
1634c2c66affSColin Finck                 if (!(pwp->flags & SWP_NOSIZE))
1635c2c66affSColin Finck                 {
1636c2c66affSColin Finck                     rcTray.right = rcTray.left + pwp->cx;
1637c2c66affSColin Finck                     rcTray.bottom = rcTray.top + pwp->cy;
1638c2c66affSColin Finck                 }
1639c2c66affSColin Finck 
1640c2c66affSColin Finck                 m_Position = GetDraggingRectFromRect(&rcTray, &m_Monitor);
1641c2c66affSColin Finck 
1642c2c66affSColin Finck                 if (!(pwp->flags & (SWP_NOMOVE | SWP_NOSIZE)))
1643c2c66affSColin Finck                 {
1644c2c66affSColin Finck                     SIZE szWnd;
1645c2c66affSColin Finck 
1646c2c66affSColin Finck                     szWnd.cx = pwp->cx;
1647c2c66affSColin Finck                     szWnd.cy = pwp->cy;
1648c2c66affSColin Finck 
1649c2c66affSColin Finck                     MakeTrayRectWithSize(m_Position, &szWnd, &rcTray);
1650c2c66affSColin Finck                 }
1651c2c66affSColin Finck 
1652c2c66affSColin Finck                 m_TrayRects[m_Position] = rcTray;
1653c2c66affSColin Finck             }
1654ce537f1aSTimo Kreuzer             else if (m_Position != (DWORD)-1)
1655c2c66affSColin Finck             {
1656c2c66affSColin Finck                 /* If the user isn't resizing the tray window we need to make sure the
1657c2c66affSColin Finck                    new size or position is valid. this is to prevent changes to the window
1658c2c66affSColin Finck                    without user interaction. */
1659c2c66affSColin Finck                 rcTray = m_TrayRects[m_Position];
1660c2c66affSColin Finck 
16612ed535daSGiannis Adamopoulos                 if (g_TaskbarSettings.sr.AutoHide)
1662c2c66affSColin Finck                 {
1663c2c66affSColin Finck                     rcTray.left += m_AutoHideOffset.cx;
1664c2c66affSColin Finck                     rcTray.right += m_AutoHideOffset.cx;
1665c2c66affSColin Finck                     rcTray.top += m_AutoHideOffset.cy;
1666c2c66affSColin Finck                     rcTray.bottom += m_AutoHideOffset.cy;
1667c2c66affSColin Finck                 }
1668c2c66affSColin Finck 
16694238f223SGiannis Adamopoulos             }
16704238f223SGiannis Adamopoulos 
16714238f223SGiannis Adamopoulos ChangePos:
16724238f223SGiannis Adamopoulos             m_TraySize.cx = rcTray.right - rcTray.left;
16734238f223SGiannis Adamopoulos             m_TraySize.cy = rcTray.bottom - rcTray.top;
16744238f223SGiannis Adamopoulos 
1675c2c66affSColin Finck             pwp->flags &= ~(SWP_NOMOVE | SWP_NOSIZE);
1676c2c66affSColin Finck             pwp->x = rcTray.left;
1677c2c66affSColin Finck             pwp->y = rcTray.top;
1678c2c66affSColin Finck             pwp->cx = m_TraySize.cx;
1679c2c66affSColin Finck             pwp->cy = m_TraySize.cy;
1680c2c66affSColin Finck         }
1681c2c66affSColin Finck     }
1682c2c66affSColin Finck 
1683c2c66affSColin Finck     VOID ApplyClipping(IN BOOL Clip)
1684c2c66affSColin Finck     {
1685c2c66affSColin Finck         RECT rcClip, rcWindow;
1686c2c66affSColin Finck         HRGN hClipRgn;
1687c2c66affSColin Finck 
1688c2c66affSColin Finck         if (GetWindowRect(&rcWindow))
1689c2c66affSColin Finck         {
1690c2c66affSColin Finck             /* Disable clipping on systems with only one monitor */
1691c2c66affSColin Finck             if (GetSystemMetrics(SM_CMONITORS) <= 1)
1692c2c66affSColin Finck                 Clip = FALSE;
1693c2c66affSColin Finck 
1694c2c66affSColin Finck             if (Clip)
1695c2c66affSColin Finck             {
1696c2c66affSColin Finck                 rcClip = rcWindow;
1697c2c66affSColin Finck 
1698c2c66affSColin Finck                 GetScreenRect(m_Monitor, &rcClip);
1699c2c66affSColin Finck 
1700c2c66affSColin Finck                 if (!IntersectRect(&rcClip, &rcClip, &rcWindow))
1701c2c66affSColin Finck                 {
1702c2c66affSColin Finck                     rcClip = rcWindow;
1703c2c66affSColin Finck                 }
1704c2c66affSColin Finck 
1705c2c66affSColin Finck                 OffsetRect(&rcClip,
1706c2c66affSColin Finck                            -rcWindow.left,
1707c2c66affSColin Finck                            -rcWindow.top);
1708c2c66affSColin Finck 
1709c2c66affSColin Finck                 hClipRgn = CreateRectRgnIndirect(&rcClip);
1710c2c66affSColin Finck             }
1711c2c66affSColin Finck             else
1712c2c66affSColin Finck                 hClipRgn = NULL;
1713c2c66affSColin Finck 
1714c2c66affSColin Finck             /* Set the clipping region or make sure the window isn't clipped
1715c2c66affSColin Finck                by disabling it explicitly. */
1716c2c66affSColin Finck             SetWindowRgn(hClipRgn, TRUE);
1717c2c66affSColin Finck         }
1718c2c66affSColin Finck     }
1719c2c66affSColin Finck 
1720c2c66affSColin Finck     VOID ResizeWorkArea()
1721c2c66affSColin Finck     {
1722c2c66affSColin Finck #if !WIN7_DEBUG_MODE
1723c2c66affSColin Finck         RECT rcTray, rcWorkArea;
1724c2c66affSColin Finck 
1725c2c66affSColin Finck         /* If monitor has changed then fix the previous monitors work area */
1726c2c66affSColin Finck         if (m_PreviousMonitor != m_Monitor)
1727c2c66affSColin Finck         {
1728c2c66affSColin Finck             GetScreenRect(m_PreviousMonitor, &rcWorkArea);
1729c2c66affSColin Finck             SystemParametersInfoW(SPI_SETWORKAREA,
1730c2c66affSColin Finck                                   1,
1731c2c66affSColin Finck                                   &rcWorkArea,
1732c2c66affSColin Finck                                   SPIF_SENDCHANGE);
1733c2c66affSColin Finck         }
1734c2c66affSColin Finck 
1735c2c66affSColin Finck         rcTray = m_TrayRects[m_Position];
1736c2c66affSColin Finck 
1737c2c66affSColin Finck         GetScreenRect(m_Monitor, &rcWorkArea);
1738c2c66affSColin Finck         m_PreviousMonitor = m_Monitor;
1739c2c66affSColin Finck 
1740c2c66affSColin Finck         /* If AutoHide is false then change the workarea to exclude
1741c2c66affSColin Finck            the area that the taskbar covers. */
17422ed535daSGiannis Adamopoulos         if (!g_TaskbarSettings.sr.AutoHide)
1743c2c66affSColin Finck         {
1744c2c66affSColin Finck             switch (m_Position)
1745c2c66affSColin Finck             {
1746c2c66affSColin Finck             case ABE_TOP:
1747c2c66affSColin Finck                 rcWorkArea.top = rcTray.bottom;
1748c2c66affSColin Finck                 break;
1749c2c66affSColin Finck             case ABE_LEFT:
1750c2c66affSColin Finck                 rcWorkArea.left = rcTray.right;
1751c2c66affSColin Finck                 break;
1752c2c66affSColin Finck             case ABE_RIGHT:
1753c2c66affSColin Finck                 rcWorkArea.right = rcTray.left;
1754c2c66affSColin Finck                 break;
1755c2c66affSColin Finck             case ABE_BOTTOM:
1756c2c66affSColin Finck                 rcWorkArea.bottom = rcTray.top;
1757c2c66affSColin Finck                 break;
1758c2c66affSColin Finck             }
1759c2c66affSColin Finck         }
1760c2c66affSColin Finck 
1761c2c66affSColin Finck         /*
1762c2c66affSColin Finck          * Resize the current monitor work area. Win32k will also send
1763c2c66affSColin Finck          * a WM_SIZE message to automatically resize the desktop.
1764c2c66affSColin Finck          */
1765c2c66affSColin Finck         SystemParametersInfoW(SPI_SETWORKAREA,
1766c2c66affSColin Finck                               1,
1767c2c66affSColin Finck                               &rcWorkArea,
1768c2c66affSColin Finck                               SPIF_SENDCHANGE);
1769c2c66affSColin Finck #endif
1770c2c66affSColin Finck     }
1771c2c66affSColin Finck 
1772c2c66affSColin Finck     VOID CheckTrayWndPosition()
1773c2c66affSColin Finck     {
17744238f223SGiannis Adamopoulos         /* Force the rebar bands to resize */
1775c2c66affSColin Finck         IUnknown_Exec(m_TrayBandSite,
1776c2c66affSColin Finck                       IID_IDeskBand,
1777c2c66affSColin Finck                       DBID_BANDINFOCHANGED,
1778c2c66affSColin Finck                       0,
1779c2c66affSColin Finck                       NULL,
1780c2c66affSColin Finck                       NULL);
1781c2c66affSColin Finck 
17824238f223SGiannis Adamopoulos         /* Calculate the size of the taskbar based on the rebar */
17834238f223SGiannis Adamopoulos         FitToRebar(&m_TrayRects[m_Position]);
1784c2c66affSColin Finck 
1785c2c66affSColin Finck         /* Move the tray window */
17864238f223SGiannis Adamopoulos         /* The handler of WM_WINDOWPOSCHANGING will override whatever size
17874238f223SGiannis Adamopoulos          * and position we use here with m_TrayRects */
17884238f223SGiannis Adamopoulos         SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOACTIVATE);
1789c2c66affSColin Finck         ResizeWorkArea();
1790c2c66affSColin Finck         ApplyClipping(TRUE);
1791c2c66affSColin Finck     }
1792c2c66affSColin Finck 
1793c2c66affSColin Finck     VOID RegLoadSettings()
1794c2c66affSColin Finck     {
1795c2c66affSColin Finck         DWORD Pos;
1796c2c66affSColin Finck         RECT rcScreen;
1797c2c66affSColin Finck         SIZE WndSize, EdgeSize, DlgFrameSize;
1798c2c66affSColin Finck         SIZE StartBtnSize = m_StartButton.GetSize();
1799c2c66affSColin Finck 
1800c2c66affSColin Finck         EdgeSize.cx = GetSystemMetrics(SM_CXEDGE);
1801c2c66affSColin Finck         EdgeSize.cy = GetSystemMetrics(SM_CYEDGE);
1802c2c66affSColin Finck         DlgFrameSize.cx = GetSystemMetrics(SM_CXDLGFRAME);
1803c2c66affSColin Finck         DlgFrameSize.cy = GetSystemMetrics(SM_CYDLGFRAME);
1804c2c66affSColin Finck 
18052ed535daSGiannis Adamopoulos         m_Position = g_TaskbarSettings.sr.Position;
18062ed535daSGiannis Adamopoulos         rcScreen = g_TaskbarSettings.sr.Rect;
18072ed535daSGiannis Adamopoulos         GetScreenRectFromRect(&rcScreen, MONITOR_DEFAULTTONEAREST);
18082ed535daSGiannis Adamopoulos 
18092ed535daSGiannis Adamopoulos         if (!g_TaskbarSettings.sr.Size.cx || !g_TaskbarSettings.sr.Size.cy)
1810c2c66affSColin Finck         {
1811c2c66affSColin Finck             /* Use the minimum size of the taskbar, we'll use the start
1812c2c66affSColin Finck                button as a minimum for now. Make sure we calculate the
1813c2c66affSColin Finck                entire window size, not just the client size. However, we
1814c2c66affSColin Finck                use a thinner border than a standard thick border, so that
1815c2c66affSColin Finck                the start button and bands are not stuck to the screen border. */
1816c2c66affSColin Finck             if(!m_Theme)
1817c2c66affSColin Finck             {
18182ed535daSGiannis Adamopoulos                 g_TaskbarSettings.sr.Size.cx = StartBtnSize.cx + (2 * (EdgeSize.cx + DlgFrameSize.cx));
18192ed535daSGiannis Adamopoulos                 g_TaskbarSettings.sr.Size.cy = StartBtnSize.cy + (2 * (EdgeSize.cy + DlgFrameSize.cy));
1820c2c66affSColin Finck             }
1821c2c66affSColin Finck             else
1822c2c66affSColin Finck             {
18232ed535daSGiannis Adamopoulos                 g_TaskbarSettings.sr.Size.cx = StartBtnSize.cx - EdgeSize.cx;
18242ed535daSGiannis Adamopoulos                 g_TaskbarSettings.sr.Size.cy = StartBtnSize.cy - EdgeSize.cy;
18252ed535daSGiannis Adamopoulos                 if(!g_TaskbarSettings.bLock)
18262ed535daSGiannis Adamopoulos                     g_TaskbarSettings.sr.Size.cy += GetSystemMetrics(SM_CYSIZEFRAME);
1827c2c66affSColin Finck             }
1828c2c66affSColin Finck         }
1829c2c66affSColin Finck         /* Determine a minimum tray window rectangle. The "client" height is
1830c2c66affSColin Finck            zero here since we cannot determine an optimal minimum width when
1831c2c66affSColin Finck            loaded as a vertical tray window. We just need to make sure the values
1832c2c66affSColin Finck            loaded from the registry are at least. The windows explorer behaves
1833c2c66affSColin Finck            the same way, it allows the user to save a zero width vertical tray
1834c2c66affSColin Finck            window, but not a zero height horizontal tray window. */
1835c2c66affSColin Finck         if(!m_Theme)
1836c2c66affSColin Finck         {
1837c2c66affSColin Finck             WndSize.cx = 2 * (EdgeSize.cx + DlgFrameSize.cx);
1838c2c66affSColin Finck             WndSize.cy = StartBtnSize.cy + (2 * (EdgeSize.cy + DlgFrameSize.cy));
1839c2c66affSColin Finck         }
1840c2c66affSColin Finck         else
1841c2c66affSColin Finck         {
1842c2c66affSColin Finck             WndSize.cx = StartBtnSize.cx;
184367ad4e7fSDoug Lyons             WndSize.cy = StartBtnSize.cy - EdgeSize.cy;
1844c2c66affSColin Finck         }
1845c2c66affSColin Finck 
18462ed535daSGiannis Adamopoulos         if (WndSize.cx < g_TaskbarSettings.sr.Size.cx)
18472ed535daSGiannis Adamopoulos             WndSize.cx = g_TaskbarSettings.sr.Size.cx;
18482ed535daSGiannis Adamopoulos         if (WndSize.cy < g_TaskbarSettings.sr.Size.cy)
18492ed535daSGiannis Adamopoulos             WndSize.cy = g_TaskbarSettings.sr.Size.cy;
1850c2c66affSColin Finck 
1851c2c66affSColin Finck         /* Save the calculated size */
1852c2c66affSColin Finck         m_TraySize = WndSize;
1853c2c66affSColin Finck 
1854c2c66affSColin Finck         /* Calculate all docking rectangles. We need to do this here so they're
1855c2c66affSColin Finck            initialized and dragging the tray window to another position gives
1856c2c66affSColin Finck            usable results */
1857c2c66affSColin Finck         for (Pos = ABE_LEFT; Pos <= ABE_BOTTOM; Pos++)
1858c2c66affSColin Finck         {
1859c2c66affSColin Finck             GetTrayRectFromScreenRect(Pos,
1860c2c66affSColin Finck                                       &rcScreen,
1861c2c66affSColin Finck                                       &m_TraySize,
1862c2c66affSColin Finck                                       &m_TrayRects[Pos]);
1863c2c66affSColin Finck             // TRACE("m_TrayRects[%d(%d)]: %d,%d,%d,%d\n", Pos, Position, m_TrayRects[Pos].left, m_TrayRects[Pos].top, m_TrayRects[Pos].right, m_TrayRects[Pos].bottom);
1864c2c66affSColin Finck         }
1865c2c66affSColin Finck 
1866c2c66affSColin Finck         /* Determine which monitor we are on. It shouldn't matter which docked
1867c2c66affSColin Finck            position rectangle we use */
1868c2c66affSColin Finck         m_Monitor = GetMonitorFromRect(&m_TrayRects[ABE_LEFT]);
1869c2c66affSColin Finck     }
1870c2c66affSColin Finck 
1871c2c66affSColin Finck     VOID AlignControls(IN PRECT prcClient OPTIONAL)
1872c2c66affSColin Finck     {
1873c2c66affSColin Finck         RECT rcClient;
1874c2c66affSColin Finck         SIZE TraySize, StartSize;
1875c2c66affSColin Finck         POINT ptTrayNotify = { 0, 0 };
1876c2c66affSColin Finck         BOOL Horizontal;
1877c2c66affSColin Finck         HDWP dwp;
1878c2c66affSColin Finck 
1879c2c66affSColin Finck         m_StartButton.UpdateSize();
1880c2c66affSColin Finck         if (prcClient != NULL)
1881c2c66affSColin Finck         {
1882c2c66affSColin Finck             rcClient = *prcClient;
1883c2c66affSColin Finck         }
1884c2c66affSColin Finck         else
1885c2c66affSColin Finck         {
1886c2c66affSColin Finck             if (!GetClientRect(&rcClient))
1887c2c66affSColin Finck             {
1888c2c66affSColin Finck                 ERR("Could not get client rect lastErr=%d\n", GetLastError());
1889c2c66affSColin Finck                 return;
1890c2c66affSColin Finck             }
1891c2c66affSColin Finck         }
1892c2c66affSColin Finck 
1893c2c66affSColin Finck         Horizontal = IsPosHorizontal();
1894c2c66affSColin Finck 
1895c2c66affSColin Finck         /* We're about to resize/move the start button, the rebar control and
1896c2c66affSColin Finck            the tray notification control */
189726efda4dSKatayama Hirofumi MZ         dwp = BeginDeferWindowPos(4);
1898c2c66affSColin Finck         if (dwp == NULL)
1899c2c66affSColin Finck         {
1900c2c66affSColin Finck             ERR("BeginDeferWindowPos failed. lastErr=%d\n", GetLastError());
1901c2c66affSColin Finck             return;
1902c2c66affSColin Finck         }
1903c2c66affSColin Finck 
1904c2c66affSColin Finck         /* Limit the Start button width to the client width, if necessary */
1905c2c66affSColin Finck         StartSize = m_StartButton.GetSize();
1906c2c66affSColin Finck         if (StartSize.cx > rcClient.right)
1907c2c66affSColin Finck             StartSize.cx = rcClient.right;
1908c2c66affSColin Finck 
1909c2c66affSColin Finck         HWND hwndTaskToolbar = ::GetWindow(m_TaskSwitch, GW_CHILD);
1910c2c66affSColin Finck         if (hwndTaskToolbar)
1911c2c66affSColin Finck         {
1912c2c66affSColin Finck             DWORD size = SendMessageW(hwndTaskToolbar, TB_GETBUTTONSIZE, 0, 0);
191367ad4e7fSDoug Lyons 
191467ad4e7fSDoug Lyons             /* Themed button covers Edge area as well */
191567ad4e7fSDoug Lyons             StartSize.cy = HIWORD(size) + (m_Theme ? GetSystemMetrics(SM_CYEDGE) : 0);
1916c2c66affSColin Finck         }
1917c2c66affSColin Finck 
1918c2c66affSColin Finck         if (m_StartButton.m_hWnd != NULL)
1919c2c66affSColin Finck         {
1920c2c66affSColin Finck             /* Resize and reposition the button */
1921c2c66affSColin Finck             dwp = m_StartButton.DeferWindowPos(dwp,
1922c2c66affSColin Finck                                                NULL,
1923c2c66affSColin Finck                                                0,
1924c2c66affSColin Finck                                                0,
1925c2c66affSColin Finck                                                StartSize.cx,
1926c2c66affSColin Finck                                                StartSize.cy,
1927c2c66affSColin Finck                                                SWP_NOZORDER | SWP_NOACTIVATE);
1928c2c66affSColin Finck             if (dwp == NULL)
1929c2c66affSColin Finck             {
1930c2c66affSColin Finck                 ERR("DeferWindowPos for start button failed. lastErr=%d\n", GetLastError());
1931c2c66affSColin Finck                 return;
1932c2c66affSColin Finck             }
1933c2c66affSColin Finck         }
1934c2c66affSColin Finck 
193526efda4dSKatayama Hirofumi MZ         if (m_ShowDesktopButton.m_hWnd)
193626efda4dSKatayama Hirofumi MZ         {
193726efda4dSKatayama Hirofumi MZ             // Get rectangle from rcClient
193826efda4dSKatayama Hirofumi MZ             RECT rc = rcClient;
193926efda4dSKatayama Hirofumi MZ             INT cxyShowDesktop = m_ShowDesktopButton.WidthOrHeight();
194026efda4dSKatayama Hirofumi MZ             if (Horizontal)
194126efda4dSKatayama Hirofumi MZ             {
194226efda4dSKatayama Hirofumi MZ                 rc.left = rc.right - cxyShowDesktop;
194326efda4dSKatayama Hirofumi MZ                 rc.right += 5; // excessive
194426efda4dSKatayama Hirofumi MZ             }
194526efda4dSKatayama Hirofumi MZ             else
194626efda4dSKatayama Hirofumi MZ             {
194726efda4dSKatayama Hirofumi MZ                 rc.top = rc.bottom - cxyShowDesktop;
194826efda4dSKatayama Hirofumi MZ                 rc.bottom += 5; // excessive
194926efda4dSKatayama Hirofumi MZ             }
195026efda4dSKatayama Hirofumi MZ 
195126efda4dSKatayama Hirofumi MZ             /* Resize and reposition the button */
195226efda4dSKatayama Hirofumi MZ             dwp = m_ShowDesktopButton.DeferWindowPos(dwp, NULL,
195326efda4dSKatayama Hirofumi MZ                                                      rc.left, rc.top,
195426efda4dSKatayama Hirofumi MZ                                                      rc.right - rc.left, rc.bottom - rc.top,
195526efda4dSKatayama Hirofumi MZ                                                      SWP_NOZORDER | SWP_NOACTIVATE);
195626efda4dSKatayama Hirofumi MZ 
195726efda4dSKatayama Hirofumi MZ             // Adjust rcClient
195826efda4dSKatayama Hirofumi MZ             if (Horizontal)
195926efda4dSKatayama Hirofumi MZ                 rcClient.right -= cxyShowDesktop + ::GetSystemMetrics(SM_CXEDGE);
196026efda4dSKatayama Hirofumi MZ             else
196126efda4dSKatayama Hirofumi MZ                 rcClient.bottom -= cxyShowDesktop + ::GetSystemMetrics(SM_CYEDGE);
196226efda4dSKatayama Hirofumi MZ         }
196326efda4dSKatayama Hirofumi MZ 
1964c2c66affSColin Finck         /* Determine the size that the tray notification window needs */
1965c2c66affSColin Finck         if (Horizontal)
1966c2c66affSColin Finck         {
1967c2c66affSColin Finck             TraySize.cx = 0;
1968c2c66affSColin Finck             TraySize.cy = rcClient.bottom;
1969c2c66affSColin Finck         }
1970c2c66affSColin Finck         else
1971c2c66affSColin Finck         {
1972c2c66affSColin Finck             TraySize.cx = rcClient.right;
1973c2c66affSColin Finck             TraySize.cy = 0;
1974c2c66affSColin Finck         }
1975c2c66affSColin Finck 
1976c2c66affSColin Finck         if (m_TrayNotify != NULL &&
1977c2c66affSColin Finck             SendMessage(m_TrayNotify,
1978c2c66affSColin Finck                         TNWM_GETMINIMUMSIZE,
1979c2c66affSColin Finck                         (WPARAM)Horizontal,
1980c2c66affSColin Finck                         (LPARAM)&TraySize))
1981c2c66affSColin Finck         {
1982c2c66affSColin Finck             /* Move the tray notification window to the desired location */
1983c2c66affSColin Finck             if (Horizontal)
1984c2c66affSColin Finck                 ptTrayNotify.x = rcClient.right - TraySize.cx;
1985c2c66affSColin Finck             else
1986c2c66affSColin Finck                 ptTrayNotify.y = rcClient.bottom - TraySize.cy;
1987c2c66affSColin Finck 
1988c2c66affSColin Finck             dwp = ::DeferWindowPos(dwp,
1989c2c66affSColin Finck                                    m_TrayNotify,
1990c2c66affSColin Finck                                    NULL,
1991c2c66affSColin Finck                                    ptTrayNotify.x,
1992c2c66affSColin Finck                                    ptTrayNotify.y,
1993c2c66affSColin Finck                                    TraySize.cx,
1994c2c66affSColin Finck                                    TraySize.cy,
1995c2c66affSColin Finck                                    SWP_NOZORDER | SWP_NOACTIVATE);
1996c2c66affSColin Finck             if (dwp == NULL)
1997c2c66affSColin Finck             {
1998c2c66affSColin Finck                 ERR("DeferWindowPos for notification area failed. lastErr=%d\n", GetLastError());
1999c2c66affSColin Finck                 return;
2000c2c66affSColin Finck             }
2001c2c66affSColin Finck         }
2002c2c66affSColin Finck 
2003c2c66affSColin Finck         /* Resize/Move the rebar control */
2004c2c66affSColin Finck         if (m_Rebar != NULL)
2005c2c66affSColin Finck         {
2006c2c66affSColin Finck             POINT ptRebar = { 0, 0 };
2007c2c66affSColin Finck             SIZE szRebar;
2008c2c66affSColin Finck 
2009c2c66affSColin Finck             SetWindowStyle(m_Rebar, CCS_VERT, Horizontal ? 0 : CCS_VERT);
2010c2c66affSColin Finck 
2011c2c66affSColin Finck             if (Horizontal)
2012c2c66affSColin Finck             {
2013c2c66affSColin Finck                 ptRebar.x = StartSize.cx + GetSystemMetrics(SM_CXSIZEFRAME);
2014c2c66affSColin Finck                 szRebar.cx = ptTrayNotify.x - ptRebar.x;
2015c2c66affSColin Finck                 szRebar.cy = rcClient.bottom;
2016c2c66affSColin Finck             }
2017c2c66affSColin Finck             else
2018c2c66affSColin Finck             {
2019c2c66affSColin Finck                 ptRebar.y = StartSize.cy + GetSystemMetrics(SM_CYSIZEFRAME);
2020c2c66affSColin Finck                 szRebar.cx = rcClient.right;
2021c2c66affSColin Finck                 szRebar.cy = ptTrayNotify.y - ptRebar.y;
2022c2c66affSColin Finck             }
2023c2c66affSColin Finck 
2024c2c66affSColin Finck             dwp = ::DeferWindowPos(dwp,
2025c2c66affSColin Finck                                    m_Rebar,
2026c2c66affSColin Finck                                    NULL,
2027c2c66affSColin Finck                                    ptRebar.x,
2028c2c66affSColin Finck                                    ptRebar.y,
2029c2c66affSColin Finck                                    szRebar.cx,
2030c2c66affSColin Finck                                    szRebar.cy,
2031c2c66affSColin Finck                                    SWP_NOZORDER | SWP_NOACTIVATE);
2032c2c66affSColin Finck         }
2033c2c66affSColin Finck 
2034c2c66affSColin Finck         if (dwp != NULL)
2035c2c66affSColin Finck             EndDeferWindowPos(dwp);
2036c2c66affSColin Finck 
2037c2c66affSColin Finck         if (m_TaskSwitch != NULL)
2038c2c66affSColin Finck         {
2039c2c66affSColin Finck             /* Update the task switch window configuration */
2040c2c66affSColin Finck             SendMessage(m_TaskSwitch, TSWM_UPDATETASKBARPOS, 0, 0);
2041c2c66affSColin Finck         }
2042c2c66affSColin Finck     }
2043c2c66affSColin Finck 
2044c2c66affSColin Finck     void FitToRebar(PRECT pRect)
2045c2c66affSColin Finck     {
2046c2c66affSColin Finck         /* Get the rect of the rebar */
2047c2c66affSColin Finck         RECT rebarRect, taskbarRect, clientRect;
2048c2c66affSColin Finck         ::GetWindowRect(m_Rebar, &rebarRect);
2049c2c66affSColin Finck         ::GetWindowRect(m_hWnd, &taskbarRect);
2050c2c66affSColin Finck         ::GetClientRect(m_hWnd, &clientRect);
2051c2c66affSColin Finck         OffsetRect(&rebarRect, -taskbarRect.left, -taskbarRect.top);
2052c2c66affSColin Finck 
2053c2c66affSColin Finck         /* Calculate the difference of size of the taskbar and the rebar */
2054c2c66affSColin Finck         SIZE margins;
2055c2c66affSColin Finck         margins.cx = taskbarRect.right - taskbarRect.left - clientRect.right + clientRect.left;
2056c2c66affSColin Finck         margins.cy = taskbarRect.bottom - taskbarRect.top - clientRect.bottom + clientRect.top;
2057c2c66affSColin Finck 
2058c2c66affSColin Finck         /* Calculate the new size of the rebar and make it resize, then change the new taskbar size */
2059c2c66affSColin Finck         switch (m_Position)
2060c2c66affSColin Finck         {
2061c2c66affSColin Finck         case ABE_TOP:
2062c2c66affSColin Finck             rebarRect.bottom = rebarRect.top + pRect->bottom - pRect->top - margins.cy;
2063c2c66affSColin Finck             ::SendMessageW(m_Rebar, RB_SIZETORECT, RBSTR_CHANGERECT,  (LPARAM)&rebarRect);
2064c2c66affSColin Finck             pRect->bottom = pRect->top + rebarRect.bottom - rebarRect.top + margins.cy;
2065c2c66affSColin Finck             break;
2066c2c66affSColin Finck         case ABE_BOTTOM:
2067c2c66affSColin Finck             rebarRect.top = rebarRect.bottom - (pRect->bottom - pRect->top - margins.cy);
2068c2c66affSColin Finck             ::SendMessageW(m_Rebar, RB_SIZETORECT, RBSTR_CHANGERECT,  (LPARAM)&rebarRect);
2069c2c66affSColin Finck             pRect->top = pRect->bottom - (rebarRect.bottom - rebarRect.top + margins.cy);
2070c2c66affSColin Finck             break;
2071c2c66affSColin Finck         case ABE_LEFT:
2072c2c66affSColin Finck             rebarRect.right = rebarRect.left + (pRect->right - pRect->left - margins.cx);
2073c2c66affSColin Finck             ::SendMessageW(m_Rebar, RB_SIZETORECT, RBSTR_CHANGERECT,  (LPARAM)&rebarRect);
2074c2c66affSColin Finck             pRect->right = pRect->left + (rebarRect.right - rebarRect.left + margins.cx);
2075c2c66affSColin Finck             break;
2076c2c66affSColin Finck         case ABE_RIGHT:
2077c2c66affSColin Finck             rebarRect.left = rebarRect.right - (pRect->right - pRect->left - margins.cx);
2078c2c66affSColin Finck             ::SendMessageW(m_Rebar, RB_SIZETORECT, RBSTR_CHANGERECT,  (LPARAM)&rebarRect);
2079c2c66affSColin Finck             pRect->left = pRect->right - (rebarRect.right - rebarRect.left + margins.cx);
2080c2c66affSColin Finck             break;
2081c2c66affSColin Finck         }
2082c2c66affSColin Finck 
2083c2c66affSColin Finck         CalculateValidSize(m_Position, pRect);
2084c2c66affSColin Finck     }
2085c2c66affSColin Finck 
2086c2c66affSColin Finck     void PopupStartMenu()
2087c2c66affSColin Finck     {
2088c2c66affSColin Finck         if (m_StartMenuPopup != NULL)
2089c2c66affSColin Finck         {
2090c2c66affSColin Finck             POINTL pt;
2091c2c66affSColin Finck             RECTL rcExclude;
2092c2c66affSColin Finck             DWORD dwFlags = 0;
2093c2c66affSColin Finck 
2094c2c66affSColin Finck             if (m_StartButton.GetWindowRect((RECT*) &rcExclude))
2095c2c66affSColin Finck             {
2096c2c66affSColin Finck                 switch (m_Position)
2097c2c66affSColin Finck                 {
2098c2c66affSColin Finck                 case ABE_BOTTOM:
2099c2c66affSColin Finck                     pt.x = rcExclude.left;
2100c2c66affSColin Finck                     pt.y = rcExclude.top;
2101c2c66affSColin Finck                     dwFlags |= MPPF_TOP;
2102c2c66affSColin Finck                     break;
2103c2c66affSColin Finck                 case ABE_TOP:
2104c2c66affSColin Finck                     pt.x = rcExclude.left;
2105c2c66affSColin Finck                     pt.y = rcExclude.bottom;
2106c2c66affSColin Finck                     dwFlags |= MPPF_BOTTOM;
2107c2c66affSColin Finck                     break;
2108c2c66affSColin Finck                 case ABE_LEFT:
2109c2c66affSColin Finck                     pt.x = rcExclude.right;
2110c2c66affSColin Finck                     pt.y = rcExclude.top;
2111c2c66affSColin Finck                     dwFlags |= MPPF_RIGHT;
2112c2c66affSColin Finck                     break;
2113c2c66affSColin Finck                 case ABE_RIGHT:
2114c2c66affSColin Finck                     pt.x = rcExclude.left;
2115c2c66affSColin Finck                     pt.y = rcExclude.top;
2116c2c66affSColin Finck                     dwFlags |= MPPF_LEFT;
2117c2c66affSColin Finck                     break;
2118c2c66affSColin Finck                 }
2119c2c66affSColin Finck 
2120c2c66affSColin Finck                 m_StartMenuPopup->Popup(&pt, &rcExclude, dwFlags);
2121c2c66affSColin Finck 
2122c2c66affSColin Finck                 m_StartButton.SendMessageW(BM_SETSTATE, TRUE, 0);
2123c2c66affSColin Finck             }
2124c2c66affSColin Finck         }
2125c2c66affSColin Finck     }
2126c2c66affSColin Finck 
2127c2c66affSColin Finck     void ProcessMouseTracking()
2128c2c66affSColin Finck     {
2129c2c66affSColin Finck         RECT rcCurrent;
2130c2c66affSColin Finck         POINT pt;
2131c2c66affSColin Finck         BOOL over;
2132c2c66affSColin Finck         UINT state = m_AutoHideState;
2133c2c66affSColin Finck 
2134c2c66affSColin Finck         GetCursorPos(&pt);
2135c2c66affSColin Finck         GetWindowRect(&rcCurrent);
2136c2c66affSColin Finck         over = PtInRect(&rcCurrent, pt);
2137c2c66affSColin Finck 
2138c2c66affSColin Finck         if (m_StartButton.SendMessage( BM_GETSTATE, 0, 0) != BST_UNCHECKED)
2139c2c66affSColin Finck         {
2140c2c66affSColin Finck             over = TRUE;
2141c2c66affSColin Finck         }
2142c2c66affSColin Finck 
2143c2c66affSColin Finck         if (over)
2144c2c66affSColin Finck         {
2145c2c66affSColin Finck             if (state == AUTOHIDE_HIDING)
2146c2c66affSColin Finck             {
2147c2c66affSColin Finck                 TRACE("AutoHide cancelling hide.\n");
2148c2c66affSColin Finck                 m_AutoHideState = AUTOHIDE_SHOWING;
2149c2c66affSColin Finck                 SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_INTERVAL_ANIMATING, NULL);
2150c2c66affSColin Finck             }
2151c2c66affSColin Finck             else if (state == AUTOHIDE_HIDDEN)
2152c2c66affSColin Finck             {
2153c2c66affSColin Finck                 TRACE("AutoHide starting show.\n");
2154c2c66affSColin Finck                 m_AutoHideState = AUTOHIDE_SHOWING;
2155c2c66affSColin Finck                 SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_DELAY_SHOW, NULL);
2156c2c66affSColin Finck             }
2157c2c66affSColin Finck         }
2158c2c66affSColin Finck         else
2159c2c66affSColin Finck         {
2160c2c66affSColin Finck             if (state == AUTOHIDE_SHOWING)
2161c2c66affSColin Finck             {
2162c2c66affSColin Finck                 TRACE("AutoHide cancelling show.\n");
2163c2c66affSColin Finck                 m_AutoHideState = AUTOHIDE_HIDING;
2164c2c66affSColin Finck                 SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_INTERVAL_ANIMATING, NULL);
2165c2c66affSColin Finck             }
2166c2c66affSColin Finck             else if (state == AUTOHIDE_SHOWN)
2167c2c66affSColin Finck             {
2168c2c66affSColin Finck                 TRACE("AutoHide starting hide.\n");
2169c2c66affSColin Finck                 m_AutoHideState = AUTOHIDE_HIDING;
2170c2c66affSColin Finck                 SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_DELAY_HIDE, NULL);
2171c2c66affSColin Finck             }
2172c2c66affSColin Finck 
2173c2c66affSColin Finck             KillTimer(TIMER_ID_MOUSETRACK);
2174c2c66affSColin Finck         }
2175c2c66affSColin Finck     }
2176c2c66affSColin Finck 
2177c2c66affSColin Finck     void ProcessAutoHide()
2178c2c66affSColin Finck     {
21794ed752e2SKatayama Hirofumi MZ         INT w = m_TraySize.cx - GetSystemMetrics(SM_CXSIZEFRAME);
21804ed752e2SKatayama Hirofumi MZ         INT h = m_TraySize.cy - GetSystemMetrics(SM_CYSIZEFRAME);
2181c2c66affSColin Finck 
2182c2c66affSColin Finck         switch (m_AutoHideState)
2183c2c66affSColin Finck         {
2184c2c66affSColin Finck         case AUTOHIDE_HIDING:
2185c2c66affSColin Finck             switch (m_Position)
2186c2c66affSColin Finck             {
2187c2c66affSColin Finck             case ABE_LEFT:
2188c2c66affSColin Finck                 m_AutoHideOffset.cy = 0;
2189c2c66affSColin Finck                 m_AutoHideOffset.cx -= AUTOHIDE_SPEED_HIDE;
2190c2c66affSColin Finck                 if (m_AutoHideOffset.cx < -w)
2191c3a4309dSJose Carlos Jesus                     m_AutoHideOffset.cx = w;
2192c2c66affSColin Finck                 break;
2193c2c66affSColin Finck             case ABE_TOP:
2194c2c66affSColin Finck                 m_AutoHideOffset.cx = 0;
2195c2c66affSColin Finck                 m_AutoHideOffset.cy -= AUTOHIDE_SPEED_HIDE;
2196c2c66affSColin Finck                 if (m_AutoHideOffset.cy < -h)
2197c3a4309dSJose Carlos Jesus                     m_AutoHideOffset.cy = h;
2198c2c66affSColin Finck                 break;
2199c2c66affSColin Finck             case ABE_RIGHT:
2200c2c66affSColin Finck                 m_AutoHideOffset.cy = 0;
2201c2c66affSColin Finck                 m_AutoHideOffset.cx += AUTOHIDE_SPEED_HIDE;
2202c2c66affSColin Finck                 if (m_AutoHideOffset.cx > w)
2203c2c66affSColin Finck                     m_AutoHideOffset.cx = w;
2204c2c66affSColin Finck                 break;
2205c2c66affSColin Finck             case ABE_BOTTOM:
2206c2c66affSColin Finck                 m_AutoHideOffset.cx = 0;
2207c2c66affSColin Finck                 m_AutoHideOffset.cy += AUTOHIDE_SPEED_HIDE;
2208c2c66affSColin Finck                 if (m_AutoHideOffset.cy > h)
2209c2c66affSColin Finck                     m_AutoHideOffset.cy = h;
2210c2c66affSColin Finck                 break;
2211c2c66affSColin Finck             }
2212c2c66affSColin Finck 
2213c2c66affSColin Finck             if (m_AutoHideOffset.cx != w && m_AutoHideOffset.cy != h)
2214c2c66affSColin Finck             {
2215c2c66affSColin Finck                 SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_INTERVAL_ANIMATING, NULL);
2216c2c66affSColin Finck                 break;
2217c2c66affSColin Finck             }
2218c2c66affSColin Finck 
2219c2c66affSColin Finck             /* fallthrough */
2220c2c66affSColin Finck         case AUTOHIDE_HIDDEN:
2221c2c66affSColin Finck 
2222c2c66affSColin Finck             switch (m_Position)
2223c2c66affSColin Finck             {
2224c2c66affSColin Finck             case ABE_LEFT:
2225c2c66affSColin Finck                 m_AutoHideOffset.cx = -w;
2226c2c66affSColin Finck                 m_AutoHideOffset.cy = 0;
2227c2c66affSColin Finck                 break;
2228c2c66affSColin Finck             case ABE_TOP:
2229c2c66affSColin Finck                 m_AutoHideOffset.cx = 0;
2230c2c66affSColin Finck                 m_AutoHideOffset.cy = -h;
2231c2c66affSColin Finck                 break;
2232c2c66affSColin Finck             case ABE_RIGHT:
2233c2c66affSColin Finck                 m_AutoHideOffset.cx = w;
2234c2c66affSColin Finck                 m_AutoHideOffset.cy = 0;
2235c2c66affSColin Finck                 break;
2236c2c66affSColin Finck             case ABE_BOTTOM:
2237c2c66affSColin Finck                 m_AutoHideOffset.cx = 0;
2238c2c66affSColin Finck                 m_AutoHideOffset.cy = h;
2239c2c66affSColin Finck                 break;
2240c2c66affSColin Finck             }
2241c2c66affSColin Finck 
2242c2c66affSColin Finck             KillTimer(TIMER_ID_AUTOHIDE);
2243c2c66affSColin Finck             m_AutoHideState = AUTOHIDE_HIDDEN;
2244c2c66affSColin Finck             break;
2245c2c66affSColin Finck 
2246c2c66affSColin Finck         case AUTOHIDE_SHOWING:
2247c2c66affSColin Finck             if (m_AutoHideOffset.cx >= AUTOHIDE_SPEED_SHOW)
2248c2c66affSColin Finck             {
2249c2c66affSColin Finck                 m_AutoHideOffset.cx -= AUTOHIDE_SPEED_SHOW;
2250c2c66affSColin Finck             }
2251c2c66affSColin Finck             else if (m_AutoHideOffset.cx <= -AUTOHIDE_SPEED_SHOW)
2252c2c66affSColin Finck             {
2253c2c66affSColin Finck                 m_AutoHideOffset.cx += AUTOHIDE_SPEED_SHOW;
2254c2c66affSColin Finck             }
2255c2c66affSColin Finck             else
2256c2c66affSColin Finck             {
2257c2c66affSColin Finck                 m_AutoHideOffset.cx = 0;
2258c2c66affSColin Finck             }
2259c2c66affSColin Finck 
2260c2c66affSColin Finck             if (m_AutoHideOffset.cy >= AUTOHIDE_SPEED_SHOW)
2261c2c66affSColin Finck             {
2262c2c66affSColin Finck                 m_AutoHideOffset.cy -= AUTOHIDE_SPEED_SHOW;
2263c2c66affSColin Finck             }
2264c2c66affSColin Finck             else if (m_AutoHideOffset.cy <= -AUTOHIDE_SPEED_SHOW)
2265c2c66affSColin Finck             {
2266c2c66affSColin Finck                 m_AutoHideOffset.cy += AUTOHIDE_SPEED_SHOW;
2267c2c66affSColin Finck             }
2268c2c66affSColin Finck             else
2269c2c66affSColin Finck             {
2270c2c66affSColin Finck                 m_AutoHideOffset.cy = 0;
2271c2c66affSColin Finck             }
2272c2c66affSColin Finck 
2273c2c66affSColin Finck             if (m_AutoHideOffset.cx != 0 || m_AutoHideOffset.cy != 0)
2274c2c66affSColin Finck             {
2275c2c66affSColin Finck                 SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_INTERVAL_ANIMATING, NULL);
2276c2c66affSColin Finck                 break;
2277c2c66affSColin Finck             }
2278c2c66affSColin Finck 
2279c2c66affSColin Finck             /* fallthrough */
2280c2c66affSColin Finck         case AUTOHIDE_SHOWN:
2281c2c66affSColin Finck 
2282c2c66affSColin Finck             KillTimer(TIMER_ID_AUTOHIDE);
2283c2c66affSColin Finck             m_AutoHideState = AUTOHIDE_SHOWN;
2284c2c66affSColin Finck             break;
2285c2c66affSColin Finck         }
2286c2c66affSColin Finck 
22874238f223SGiannis Adamopoulos         SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOZORDER);
2288c2c66affSColin Finck     }
2289c2c66affSColin Finck 
2290c2c66affSColin Finck 
2291c2c66affSColin Finck 
2292c2c66affSColin Finck 
2293c2c66affSColin Finck 
2294c2c66affSColin Finck     /**********************************************************
2295c2c66affSColin Finck      *    ##### taskbar drawing #####
2296c2c66affSColin Finck      */
2297c2c66affSColin Finck 
2298c2c66affSColin Finck     LRESULT EraseBackgroundWithTheme(HDC hdc)
2299c2c66affSColin Finck     {
2300c2c66affSColin Finck         RECT rect;
2301c2c66affSColin Finck         int iSBkgndPart[4] = {TBP_BACKGROUNDLEFT, TBP_BACKGROUNDTOP, TBP_BACKGROUNDRIGHT, TBP_BACKGROUNDBOTTOM};
2302c2c66affSColin Finck 
2303c2c66affSColin Finck         ASSERT(m_Position <= ABE_BOTTOM);
2304c2c66affSColin Finck 
2305c2c66affSColin Finck         if (m_Theme)
2306c2c66affSColin Finck         {
2307c2c66affSColin Finck             GetClientRect(&rect);
2308c2c66affSColin Finck             DrawThemeBackground(m_Theme, hdc, iSBkgndPart[m_Position], 0, &rect, 0);
2309c2c66affSColin Finck         }
2310c2c66affSColin Finck 
2311c2c66affSColin Finck         return 0;
2312c2c66affSColin Finck     }
2313c2c66affSColin Finck 
2314c2c66affSColin Finck     int DrawSizerWithTheme(IN HRGN hRgn)
2315c2c66affSColin Finck     {
2316c2c66affSColin Finck         HDC hdc;
2317c2c66affSColin Finck         RECT rect;
2318c2c66affSColin Finck         int iSizerPart[4] = {TBP_SIZINGBARLEFT, TBP_SIZINGBARTOP, TBP_SIZINGBARRIGHT, TBP_SIZINGBARBOTTOM};
2319c2c66affSColin Finck         SIZE size;
2320c2c66affSColin Finck 
2321c2c66affSColin Finck         ASSERT(m_Position <= ABE_BOTTOM);
2322c2c66affSColin Finck 
2323c2c66affSColin Finck         HRESULT hr = GetThemePartSize(m_Theme, NULL, iSizerPart[m_Position], 0, NULL, TS_TRUE, &size);
2324c2c66affSColin Finck         if (FAILED_UNEXPECTEDLY(hr))
2325c2c66affSColin Finck             return 0;
2326c2c66affSColin Finck 
2327c2c66affSColin Finck         GetWindowRect(&rect);
2328c2c66affSColin Finck         OffsetRect(&rect, -rect.left, -rect.top);
2329c2c66affSColin Finck 
2330c2c66affSColin Finck         hdc = GetWindowDC();
2331c2c66affSColin Finck 
2332c2c66affSColin Finck         switch (m_Position)
2333c2c66affSColin Finck         {
2334c2c66affSColin Finck         case ABE_LEFT:
2335c2c66affSColin Finck             rect.left = rect.right - size.cx;
2336c2c66affSColin Finck             break;
2337c2c66affSColin Finck         case ABE_TOP:
2338c2c66affSColin Finck             rect.top = rect.bottom - size.cy;
2339c2c66affSColin Finck             break;
2340c2c66affSColin Finck         case ABE_RIGHT:
2341c2c66affSColin Finck             rect.right = rect.left + size.cx;
2342c2c66affSColin Finck             break;
2343c2c66affSColin Finck         case ABE_BOTTOM:
2344c2c66affSColin Finck         default:
2345c2c66affSColin Finck             rect.bottom = rect.top + size.cy;
2346c2c66affSColin Finck             break;
2347c2c66affSColin Finck         }
2348c2c66affSColin Finck 
2349c2c66affSColin Finck         DrawThemeBackground(m_Theme, hdc, iSizerPart[m_Position], 0, &rect, 0);
2350c2c66affSColin Finck 
2351c2c66affSColin Finck         ReleaseDC(hdc);
2352c2c66affSColin Finck         return 0;
2353c2c66affSColin Finck     }
2354c2c66affSColin Finck 
2355c2c66affSColin Finck 
2356c2c66affSColin Finck 
2357c2c66affSColin Finck 
2358c2c66affSColin Finck 
2359c2c66affSColin Finck     /*
2360c2c66affSColin Finck      * ITrayWindow
2361c2c66affSColin Finck      */
2362c2c66affSColin Finck     HRESULT STDMETHODCALLTYPE Open()
2363c2c66affSColin Finck     {
2364c2c66affSColin Finck         RECT rcWnd;
2365c2c66affSColin Finck 
2366c2c66affSColin Finck         /* Check if there's already a window created and try to show it.
2367c2c66affSColin Finck            If it was somehow destroyed just create a new tray window. */
2368c2c66affSColin Finck         if (m_hWnd != NULL && IsWindow())
2369c2c66affSColin Finck         {
2370c2c66affSColin Finck             return S_OK;
2371c2c66affSColin Finck         }
2372c2c66affSColin Finck 
2373c2c66affSColin Finck         DWORD dwExStyle = WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE;
23742ed535daSGiannis Adamopoulos         if (g_TaskbarSettings.sr.AlwaysOnTop)
2375c2c66affSColin Finck             dwExStyle |= WS_EX_TOPMOST;
2376c2c66affSColin Finck 
2377c2c66affSColin Finck         DWORD dwStyle = WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
2378c2c66affSColin Finck         if(!m_Theme)
2379c2c66affSColin Finck         {
2380c2c66affSColin Finck             dwStyle |= WS_THICKFRAME | WS_BORDER;
2381c2c66affSColin Finck         }
2382c2c66affSColin Finck 
2383c2c66affSColin Finck         ZeroMemory(&rcWnd, sizeof(rcWnd));
2384c2c66affSColin Finck         if (m_Position != (DWORD) -1)
2385c2c66affSColin Finck             rcWnd = m_TrayRects[m_Position];
2386c2c66affSColin Finck 
2387c2c66affSColin Finck         if (!Create(NULL, rcWnd, NULL, dwStyle, dwExStyle))
2388c2c66affSColin Finck             return E_FAIL;
2389c2c66affSColin Finck 
2390c2c66affSColin Finck         /* Align all controls on the tray window */
2391c2c66affSColin Finck         AlignControls(NULL);
2392c2c66affSColin Finck 
2393c2c66affSColin Finck         /* Move the tray window to the right position and resize it if necessary */
2394c2c66affSColin Finck         CheckTrayWndPosition();
2395c2c66affSColin Finck 
2396c2c66affSColin Finck         return S_OK;
2397c2c66affSColin Finck     }
2398c2c66affSColin Finck 
2399c2c66affSColin Finck     HRESULT STDMETHODCALLTYPE Close()
2400c2c66affSColin Finck     {
2401c2c66affSColin Finck         if (m_hWnd != NULL)
2402c2c66affSColin Finck         {
2403c2c66affSColin Finck             SendMessage(m_hWnd,
2404c2c66affSColin Finck                         WM_APP_TRAYDESTROY,
2405c2c66affSColin Finck                         0,
2406c2c66affSColin Finck                         0);
2407c2c66affSColin Finck         }
2408c2c66affSColin Finck 
2409c2c66affSColin Finck         return S_OK;
2410c2c66affSColin Finck     }
2411c2c66affSColin Finck 
2412c2c66affSColin Finck     HWND STDMETHODCALLTYPE GetHWND()
2413c2c66affSColin Finck     {
2414c2c66affSColin Finck         return m_hWnd;
2415c2c66affSColin Finck     }
2416c2c66affSColin Finck 
2417c2c66affSColin Finck     BOOL STDMETHODCALLTYPE IsSpecialHWND(IN HWND hWnd)
2418c2c66affSColin Finck     {
2419c2c66affSColin Finck         return (m_hWnd == hWnd ||
2420c2c66affSColin Finck                 (m_DesktopWnd != NULL && m_hWnd == m_DesktopWnd));
2421c2c66affSColin Finck     }
2422c2c66affSColin Finck 
2423c2c66affSColin Finck     BOOL STDMETHODCALLTYPE IsHorizontal()
2424c2c66affSColin Finck     {
2425c2c66affSColin Finck         return IsPosHorizontal();
2426c2c66affSColin Finck     }
2427c2c66affSColin Finck 
2428c2c66affSColin Finck     BOOL STDMETHODCALLTYPE Lock(IN BOOL bLock)
2429c2c66affSColin Finck     {
24302ed535daSGiannis Adamopoulos         BOOL bPrevLock = g_TaskbarSettings.bLock;
2431c2c66affSColin Finck 
24322ed535daSGiannis Adamopoulos         if (g_TaskbarSettings.bLock != bLock)
2433c2c66affSColin Finck         {
24342ed535daSGiannis Adamopoulos             g_TaskbarSettings.bLock = bLock;
2435c2c66affSColin Finck 
2436c2c66affSColin Finck             if (m_TrayBandSite != NULL)
2437c2c66affSColin Finck             {
2438c2c66affSColin Finck                 if (!SUCCEEDED(m_TrayBandSite->Lock(bLock)))
2439c2c66affSColin Finck                 {
2440c2c66affSColin Finck                     /* Reset?? */
24412ed535daSGiannis Adamopoulos                     g_TaskbarSettings.bLock = bPrevLock;
2442c2c66affSColin Finck                     return bPrevLock;
2443c2c66affSColin Finck                 }
2444c2c66affSColin Finck             }
2445c2c66affSColin Finck 
2446c2c66affSColin Finck             if (m_Theme)
2447c2c66affSColin Finck             {
2448c2c66affSColin Finck                 /* Update cached tray sizes */
2449c2c66affSColin Finck                 for(DWORD Pos = ABE_LEFT; Pos <= ABE_BOTTOM; Pos++)
2450c2c66affSColin Finck                 {
2451c2c66affSColin Finck                     RECT rcGripper = {0};
2452c2c66affSColin Finck                     AdjustSizerRect(&rcGripper, Pos);
2453c2c66affSColin Finck 
24542ed535daSGiannis Adamopoulos                     if(g_TaskbarSettings.bLock)
2455c2c66affSColin Finck                     {
2456c2c66affSColin Finck                         m_TrayRects[Pos].top += rcGripper.top;
2457c2c66affSColin Finck                         m_TrayRects[Pos].left += rcGripper.left;
2458c2c66affSColin Finck                         m_TrayRects[Pos].bottom += rcGripper.bottom;
2459c2c66affSColin Finck                         m_TrayRects[Pos].right += rcGripper.right;
2460c2c66affSColin Finck                     }
2461c2c66affSColin Finck                     else
2462c2c66affSColin Finck                     {
2463c2c66affSColin Finck                         m_TrayRects[Pos].top -= rcGripper.top;
2464c2c66affSColin Finck                         m_TrayRects[Pos].left -= rcGripper.left;
2465c2c66affSColin Finck                         m_TrayRects[Pos].bottom -= rcGripper.bottom;
2466c2c66affSColin Finck                         m_TrayRects[Pos].right -= rcGripper.right;
2467c2c66affSColin Finck                     }
2468c2c66affSColin Finck                 }
2469c2c66affSColin Finck             }
2470c2c66affSColin Finck             SetWindowPos(NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER);
2471c2c66affSColin Finck             ResizeWorkArea();
2472c2c66affSColin Finck             ApplyClipping(TRUE);
2473c2c66affSColin Finck         }
2474c2c66affSColin Finck 
2475c2c66affSColin Finck         return bPrevLock;
2476c2c66affSColin Finck     }
2477c2c66affSColin Finck 
2478e6bced7aSKatayama Hirofumi MZ     /* The task window is visible and non-WS_EX_TOOLWINDOW and
2479e6bced7aSKatayama Hirofumi MZ        { has WS_EX_APPWINDOW style or has no owner } and is none of explorer's
2480e6bced7aSKatayama Hirofumi MZ        special windows (such as the desktop or the tray window) */
2481e6bced7aSKatayama Hirofumi MZ     BOOL STDMETHODCALLTYPE IsTaskWnd(HWND hWnd)
2482e6bced7aSKatayama Hirofumi MZ     {
2483e6bced7aSKatayama Hirofumi MZ         if (::IsWindow(hWnd) && ::IsWindowVisible(hWnd) && !IsSpecialHWND(hWnd))
2484e6bced7aSKatayama Hirofumi MZ         {
2485e6bced7aSKatayama Hirofumi MZ             DWORD exStyle = (DWORD)::GetWindowLongPtr(hWnd, GWL_EXSTYLE);
2486e6bced7aSKatayama Hirofumi MZ             if (((exStyle & WS_EX_APPWINDOW) || ::GetWindow(hWnd, GW_OWNER) == NULL) &&
2487e6bced7aSKatayama Hirofumi MZ                 !(exStyle & WS_EX_TOOLWINDOW))
2488e6bced7aSKatayama Hirofumi MZ             {
2489e6bced7aSKatayama Hirofumi MZ                 return TRUE;
2490e6bced7aSKatayama Hirofumi MZ             }
2491e6bced7aSKatayama Hirofumi MZ         }
2492e6bced7aSKatayama Hirofumi MZ         return FALSE;
2493e6bced7aSKatayama Hirofumi MZ     }
2494c2c66affSColin Finck 
2495c2c66affSColin Finck     /*
2496c2c66affSColin Finck      *  IContextMenu
2497c2c66affSColin Finck      */
2498c2c66affSColin Finck     HRESULT STDMETHODCALLTYPE QueryContextMenu(HMENU hPopup,
2499c2c66affSColin Finck                                                UINT indexMenu,
2500c2c66affSColin Finck                                                UINT idCmdFirst,
2501c2c66affSColin Finck                                                UINT idCmdLast,
2502c2c66affSColin Finck                                                UINT uFlags)
2503c2c66affSColin Finck     {
2504c2c66affSColin Finck         if (!m_ContextMenu)
2505c2c66affSColin Finck         {
2506c2c66affSColin Finck             HRESULT hr = TrayWindowCtxMenuCreator(this, m_hWnd, &m_ContextMenu);
2507c2c66affSColin Finck             if (FAILED_UNEXPECTEDLY(hr))
2508c2c66affSColin Finck                 return hr;
2509c2c66affSColin Finck         }
2510c2c66affSColin Finck 
2511c2c66affSColin Finck         return m_ContextMenu->QueryContextMenu(hPopup, indexMenu, idCmdFirst, idCmdLast, uFlags);
2512c2c66affSColin Finck     }
2513c2c66affSColin Finck 
2514c2c66affSColin Finck     HRESULT STDMETHODCALLTYPE InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
2515c2c66affSColin Finck     {
2516c2c66affSColin Finck         if (!m_ContextMenu)
2517c2c66affSColin Finck             return E_INVALIDARG;
2518c2c66affSColin Finck 
2519c2c66affSColin Finck         return m_ContextMenu->InvokeCommand(lpici);
2520c2c66affSColin Finck     }
2521c2c66affSColin Finck 
2522c2c66affSColin Finck     HRESULT STDMETHODCALLTYPE GetCommandString(UINT_PTR idCmd,
2523c2c66affSColin Finck                                                UINT uType,
2524c2c66affSColin Finck                                                UINT *pwReserved,
2525c2c66affSColin Finck                                                LPSTR pszName,
2526c2c66affSColin Finck                                                UINT cchMax)
2527c2c66affSColin Finck     {
2528c2c66affSColin Finck         if (!m_ContextMenu)
2529c2c66affSColin Finck             return E_INVALIDARG;
2530c2c66affSColin Finck 
2531c2c66affSColin Finck         return m_ContextMenu->GetCommandString(idCmd, uType, pwReserved, pszName, cchMax);
2532c2c66affSColin Finck     }
2533c2c66affSColin Finck 
2534c2c66affSColin Finck     /**********************************************************
2535c2c66affSColin Finck      *    ##### message handling #####
2536c2c66affSColin Finck      */
2537c2c66affSColin Finck 
2538c2c66affSColin Finck     LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2539c2c66affSColin Finck     {
2540c2c66affSColin Finck         HRESULT hRet;
2541c2c66affSColin Finck 
2542c2c66affSColin Finck         ((ITrayWindow*)this)->AddRef();
2543c2c66affSColin Finck 
2544c2c66affSColin Finck         SetWindowTheme(m_hWnd, L"TaskBar", NULL);
2545c2c66affSColin Finck 
2546c2c66affSColin Finck         /* Create the Start button */
2547c2c66affSColin Finck         m_StartButton.Create(m_hWnd);
2548c2c66affSColin Finck 
254926efda4dSKatayama Hirofumi MZ         /* Create the 'Show Desktop' button if necessary */
255028ae9fb7SCarl J. Bialorucki         if (g_TaskbarSettings.bShowDesktopButton)
255126efda4dSKatayama Hirofumi MZ             m_ShowDesktopButton.DoCreate(m_hWnd);
255226efda4dSKatayama Hirofumi MZ 
2553c2c66affSColin Finck         /* Load the saved tray window settings */
2554c2c66affSColin Finck         RegLoadSettings();
2555c2c66affSColin Finck 
2556c2c66affSColin Finck         /* Create and initialize the start menu */
2557c2c66affSColin Finck         HBITMAP hbmBanner = LoadBitmapW(hExplorerInstance, MAKEINTRESOURCEW(IDB_STARTMENU));
2558*17b0623cSKatayama Hirofumi MZ         m_StartMenuPopup = CreateStartMenu(this, &m_StartMenuBand, hbmBanner,
2559*17b0623cSKatayama Hirofumi MZ                                            g_TaskbarSettings.sr.SmSmallIcons);
2560c2c66affSColin Finck 
2561c2c66affSColin Finck         /* Create the task band */
2562c2c66affSColin Finck         hRet = CTaskBand_CreateInstance(this, m_StartButton.m_hWnd, IID_PPV_ARG(IDeskBand, &m_TaskBand));
2563c2c66affSColin Finck         if (FAILED_UNEXPECTEDLY(hRet))
2564c2c66affSColin Finck             return FALSE;
2565c2c66affSColin Finck 
2566c2c66affSColin Finck         /* Create the rebar band site. This actually creates the rebar and the tasks toolbar. */
2567c2c66affSColin Finck         hRet = CTrayBandSite_CreateInstance(this, m_TaskBand, &m_TrayBandSite);
2568c2c66affSColin Finck         if (FAILED_UNEXPECTEDLY(hRet))
2569c2c66affSColin Finck             return FALSE;
2570c2c66affSColin Finck 
2571455bce68SGiannis Adamopoulos         /* Create the tray notification window */
2572455bce68SGiannis Adamopoulos         hRet = CTrayNotifyWnd_CreateInstance(m_hWnd, IID_PPV_ARG(IUnknown, &m_TrayNotifyInstance));
2573455bce68SGiannis Adamopoulos         if (FAILED_UNEXPECTEDLY(hRet))
2574455bce68SGiannis Adamopoulos             return FALSE;
2575455bce68SGiannis Adamopoulos 
2576c2c66affSColin Finck         /* Get the hwnd of the rebar */
2577c2c66affSColin Finck         hRet = IUnknown_GetWindow(m_TrayBandSite, &m_Rebar);
2578c2c66affSColin Finck         if (FAILED_UNEXPECTEDLY(hRet))
2579c2c66affSColin Finck             return FALSE;
2580c2c66affSColin Finck 
2581c2c66affSColin Finck         /* Get the hwnd of the tasks toolbar */
2582c2c66affSColin Finck         hRet = IUnknown_GetWindow(m_TaskBand, &m_TaskSwitch);
2583c2c66affSColin Finck         if (FAILED_UNEXPECTEDLY(hRet))
2584c2c66affSColin Finck             return FALSE;
2585c2c66affSColin Finck 
2586455bce68SGiannis Adamopoulos         /* Get the hwnd of the tray notification window */
2587455bce68SGiannis Adamopoulos         hRet = IUnknown_GetWindow(m_TrayNotifyInstance, &m_TrayNotify);
2588455bce68SGiannis Adamopoulos         if (FAILED_UNEXPECTEDLY(hRet))
2589455bce68SGiannis Adamopoulos             return FALSE;
2590c2c66affSColin Finck 
2591455bce68SGiannis Adamopoulos         SetWindowTheme(m_Rebar, L"TaskBar", NULL);
2592c2c66affSColin Finck 
2593c2c66affSColin Finck         UpdateFonts();
2594c2c66affSColin Finck 
2595c2c66affSColin Finck         InitShellServices(&m_ShellServices);
2596c2c66affSColin Finck 
25972ed535daSGiannis Adamopoulos         if (g_TaskbarSettings.sr.AutoHide)
2598c2c66affSColin Finck         {
2599c2c66affSColin Finck             m_AutoHideState = AUTOHIDE_HIDING;
2600c2c66affSColin Finck             SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_DELAY_HIDE, NULL);
2601c2c66affSColin Finck         }
2602c2c66affSColin Finck 
2603b95fff5bSGiannis Adamopoulos         /* Set the initial lock state in the band site */
2604b95fff5bSGiannis Adamopoulos         m_TrayBandSite->Lock(g_TaskbarSettings.bLock);
2605b95fff5bSGiannis Adamopoulos 
2606c2c66affSColin Finck         RegisterHotKey(m_hWnd, IDHK_RUN, MOD_WIN, 'R');
2607c2c66affSColin Finck         RegisterHotKey(m_hWnd, IDHK_MINIMIZE_ALL, MOD_WIN, 'M');
2608c2c66affSColin Finck         RegisterHotKey(m_hWnd, IDHK_RESTORE_ALL, MOD_WIN|MOD_SHIFT, 'M');
2609c2c66affSColin Finck         RegisterHotKey(m_hWnd, IDHK_HELP, MOD_WIN, VK_F1);
2610c2c66affSColin Finck         RegisterHotKey(m_hWnd, IDHK_EXPLORE, MOD_WIN, 'E');
2611c2c66affSColin Finck         RegisterHotKey(m_hWnd, IDHK_FIND, MOD_WIN, 'F');
2612c2c66affSColin Finck         RegisterHotKey(m_hWnd, IDHK_FIND_COMPUTER, MOD_WIN|MOD_CONTROL, 'F');
2613c2c66affSColin Finck         RegisterHotKey(m_hWnd, IDHK_NEXT_TASK, MOD_WIN, VK_TAB);
2614c2c66affSColin Finck         RegisterHotKey(m_hWnd, IDHK_PREV_TASK, MOD_WIN|MOD_SHIFT, VK_TAB);
2615c2c66affSColin Finck         RegisterHotKey(m_hWnd, IDHK_SYS_PROPERTIES, MOD_WIN, VK_PAUSE);
2616c2c66affSColin Finck         RegisterHotKey(m_hWnd, IDHK_DESKTOP, MOD_WIN, 'D');
2617c2c66affSColin Finck         RegisterHotKey(m_hWnd, IDHK_PAGER, MOD_WIN, 'B');
2618c2c66affSColin Finck 
2619c2c66affSColin Finck         return TRUE;
2620c2c66affSColin Finck     }
2621c2c66affSColin Finck 
2622e6bced7aSKatayama Hirofumi MZ #define TIMER_ID_IGNOREPULSERESET 888
2623e6bced7aSKatayama Hirofumi MZ #define TIMER_IGNOREPULSERESET_TIMEOUT 200
2624e6bced7aSKatayama Hirofumi MZ 
2625e6bced7aSKatayama Hirofumi MZ     LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2626e6bced7aSKatayama Hirofumi MZ     {
2627e6bced7aSKatayama Hirofumi MZ         KillTimer(TIMER_ID_IGNOREPULSERESET);
2628e6bced7aSKatayama Hirofumi MZ         return 0;
2629e6bced7aSKatayama Hirofumi MZ     }
2630e6bced7aSKatayama Hirofumi MZ 
2631c2c66affSColin Finck     LRESULT OnThemeChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2632c2c66affSColin Finck     {
2633c2c66affSColin Finck         if (m_Theme)
2634c2c66affSColin Finck             CloseThemeData(m_Theme);
2635c2c66affSColin Finck 
2636c2c66affSColin Finck         m_Theme = OpenThemeData(m_hWnd, L"TaskBar");
2637c2c66affSColin Finck 
2638c2c66affSColin Finck         if (m_Theme)
2639c2c66affSColin Finck         {
2640c2c66affSColin Finck             SetWindowStyle(m_hWnd, WS_THICKFRAME | WS_BORDER, 0);
2641c2c66affSColin Finck         }
2642c2c66affSColin Finck         else
2643c2c66affSColin Finck         {
2644c2c66affSColin Finck             SetWindowStyle(m_hWnd, WS_THICKFRAME | WS_BORDER, WS_THICKFRAME | WS_BORDER);
2645c2c66affSColin Finck         }
2646c2c66affSColin Finck         SetWindowPos(NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER);
2647c2c66affSColin Finck 
2648c2c66affSColin Finck         return TRUE;
2649c2c66affSColin Finck     }
2650c2c66affSColin Finck 
2651c2c66affSColin Finck     LRESULT OnSettingChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2652c2c66affSColin Finck     {
2653c2c66affSColin Finck         if (wParam == SPI_SETNONCLIENTMETRICS)
2654c2c66affSColin Finck         {
2655c2c66affSColin Finck             SendMessage(m_TrayNotify, uMsg, wParam, lParam);
2656c2c66affSColin Finck             SendMessage(m_TaskSwitch, uMsg, wParam, lParam);
2657c2c66affSColin Finck             UpdateFonts();
2658c2c66affSColin Finck             AlignControls(NULL);
2659c2c66affSColin Finck             CheckTrayWndPosition();
2660c2c66affSColin Finck         }
2661c2c66affSColin Finck 
2662d1ac33a9SKatayama Hirofumi MZ         if (m_StartMenuPopup && lstrcmpiW((LPCWSTR)lParam, L"TraySettings") == 0)
2663d1ac33a9SKatayama Hirofumi MZ         {
2664d1ac33a9SKatayama Hirofumi MZ             HideStartMenu();
2665ad748b0bSKatayama Hirofumi MZ 
2666d1ac33a9SKatayama Hirofumi MZ             HBITMAP hbmBanner = LoadBitmapW(hExplorerInstance, MAKEINTRESOURCEW(IDB_STARTMENU));
2667*17b0623cSKatayama Hirofumi MZ #if 1 // FIXME: Please re-use the start menu
2668*17b0623cSKatayama Hirofumi MZ             /* Re-create the start menu */
2669*17b0623cSKatayama Hirofumi MZ             m_StartMenuBand.Release();
2670*17b0623cSKatayama Hirofumi MZ             m_StartMenuPopup = CreateStartMenu(this, &m_StartMenuBand, hbmBanner,
2671*17b0623cSKatayama Hirofumi MZ                                                g_TaskbarSettings.sr.SmSmallIcons);
2672*17b0623cSKatayama Hirofumi MZ             FIXME("Use UpdateStartMenu\n");
2673*17b0623cSKatayama Hirofumi MZ #else
2674*17b0623cSKatayama Hirofumi MZ             // Update the start menu
2675*17b0623cSKatayama Hirofumi MZ             UpdateStartMenu(m_StartMenuPopup, hbmBanner, g_TaskbarSettings.sr.SmSmallIcons, TRUE);
2676*17b0623cSKatayama Hirofumi MZ #endif
2677d1ac33a9SKatayama Hirofumi MZ         }
2678d1ac33a9SKatayama Hirofumi MZ 
2679c2c66affSColin Finck         return 0;
2680c2c66affSColin Finck     }
2681c2c66affSColin Finck 
2682c2c66affSColin Finck     LRESULT OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2683c2c66affSColin Finck     {
2684c2c66affSColin Finck         HDC hdc = (HDC) wParam;
2685c2c66affSColin Finck 
2686c2c66affSColin Finck         if (!m_Theme)
2687c2c66affSColin Finck         {
2688c2c66affSColin Finck             bHandled = FALSE;
2689c2c66affSColin Finck             return 0;
2690c2c66affSColin Finck         }
2691c2c66affSColin Finck 
2692c2c66affSColin Finck         return EraseBackgroundWithTheme(hdc);
2693c2c66affSColin Finck     }
2694c2c66affSColin Finck 
2695c2c66affSColin Finck     LRESULT OnDisplayChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2696c2c66affSColin Finck     {
2697c2c66affSColin Finck         /* Load the saved tray window settings */
2698c2c66affSColin Finck         RegLoadSettings();
2699c2c66affSColin Finck 
2700c2c66affSColin Finck         /* Move the tray window to the right position and resize it if necessary */
2701c2c66affSColin Finck         CheckTrayWndPosition();
2702c2c66affSColin Finck 
2703c2c66affSColin Finck         return TRUE;
2704c2c66affSColin Finck     }
2705c2c66affSColin Finck 
2706c2c66affSColin Finck     LRESULT OnCopyData(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2707c2c66affSColin Finck     {
270822ab8c81SKatayama Hirofumi MZ         COPYDATASTRUCT *pCopyData = (COPYDATASTRUCT *)lParam;
27091c400705SKatayama Hirofumi MZ         switch (pCopyData->dwData)
27101c400705SKatayama Hirofumi MZ         {
27111c400705SKatayama Hirofumi MZ             case TABDMC_APPBAR:
27121c400705SKatayama Hirofumi MZ                 return appbar_message(pCopyData);
27131c400705SKatayama Hirofumi MZ             case TABDMC_NOTIFY:
27141c400705SKatayama Hirofumi MZ             case TABDMC_LOADINPROC:
27151c400705SKatayama Hirofumi MZ                 return ::SendMessageW(m_TrayNotify, uMsg, wParam, lParam);
27161c400705SKatayama Hirofumi MZ         }
27171c400705SKatayama Hirofumi MZ         return FALSE;
2718c2c66affSColin Finck     }
2719c2c66affSColin Finck 
272026efda4dSKatayama Hirofumi MZ     // We have to draw non-client area because the 'Show Desktop' button is beyond client area.
272126efda4dSKatayama Hirofumi MZ     void DrawShowDesktopButton()
272226efda4dSKatayama Hirofumi MZ     {
2723ba2cead8SKatayama Hirofumi MZ         if (!m_ShowDesktopButton.IsWindow())
2724ba2cead8SKatayama Hirofumi MZ             return;
272526efda4dSKatayama Hirofumi MZ         // Get the rectangle in window coordinates
272626efda4dSKatayama Hirofumi MZ         RECT rcButton, rcWnd;
272726efda4dSKatayama Hirofumi MZ         GetWindowRect(&rcWnd);
272826efda4dSKatayama Hirofumi MZ         m_ShowDesktopButton.GetWindowRect(&rcButton);
272926efda4dSKatayama Hirofumi MZ         ::OffsetRect(&rcButton, -rcWnd.left, -rcWnd.top);
273026efda4dSKatayama Hirofumi MZ 
2731ba2cead8SKatayama Hirofumi MZ         HDC hdc = GetDCEx(NULL, DCX_WINDOW | DCX_CACHE);
273226efda4dSKatayama Hirofumi MZ         m_ShowDesktopButton.OnDraw(hdc, &rcButton); // Draw the button
273326efda4dSKatayama Hirofumi MZ         ReleaseDC(hdc);
273426efda4dSKatayama Hirofumi MZ     }
273526efda4dSKatayama Hirofumi MZ 
2736c2c66affSColin Finck     LRESULT OnNcPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2737c2c66affSColin Finck     {
273826efda4dSKatayama Hirofumi MZ         DefWindowProc(uMsg, wParam, lParam);
273926efda4dSKatayama Hirofumi MZ         bHandled = TRUE;
274026efda4dSKatayama Hirofumi MZ 
274126efda4dSKatayama Hirofumi MZ         if (!m_Theme || g_TaskbarSettings.bLock)
2742c2c66affSColin Finck         {
274326efda4dSKatayama Hirofumi MZ             DrawShowDesktopButton(); // We have to draw non-client area
2744c54c5ebbSGiannis Adamopoulos             return 0;
2745c54c5ebbSGiannis Adamopoulos         }
2746c2c66affSColin Finck 
274726efda4dSKatayama Hirofumi MZ         DrawSizerWithTheme((HRGN) wParam);
274826efda4dSKatayama Hirofumi MZ         DrawShowDesktopButton(); // We have to draw non-client area
274926efda4dSKatayama Hirofumi MZ         return 0;
2750c2c66affSColin Finck     }
2751c2c66affSColin Finck 
2752c2c66affSColin Finck     LRESULT OnCtlColorBtn(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2753c2c66affSColin Finck     {
2754c2c66affSColin Finck         SetBkMode((HDC) wParam, TRANSPARENT);
2755c2c66affSColin Finck         return (LRESULT) GetStockObject(HOLLOW_BRUSH);
2756c2c66affSColin Finck     }
2757c2c66affSColin Finck 
2758c2c66affSColin Finck     LRESULT OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2759c2c66affSColin Finck     {
2760c2c66affSColin Finck         RECT rcClient;
2761c2c66affSColin Finck         POINT pt;
2762c2c66affSColin Finck 
27632ed535daSGiannis Adamopoulos         if (g_TaskbarSettings.bLock)
2764c2c66affSColin Finck         {
2765c2c66affSColin Finck             /* The user may not be able to resize the tray window.
2766c2c66affSColin Finck             Pretend like the window is not sizeable when the user
2767c2c66affSColin Finck             clicks on the border. */
2768c2c66affSColin Finck             return HTBORDER;
2769c2c66affSColin Finck         }
2770c2c66affSColin Finck 
2771c2c66affSColin Finck         SetLastError(ERROR_SUCCESS);
2772c2c66affSColin Finck         if (GetClientRect(&rcClient) &&
2773c2c66affSColin Finck             (MapWindowPoints(NULL, (LPPOINT) &rcClient, 2) != 0 || GetLastError() == ERROR_SUCCESS))
2774c2c66affSColin Finck         {
2775c2c66affSColin Finck             pt.x = (SHORT) LOWORD(lParam);
2776c2c66affSColin Finck             pt.y = (SHORT) HIWORD(lParam);
2777c2c66affSColin Finck 
2778eff4c213SHermès Bélusca-Maïto             if (PtInRect(&rcClient, pt))
2779c2c66affSColin Finck             {
2780c2c66affSColin Finck                 /* The user is trying to drag the tray window */
2781c2c66affSColin Finck                 return HTCAPTION;
2782c2c66affSColin Finck             }
2783c2c66affSColin Finck 
2784c2c66affSColin Finck             /* Depending on the position of the tray window, allow only
2785c2c66affSColin Finck             changing the border next to the monitor working area */
2786c2c66affSColin Finck             switch (m_Position)
2787c2c66affSColin Finck             {
2788c2c66affSColin Finck             case ABE_TOP:
2789c2c66affSColin Finck                 if (pt.y > rcClient.bottom)
2790c2c66affSColin Finck                     return HTBOTTOM;
2791c2c66affSColin Finck                 break;
2792c2c66affSColin Finck             case ABE_LEFT:
2793c2c66affSColin Finck                 if (pt.x > rcClient.right)
2794c2c66affSColin Finck                     return HTRIGHT;
2795c2c66affSColin Finck                 break;
2796c2c66affSColin Finck             case ABE_RIGHT:
2797c2c66affSColin Finck                 if (pt.x < rcClient.left)
2798c2c66affSColin Finck                     return HTLEFT;
2799c2c66affSColin Finck                 break;
2800c2c66affSColin Finck             case ABE_BOTTOM:
2801c2c66affSColin Finck             default:
2802c2c66affSColin Finck                 if (pt.y < rcClient.top)
2803c2c66affSColin Finck                     return HTTOP;
2804c2c66affSColin Finck                 break;
2805c2c66affSColin Finck             }
2806c2c66affSColin Finck         }
2807c2c66affSColin Finck         return HTBORDER;
2808c2c66affSColin Finck     }
2809c2c66affSColin Finck 
2810c2c66affSColin Finck     LRESULT OnMoving(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2811c2c66affSColin Finck     {
2812c2c66affSColin Finck         POINT ptCursor;
2813c2c66affSColin Finck         PRECT pRect = (PRECT) lParam;
2814c2c66affSColin Finck 
2815c2c66affSColin Finck         /* We need to ensure that an application can not accidently
2816c2c66affSColin Finck         move the tray window (using SetWindowPos). However, we still
2817c2c66affSColin Finck         need to be able to move the window in case the user wants to
2818c2c66affSColin Finck         drag the tray window to another position or in case the user
2819c2c66affSColin Finck         wants to resize the tray window. */
28202ed535daSGiannis Adamopoulos         if (!g_TaskbarSettings.bLock && GetCursorPos(&ptCursor))
2821c2c66affSColin Finck         {
2822c2c66affSColin Finck             IsDragging = TRUE;
2823c2c66affSColin Finck             m_DraggingPosition = GetDraggingRectFromPt(ptCursor, pRect, &m_DraggingMonitor);
2824c2c66affSColin Finck         }
2825c2c66affSColin Finck         else
2826c2c66affSColin Finck         {
2827c2c66affSColin Finck             *pRect = m_TrayRects[m_Position];
2828c2c66affSColin Finck         }
2829c2c66affSColin Finck         return TRUE;
2830c2c66affSColin Finck     }
2831c2c66affSColin Finck 
2832c2c66affSColin Finck     LRESULT OnSizing(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2833c2c66affSColin Finck     {
2834c2c66affSColin Finck         PRECT pRect = (PRECT) lParam;
2835c2c66affSColin Finck 
28362ed535daSGiannis Adamopoulos         if (!g_TaskbarSettings.bLock)
2837c2c66affSColin Finck         {
2838c2c66affSColin Finck             FitToRebar(pRect);
2839c2c66affSColin Finck         }
2840c2c66affSColin Finck         else
2841c2c66affSColin Finck         {
2842c2c66affSColin Finck             *pRect = m_TrayRects[m_Position];
2843c2c66affSColin Finck         }
2844c2c66affSColin Finck         return TRUE;
2845c2c66affSColin Finck     }
2846c2c66affSColin Finck 
28474238f223SGiannis Adamopoulos     LRESULT OnWindowPosChanging(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2848c2c66affSColin Finck     {
2849c2c66affSColin Finck         ChangingWinPos((LPWINDOWPOS) lParam);
2850c2c66affSColin Finck         return TRUE;
2851c2c66affSColin Finck     }
2852c2c66affSColin Finck 
2853c2c66affSColin Finck     LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2854c2c66affSColin Finck     {
2855c2c66affSColin Finck         RECT rcClient;
2856c2c66affSColin Finck         if (wParam == SIZE_RESTORED && lParam == 0)
2857c2c66affSColin Finck         {
2858c2c66affSColin Finck             ResizeWorkArea();
2859c2c66affSColin Finck             /* Clip the tray window on multi monitor systems so the edges can't
2860c2c66affSColin Finck             overlap into another monitor */
2861c2c66affSColin Finck             ApplyClipping(TRUE);
2862c2c66affSColin Finck 
2863c2c66affSColin Finck             if (!GetClientRect(&rcClient))
2864c2c66affSColin Finck             {
2865c2c66affSColin Finck                 return FALSE;
2866c2c66affSColin Finck             }
2867c2c66affSColin Finck         }
2868c2c66affSColin Finck         else
2869c2c66affSColin Finck         {
2870c2c66affSColin Finck             rcClient.left = rcClient.top = 0;
2871c2c66affSColin Finck             rcClient.right = LOWORD(lParam);
2872c2c66affSColin Finck             rcClient.bottom = HIWORD(lParam);
2873c2c66affSColin Finck         }
2874c2c66affSColin Finck 
2875c2c66affSColin Finck         AlignControls(&rcClient);
2876c2c66affSColin Finck         return TRUE;
2877c2c66affSColin Finck     }
2878c2c66affSColin Finck 
2879c2c66affSColin Finck     LRESULT OnEnterSizeMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2880c2c66affSColin Finck     {
2881c2c66affSColin Finck         InSizeMove = TRUE;
2882c2c66affSColin Finck         IsDragging = FALSE;
28832ed535daSGiannis Adamopoulos         if (!g_TaskbarSettings.bLock)
2884c2c66affSColin Finck         {
2885c2c66affSColin Finck             /* Remove the clipping on multi monitor systems while dragging around */
2886c2c66affSColin Finck             ApplyClipping(FALSE);
2887c2c66affSColin Finck         }
2888c2c66affSColin Finck         return TRUE;
2889c2c66affSColin Finck     }
2890c2c66affSColin Finck 
2891c2c66affSColin Finck     LRESULT OnExitSizeMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2892c2c66affSColin Finck     {
2893c2c66affSColin Finck         InSizeMove = FALSE;
28942ed535daSGiannis Adamopoulos         if (!g_TaskbarSettings.bLock)
2895c2c66affSColin Finck         {
2896c2c66affSColin Finck             FitToRebar(&m_TrayRects[m_Position]);
2897c2c66affSColin Finck 
2898c2c66affSColin Finck             /* Apply clipping */
2899c2c66affSColin Finck             PostMessage(WM_SIZE, SIZE_RESTORED, 0);
2900c2c66affSColin Finck         }
2901c2c66affSColin Finck         return TRUE;
2902c2c66affSColin Finck     }
2903c2c66affSColin Finck 
2904c2c66affSColin Finck     LRESULT OnSysChar(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2905c2c66affSColin Finck     {
2906c2c66affSColin Finck         switch (wParam)
2907c2c66affSColin Finck         {
2908c2c66affSColin Finck         case TEXT(' '):
2909c2c66affSColin Finck         {
2910c2c66affSColin Finck             /* The user pressed Alt+Space, this usually brings up the system menu of a window.
2911c2c66affSColin Finck             The tray window needs to handle this specially, since it normally doesn't have
2912c2c66affSColin Finck             a system menu. */
2913c2c66affSColin Finck 
2914c2c66affSColin Finck             static const UINT uidDisableItem [] = {
2915c2c66affSColin Finck                 SC_RESTORE,
2916c2c66affSColin Finck                 SC_MOVE,
2917c2c66affSColin Finck                 SC_SIZE,
2918c2c66affSColin Finck                 SC_MAXIMIZE,
2919c2c66affSColin Finck                 SC_MINIMIZE,
2920c2c66affSColin Finck             };
2921c2c66affSColin Finck             HMENU hSysMenu;
2922c2c66affSColin Finck             UINT i, uId;
2923c2c66affSColin Finck 
2924c2c66affSColin Finck             /* temporarily enable the system menu */
2925c2c66affSColin Finck             SetWindowStyle(m_hWnd, WS_SYSMENU, WS_SYSMENU);
2926c2c66affSColin Finck 
2927c2c66affSColin Finck             hSysMenu = GetSystemMenu(FALSE);
2928c2c66affSColin Finck             if (hSysMenu != NULL)
2929c2c66affSColin Finck             {
2930c2c66affSColin Finck                 /* Disable all items that are not relevant */
2931c2c66affSColin Finck                 for (i = 0; i < _countof(uidDisableItem); i++)
2932c2c66affSColin Finck                 {
2933c2c66affSColin Finck                     EnableMenuItem(hSysMenu,
2934c2c66affSColin Finck                                    uidDisableItem[i],
2935c2c66affSColin Finck                                    MF_BYCOMMAND | MF_GRAYED);
2936c2c66affSColin Finck                 }
2937c2c66affSColin Finck 
2938c2c66affSColin Finck                 EnableMenuItem(hSysMenu,
2939c2c66affSColin Finck                                SC_CLOSE,
2940c2c66affSColin Finck                                MF_BYCOMMAND |
2941c2c66affSColin Finck                                (SHRestricted(REST_NOCLOSE) ? MF_GRAYED : MF_ENABLED));
2942c2c66affSColin Finck 
2943c2c66affSColin Finck                 /* Display the system menu */
2944c2c66affSColin Finck                 uId = TrackMenu(
2945c2c66affSColin Finck                     hSysMenu,
2946c2c66affSColin Finck                     NULL,
2947c2c66affSColin Finck                     m_StartButton.m_hWnd,
2948c2c66affSColin Finck                     m_Position != ABE_TOP,
2949c2c66affSColin Finck                     FALSE);
2950c2c66affSColin Finck                 if (uId != 0)
2951c2c66affSColin Finck                 {
2952c2c66affSColin Finck                     SendMessage(m_hWnd, WM_SYSCOMMAND, (WPARAM) uId, 0);
2953c2c66affSColin Finck                 }
2954c2c66affSColin Finck             }
2955c2c66affSColin Finck 
2956c2c66affSColin Finck             /* revert the system menu window style */
2957c2c66affSColin Finck             SetWindowStyle(m_hWnd, WS_SYSMENU, 0);
2958c2c66affSColin Finck             break;
2959c2c66affSColin Finck         }
2960c2c66affSColin Finck 
2961c2c66affSColin Finck         default:
2962c2c66affSColin Finck             bHandled = FALSE;
2963c2c66affSColin Finck         }
2964c2c66affSColin Finck         return TRUE;
2965c2c66affSColin Finck     }
2966c2c66affSColin Finck 
2967c2c66affSColin Finck     LRESULT OnNcLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2968c2c66affSColin Finck     {
2969c2c66affSColin Finck         /* This handler implements the trick that makes  the start button to
2970c2c66affSColin Finck            get pressed when the user clicked left or below the button */
2971c2c66affSColin Finck 
2972c2c66affSColin Finck         POINT pt = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
2973c2c66affSColin Finck         WINDOWINFO wi = {sizeof(WINDOWINFO)};
2974c2c66affSColin Finck 
2975c2c66affSColin Finck         bHandled = FALSE;
2976c2c66affSColin Finck 
297726efda4dSKatayama Hirofumi MZ         RECT rcStartBtn;
2978c2c66affSColin Finck         m_StartButton.GetWindowRect(&rcStartBtn);
297926efda4dSKatayama Hirofumi MZ 
2980c2c66affSColin Finck         GetWindowInfo(m_hWnd, &wi);
2981c2c66affSColin Finck 
2982c2c66affSColin Finck         switch (m_Position)
2983c2c66affSColin Finck         {
2984c2c66affSColin Finck             case ABE_TOP:
2985c2c66affSColin Finck             case ABE_LEFT:
2986c2c66affSColin Finck             {
2987c2c66affSColin Finck                 if (pt.x > rcStartBtn.right || pt.y > rcStartBtn.bottom)
2988c2c66affSColin Finck                     return 0;
2989c2c66affSColin Finck                 break;
2990c2c66affSColin Finck             }
2991c2c66affSColin Finck             case ABE_RIGHT:
2992c2c66affSColin Finck             {
2993c2c66affSColin Finck                 if (pt.x < rcStartBtn.left || pt.y > rcStartBtn.bottom)
2994c2c66affSColin Finck                     return 0;
2995c2c66affSColin Finck 
2996c2c66affSColin Finck                 if (rcStartBtn.right + (int)wi.cxWindowBorders * 2 + 1 < wi.rcWindow.right &&
2997c2c66affSColin Finck                     pt.x > rcStartBtn.right)
2998c2c66affSColin Finck                 {
2999c2c66affSColin Finck                     return 0;
3000c2c66affSColin Finck                 }
3001c2c66affSColin Finck                 break;
3002c2c66affSColin Finck             }
3003c2c66affSColin Finck             case ABE_BOTTOM:
3004c2c66affSColin Finck             {
3005c2c66affSColin Finck                 if (pt.x > rcStartBtn.right || pt.y < rcStartBtn.top)
3006c2c66affSColin Finck                     return 0;
3007c2c66affSColin Finck 
3008c2c66affSColin Finck                 if (rcStartBtn.bottom + (int)wi.cyWindowBorders * 2 + 1 < wi.rcWindow.bottom &&
3009c2c66affSColin Finck                     pt.y > rcStartBtn.bottom)
3010c2c66affSColin Finck                 {
3011c2c66affSColin Finck                     return 0;
3012c2c66affSColin Finck                 }
3013c2c66affSColin Finck 
3014c2c66affSColin Finck                 break;
3015c2c66affSColin Finck             }
3016c2c66affSColin Finck         }
3017c2c66affSColin Finck 
3018c2c66affSColin Finck         bHandled = TRUE;
3019c2c66affSColin Finck         PopupStartMenu();
3020c2c66affSColin Finck         return 0;
3021c2c66affSColin Finck     }
3022c2c66affSColin Finck 
3023c2c66affSColin Finck     LRESULT OnNcRButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
3024c2c66affSColin Finck     {
3025c2c66affSColin Finck         /* We want the user to be able to get a context menu even on the nonclient
3026c2c66affSColin Finck         area (including the sizing border)! */
3027c2c66affSColin Finck         uMsg = WM_CONTEXTMENU;
3028c2c66affSColin Finck         wParam = (WPARAM) m_hWnd;
3029c2c66affSColin Finck 
3030c2c66affSColin Finck         return OnContextMenu(uMsg, wParam, lParam, bHandled);
3031c2c66affSColin Finck     }
3032c2c66affSColin Finck 
3033c2c66affSColin Finck     LRESULT OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
3034c2c66affSColin Finck     {
3035c2c66affSColin Finck         LRESULT Ret = FALSE;
3036c2c66affSColin Finck         POINT pt, *ppt = NULL;
3037c2c66affSColin Finck         HWND hWndExclude = NULL;
3038c2c66affSColin Finck 
3039c2c66affSColin Finck         /* Check if the administrator has forbidden access to context menus */
3040c2c66affSColin Finck         if (SHRestricted(REST_NOTRAYCONTEXTMENU))
3041c2c66affSColin Finck             return FALSE;
3042c2c66affSColin Finck 
3043c2c66affSColin Finck         pt.x = (SHORT) LOWORD(lParam);
3044c2c66affSColin Finck         pt.y = (SHORT) HIWORD(lParam);
3045c2c66affSColin Finck 
3046c2c66affSColin Finck         if (pt.x != -1 || pt.y != -1)
3047c2c66affSColin Finck             ppt = &pt;
3048c2c66affSColin Finck         else
3049c2c66affSColin Finck             hWndExclude = m_StartButton.m_hWnd;
3050c2c66affSColin Finck 
3051c2c66affSColin Finck         if ((HWND) wParam == m_StartButton.m_hWnd)
3052c2c66affSColin Finck         {
3053c2c66affSColin Finck             /* Make sure we can't track the context menu if the start
3054c2c66affSColin Finck             menu is currently being shown */
3055c2c66affSColin Finck             if (!(m_StartButton.SendMessage(BM_GETSTATE, 0, 0) & BST_PUSHED))
3056c2c66affSColin Finck             {
3057c2c66affSColin Finck                 CComPtr<IContextMenu> ctxMenu;
305884fa20ecSGiannis Adamopoulos                 CStartMenuBtnCtxMenu_CreateInstance(this, m_hWnd, &ctxMenu);
3059c2c66affSColin Finck                 TrackCtxMenu(ctxMenu, ppt, hWndExclude, m_Position == ABE_BOTTOM, this);
3060c2c66affSColin Finck             }
3061c2c66affSColin Finck         }
3062c2c66affSColin Finck         else
3063c2c66affSColin Finck         {
3064c2c66affSColin Finck             /* See if the context menu should be handled by the task band site */
3065c2c66affSColin Finck             if (ppt != NULL && m_TrayBandSite != NULL)
3066c2c66affSColin Finck             {
3067c2c66affSColin Finck                 HWND hWndAtPt;
3068c2c66affSColin Finck                 POINT ptClient = *ppt;
3069c2c66affSColin Finck 
3070c2c66affSColin Finck                 /* Convert the coordinates to client-coordinates */
3071c2c66affSColin Finck                 ::MapWindowPoints(NULL, m_hWnd, &ptClient, 1);
3072c2c66affSColin Finck 
3073c2c66affSColin Finck                 hWndAtPt = ChildWindowFromPoint(ptClient);
3074c2c66affSColin Finck                 if (hWndAtPt != NULL &&
3075c2c66affSColin Finck                     (hWndAtPt == m_Rebar || ::IsChild(m_Rebar, hWndAtPt)))
3076c2c66affSColin Finck                 {
3077c2c66affSColin Finck                     /* Check if the user clicked on the task switch window */
3078c2c66affSColin Finck                     ptClient = *ppt;
3079c2c66affSColin Finck                     ::MapWindowPoints(NULL, m_Rebar, &ptClient, 1);
3080c2c66affSColin Finck 
3081c2c66affSColin Finck                     hWndAtPt = ::ChildWindowFromPointEx(m_Rebar, ptClient, CWP_SKIPINVISIBLE | CWP_SKIPDISABLED);
3082c2c66affSColin Finck                     if (hWndAtPt == m_TaskSwitch)
3083c2c66affSColin Finck                         goto HandleTrayContextMenu;
3084c2c66affSColin Finck 
3085c2c66affSColin Finck                     /* Forward the message to the task band site */
3086c2c66affSColin Finck                     m_TrayBandSite->ProcessMessage(m_hWnd, uMsg, wParam, lParam, &Ret);
3087c2c66affSColin Finck                 }
3088c2c66affSColin Finck                 else
3089c2c66affSColin Finck                     goto HandleTrayContextMenu;
3090c2c66affSColin Finck             }
3091c2c66affSColin Finck             else
3092c2c66affSColin Finck             {
3093c2c66affSColin Finck HandleTrayContextMenu:
3094c2c66affSColin Finck                 /* Tray the default tray window context menu */
3095c2c66affSColin Finck                 TrackCtxMenu(this, ppt, NULL, FALSE, this);
3096c2c66affSColin Finck             }
3097c2c66affSColin Finck         }
3098c2c66affSColin Finck         return Ret;
3099c2c66affSColin Finck     }
3100c2c66affSColin Finck 
3101c2c66affSColin Finck     LRESULT OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
3102c2c66affSColin Finck     {
3103c2c66affSColin Finck         LRESULT Ret = FALSE;
3104c2c66affSColin Finck         /* FIXME: We can't check with IsChild whether the hwnd is somewhere inside
3105c2c66affSColin Finck         the rebar control! But we shouldn't forward messages that the band
3106c2c66affSColin Finck         site doesn't handle, such as other controls (start button, tray window */
3107c2c66affSColin Finck 
3108c2c66affSColin Finck         HRESULT hr = E_FAIL;
3109c2c66affSColin Finck 
3110c2c66affSColin Finck         if (m_TrayBandSite)
3111c2c66affSColin Finck         {
3112c2c66affSColin Finck             hr = m_TrayBandSite->ProcessMessage(m_hWnd, uMsg, wParam, lParam, &Ret);
3113c2c66affSColin Finck             if (SUCCEEDED(hr))
3114c2c66affSColin Finck                 return Ret;
3115c2c66affSColin Finck         }
3116c2c66affSColin Finck 
3117c2c66affSColin Finck         if (m_TrayBandSite == NULL || FAILED(hr))
3118c2c66affSColin Finck         {
3119c2c66affSColin Finck             const NMHDR *nmh = (const NMHDR *) lParam;
3120c2c66affSColin Finck 
3121c2c66affSColin Finck             if (nmh->hwndFrom == m_TrayNotify)
3122c2c66affSColin Finck             {
3123c2c66affSColin Finck                 switch (nmh->code)
3124c2c66affSColin Finck                 {
3125c2c66affSColin Finck                 case NTNWM_REALIGN:
3126c2c66affSColin Finck                     /* Cause all controls to be aligned */
3127c2c66affSColin Finck                     PostMessage(WM_SIZE, SIZE_RESTORED, 0);
3128c2c66affSColin Finck                     break;
3129c2c66affSColin Finck                 }
3130c2c66affSColin Finck             }
3131c2c66affSColin Finck         }
3132c2c66affSColin Finck         return Ret;
3133c2c66affSColin Finck     }
3134c2c66affSColin Finck 
313526efda4dSKatayama Hirofumi MZ     BOOL CheckShowDesktopButtonClick(LPARAM lParam, BOOL& bHandled)
313626efda4dSKatayama Hirofumi MZ     {
313726efda4dSKatayama Hirofumi MZ         POINT pt = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
313826efda4dSKatayama Hirofumi MZ         if (m_ShowDesktopButton.PtInButton(pt)) // Did you click the button?
313926efda4dSKatayama Hirofumi MZ         {
314026efda4dSKatayama Hirofumi MZ             m_ShowDesktopButton.Click();
314126efda4dSKatayama Hirofumi MZ             bHandled = TRUE;
314226efda4dSKatayama Hirofumi MZ             return TRUE;
314326efda4dSKatayama Hirofumi MZ         }
314426efda4dSKatayama Hirofumi MZ 
314526efda4dSKatayama Hirofumi MZ         return FALSE;
314626efda4dSKatayama Hirofumi MZ     }
314726efda4dSKatayama Hirofumi MZ 
3148c2c66affSColin Finck     LRESULT OnNcLButtonDblClick(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
3149c2c66affSColin Finck     {
315072ea2d4cSAndrew Dent         /* Let the clock handle the double-click */
31517f35908aSGiannis Adamopoulos         ::SendMessageW(m_TrayNotify, uMsg, wParam, lParam);
31527f35908aSGiannis Adamopoulos 
3153c2c66affSColin Finck         /* We "handle" this message so users can't cause a weird maximize/restore
3154c2c66affSColin Finck         window animation when double-clicking the tray window! */
3155c2c66affSColin Finck         return TRUE;
3156c2c66affSColin Finck     }
3157c2c66affSColin Finck 
315846de3a22SKatayama Hirofumi MZ     LRESULT OnNcLButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
315946de3a22SKatayama Hirofumi MZ     {
316063fa6747SJoachim Henze         CheckShowDesktopButtonClick(lParam, bHandled);
316163fa6747SJoachim Henze         return FALSE;
316246de3a22SKatayama Hirofumi MZ     }
316346de3a22SKatayama Hirofumi MZ 
3164c2c66affSColin Finck     LRESULT OnAppTrayDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
3165c2c66affSColin Finck     {
3166c2c66affSColin Finck         DestroyWindow();
3167c2c66affSColin Finck         return TRUE;
3168c2c66affSColin Finck     }
3169c2c66affSColin Finck 
3170c2c66affSColin Finck     LRESULT OnOpenStartMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
3171c2c66affSColin Finck     {
3172c2c66affSColin Finck         HWND hwndStartMenu;
3173c2c66affSColin Finck         HRESULT hr = IUnknown_GetWindow(m_StartMenuPopup, &hwndStartMenu);
3174c2c66affSColin Finck         if (FAILED_UNEXPECTEDLY(hr))
3175c2c66affSColin Finck             return FALSE;
3176c2c66affSColin Finck 
3177c2c66affSColin Finck         if (::IsWindowVisible(hwndStartMenu))
3178802a87dfSKatayama Hirofumi MZ             HideStartMenu();
3179c2c66affSColin Finck         else
3180c2c66affSColin Finck             PopupStartMenu();
3181c2c66affSColin Finck 
3182c2c66affSColin Finck         return TRUE;
3183c2c66affSColin Finck     }
3184c2c66affSColin Finck 
3185c2c66affSColin Finck     LRESULT OnDoExitWindows(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
3186c2c66affSColin Finck     {
3187c2c66affSColin Finck         /*
3188c2c66affSColin Finck          * TWM_DOEXITWINDOWS is send by the CDesktopBrowser to us
3189c2c66affSColin Finck          * to show the shutdown dialog. Also a WM_CLOSE message sent
3190c2c66affSColin Finck          * by apps should show the dialog.
3191c2c66affSColin Finck          */
3192c2c66affSColin Finck         return DoExitWindows();
3193c2c66affSColin Finck     }
3194c2c66affSColin Finck 
3195c2c66affSColin Finck     LRESULT OnSysCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
3196c2c66affSColin Finck     {
3197c2c66affSColin Finck         if (wParam == SC_CLOSE)
3198c2c66affSColin Finck         {
3199c2c66affSColin Finck             return DoExitWindows();
3200c2c66affSColin Finck         }
3201c2c66affSColin Finck 
3202c2c66affSColin Finck         bHandled = FALSE;
3203c2c66affSColin Finck         return TRUE;
3204c2c66affSColin Finck     }
3205c2c66affSColin Finck 
32066940d9fdSMark Jansen     LRESULT OnGetTaskSwitch(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
32076940d9fdSMark Jansen     {
32086940d9fdSMark Jansen         bHandled = TRUE;
32096940d9fdSMark Jansen         return (LRESULT)m_TaskSwitch;
32106940d9fdSMark Jansen     }
32116940d9fdSMark Jansen 
3212e6bced7aSKatayama Hirofumi MZ     void RestoreMinimizedNonTaskWnds(BOOL bDestroyed, HWND hwndActive)
3213e6bced7aSKatayama Hirofumi MZ     {
3214e6bced7aSKatayama Hirofumi MZ         for (INT i = g_MinimizedAll.GetSize() - 1; i >= 0; --i)
3215e6bced7aSKatayama Hirofumi MZ         {
3216e6bced7aSKatayama Hirofumi MZ             HWND hwnd = g_MinimizedAll[i].hwnd;
3217e6bced7aSKatayama Hirofumi MZ             if (!hwnd || hwndActive == hwnd)
3218e6bced7aSKatayama Hirofumi MZ                 continue;
3219e6bced7aSKatayama Hirofumi MZ 
3220e6bced7aSKatayama Hirofumi MZ             if (::IsWindowVisible(hwnd) && ::IsIconic(hwnd) &&
3221e6bced7aSKatayama Hirofumi MZ                 (!IsTaskWnd(hwnd) || !::IsWindowEnabled(hwnd)))
3222e6bced7aSKatayama Hirofumi MZ             {
3223e6bced7aSKatayama Hirofumi MZ                 ::SetWindowPlacement(hwnd, &g_MinimizedAll[i].wndpl); // Restore
3224e6bced7aSKatayama Hirofumi MZ             }
3225e6bced7aSKatayama Hirofumi MZ         }
3226e6bced7aSKatayama Hirofumi MZ 
3227e6bced7aSKatayama Hirofumi MZ         g_MinimizedAll.RemoveAll();
3228e6bced7aSKatayama Hirofumi MZ 
3229e6bced7aSKatayama Hirofumi MZ         if (!bDestroyed)
3230e6bced7aSKatayama Hirofumi MZ             ::SetForegroundWindow(hwndActive);
3231e6bced7aSKatayama Hirofumi MZ     }
3232e6bced7aSKatayama Hirofumi MZ 
3233e6bced7aSKatayama Hirofumi MZ     LRESULT OnPulse(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
3234e6bced7aSKatayama Hirofumi MZ     {
3235e6bced7aSKatayama Hirofumi MZ         if (IgnorePulse)
3236e6bced7aSKatayama Hirofumi MZ             return 0;
3237e6bced7aSKatayama Hirofumi MZ 
3238e6bced7aSKatayama Hirofumi MZ         KillTimer(TIMER_ID_IGNOREPULSERESET);
3239e6bced7aSKatayama Hirofumi MZ         IgnorePulse = TRUE;
3240e6bced7aSKatayama Hirofumi MZ         RestoreMinimizedNonTaskWnds((BOOL)wParam, (HWND)lParam);
3241e6bced7aSKatayama Hirofumi MZ         SetTimer(TIMER_ID_IGNOREPULSERESET, TIMER_IGNOREPULSERESET_TIMEOUT, NULL);
3242e6bced7aSKatayama Hirofumi MZ         return 0;
3243e6bced7aSKatayama Hirofumi MZ     }
3244e6bced7aSKatayama Hirofumi MZ 
3245c2c66affSColin Finck     LRESULT OnHotkey(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
3246c2c66affSColin Finck     {
3247c2c66affSColin Finck         return HandleHotKey(wParam);
3248c2c66affSColin Finck     }
3249c2c66affSColin Finck 
325075b09f3fSKatayama Hirofumi MZ     struct MINIMIZE_INFO
325175b09f3fSKatayama Hirofumi MZ     {
325275b09f3fSKatayama Hirofumi MZ         HWND hwndDesktop;
325375b09f3fSKatayama Hirofumi MZ         HWND hTrayWnd;
325475b09f3fSKatayama Hirofumi MZ         HWND hwndProgman;
3255e6bced7aSKatayama Hirofumi MZ         CSimpleArray<MINWNDPOS> *pMinimizedAll;
325675b09f3fSKatayama Hirofumi MZ         BOOL bShowDesktop;
325775b09f3fSKatayama Hirofumi MZ     };
325875b09f3fSKatayama Hirofumi MZ 
325975b09f3fSKatayama Hirofumi MZ     static BOOL IsDialog(HWND hwnd)
326075b09f3fSKatayama Hirofumi MZ     {
326175b09f3fSKatayama Hirofumi MZ         WCHAR szClass[32];
326275b09f3fSKatayama Hirofumi MZ         GetClassNameW(hwnd, szClass, _countof(szClass));
326375b09f3fSKatayama Hirofumi MZ         return wcscmp(szClass, L"#32770") == 0;
326475b09f3fSKatayama Hirofumi MZ     }
326575b09f3fSKatayama Hirofumi MZ 
326675b09f3fSKatayama Hirofumi MZ     static BOOL CALLBACK MinimizeWindowsProc(HWND hwnd, LPARAM lParam)
326775b09f3fSKatayama Hirofumi MZ     {
326875b09f3fSKatayama Hirofumi MZ         MINIMIZE_INFO *info = (MINIMIZE_INFO *)lParam;
3269e6bced7aSKatayama Hirofumi MZ         if (hwnd == info->hwndDesktop || hwnd == info->hTrayWnd || hwnd == info->hwndProgman)
3270e6bced7aSKatayama Hirofumi MZ             return TRUE; // Ignore special windows
3271e6bced7aSKatayama Hirofumi MZ 
327275b09f3fSKatayama Hirofumi MZ         if (!info->bShowDesktop)
327375b09f3fSKatayama Hirofumi MZ         {
327475b09f3fSKatayama Hirofumi MZ             if (!::IsWindowEnabled(hwnd) || IsDialog(hwnd))
327575b09f3fSKatayama Hirofumi MZ                 return TRUE;
327675b09f3fSKatayama Hirofumi MZ             HWND hwndOwner = ::GetWindow(hwnd, GW_OWNER);
327775b09f3fSKatayama Hirofumi MZ             if (hwndOwner && !::IsWindowEnabled(hwndOwner))
327875b09f3fSKatayama Hirofumi MZ                 return TRUE;
327975b09f3fSKatayama Hirofumi MZ         }
3280e6bced7aSKatayama Hirofumi MZ 
328122ab8c81SKatayama Hirofumi MZ         if (CanBeMinimized(hwnd))
328275b09f3fSKatayama Hirofumi MZ         {
328322ab8c81SKatayama Hirofumi MZ             MINWNDPOS mwp = { hwnd, { sizeof(mwp.wndpl) } };
328422ab8c81SKatayama Hirofumi MZ             if (::GetWindowPlacement(hwnd, &mwp.wndpl) && // Save the position and status
328522ab8c81SKatayama Hirofumi MZ                 ::ShowWindowAsync(hwnd, SW_SHOWMINNOACTIVE)) // Minimize
328622ab8c81SKatayama Hirofumi MZ             {
3287e6bced7aSKatayama Hirofumi MZ                 info->pMinimizedAll->Add(mwp);
328822ab8c81SKatayama Hirofumi MZ             }
328975b09f3fSKatayama Hirofumi MZ         }
3290e6bced7aSKatayama Hirofumi MZ 
329175b09f3fSKatayama Hirofumi MZ         return TRUE;
329275b09f3fSKatayama Hirofumi MZ     }
329375b09f3fSKatayama Hirofumi MZ 
329475b09f3fSKatayama Hirofumi MZ     VOID MinimizeAll(BOOL bShowDesktop = FALSE)
329575b09f3fSKatayama Hirofumi MZ     {
3296e6bced7aSKatayama Hirofumi MZ         IgnorePulse = TRUE;
3297e6bced7aSKatayama Hirofumi MZ         KillTimer(TIMER_ID_IGNOREPULSERESET);
3298e6bced7aSKatayama Hirofumi MZ 
329975b09f3fSKatayama Hirofumi MZ         MINIMIZE_INFO info;
330075b09f3fSKatayama Hirofumi MZ         info.hwndDesktop = GetDesktopWindow();;
330175b09f3fSKatayama Hirofumi MZ         info.hTrayWnd = FindWindowW(L"Shell_TrayWnd", NULL);
330275b09f3fSKatayama Hirofumi MZ         info.hwndProgman = FindWindowW(L"Progman", NULL);
330375b09f3fSKatayama Hirofumi MZ         info.pMinimizedAll = &g_MinimizedAll;
330475b09f3fSKatayama Hirofumi MZ         info.bShowDesktop = bShowDesktop;
330575b09f3fSKatayama Hirofumi MZ         EnumWindows(MinimizeWindowsProc, (LPARAM)&info);
330675b09f3fSKatayama Hirofumi MZ 
330775b09f3fSKatayama Hirofumi MZ         ::SetForegroundWindow(m_DesktopWnd);
330875b09f3fSKatayama Hirofumi MZ         ::SetFocus(m_DesktopWnd);
3309e6bced7aSKatayama Hirofumi MZ         SetTimer(TIMER_ID_IGNOREPULSERESET, TIMER_IGNOREPULSERESET_TIMEOUT, NULL);
331075b09f3fSKatayama Hirofumi MZ     }
331175b09f3fSKatayama Hirofumi MZ 
331275b09f3fSKatayama Hirofumi MZ     VOID ShowDesktop()
331375b09f3fSKatayama Hirofumi MZ     {
331475b09f3fSKatayama Hirofumi MZ         MinimizeAll(TRUE);
331575b09f3fSKatayama Hirofumi MZ     }
331675b09f3fSKatayama Hirofumi MZ 
331775b09f3fSKatayama Hirofumi MZ     VOID RestoreAll()
331875b09f3fSKatayama Hirofumi MZ     {
3319e6bced7aSKatayama Hirofumi MZ         IgnorePulse = TRUE;
3320e6bced7aSKatayama Hirofumi MZ         KillTimer(TIMER_ID_IGNOREPULSERESET);
3321e6bced7aSKatayama Hirofumi MZ 
332275b09f3fSKatayama Hirofumi MZ         for (INT i = g_MinimizedAll.GetSize() - 1; i >= 0; --i)
332375b09f3fSKatayama Hirofumi MZ         {
3324e6bced7aSKatayama Hirofumi MZ             HWND hwnd = g_MinimizedAll[i].hwnd;
332575b09f3fSKatayama Hirofumi MZ             if (::IsWindowVisible(hwnd) && ::IsIconic(hwnd))
3326e6bced7aSKatayama Hirofumi MZ                 ::SetWindowPlacement(hwnd, &g_MinimizedAll[i].wndpl);
332775b09f3fSKatayama Hirofumi MZ         }
3328e6bced7aSKatayama Hirofumi MZ 
332975b09f3fSKatayama Hirofumi MZ         g_MinimizedAll.RemoveAll();
3330e6bced7aSKatayama Hirofumi MZ         SetTimer(TIMER_ID_IGNOREPULSERESET, TIMER_IGNOREPULSERESET_TIMEOUT, NULL);
333175b09f3fSKatayama Hirofumi MZ     }
333275b09f3fSKatayama Hirofumi MZ 
3333c2c66affSColin Finck     LRESULT OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
3334c2c66affSColin Finck     {
3335c2c66affSColin Finck         LRESULT Ret = FALSE;
3336c2c66affSColin Finck 
3337c2c66affSColin Finck         if ((HWND) lParam == m_StartButton.m_hWnd)
3338c2c66affSColin Finck         {
3339c2c66affSColin Finck             return FALSE;
3340c2c66affSColin Finck         }
3341c2c66affSColin Finck 
3342c2c66affSColin Finck         if (m_TrayBandSite == NULL || FAILED_UNEXPECTEDLY(m_TrayBandSite->ProcessMessage(m_hWnd, uMsg, wParam, lParam, &Ret)))
3343c2c66affSColin Finck         {
3344c2c66affSColin Finck             return HandleCommand(LOWORD(wParam));
3345c2c66affSColin Finck         }
3346c2c66affSColin Finck         return Ret;
3347c2c66affSColin Finck     }
3348c2c66affSColin Finck 
3349c2c66affSColin Finck     LRESULT OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
3350c2c66affSColin Finck     {
335126efda4dSKatayama Hirofumi MZ         POINT pt;
335226efda4dSKatayama Hirofumi MZ         ::GetCursorPos(&pt);
335326efda4dSKatayama Hirofumi MZ         if (m_ShowDesktopButton.PtInButton(pt))
335426efda4dSKatayama Hirofumi MZ             m_ShowDesktopButton.StartHovering();
335526efda4dSKatayama Hirofumi MZ 
33562ed535daSGiannis Adamopoulos         if (g_TaskbarSettings.sr.AutoHide)
3357c2c66affSColin Finck         {
3358c2c66affSColin Finck             SetTimer(TIMER_ID_MOUSETRACK, MOUSETRACK_INTERVAL, NULL);
3359c2c66affSColin Finck         }
3360c2c66affSColin Finck 
3361c2c66affSColin Finck         return TRUE;
3362c2c66affSColin Finck     }
3363c2c66affSColin Finck 
3364c2c66affSColin Finck     LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
3365c2c66affSColin Finck     {
3366c2c66affSColin Finck         if (wParam == TIMER_ID_MOUSETRACK)
3367c2c66affSColin Finck         {
3368c2c66affSColin Finck             ProcessMouseTracking();
3369c2c66affSColin Finck         }
3370c2c66affSColin Finck         else if (wParam == TIMER_ID_AUTOHIDE)
3371c2c66affSColin Finck         {
3372c2c66affSColin Finck             ProcessAutoHide();
3373c2c66affSColin Finck         }
3374e6bced7aSKatayama Hirofumi MZ         else if (wParam == TIMER_ID_IGNOREPULSERESET)
3375e6bced7aSKatayama Hirofumi MZ         {
3376e6bced7aSKatayama Hirofumi MZ             KillTimer(TIMER_ID_IGNOREPULSERESET);
3377e6bced7aSKatayama Hirofumi MZ             IgnorePulse = FALSE;
3378e6bced7aSKatayama Hirofumi MZ         }
3379e6bced7aSKatayama Hirofumi MZ         return 0;
3380c2c66affSColin Finck     }
3381c2c66affSColin Finck 
338226efda4dSKatayama Hirofumi MZ     LRESULT OnNcActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
338326efda4dSKatayama Hirofumi MZ     {
3384ba2cead8SKatayama Hirofumi MZ         LRESULT ret = DefWindowProc(uMsg, wParam, lParam);
338526efda4dSKatayama Hirofumi MZ         DrawShowDesktopButton(); // We have to draw non-client area
338626efda4dSKatayama Hirofumi MZ         bHandled = TRUE;
3387ba2cead8SKatayama Hirofumi MZ         return ret;
338826efda4dSKatayama Hirofumi MZ     }
338926efda4dSKatayama Hirofumi MZ 
3390c2c66affSColin Finck     LRESULT OnNcCalcSize(INT code, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
3391c2c66affSColin Finck     {
3392c2c66affSColin Finck         RECT *rc = NULL;
3393c2c66affSColin Finck         /* Ignore WM_NCCALCSIZE if we are not themed or locked */
33942ed535daSGiannis Adamopoulos         if(!m_Theme || g_TaskbarSettings.bLock)
3395c2c66affSColin Finck         {
3396c2c66affSColin Finck             bHandled = FALSE;
3397c2c66affSColin Finck             return 0;
3398c2c66affSColin Finck         }
3399c2c66affSColin Finck         if(!wParam)
3400c2c66affSColin Finck         {
3401c2c66affSColin Finck             rc = (RECT*)wParam;
3402c2c66affSColin Finck         }
3403c2c66affSColin Finck         else
3404c2c66affSColin Finck         {
3405c2c66affSColin Finck             NCCALCSIZE_PARAMS *prms = (NCCALCSIZE_PARAMS*)lParam;
3406c2c66affSColin Finck             if(prms->lppos->flags & SWP_NOSENDCHANGING)
3407c2c66affSColin Finck             {
3408c2c66affSColin Finck                 bHandled = FALSE;
3409c2c66affSColin Finck                 return 0;
3410c2c66affSColin Finck             }
3411c2c66affSColin Finck             rc = &prms->rgrc[0];
3412c2c66affSColin Finck         }
3413c2c66affSColin Finck 
3414c2c66affSColin Finck         AdjustSizerRect(rc, m_Position);
3415c2c66affSColin Finck 
3416c2c66affSColin Finck         return 0;
3417c2c66affSColin Finck     }
3418c2c66affSColin Finck 
341975b09f3fSKatayama Hirofumi MZ     LRESULT OnInitMenuPopup(INT code, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
342075b09f3fSKatayama Hirofumi MZ     {
342175b09f3fSKatayama Hirofumi MZ         HMENU hMenu = (HMENU)wParam;
342275b09f3fSKatayama Hirofumi MZ         if (::IsThereAnyEffectiveWindow(FALSE))
342375b09f3fSKatayama Hirofumi MZ         {
342475b09f3fSKatayama Hirofumi MZ             ::EnableMenuItem(hMenu, ID_SHELL_CMD_CASCADE_WND, MF_BYCOMMAND | MF_ENABLED);
342575b09f3fSKatayama Hirofumi MZ             ::EnableMenuItem(hMenu, ID_SHELL_CMD_TILE_WND_H, MF_BYCOMMAND | MF_ENABLED);
342675b09f3fSKatayama Hirofumi MZ             ::EnableMenuItem(hMenu, ID_SHELL_CMD_TILE_WND_V, MF_BYCOMMAND | MF_ENABLED);
3427be970d8dSTuur Martens             if (g_Arrangement != NONE)
3428be970d8dSTuur Martens             {
3429be970d8dSTuur Martens                 CStringW strCaption((g_Arrangement == TILED) ? MAKEINTRESOURCEW(IDS_TRAYWND_UNDO_TILE)
3430be970d8dSTuur Martens                                                              : MAKEINTRESOURCEW(IDS_TRAYWND_UNDO_CASCADE));
3431be970d8dSTuur Martens                 MENUITEMINFOW mii = { sizeof(mii) };
3432be970d8dSTuur Martens                 ::GetMenuItemInfoW(hMenu, ID_SHELL_CMD_UNDO_ACTION, FALSE, &mii);
3433be970d8dSTuur Martens                 mii.fMask = MIIM_TYPE;
3434be970d8dSTuur Martens                 mii.fType = MFT_STRING;
3435be970d8dSTuur Martens                 mii.dwTypeData = const_cast<LPWSTR>(&strCaption[0]);
3436be970d8dSTuur Martens                 ::SetMenuItemInfoW(hMenu, ID_SHELL_CMD_UNDO_ACTION, FALSE, &mii);
3437be970d8dSTuur Martens             }
3438be970d8dSTuur Martens             else
3439be970d8dSTuur Martens             {
3440be970d8dSTuur Martens                 ::DeleteMenu(hMenu, ID_SHELL_CMD_UNDO_ACTION, MF_BYCOMMAND);
3441be970d8dSTuur Martens             }
344275b09f3fSKatayama Hirofumi MZ         }
344375b09f3fSKatayama Hirofumi MZ         else
344475b09f3fSKatayama Hirofumi MZ         {
344575b09f3fSKatayama Hirofumi MZ             ::EnableMenuItem(hMenu, ID_SHELL_CMD_CASCADE_WND, MF_BYCOMMAND | MF_GRAYED);
344675b09f3fSKatayama Hirofumi MZ             ::EnableMenuItem(hMenu, ID_SHELL_CMD_TILE_WND_H, MF_BYCOMMAND | MF_GRAYED);
344775b09f3fSKatayama Hirofumi MZ             ::EnableMenuItem(hMenu, ID_SHELL_CMD_TILE_WND_V, MF_BYCOMMAND | MF_GRAYED);
3448be970d8dSTuur Martens             ::DeleteMenu(hMenu, ID_SHELL_CMD_UNDO_ACTION, MF_BYCOMMAND);
3449be970d8dSTuur Martens             g_Arrangement = NONE;
3450be970d8dSTuur Martens             g_WindowPosBackup.RemoveAll();
345175b09f3fSKatayama Hirofumi MZ         }
345275b09f3fSKatayama Hirofumi MZ         return 0;
345375b09f3fSKatayama Hirofumi MZ     }
345475b09f3fSKatayama Hirofumi MZ 
3455c2c66affSColin Finck     LRESULT OnRebarAutoSize(INT code, LPNMHDR nmhdr, BOOL& bHandled)
3456c2c66affSColin Finck     {
3457c2c66affSColin Finck #if 0
3458c2c66affSColin Finck         LPNMRBAUTOSIZE as = (LPNMRBAUTOSIZE) nmhdr;
3459c2c66affSColin Finck 
3460c2c66affSColin Finck         if (!as->fChanged)
3461c2c66affSColin Finck             return 0;
3462c2c66affSColin Finck 
3463c2c66affSColin Finck         RECT rc;
3464c2c66affSColin Finck         ::GetWindowRect(m_hWnd, &rc);
3465c2c66affSColin Finck 
3466c2c66affSColin Finck         SIZE szWindow = {
3467c2c66affSColin Finck             rc.right - rc.left,
3468c2c66affSColin Finck             rc.bottom - rc.top };
3469c2c66affSColin Finck         SIZE szTarget = {
3470c2c66affSColin Finck             as->rcTarget.right - as->rcTarget.left,
3471c2c66affSColin Finck             as->rcTarget.bottom - as->rcTarget.top };
3472c2c66affSColin Finck         SIZE szActual = {
3473c2c66affSColin Finck             as->rcActual.right - as->rcActual.left,
3474c2c66affSColin Finck             as->rcActual.bottom - as->rcActual.top };
3475c2c66affSColin Finck 
3476c2c66affSColin Finck         SIZE borders = {
3477c2c66affSColin Finck             szWindow.cx - szTarget.cx,
3478c2c66affSColin Finck             szWindow.cy - szTarget.cx,
3479c2c66affSColin Finck         };
3480c2c66affSColin Finck 
3481c2c66affSColin Finck         switch (m_Position)
3482c2c66affSColin Finck         {
3483c2c66affSColin Finck         case ABE_LEFT:
3484c2c66affSColin Finck             szWindow.cx = szActual.cx + borders.cx;
3485c2c66affSColin Finck             break;
3486c2c66affSColin Finck         case ABE_TOP:
3487c2c66affSColin Finck             szWindow.cy = szActual.cy + borders.cy;
3488c2c66affSColin Finck             break;
3489c2c66affSColin Finck         case ABE_RIGHT:
3490c2c66affSColin Finck             szWindow.cx = szActual.cx + borders.cx;
3491c2c66affSColin Finck             rc.left = rc.right - szWindow.cy;
3492c2c66affSColin Finck             break;
3493c2c66affSColin Finck         case ABE_BOTTOM:
3494c2c66affSColin Finck             szWindow.cy = szActual.cy + borders.cy;
3495c2c66affSColin Finck             rc.top = rc.bottom - szWindow.cy;
3496c2c66affSColin Finck             break;
3497c2c66affSColin Finck         }
3498c2c66affSColin Finck 
3499c2c66affSColin Finck         SetWindowPos(NULL, rc.left, rc.top, szWindow.cx, szWindow.cy, SWP_NOACTIVATE | SWP_NOZORDER);
3500c2c66affSColin Finck #else
3501c2c66affSColin Finck         bHandled = FALSE;
3502c2c66affSColin Finck #endif
3503c2c66affSColin Finck         return 0;
3504c2c66affSColin Finck     }
3505c2c66affSColin Finck 
35062ed535daSGiannis Adamopoulos     LRESULT OnTaskbarSettingsChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
35072ed535daSGiannis Adamopoulos     {
35082ed535daSGiannis Adamopoulos         TaskbarSettings* newSettings = (TaskbarSettings*)lParam;
35092ed535daSGiannis Adamopoulos 
35102ed535daSGiannis Adamopoulos         /* Propagate the new settings to the children */
35112ed535daSGiannis Adamopoulos         ::SendMessageW(m_TaskSwitch, uMsg, wParam, lParam);
35122ed535daSGiannis Adamopoulos         ::SendMessageW(m_TrayNotify, uMsg, wParam, lParam);
35132ed535daSGiannis Adamopoulos 
35142ed535daSGiannis Adamopoulos         /* Toggle autohide */
35152ed535daSGiannis Adamopoulos         if (newSettings->sr.AutoHide != g_TaskbarSettings.sr.AutoHide)
35162ed535daSGiannis Adamopoulos         {
35172ed535daSGiannis Adamopoulos             g_TaskbarSettings.sr.AutoHide = newSettings->sr.AutoHide;
35182ed535daSGiannis Adamopoulos             memset(&m_AutoHideOffset, 0, sizeof(m_AutoHideOffset));
35192ed535daSGiannis Adamopoulos             m_AutoHideState = AUTOHIDE_SHOWN;
35202ed535daSGiannis Adamopoulos             if (!newSettings->sr.AutoHide)
35212ed535daSGiannis Adamopoulos                 SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOZORDER);
35222ed535daSGiannis Adamopoulos             else
35232ed535daSGiannis Adamopoulos                 SetTimer(TIMER_ID_MOUSETRACK, MOUSETRACK_INTERVAL, NULL);
35242ed535daSGiannis Adamopoulos         }
35252ed535daSGiannis Adamopoulos 
35262ed535daSGiannis Adamopoulos         /* Toggle lock state */
35272ed535daSGiannis Adamopoulos         Lock(newSettings->bLock);
35282ed535daSGiannis Adamopoulos 
35292ed535daSGiannis Adamopoulos         /* Toggle OnTop state */
35302ed535daSGiannis Adamopoulos         if (newSettings->sr.AlwaysOnTop != g_TaskbarSettings.sr.AlwaysOnTop)
35312ed535daSGiannis Adamopoulos         {
35322ed535daSGiannis Adamopoulos             g_TaskbarSettings.sr.AlwaysOnTop = newSettings->sr.AlwaysOnTop;
35332ed535daSGiannis Adamopoulos             HWND hWndInsertAfter = newSettings->sr.AlwaysOnTop ? HWND_TOPMOST : HWND_BOTTOM;
35342ed535daSGiannis Adamopoulos             SetWindowPos(hWndInsertAfter, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
35352ed535daSGiannis Adamopoulos         }
35362ed535daSGiannis Adamopoulos 
353728ae9fb7SCarl J. Bialorucki         /* Toggle show desktop button */
353828ae9fb7SCarl J. Bialorucki         if (newSettings->bShowDesktopButton != g_TaskbarSettings.bShowDesktopButton)
353928ae9fb7SCarl J. Bialorucki         {
354028ae9fb7SCarl J. Bialorucki             g_TaskbarSettings.bShowDesktopButton = newSettings->bShowDesktopButton;
354128ae9fb7SCarl J. Bialorucki             if (!g_TaskbarSettings.bShowDesktopButton)
354228ae9fb7SCarl J. Bialorucki                 ::DestroyWindow(m_ShowDesktopButton.m_hWnd);
354328ae9fb7SCarl J. Bialorucki             else if (!m_ShowDesktopButton.IsWindow())
354428ae9fb7SCarl J. Bialorucki                 m_ShowDesktopButton.DoCreate(m_hWnd);
354528ae9fb7SCarl J. Bialorucki             AlignControls(NULL);
354628ae9fb7SCarl J. Bialorucki         }
354728ae9fb7SCarl J. Bialorucki 
354828ae9fb7SCarl J. Bialorucki         /* Adjust taskbar size */
354928ae9fb7SCarl J. Bialorucki         CheckTrayWndPosition();
355028ae9fb7SCarl J. Bialorucki 
35512ed535daSGiannis Adamopoulos         g_TaskbarSettings.Save();
35522ed535daSGiannis Adamopoulos         return 0;
35532ed535daSGiannis Adamopoulos     }
35542ed535daSGiannis Adamopoulos 
3555c2c66affSColin Finck     DECLARE_WND_CLASS_EX(szTrayWndClass, CS_DBLCLKS, COLOR_3DFACE)
3556c2c66affSColin Finck 
3557c2c66affSColin Finck     BEGIN_MSG_MAP(CTrayWindow)
3558c2c66affSColin Finck         if (m_StartMenuBand != NULL)
3559c2c66affSColin Finck         {
3560c2c66affSColin Finck             MSG Msg;
3561c2c66affSColin Finck             LRESULT lRet;
3562c2c66affSColin Finck 
3563c2c66affSColin Finck             Msg.hwnd = m_hWnd;
3564c2c66affSColin Finck             Msg.message = uMsg;
3565c2c66affSColin Finck             Msg.wParam = wParam;
3566c2c66affSColin Finck             Msg.lParam = lParam;
3567c2c66affSColin Finck 
3568c2c66affSColin Finck             if (m_StartMenuBand->TranslateMenuMessage(&Msg, &lRet) == S_OK)
3569c2c66affSColin Finck             {
3570c2c66affSColin Finck                 return lRet;
3571c2c66affSColin Finck             }
3572c2c66affSColin Finck 
3573c2c66affSColin Finck             wParam = Msg.wParam;
3574c2c66affSColin Finck             lParam = Msg.lParam;
3575c2c66affSColin Finck         }
3576c2c66affSColin Finck         MESSAGE_HANDLER(WM_THEMECHANGED, OnThemeChanged)
3577c2c66affSColin Finck         MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChanged)
3578c2c66affSColin Finck         NOTIFY_CODE_HANDLER(RBN_AUTOSIZE, OnRebarAutoSize) // Doesn't quite work ;P
3579c2c66affSColin Finck         MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
3580c2c66affSColin Finck         MESSAGE_HANDLER(WM_SIZE, OnSize)
3581c2c66affSColin Finck         MESSAGE_HANDLER(WM_CREATE, OnCreate)
3582e6bced7aSKatayama Hirofumi MZ         MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
3583c2c66affSColin Finck         MESSAGE_HANDLER(WM_NCHITTEST, OnNcHitTest)
3584c2c66affSColin Finck         MESSAGE_HANDLER(WM_COMMAND, OnCommand)
3585c2c66affSColin Finck         MESSAGE_HANDLER(WM_SYSCOMMAND, OnSysCommand)
3586c2c66affSColin Finck         MESSAGE_HANDLER(WM_NOTIFY, OnNotify)
3587c2c66affSColin Finck         MESSAGE_HANDLER(WM_CONTEXTMENU, OnContextMenu)
3588c2c66affSColin Finck         MESSAGE_HANDLER(WM_TIMER, OnTimer)
3589c2c66affSColin Finck         MESSAGE_HANDLER(WM_DISPLAYCHANGE, OnDisplayChange)
3590c2c66affSColin Finck         MESSAGE_HANDLER(WM_COPYDATA, OnCopyData)
3591c2c66affSColin Finck         MESSAGE_HANDLER(WM_NCPAINT, OnNcPaint)
359226efda4dSKatayama Hirofumi MZ         MESSAGE_HANDLER(WM_NCACTIVATE, OnNcActivate)
3593c2c66affSColin Finck         MESSAGE_HANDLER(WM_CTLCOLORBTN, OnCtlColorBtn)
3594c2c66affSColin Finck         MESSAGE_HANDLER(WM_MOVING, OnMoving)
3595c2c66affSColin Finck         MESSAGE_HANDLER(WM_SIZING, OnSizing)
35964238f223SGiannis Adamopoulos         MESSAGE_HANDLER(WM_WINDOWPOSCHANGING, OnWindowPosChanging)
3597c2c66affSColin Finck         MESSAGE_HANDLER(WM_ENTERSIZEMOVE, OnEnterSizeMove)
3598c2c66affSColin Finck         MESSAGE_HANDLER(WM_EXITSIZEMOVE, OnExitSizeMove)
3599c2c66affSColin Finck         MESSAGE_HANDLER(WM_NCLBUTTONDOWN, OnNcLButtonDown)
3600c2c66affSColin Finck         MESSAGE_HANDLER(WM_SYSCHAR, OnSysChar)
3601c2c66affSColin Finck         MESSAGE_HANDLER(WM_NCRBUTTONUP, OnNcRButtonUp)
3602c2c66affSColin Finck         MESSAGE_HANDLER(WM_NCLBUTTONDBLCLK, OnNcLButtonDblClick)
360346de3a22SKatayama Hirofumi MZ         MESSAGE_HANDLER(WM_NCLBUTTONUP, OnNcLButtonUp)
3604c2c66affSColin Finck         MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
3605c2c66affSColin Finck         MESSAGE_HANDLER(WM_NCMOUSEMOVE, OnMouseMove)
3606c2c66affSColin Finck         MESSAGE_HANDLER(WM_APP_TRAYDESTROY, OnAppTrayDestroy)
3607c2c66affSColin Finck         MESSAGE_HANDLER(WM_CLOSE, OnDoExitWindows)
3608c2c66affSColin Finck         MESSAGE_HANDLER(WM_HOTKEY, OnHotkey)
3609c2c66affSColin Finck         MESSAGE_HANDLER(WM_NCCALCSIZE, OnNcCalcSize)
361075b09f3fSKatayama Hirofumi MZ         MESSAGE_HANDLER(WM_INITMENUPOPUP, OnInitMenuPopup)
36112ed535daSGiannis Adamopoulos         MESSAGE_HANDLER(TWM_SETTINGSCHANGED, OnTaskbarSettingsChanged)
3612a882ec7aSKatayama Hirofumi MZ         MESSAGE_HANDLER(TWM_OPENSTARTMENU, OnOpenStartMenu)
3613a882ec7aSKatayama Hirofumi MZ         MESSAGE_HANDLER(TWM_DOEXITWINDOWS, OnDoExitWindows)
36146940d9fdSMark Jansen         MESSAGE_HANDLER(TWM_GETTASKSWITCH, OnGetTaskSwitch)
3615e6bced7aSKatayama Hirofumi MZ         MESSAGE_HANDLER(TWM_PULSE, OnPulse)
3616c2c66affSColin Finck     ALT_MSG_MAP(1)
3617c2c66affSColin Finck     END_MSG_MAP()
3618c2c66affSColin Finck 
3619c2c66affSColin Finck     /*****************************************************************************/
3620c2c66affSColin Finck 
3621c2c66affSColin Finck     VOID TrayProcessMessages()
3622c2c66affSColin Finck     {
3623c2c66affSColin Finck         MSG Msg;
3624c2c66affSColin Finck 
3625c2c66affSColin Finck         /* FIXME: We should keep a reference here... */
3626c2c66affSColin Finck 
3627c2c66affSColin Finck         while (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))
3628c2c66affSColin Finck         {
3629c2c66affSColin Finck             if (Msg.message == WM_QUIT)
3630c2c66affSColin Finck                 break;
3631c2c66affSColin Finck 
3632c2c66affSColin Finck             if (m_StartMenuBand == NULL ||
3633c2c66affSColin Finck                 m_StartMenuBand->IsMenuMessage(&Msg) != S_OK)
3634c2c66affSColin Finck             {
3635c2c66affSColin Finck                 TranslateMessage(&Msg);
3636c2c66affSColin Finck                 DispatchMessage(&Msg);
3637c2c66affSColin Finck             }
3638c2c66affSColin Finck         }
3639c2c66affSColin Finck     }
3640c2c66affSColin Finck 
3641c2c66affSColin Finck     VOID TrayMessageLoop()
3642c2c66affSColin Finck     {
3643c2c66affSColin Finck         MSG Msg;
3644c2c66affSColin Finck         BOOL Ret;
3645c2c66affSColin Finck 
3646c2c66affSColin Finck         /* FIXME: We should keep a reference here... */
3647c2c66affSColin Finck 
3648c2c66affSColin Finck         while (true)
3649c2c66affSColin Finck         {
3650c2c66affSColin Finck             Ret = GetMessage(&Msg, NULL, 0, 0);
3651c2c66affSColin Finck 
3652c2c66affSColin Finck             if (!Ret || Ret == -1)
3653c2c66affSColin Finck                 break;
3654c2c66affSColin Finck 
3655c2c66affSColin Finck             if (m_StartMenuBand == NULL ||
3656c2c66affSColin Finck                 m_StartMenuBand->IsMenuMessage(&Msg) != S_OK)
3657c2c66affSColin Finck             {
3658c2c66affSColin Finck                 TranslateMessage(&Msg);
3659c2c66affSColin Finck                 DispatchMessage(&Msg);
3660c2c66affSColin Finck             }
3661c2c66affSColin Finck         }
3662c2c66affSColin Finck     }
3663c2c66affSColin Finck 
3664c2c66affSColin Finck     /*
3665c2c66affSColin Finck      * IShellDesktopTray
3666c2c66affSColin Finck      *
3667c2c66affSColin Finck      * NOTE: this is a very windows-specific COM interface used by SHCreateDesktop()!
3668c2c66affSColin Finck      *       These are the calls I observed, it may be wrong/incomplete/buggy!!!
3669c2c66affSColin Finck      *       The reason we implement it is because we have to use SHCreateDesktop() so
3670c2c66affSColin Finck      *       that the shell provides the desktop window and all the features that come
3671c2c66affSColin Finck      *       with it (especially positioning of desktop icons)
3672c2c66affSColin Finck      */
3673c2c66affSColin Finck 
3674c2c66affSColin Finck     virtual ULONG STDMETHODCALLTYPE GetState()
3675c2c66affSColin Finck     {
3676c2c66affSColin Finck         /* FIXME: Return ABS_ flags? */
3677c2c66affSColin Finck         TRACE("IShellDesktopTray::GetState() unimplemented!\n");
3678c2c66affSColin Finck         return 0;
3679c2c66affSColin Finck     }
3680c2c66affSColin Finck 
3681c2c66affSColin Finck     virtual HRESULT STDMETHODCALLTYPE GetTrayWindow(OUT HWND *phWndTray)
3682c2c66affSColin Finck     {
3683c2c66affSColin Finck         TRACE("IShellDesktopTray::GetTrayWindow(0x%p)\n", phWndTray);
3684c2c66affSColin Finck         *phWndTray = m_hWnd;
3685c2c66affSColin Finck         return S_OK;
3686c2c66affSColin Finck     }
3687c2c66affSColin Finck 
3688c2c66affSColin Finck     virtual HRESULT STDMETHODCALLTYPE RegisterDesktopWindow(IN HWND hWndDesktop)
3689c2c66affSColin Finck     {
3690c2c66affSColin Finck         TRACE("IShellDesktopTray::RegisterDesktopWindow(0x%p)\n", hWndDesktop);
3691c2c66affSColin Finck 
3692c2c66affSColin Finck         m_DesktopWnd = hWndDesktop;
3693c2c66affSColin Finck         return S_OK;
3694c2c66affSColin Finck     }
3695c2c66affSColin Finck 
3696c2c66affSColin Finck     virtual HRESULT STDMETHODCALLTYPE Unknown(IN DWORD dwUnknown1, IN DWORD dwUnknown2)
3697c2c66affSColin Finck     {
3698c2c66affSColin Finck         TRACE("IShellDesktopTray::Unknown(%u,%u) unimplemented!\n", dwUnknown1, dwUnknown2);
3699c2c66affSColin Finck         return S_OK;
3700c2c66affSColin Finck     }
3701c2c66affSColin Finck 
3702c2c66affSColin Finck     virtual HRESULT RaiseStartButton()
3703c2c66affSColin Finck     {
3704c2c66affSColin Finck         m_StartButton.SendMessageW(BM_SETSTATE, FALSE, 0);
3705c2c66affSColin Finck         return S_OK;
3706c2c66affSColin Finck     }
3707c2c66affSColin Finck 
3708c2c66affSColin Finck     HRESULT WINAPI GetWindow(HWND* phwnd)
3709c2c66affSColin Finck     {
3710c2c66affSColin Finck         if (!phwnd)
3711c2c66affSColin Finck             return E_INVALIDARG;
3712c2c66affSColin Finck         *phwnd = m_hWnd;
3713c2c66affSColin Finck         return S_OK;
3714c2c66affSColin Finck     }
3715c2c66affSColin Finck 
3716c2c66affSColin Finck     HRESULT WINAPI ContextSensitiveHelp(BOOL fEnterMode)
3717c2c66affSColin Finck     {
3718c2c66affSColin Finck         return E_NOTIMPL;
3719c2c66affSColin Finck     }
3720c2c66affSColin Finck 
3721c2c66affSColin Finck     void _Init()
3722c2c66affSColin Finck     {
3723c2c66affSColin Finck         m_Position = (DWORD) -1;
3724c2c66affSColin Finck     }
3725c2c66affSColin Finck 
3726c2c66affSColin Finck     DECLARE_NOT_AGGREGATABLE(CTrayWindow)
3727c2c66affSColin Finck 
3728c2c66affSColin Finck     DECLARE_PROTECT_FINAL_CONSTRUCT()
3729c2c66affSColin Finck     BEGIN_COM_MAP(CTrayWindow)
3730c2c66affSColin Finck         /*COM_INTERFACE_ENTRY_IID(IID_ITrayWindow, ITrayWindow)*/
3731c2c66affSColin Finck         COM_INTERFACE_ENTRY_IID(IID_IShellDesktopTray, IShellDesktopTray)
3732c2c66affSColin Finck         COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
3733c2c66affSColin Finck         COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
3734c2c66affSColin Finck     END_COM_MAP()
3735c2c66affSColin Finck };
3736c2c66affSColin Finck 
3737c2c66affSColin Finck class CTrayWindowCtxMenu :
3738c2c66affSColin Finck     public CComCoClass<CTrayWindowCtxMenu>,
3739c2c66affSColin Finck     public CComObjectRootEx<CComMultiThreadModelNoCS>,
3740c2c66affSColin Finck     public IContextMenu
3741c2c66affSColin Finck {
3742c2c66affSColin Finck     HWND hWndOwner;
3743c2c66affSColin Finck     CComPtr<CTrayWindow> TrayWnd;
3744c2c66affSColin Finck     CComPtr<IContextMenu> pcm;
3745c2c66affSColin Finck     UINT m_idCmdCmFirst;
3746c2c66affSColin Finck 
3747c2c66affSColin Finck public:
3748c2c66affSColin Finck     HRESULT Initialize(ITrayWindow * pTrayWnd, IN HWND hWndOwner)
3749c2c66affSColin Finck     {
3750c2c66affSColin Finck         this->TrayWnd = (CTrayWindow *) pTrayWnd;
3751c2c66affSColin Finck         this->hWndOwner = hWndOwner;
3752c2c66affSColin Finck         this->m_idCmdCmFirst = 0;
3753c2c66affSColin Finck         return S_OK;
3754c2c66affSColin Finck     }
3755c2c66affSColin Finck 
3756c2c66affSColin Finck     virtual HRESULT STDMETHODCALLTYPE
3757c2c66affSColin Finck         QueryContextMenu(HMENU hPopup,
3758c2c66affSColin Finck                          UINT indexMenu,
3759c2c66affSColin Finck                          UINT idCmdFirst,
3760c2c66affSColin Finck                          UINT idCmdLast,
3761c2c66affSColin Finck                          UINT uFlags)
3762c2c66affSColin Finck     {
376375b09f3fSKatayama Hirofumi MZ         HMENU hMenuBase;
376475b09f3fSKatayama Hirofumi MZ 
376575b09f3fSKatayama Hirofumi MZ         hMenuBase = LoadPopupMenu(hExplorerInstance, MAKEINTRESOURCEW(IDM_TRAYWND));
376675b09f3fSKatayama Hirofumi MZ 
376775b09f3fSKatayama Hirofumi MZ         if (g_MinimizedAll.GetSize() != 0 && !::IsThereAnyEffectiveWindow(TRUE))
376875b09f3fSKatayama Hirofumi MZ         {
376975b09f3fSKatayama Hirofumi MZ             CStringW strRestoreAll(MAKEINTRESOURCEW(IDS_RESTORE_ALL));
377075b09f3fSKatayama Hirofumi MZ             MENUITEMINFOW mii = { sizeof(mii) };
377175b09f3fSKatayama Hirofumi MZ             mii.fMask = MIIM_ID | MIIM_TYPE;
377275b09f3fSKatayama Hirofumi MZ             mii.wID = ID_SHELL_CMD_RESTORE_ALL;
377375b09f3fSKatayama Hirofumi MZ             mii.fType = MFT_STRING;
377475b09f3fSKatayama Hirofumi MZ             mii.dwTypeData = const_cast<LPWSTR>(&strRestoreAll[0]);
377575b09f3fSKatayama Hirofumi MZ             SetMenuItemInfoW(hMenuBase, ID_SHELL_CMD_SHOW_DESKTOP, FALSE, &mii);
377675b09f3fSKatayama Hirofumi MZ         }
377775b09f3fSKatayama Hirofumi MZ 
377875b09f3fSKatayama Hirofumi MZ         if (!hMenuBase)
3779c2c66affSColin Finck             return HRESULT_FROM_WIN32(GetLastError());
3780c2c66affSColin Finck 
3781c2c66affSColin Finck         if (SHRestricted(REST_CLASSICSHELL) != 0)
3782c2c66affSColin Finck         {
3783c2c66affSColin Finck             DeleteMenu(hPopup,
3784c2c66affSColin Finck                        ID_LOCKTASKBAR,
3785c2c66affSColin Finck                        MF_BYCOMMAND);
3786c2c66affSColin Finck         }
3787c2c66affSColin Finck 
378875b09f3fSKatayama Hirofumi MZ         CheckMenuItem(hMenuBase,
3789c2c66affSColin Finck                       ID_LOCKTASKBAR,
37902ed535daSGiannis Adamopoulos                       MF_BYCOMMAND | (g_TaskbarSettings.bLock ? MF_CHECKED : MF_UNCHECKED));
3791c2c66affSColin Finck 
3792c2c66affSColin Finck         UINT idCmdNext;
379375b09f3fSKatayama Hirofumi MZ         idCmdNext = Shell_MergeMenus(hPopup, hMenuBase, indexMenu, idCmdFirst, idCmdLast, MM_SUBMENUSHAVEIDS | MM_ADDSEPARATOR);
3794c2c66affSColin Finck         m_idCmdCmFirst = idCmdNext - idCmdFirst;
3795c2c66affSColin Finck 
379675b09f3fSKatayama Hirofumi MZ         ::DestroyMenu(hMenuBase);
3797c2c66affSColin Finck 
3798c2c66affSColin Finck         if (TrayWnd->m_TrayBandSite != NULL)
3799c2c66affSColin Finck         {
3800d9589502SKatayama Hirofumi MZ             pcm.Release();
3801c2c66affSColin Finck             if (FAILED(TrayWnd->m_TrayBandSite->AddContextMenus(
3802c2c66affSColin Finck                 hPopup,
3803c2c66affSColin Finck                 indexMenu,
3804c2c66affSColin Finck                 idCmdNext,
3805c2c66affSColin Finck                 idCmdLast,
3806c2c66affSColin Finck                 CMF_NORMAL,
3807c2c66affSColin Finck                 &pcm)))
3808c2c66affSColin Finck             {
3809c2c66affSColin Finck                 WARN("AddContextMenus failed.\n");
3810d9589502SKatayama Hirofumi MZ                 pcm.Release();
3811c2c66affSColin Finck             }
3812c2c66affSColin Finck         }
3813c2c66affSColin Finck 
3814c2c66affSColin Finck         return S_OK;
3815c2c66affSColin Finck     }
3816c2c66affSColin Finck 
3817c2c66affSColin Finck     virtual HRESULT STDMETHODCALLTYPE
3818c2c66affSColin Finck         InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
3819c2c66affSColin Finck     {
3820cf77354dSTimo Kreuzer         UINT uiCmdId = PtrToUlong(lpici->lpVerb);
3821c2c66affSColin Finck         if (uiCmdId != 0)
3822c2c66affSColin Finck         {
3823c2c66affSColin Finck             if (uiCmdId >= m_idCmdCmFirst)
3824c2c66affSColin Finck             {
3825c2c66affSColin Finck                 CMINVOKECOMMANDINFO cmici = { 0 };
3826c2c66affSColin Finck 
3827c2c66affSColin Finck                 if (pcm != NULL)
3828c2c66affSColin Finck                 {
3829c2c66affSColin Finck                     /* Setup and invoke the shell command */
3830c2c66affSColin Finck                     cmici.cbSize = sizeof(cmici);
3831c2c66affSColin Finck                     cmici.hwnd = hWndOwner;
3832c2c66affSColin Finck                     cmici.lpVerb = (LPCSTR) MAKEINTRESOURCEW(uiCmdId - m_idCmdCmFirst);
3833c2c66affSColin Finck                     cmici.nShow = SW_NORMAL;
3834c2c66affSColin Finck 
3835c2c66affSColin Finck                     pcm->InvokeCommand(&cmici);
3836c2c66affSColin Finck                 }
3837c2c66affSColin Finck             }
3838c2c66affSColin Finck             else
3839c2c66affSColin Finck             {
3840c2c66affSColin Finck                 TrayWnd->ExecContextMenuCmd(uiCmdId);
3841c2c66affSColin Finck             }
3842c2c66affSColin Finck         }
3843c2c66affSColin Finck 
3844c2c66affSColin Finck         return S_OK;
3845c2c66affSColin Finck     }
3846c2c66affSColin Finck 
3847c2c66affSColin Finck     virtual HRESULT STDMETHODCALLTYPE
3848c2c66affSColin Finck         GetCommandString(UINT_PTR idCmd,
3849c2c66affSColin Finck         UINT uType,
3850c2c66affSColin Finck         UINT *pwReserved,
3851c2c66affSColin Finck         LPSTR pszName,
3852c2c66affSColin Finck         UINT cchMax)
3853c2c66affSColin Finck     {
3854c2c66affSColin Finck         return E_NOTIMPL;
3855c2c66affSColin Finck     }
3856c2c66affSColin Finck 
3857c2c66affSColin Finck     CTrayWindowCtxMenu()
3858c2c66affSColin Finck     {
3859c2c66affSColin Finck     }
3860c2c66affSColin Finck 
3861c2c66affSColin Finck     virtual ~CTrayWindowCtxMenu()
3862c2c66affSColin Finck     {
3863c2c66affSColin Finck     }
3864c2c66affSColin Finck 
3865c2c66affSColin Finck     BEGIN_COM_MAP(CTrayWindowCtxMenu)
3866c2c66affSColin Finck         COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
3867c2c66affSColin Finck     END_COM_MAP()
3868c2c66affSColin Finck };
3869c2c66affSColin Finck 
3870c2c66affSColin Finck HRESULT TrayWindowCtxMenuCreator(ITrayWindow * TrayWnd, IN HWND hWndOwner, IContextMenu ** ppCtxMenu)
3871c2c66affSColin Finck {
3872c2c66affSColin Finck     CTrayWindowCtxMenu * mnu = new CComObject<CTrayWindowCtxMenu>();
3873c2c66affSColin Finck     mnu->Initialize(TrayWnd, hWndOwner);
3874c2c66affSColin Finck     *ppCtxMenu = mnu;
3875c2c66affSColin Finck     return S_OK;
3876c2c66affSColin Finck }
3877c2c66affSColin Finck 
3878c2c66affSColin Finck HRESULT CreateTrayWindow(ITrayWindow ** ppTray)
3879c2c66affSColin Finck {
3880c2c66affSColin Finck     CComPtr<CTrayWindow> Tray = new CComObject<CTrayWindow>();
3881c2c66affSColin Finck     if (Tray == NULL)
3882c2c66affSColin Finck         return E_OUTOFMEMORY;
3883c2c66affSColin Finck 
3884c2c66affSColin Finck     Tray->_Init();
3885c2c66affSColin Finck     Tray->Open();
3886c2c66affSColin Finck 
3887c2c66affSColin Finck     *ppTray = (ITrayWindow *) Tray;
3888c2c66affSColin Finck 
3889c2c66affSColin Finck     return S_OK;
3890c2c66affSColin Finck }
3891c2c66affSColin Finck 
3892c2c66affSColin Finck HRESULT
3893c2c66affSColin Finck Tray_OnStartMenuDismissed(ITrayWindow* Tray)
3894c2c66affSColin Finck {
3895c2c66affSColin Finck     CTrayWindow * TrayWindow = static_cast<CTrayWindow *>(Tray);
3896c2c66affSColin Finck     return TrayWindow->RaiseStartButton();
3897c2c66affSColin Finck }
3898c2c66affSColin Finck 
3899c2c66affSColin Finck VOID TrayProcessMessages(ITrayWindow *Tray)
3900c2c66affSColin Finck {
3901c2c66affSColin Finck     CTrayWindow * TrayWindow = static_cast<CTrayWindow *>(Tray);
3902c2c66affSColin Finck     TrayWindow->TrayProcessMessages();
3903c2c66affSColin Finck }
3904c2c66affSColin Finck 
3905c2c66affSColin Finck VOID TrayMessageLoop(ITrayWindow *Tray)
3906c2c66affSColin Finck {
3907c2c66affSColin Finck     CTrayWindow * TrayWindow = static_cast<CTrayWindow *>(Tray);
3908c2c66affSColin Finck     TrayWindow->TrayMessageLoop();
3909c2c66affSColin Finck }
3910