xref: /reactos/base/shell/explorer/traywnd.cpp (revision 751641c2)
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 
BackupWindowsPosProc(HWND hwnd,LPARAM lParam)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 
BackupWindowPos()85be970d8dSTuur Martens VOID BackupWindowPos()
86be970d8dSTuur Martens {
87be970d8dSTuur Martens     EnumWindows(BackupWindowsPosProc, NULL);
88be970d8dSTuur Martens }
89be970d8dSTuur Martens 
RestoreWindowPos()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 
CanBeMinimized(HWND hwnd)10222ab8c81SKatayama Hirofumi MZ BOOL CanBeMinimized(HWND hwnd)
10322ab8c81SKatayama Hirofumi MZ {
10492551f54SKatayama Hirofumi MZ     if (::IsWindowVisible(hwnd) && !::IsIconic(hwnd) && ::IsWindowEnabled(hwnd) &&
10592551f54SKatayama Hirofumi MZ         !::IsHungAppWindow(hwnd))
10622ab8c81SKatayama Hirofumi MZ     {
10722ab8c81SKatayama Hirofumi MZ         if (::GetClassLongPtrW(hwnd, GCW_ATOM) == (ULONG_PTR)WC_DIALOG)
10822ab8c81SKatayama Hirofumi MZ             return TRUE;
10922ab8c81SKatayama Hirofumi MZ 
11022ab8c81SKatayama Hirofumi MZ         DWORD exstyle = (DWORD)::GetWindowLongPtrW(hwnd, GWL_EXSTYLE);
11122ab8c81SKatayama Hirofumi MZ         if (!(exstyle & WS_EX_TOPMOST))
11222ab8c81SKatayama Hirofumi MZ             return TRUE;
11322ab8c81SKatayama Hirofumi MZ     }
11422ab8c81SKatayama Hirofumi MZ     return FALSE;
11522ab8c81SKatayama Hirofumi MZ }
11622ab8c81SKatayama Hirofumi MZ 
11775b09f3fSKatayama Hirofumi MZ struct EFFECTIVE_INFO
11875b09f3fSKatayama Hirofumi MZ {
11975b09f3fSKatayama Hirofumi MZ     HWND hwndFound;
12075b09f3fSKatayama Hirofumi MZ     HWND hwndDesktop;
12175b09f3fSKatayama Hirofumi MZ     HWND hwndProgman;
12275b09f3fSKatayama Hirofumi MZ     HWND hTrayWnd;
12375b09f3fSKatayama Hirofumi MZ     BOOL bMustBeInMonitor;
12475b09f3fSKatayama Hirofumi MZ };
12575b09f3fSKatayama Hirofumi MZ 
12675b09f3fSKatayama Hirofumi MZ static BOOL CALLBACK
FindEffectiveProc(HWND hwnd,LPARAM lParam)12775b09f3fSKatayama Hirofumi MZ FindEffectiveProc(HWND hwnd, LPARAM lParam)
12875b09f3fSKatayama Hirofumi MZ {
12975b09f3fSKatayama Hirofumi MZ     EFFECTIVE_INFO *pei = (EFFECTIVE_INFO *)lParam;
13075b09f3fSKatayama Hirofumi MZ 
13122ab8c81SKatayama Hirofumi MZ     if (!CanBeMinimized(hwnd))
13275b09f3fSKatayama Hirofumi MZ         return TRUE;    // continue
13375b09f3fSKatayama Hirofumi MZ 
13475b09f3fSKatayama Hirofumi MZ     if (pei->hTrayWnd == hwnd || pei->hwndDesktop == hwnd ||
13575b09f3fSKatayama Hirofumi MZ         pei->hwndProgman == hwnd)
13675b09f3fSKatayama Hirofumi MZ     {
13775b09f3fSKatayama Hirofumi MZ         return TRUE;    // continue
13875b09f3fSKatayama Hirofumi MZ     }
13975b09f3fSKatayama Hirofumi MZ 
14075b09f3fSKatayama Hirofumi MZ     if (pei->bMustBeInMonitor)
14175b09f3fSKatayama Hirofumi MZ     {
14275b09f3fSKatayama Hirofumi MZ         // is the window in the nearest monitor?
14375b09f3fSKatayama Hirofumi MZ         HMONITOR hMon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
14475b09f3fSKatayama Hirofumi MZ         if (hMon)
14575b09f3fSKatayama Hirofumi MZ         {
14675b09f3fSKatayama Hirofumi MZ             MONITORINFO info;
14775b09f3fSKatayama Hirofumi MZ             ZeroMemory(&info, sizeof(info));
14875b09f3fSKatayama Hirofumi MZ             info.cbSize = sizeof(info);
14975b09f3fSKatayama Hirofumi MZ             if (GetMonitorInfoW(hMon, &info))
15075b09f3fSKatayama Hirofumi MZ             {
15175b09f3fSKatayama Hirofumi MZ                 RECT rcWindow, rcMonitor, rcIntersect;
15275b09f3fSKatayama Hirofumi MZ                 rcMonitor = info.rcMonitor;
15375b09f3fSKatayama Hirofumi MZ 
15475b09f3fSKatayama Hirofumi MZ                 GetWindowRect(hwnd, &rcWindow);
15575b09f3fSKatayama Hirofumi MZ 
15675b09f3fSKatayama Hirofumi MZ                 if (!IntersectRect(&rcIntersect, &rcMonitor, &rcWindow))
15775b09f3fSKatayama Hirofumi MZ                     return TRUE;    // continue
15875b09f3fSKatayama Hirofumi MZ             }
15975b09f3fSKatayama Hirofumi MZ         }
16075b09f3fSKatayama Hirofumi MZ     }
16175b09f3fSKatayama Hirofumi MZ 
16275b09f3fSKatayama Hirofumi MZ     pei->hwndFound = hwnd;
16375b09f3fSKatayama Hirofumi MZ     return FALSE;   // stop if found
16475b09f3fSKatayama Hirofumi MZ }
16575b09f3fSKatayama Hirofumi MZ 
16675b09f3fSKatayama Hirofumi MZ static BOOL
IsThereAnyEffectiveWindow(BOOL bMustBeInMonitor)16775b09f3fSKatayama Hirofumi MZ IsThereAnyEffectiveWindow(BOOL bMustBeInMonitor)
16875b09f3fSKatayama Hirofumi MZ {
16975b09f3fSKatayama Hirofumi MZ     EFFECTIVE_INFO ei;
17075b09f3fSKatayama Hirofumi MZ     ei.hwndFound = NULL;
17175b09f3fSKatayama Hirofumi MZ     ei.hwndDesktop = GetDesktopWindow();
17275b09f3fSKatayama Hirofumi MZ     ei.hTrayWnd = FindWindowW(L"Shell_TrayWnd", NULL);
17375b09f3fSKatayama Hirofumi MZ     ei.hwndProgman = FindWindowW(L"Progman", NULL);
17475b09f3fSKatayama Hirofumi MZ     ei.bMustBeInMonitor = bMustBeInMonitor;
17575b09f3fSKatayama Hirofumi MZ 
17675b09f3fSKatayama Hirofumi MZ     EnumWindows(FindEffectiveProc, (LPARAM)&ei);
17775b09f3fSKatayama Hirofumi MZ     return ei.hwndFound != NULL;
17875b09f3fSKatayama Hirofumi MZ }
17975b09f3fSKatayama Hirofumi MZ 
180e6bced7aSKatayama Hirofumi MZ /* Minimized window position info */
181e6bced7aSKatayama Hirofumi MZ struct MINWNDPOS
182e6bced7aSKatayama Hirofumi MZ {
183e6bced7aSKatayama Hirofumi MZ     HWND hwnd;
184e6bced7aSKatayama Hirofumi MZ     WINDOWPLACEMENT wndpl;
185e6bced7aSKatayama Hirofumi MZ };
186e6bced7aSKatayama Hirofumi MZ CSimpleArray<MINWNDPOS>  g_MinimizedAll;
18775b09f3fSKatayama Hirofumi MZ 
188c2c66affSColin Finck /*
189c2c66affSColin Finck  * ITrayWindow
190c2c66affSColin Finck  */
191c2c66affSColin Finck 
192c2c66affSColin Finck const GUID IID_IShellDesktopTray = { 0x213e2df9, 0x9a14, 0x4328, { 0x99, 0xb1, 0x69, 0x61, 0xf9, 0x14, 0x3c, 0xe9 } };
193c2c66affSColin Finck 
194c2c66affSColin Finck class CStartButton
195c2c66affSColin Finck     : public CWindowImpl<CStartButton>
196c2c66affSColin Finck {
197c2c66affSColin Finck     HIMAGELIST m_ImageList;
198c2c66affSColin Finck     SIZE       m_Size;
199c2c66affSColin Finck     HFONT      m_Font;
200c2c66affSColin Finck 
201c2c66affSColin Finck public:
CStartButton()202c2c66affSColin Finck     CStartButton()
203c2c66affSColin Finck         : m_ImageList(NULL),
204c2c66affSColin Finck           m_Font(NULL)
205c2c66affSColin Finck     {
206c2c66affSColin Finck         m_Size.cx = 0;
207c2c66affSColin Finck         m_Size.cy = 0;
208c2c66affSColin Finck     }
209c2c66affSColin Finck 
~CStartButton()210c2c66affSColin Finck     virtual ~CStartButton()
211c2c66affSColin Finck     {
212c2c66affSColin Finck         if (m_ImageList != NULL)
213c2c66affSColin Finck             ImageList_Destroy(m_ImageList);
214c2c66affSColin Finck 
215c2c66affSColin Finck         if (m_Font != NULL)
216c2c66affSColin Finck             DeleteObject(m_Font);
217c2c66affSColin Finck     }
218c2c66affSColin Finck 
GetSize()219c2c66affSColin Finck     SIZE GetSize()
220c2c66affSColin Finck     {
221c2c66affSColin Finck         return m_Size;
222c2c66affSColin Finck     }
223c2c66affSColin Finck 
UpdateSize()224c2c66affSColin Finck     VOID UpdateSize()
225c2c66affSColin Finck     {
226c2c66affSColin Finck         SIZE Size = { 0, 0 };
227c2c66affSColin Finck 
228c2c66affSColin Finck         if (m_ImageList == NULL ||
229c2c66affSColin Finck             !SendMessageW(BCM_GETIDEALSIZE, 0, (LPARAM) &Size))
230c2c66affSColin Finck         {
231c2c66affSColin Finck             Size.cx = 2 * GetSystemMetrics(SM_CXEDGE) + GetSystemMetrics(SM_CYCAPTION) * 3;
232c2c66affSColin Finck         }
233c2c66affSColin Finck 
234c2c66affSColin Finck         Size.cy = max(Size.cy, GetSystemMetrics(SM_CYCAPTION));
235c2c66affSColin Finck 
236c2c66affSColin Finck         /* Save the size of the start button */
237c2c66affSColin Finck         m_Size = Size;
238c2c66affSColin Finck     }
239c2c66affSColin Finck 
UpdateFont()240c2c66affSColin Finck     VOID UpdateFont()
241c2c66affSColin Finck     {
242c2c66affSColin Finck         /* Get the system fonts, we use the caption font, always bold, though. */
243c2c66affSColin Finck         NONCLIENTMETRICS ncm = {sizeof(ncm)};
244c2c66affSColin Finck         if (!SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, FALSE))
245c2c66affSColin Finck             return;
246c2c66affSColin Finck 
247c2c66affSColin Finck         if (m_Font)
248c2c66affSColin Finck             DeleteObject(m_Font);
249c2c66affSColin Finck 
250c2c66affSColin Finck         ncm.lfCaptionFont.lfWeight = FW_BOLD;
251c2c66affSColin Finck         m_Font = CreateFontIndirect(&ncm.lfCaptionFont);
252c2c66affSColin Finck 
253c2c66affSColin Finck         SetFont(m_Font, FALSE);
254c2c66affSColin Finck     }
255c2c66affSColin Finck 
Initialize()256c2c66affSColin Finck     VOID Initialize()
257c2c66affSColin Finck     {
258d9589502SKatayama Hirofumi MZ         // HACK & FIXME: CORE-18016
259d9589502SKatayama Hirofumi MZ         HWND hWnd = m_hWnd;
260d9589502SKatayama Hirofumi MZ         m_hWnd = NULL;
261d9589502SKatayama Hirofumi MZ         SubclassWindow(hWnd);
2621952e5b7SMark Jansen 
263c2c66affSColin Finck         SetWindowTheme(m_hWnd, L"Start", NULL);
264c2c66affSColin Finck 
265c2c66affSColin Finck         m_ImageList = ImageList_LoadImageW(hExplorerInstance,
266c2c66affSColin Finck                                            MAKEINTRESOURCEW(IDB_START),
267c2c66affSColin Finck                                            0, 0, 0,
268c2c66affSColin Finck                                            IMAGE_BITMAP,
269c2c66affSColin Finck                                            LR_LOADTRANSPARENT | LR_CREATEDIBSECTION);
270c2c66affSColin Finck 
271c2c66affSColin Finck         BUTTON_IMAGELIST bil = {m_ImageList, {1,1,1,1}, BUTTON_IMAGELIST_ALIGN_LEFT};
272c2c66affSColin Finck         SendMessageW(BCM_SETIMAGELIST, 0, (LPARAM) &bil);
273c2c66affSColin Finck         UpdateSize();
274c2c66affSColin Finck     }
275c2c66affSColin Finck 
Create(HWND hwndParent)276c2c66affSColin Finck     HWND Create(HWND hwndParent)
277c2c66affSColin Finck     {
278c2c66affSColin Finck         WCHAR szStartCaption[32];
279c2c66affSColin Finck         if (!LoadStringW(hExplorerInstance,
280c2c66affSColin Finck                          IDS_START,
281c2c66affSColin Finck                          szStartCaption,
282c2c66affSColin Finck                          _countof(szStartCaption)))
283c2c66affSColin Finck         {
284c2c66affSColin Finck             wcscpy(szStartCaption, L"Start");
285c2c66affSColin Finck         }
286c2c66affSColin Finck 
287c2c66affSColin Finck         DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | BS_PUSHBUTTON | BS_LEFT | BS_VCENTER;
288c2c66affSColin Finck 
289d9589502SKatayama Hirofumi MZ         // HACK & FIXME: CORE-18016
290c2c66affSColin Finck         m_hWnd = CreateWindowEx(
291c2c66affSColin Finck             0,
292c2c66affSColin Finck             WC_BUTTON,
293c2c66affSColin Finck             szStartCaption,
294c2c66affSColin Finck             dwStyle,
295c2c66affSColin Finck             0, 0, 0, 0,
296c2c66affSColin Finck             hwndParent,
297c2c66affSColin Finck             (HMENU) IDC_STARTBTN,
298c2c66affSColin Finck             hExplorerInstance,
299c2c66affSColin Finck             NULL);
300c2c66affSColin Finck 
301c2c66affSColin Finck         if (m_hWnd)
302c2c66affSColin Finck             Initialize();
303c2c66affSColin Finck 
304c2c66affSColin Finck         return m_hWnd;
305c2c66affSColin Finck     }
306c2c66affSColin Finck 
OnLButtonDown(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)307c2c66affSColin Finck     LRESULT OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
308c2c66affSColin Finck     {
309c2c66affSColin Finck         if (uMsg == WM_KEYUP && wParam != VK_SPACE)
310c2c66affSColin Finck             return 0;
311c2c66affSColin Finck 
312c2c66affSColin Finck         GetParent().PostMessage(TWM_OPENSTARTMENU);
313c2c66affSColin Finck         return 0;
314c2c66affSColin Finck     }
315c2c66affSColin Finck 
316c2c66affSColin Finck     BEGIN_MSG_MAP(CStartButton)
317c2c66affSColin Finck         MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
318c2c66affSColin Finck     END_MSG_MAP()
319c2c66affSColin Finck 
320c2c66affSColin Finck };
321c2c66affSColin Finck 
322c2c66affSColin Finck class CTrayWindow :
323c2c66affSColin Finck     public CComCoClass<CTrayWindow>,
324c2c66affSColin Finck     public CComObjectRootEx<CComMultiThreadModelNoCS>,
325c2c66affSColin Finck     public CWindowImpl < CTrayWindow, CWindow, CControlWinTraits >,
326c2c66affSColin Finck     public ITrayWindow,
327c2c66affSColin Finck     public IShellDesktopTray,
328c2c66affSColin Finck     public IOleWindow,
329c2c66affSColin Finck     public IContextMenu
330c2c66affSColin Finck {
331c2c66affSColin Finck     CStartButton m_StartButton;
33270d7009aSEthan Rodensky     CTrayShowDesktopButton* m_pShowDesktopButton;
333c2c66affSColin Finck 
334c2c66affSColin Finck     CComPtr<IMenuBand>  m_StartMenuBand;
335c2c66affSColin Finck     CComPtr<IMenuPopup> m_StartMenuPopup;
336c2c66affSColin Finck 
337c2c66affSColin Finck     CComPtr<IDeskBand> m_TaskBand;
338c2c66affSColin Finck     CComPtr<IContextMenu> m_ContextMenu;
339c2c66affSColin Finck     HTHEME m_Theme;
340c2c66affSColin Finck 
341c2c66affSColin Finck     HFONT m_Font;
342c2c66affSColin Finck 
343c2c66affSColin Finck     HWND m_DesktopWnd;
344c2c66affSColin Finck     HWND m_Rebar;
345c2c66affSColin Finck     HWND m_TaskSwitch;
346c2c66affSColin Finck     HWND m_TrayNotify;
347c2c66affSColin Finck 
348455bce68SGiannis Adamopoulos     CComPtr<IUnknown> m_TrayNotifyInstance;
349c2c66affSColin Finck 
350c2c66affSColin Finck     DWORD    m_Position;
351c2c66affSColin Finck     HMONITOR m_Monitor;
352c2c66affSColin Finck     HMONITOR m_PreviousMonitor;
353c2c66affSColin Finck     DWORD    m_DraggingPosition;
354c2c66affSColin Finck     HMONITOR m_DraggingMonitor;
355c2c66affSColin Finck 
356c2c66affSColin Finck     RECT m_TrayRects[4];
357c2c66affSColin Finck     SIZE m_TraySize;
358c2c66affSColin Finck 
359c2c66affSColin Finck     HWND m_TrayPropertiesOwner;
360c2c66affSColin Finck     HWND m_RunFileDlgOwner;
361c2c66affSColin Finck 
362c2c66affSColin Finck     UINT m_AutoHideState;
363c2c66affSColin Finck     SIZE m_AutoHideOffset;
364c2c66affSColin Finck     TRACKMOUSEEVENT m_MouseTrackingInfo;
365c2c66affSColin Finck 
366c2c66affSColin Finck     HDPA m_ShellServices;
367c2c66affSColin Finck 
368c2c66affSColin Finck public:
369c2c66affSColin Finck     CComPtr<ITrayBandSite> m_TrayBandSite;
370c2c66affSColin Finck 
371c2c66affSColin Finck     union
372c2c66affSColin Finck     {
373c2c66affSColin Finck         DWORD Flags;
374c2c66affSColin Finck         struct
375c2c66affSColin Finck         {
376c2c66affSColin Finck             /* UI Status */
377c2c66affSColin Finck             DWORD InSizeMove : 1;
378c2c66affSColin Finck             DWORD IsDragging : 1;
379c2c66affSColin Finck             DWORD NewPosSize : 1;
380e6bced7aSKatayama Hirofumi MZ             DWORD IgnorePulse : 1;
381c2c66affSColin Finck         };
382c2c66affSColin Finck     };
383c2c66affSColin Finck 
384c2c66affSColin Finck public:
CTrayWindow()385c2c66affSColin Finck     CTrayWindow() :
386c2c66affSColin Finck         m_StartButton(),
38770d7009aSEthan Rodensky         m_pShowDesktopButton(NULL),
388c2c66affSColin Finck         m_Theme(NULL),
389c2c66affSColin Finck         m_Font(NULL),
390c2c66affSColin Finck         m_DesktopWnd(NULL),
391c2c66affSColin Finck         m_Rebar(NULL),
392c2c66affSColin Finck         m_TaskSwitch(NULL),
393c2c66affSColin Finck         m_TrayNotify(NULL),
394c2c66affSColin Finck         m_Position(0),
395c2c66affSColin Finck         m_Monitor(NULL),
396c2c66affSColin Finck         m_PreviousMonitor(NULL),
397c2c66affSColin Finck         m_DraggingPosition(0),
398c2c66affSColin Finck         m_DraggingMonitor(NULL),
399c2c66affSColin Finck         m_TrayPropertiesOwner(NULL),
400c2c66affSColin Finck         m_RunFileDlgOwner(NULL),
401c2c66affSColin Finck         m_AutoHideState(NULL),
402c2c66affSColin Finck         m_ShellServices(NULL),
403c2c66affSColin Finck         Flags(0)
404c2c66affSColin Finck     {
405c2c66affSColin Finck         ZeroMemory(&m_TrayRects, sizeof(m_TrayRects));
406c2c66affSColin Finck         ZeroMemory(&m_TraySize, sizeof(m_TraySize));
407c2c66affSColin Finck         ZeroMemory(&m_AutoHideOffset, sizeof(m_AutoHideOffset));
408c2c66affSColin Finck         ZeroMemory(&m_MouseTrackingInfo, sizeof(m_MouseTrackingInfo));
409e6bced7aSKatayama Hirofumi MZ         IgnorePulse = TRUE;
410c2c66affSColin Finck     }
411c2c66affSColin Finck 
~CTrayWindow()412c2c66affSColin Finck     virtual ~CTrayWindow()
413c2c66affSColin Finck     {
414c2c66affSColin Finck         if (m_ShellServices != NULL)
415c2c66affSColin Finck         {
416c2c66affSColin Finck             ShutdownShellServices(m_ShellServices);
417c2c66affSColin Finck             m_ShellServices = NULL;
418c2c66affSColin Finck         }
419c2c66affSColin Finck 
420c2c66affSColin Finck         if (m_Font != NULL)
421c2c66affSColin Finck         {
422c2c66affSColin Finck             DeleteObject(m_Font);
423c2c66affSColin Finck             m_Font = NULL;
424c2c66affSColin Finck         }
425c2c66affSColin Finck 
426c2c66affSColin Finck         if (m_Theme)
427c2c66affSColin Finck         {
428c2c66affSColin Finck             CloseThemeData(m_Theme);
429c2c66affSColin Finck             m_Theme = NULL;
430c2c66affSColin Finck         }
431c2c66affSColin Finck 
432c2c66affSColin Finck         PostQuitMessage(0);
433c2c66affSColin Finck     }
434c2c66affSColin Finck 
435c2c66affSColin Finck 
436c2c66affSColin Finck 
437c2c66affSColin Finck 
438c2c66affSColin Finck 
439c2c66affSColin Finck     /**********************************************************
440c2c66affSColin Finck      *    ##### command handling #####
441c2c66affSColin Finck      */
442c2c66affSColin Finck 
ExecResourceCmd(int id)443c2c66affSColin Finck     HRESULT ExecResourceCmd(int id)
444c2c66affSColin Finck     {
445c2c66affSColin Finck         WCHAR szCommand[256];
446c2c66affSColin Finck         WCHAR *pszParameters;
447c2c66affSColin Finck 
448c2c66affSColin Finck         if (!LoadStringW(hExplorerInstance,
449c2c66affSColin Finck                          id,
450c2c66affSColin Finck                          szCommand,
451c2c66affSColin Finck                          _countof(szCommand)))
452c2c66affSColin Finck         {
453c2c66affSColin Finck             return E_FAIL;
454c2c66affSColin Finck         }
455c2c66affSColin Finck 
456c2c66affSColin Finck         pszParameters = wcschr(szCommand, L'>');
457c2c66affSColin Finck         if (pszParameters)
458c2c66affSColin Finck         {
459c2c66affSColin Finck             *pszParameters = 0;
460c2c66affSColin Finck             pszParameters++;
461c2c66affSColin Finck         }
462c2c66affSColin Finck 
463c2c66affSColin Finck         ShellExecuteW(m_hWnd, NULL, szCommand, pszParameters, NULL, SW_SHOWNORMAL);
464c2c66affSColin Finck         return S_OK;
465c2c66affSColin Finck     }
466c2c66affSColin Finck 
SaveState()467802dc971SWhindmar Saksit     void SaveState()
468802dc971SWhindmar Saksit     {
469802dc971SWhindmar Saksit         if (SHRestricted(REST_NOSAVESET))
470802dc971SWhindmar Saksit             return;
471802dc971SWhindmar Saksit 
472802dc971SWhindmar Saksit         SendMessage(m_DesktopWnd, WM_PROGMAN_SAVESTATE, 0, 0);
473802dc971SWhindmar Saksit     }
474802dc971SWhindmar Saksit 
DoExitWindows()475c2c66affSColin Finck     LRESULT DoExitWindows()
476c2c66affSColin Finck     {
477802dc971SWhindmar Saksit         SaveState();
478802dc971SWhindmar Saksit 
479c62bccddSHermès Bélusca-Maïto         /* Display the ReactOS Shutdown Dialog */
480c2c66affSColin Finck         ExitWindowsDialog(m_hWnd);
481c62bccddSHermès Bélusca-Maïto 
482c62bccddSHermès Bélusca-Maïto         /*
483c62bccddSHermès Bélusca-Maïto          * If the user presses CTRL+ALT+SHIFT while exiting
484c62bccddSHermès Bélusca-Maïto          * the shutdown dialog, exit the shell cleanly.
485c62bccddSHermès Bélusca-Maïto          */
486c62bccddSHermès Bélusca-Maïto         if ((GetKeyState(VK_CONTROL) & 0x8000) &&
487c62bccddSHermès Bélusca-Maïto             (GetKeyState(VK_SHIFT)   & 0x8000) &&
488c62bccddSHermès Bélusca-Maïto             (GetKeyState(VK_MENU)    & 0x8000))
489c62bccddSHermès Bélusca-Maïto         {
490c62bccddSHermès Bélusca-Maïto             PostMessage(WM_QUIT, 0, 0);
491c62bccddSHermès Bélusca-Maïto         }
492c2c66affSColin Finck         return 0;
493c2c66affSColin Finck     }
494c2c66affSColin Finck 
RunFileDlgThread()495c2c66affSColin Finck     DWORD WINAPI RunFileDlgThread()
496c2c66affSColin Finck     {
497c2c66affSColin Finck         HWND hwnd;
498c2c66affSColin Finck         RECT posRect;
499c2c66affSColin Finck 
500c2c66affSColin Finck         m_StartButton.GetWindowRect(&posRect);
501c2c66affSColin Finck 
502c2c66affSColin Finck         hwnd = CreateWindowEx(0,
503c2c66affSColin Finck                               WC_STATIC,
504c2c66affSColin Finck                               NULL,
505c2c66affSColin Finck                               WS_OVERLAPPED | WS_DISABLED | WS_CLIPSIBLINGS | WS_BORDER | SS_LEFT,
506c2c66affSColin Finck                               posRect.left,
507c2c66affSColin Finck                               posRect.top,
508c2c66affSColin Finck                               posRect.right - posRect.left,
509c2c66affSColin Finck                               posRect.bottom - posRect.top,
510c2c66affSColin Finck                               NULL,
511c2c66affSColin Finck                               NULL,
512c2c66affSColin Finck                               NULL,
513c2c66affSColin Finck                               NULL);
514c2c66affSColin Finck 
515c2c66affSColin Finck         m_RunFileDlgOwner = hwnd;
516c2c66affSColin Finck 
517c84f3983SKatayama Hirofumi MZ         // build the default directory from two environment variables
518c84f3983SKatayama Hirofumi MZ         CStringW strDefaultDir, strHomePath;
519c84f3983SKatayama Hirofumi MZ         strDefaultDir.GetEnvironmentVariable(L"HOMEDRIVE");
520c84f3983SKatayama Hirofumi MZ         strHomePath.GetEnvironmentVariable(L"HOMEPATH");
521c84f3983SKatayama Hirofumi MZ         strDefaultDir += strHomePath;
522c84f3983SKatayama Hirofumi MZ 
523c84f3983SKatayama Hirofumi MZ         RunFileDlg(hwnd, NULL, (LPCWSTR)strDefaultDir, NULL, NULL, RFF_CALCDIRECTORY);
524c2c66affSColin Finck 
525c2c66affSColin Finck         m_RunFileDlgOwner = NULL;
526c2c66affSColin Finck         ::DestroyWindow(hwnd);
527c2c66affSColin Finck 
528c2c66affSColin Finck         return 0;
529c2c66affSColin Finck     }
530c2c66affSColin Finck 
s_RunFileDlgThread(IN OUT PVOID pParam)531c2c66affSColin Finck     static DWORD WINAPI s_RunFileDlgThread(IN OUT PVOID pParam)
532c2c66affSColin Finck     {
533c2c66affSColin Finck         CTrayWindow * This = (CTrayWindow*) pParam;
534c2c66affSColin Finck         return This->RunFileDlgThread();
535c2c66affSColin Finck     }
536c2c66affSColin Finck 
DisplayRunFileDlg()537c2c66affSColin Finck     void DisplayRunFileDlg()
538c2c66affSColin Finck     {
539c2c66affSColin Finck         HWND hRunDlg;
540c2c66affSColin Finck         if (m_RunFileDlgOwner)
541c2c66affSColin Finck         {
542c2c66affSColin Finck             hRunDlg = ::GetLastActivePopup(m_RunFileDlgOwner);
543c2c66affSColin Finck             if (hRunDlg != NULL &&
544c2c66affSColin Finck                 hRunDlg != m_RunFileDlgOwner)
545c2c66affSColin Finck             {
546c2c66affSColin Finck                 SetForegroundWindow(hRunDlg);
547c2c66affSColin Finck                 return;
548c2c66affSColin Finck             }
549c2c66affSColin Finck         }
550c2c66affSColin Finck 
551c2c66affSColin Finck         CloseHandle(CreateThread(NULL, 0, s_RunFileDlgThread, this, 0, NULL));
552c2c66affSColin Finck     }
553c2c66affSColin Finck 
TrayPropertiesThread()554c2c66affSColin Finck     DWORD WINAPI TrayPropertiesThread()
555c2c66affSColin Finck     {
556c2c66affSColin Finck         HWND hwnd;
557c2c66affSColin Finck         RECT posRect;
558c2c66affSColin Finck 
559c2c66affSColin Finck         m_StartButton.GetWindowRect(&posRect);
560c2c66affSColin Finck         hwnd = CreateWindowEx(0,
561c2c66affSColin Finck                               WC_STATIC,
562c2c66affSColin Finck                               NULL,
563c2c66affSColin Finck                               WS_OVERLAPPED | WS_DISABLED | WS_CLIPSIBLINGS | WS_BORDER | SS_LEFT,
564c2c66affSColin Finck                               posRect.left,
565c2c66affSColin Finck                               posRect.top,
566c2c66affSColin Finck                               posRect.right - posRect.left,
567c2c66affSColin Finck                               posRect.bottom - posRect.top,
568c2c66affSColin Finck                               NULL,
569c2c66affSColin Finck                               NULL,
570c2c66affSColin Finck                               NULL,
571c2c66affSColin Finck                               NULL);
572c2c66affSColin Finck 
573c2c66affSColin Finck         m_TrayPropertiesOwner = hwnd;
574c2c66affSColin Finck 
5752ed535daSGiannis Adamopoulos         DisplayTrayProperties(hwnd, m_hWnd);
576c2c66affSColin Finck 
577c2c66affSColin Finck         m_TrayPropertiesOwner = NULL;
578c2c66affSColin Finck         ::DestroyWindow(hwnd);
579c2c66affSColin Finck 
580c2c66affSColin Finck         return 0;
581c2c66affSColin Finck     }
582c2c66affSColin Finck 
s_TrayPropertiesThread(IN OUT PVOID pParam)583c2c66affSColin Finck     static DWORD WINAPI s_TrayPropertiesThread(IN OUT PVOID pParam)
584c2c66affSColin Finck     {
585c2c66affSColin Finck         CTrayWindow *This = (CTrayWindow*) pParam;
586c2c66affSColin Finck 
587c2c66affSColin Finck         return This->TrayPropertiesThread();
588c2c66affSColin Finck     }
589c2c66affSColin Finck 
DisplayProperties()590c2c66affSColin Finck     HWND STDMETHODCALLTYPE DisplayProperties()
591c2c66affSColin Finck     {
592c2c66affSColin Finck         HWND hTrayProp;
593c2c66affSColin Finck 
594c2c66affSColin Finck         if (m_TrayPropertiesOwner)
595c2c66affSColin Finck         {
596c2c66affSColin Finck             hTrayProp = ::GetLastActivePopup(m_TrayPropertiesOwner);
597c2c66affSColin Finck             if (hTrayProp != NULL &&
598c2c66affSColin Finck                 hTrayProp != m_TrayPropertiesOwner)
599c2c66affSColin Finck             {
600c2c66affSColin Finck                 SetForegroundWindow(hTrayProp);
601c2c66affSColin Finck                 return NULL;
602c2c66affSColin Finck             }
603c2c66affSColin Finck         }
604c2c66affSColin Finck 
605c2c66affSColin Finck         CloseHandle(CreateThread(NULL, 0, s_TrayPropertiesThread, this, 0, NULL));
606c2c66affSColin Finck         return NULL;
607c2c66affSColin Finck     }
608c2c66affSColin Finck 
OpenCommonStartMenuDirectory(IN HWND hWndOwner,IN LPCTSTR lpOperation)609c2c66affSColin Finck     VOID OpenCommonStartMenuDirectory(IN HWND hWndOwner, IN LPCTSTR lpOperation)
610c2c66affSColin Finck     {
611c2c66affSColin Finck         WCHAR szDir[MAX_PATH];
612c2c66affSColin Finck 
613c2c66affSColin Finck         if (SHGetSpecialFolderPath(hWndOwner,
614c2c66affSColin Finck             szDir,
615c2c66affSColin Finck             CSIDL_COMMON_STARTMENU,
616c2c66affSColin Finck             FALSE))
617c2c66affSColin Finck         {
618c2c66affSColin Finck             ShellExecute(hWndOwner,
619c2c66affSColin Finck                          lpOperation,
620c2c66affSColin Finck                          szDir,
621c2c66affSColin Finck                          NULL,
622c2c66affSColin Finck                          NULL,
623c2c66affSColin Finck                          SW_SHOWNORMAL);
624c2c66affSColin Finck         }
625c2c66affSColin Finck     }
626c2c66affSColin Finck 
OpenTaskManager(IN HWND hWndOwner)627c2c66affSColin Finck     VOID OpenTaskManager(IN HWND hWndOwner)
628c2c66affSColin Finck     {
629c2c66affSColin Finck         ShellExecute(hWndOwner,
630c2c66affSColin Finck                      TEXT("open"),
631c2c66affSColin Finck                      TEXT("taskmgr.exe"),
632c2c66affSColin Finck                      NULL,
633c2c66affSColin Finck                      NULL,
634c2c66affSColin Finck                      SW_SHOWNORMAL);
635c2c66affSColin Finck     }
636c2c66affSColin Finck 
ToggleDesktop()63775b09f3fSKatayama Hirofumi MZ     VOID ToggleDesktop()
63875b09f3fSKatayama Hirofumi MZ     {
63975b09f3fSKatayama Hirofumi MZ         if (::IsThereAnyEffectiveWindow(TRUE))
64075b09f3fSKatayama Hirofumi MZ         {
64175b09f3fSKatayama Hirofumi MZ             ShowDesktop();
64275b09f3fSKatayama Hirofumi MZ         }
64375b09f3fSKatayama Hirofumi MZ         else
64475b09f3fSKatayama Hirofumi MZ         {
64575b09f3fSKatayama Hirofumi MZ             RestoreAll();
64675b09f3fSKatayama Hirofumi MZ         }
64775b09f3fSKatayama Hirofumi MZ     }
64875b09f3fSKatayama Hirofumi MZ 
ExecContextMenuCmd(IN UINT uiCmd)649c2c66affSColin Finck     BOOL STDMETHODCALLTYPE ExecContextMenuCmd(IN UINT uiCmd)
650c2c66affSColin Finck     {
651c2c66affSColin Finck         switch (uiCmd)
652c2c66affSColin Finck         {
653c2c66affSColin Finck         case ID_SHELL_CMD_PROPERTIES:
654c2c66affSColin Finck             DisplayProperties();
655c2c66affSColin Finck             break;
656c2c66affSColin Finck 
657c2c66affSColin Finck         case ID_SHELL_CMD_OPEN_ALL_USERS:
658c2c66affSColin Finck             OpenCommonStartMenuDirectory(m_hWnd,
659c2c66affSColin Finck                                          TEXT("open"));
660c2c66affSColin Finck             break;
661c2c66affSColin Finck 
662c2c66affSColin Finck         case ID_SHELL_CMD_EXPLORE_ALL_USERS:
663c2c66affSColin Finck             OpenCommonStartMenuDirectory(m_hWnd,
664c2c66affSColin Finck                                          TEXT("explore"));
665c2c66affSColin Finck             break;
666c2c66affSColin Finck 
667c2c66affSColin Finck         case ID_LOCKTASKBAR:
6687fafeb63SCarl J. Bialorucki             HandleCommand(TRAYCMD_LOCK_TASKBAR);
669c2c66affSColin Finck             break;
670c2c66affSColin Finck 
671c2c66affSColin Finck         case ID_SHELL_CMD_OPEN_TASKMGR:
672c2c66affSColin Finck             OpenTaskManager(m_hWnd);
673c2c66affSColin Finck             break;
674c2c66affSColin Finck 
675c2c66affSColin Finck         case ID_SHELL_CMD_UNDO_ACTION:
676be970d8dSTuur Martens             RestoreWindowPos();
677c2c66affSColin Finck             break;
678c2c66affSColin Finck 
679c2c66affSColin Finck         case ID_SHELL_CMD_SHOW_DESKTOP:
68075b09f3fSKatayama Hirofumi MZ             ShowDesktop();
681c2c66affSColin Finck             break;
682c2c66affSColin Finck 
683c2c66affSColin Finck         case ID_SHELL_CMD_TILE_WND_H:
684451a9c6fSKatayama Hirofumi MZ             appbar_notify_all(NULL, ABN_WINDOWARRANGE, NULL, TRUE);
685be970d8dSTuur Martens             if (g_Arrangement == NONE)
686be970d8dSTuur Martens             {
687be970d8dSTuur Martens                 BackupWindowPos();
688be970d8dSTuur Martens             }
689c2c66affSColin Finck             TileWindows(NULL, MDITILE_HORIZONTAL, NULL, 0, NULL);
690451a9c6fSKatayama Hirofumi MZ             appbar_notify_all(NULL, ABN_WINDOWARRANGE, NULL, FALSE);
691be970d8dSTuur Martens             g_Arrangement = TILED;
692c2c66affSColin Finck             break;
693c2c66affSColin Finck 
694c2c66affSColin Finck         case ID_SHELL_CMD_TILE_WND_V:
695451a9c6fSKatayama Hirofumi MZ             appbar_notify_all(NULL, ABN_WINDOWARRANGE, NULL, TRUE);
696be970d8dSTuur Martens             if (g_Arrangement == NONE)
697be970d8dSTuur Martens             {
698be970d8dSTuur Martens                 BackupWindowPos();
699be970d8dSTuur Martens             }
700c2c66affSColin Finck             TileWindows(NULL, MDITILE_VERTICAL, NULL, 0, NULL);
701451a9c6fSKatayama Hirofumi MZ             appbar_notify_all(NULL, ABN_WINDOWARRANGE, NULL, FALSE);
702be970d8dSTuur Martens             g_Arrangement = TILED;
703c2c66affSColin Finck             break;
704c2c66affSColin Finck 
705c2c66affSColin Finck         case ID_SHELL_CMD_CASCADE_WND:
706451a9c6fSKatayama Hirofumi MZ             appbar_notify_all(NULL, ABN_WINDOWARRANGE, NULL, TRUE);
707be970d8dSTuur Martens             if (g_Arrangement == NONE)
708be970d8dSTuur Martens             {
709be970d8dSTuur Martens                 BackupWindowPos();
710be970d8dSTuur Martens             }
711c2c66affSColin Finck             CascadeWindows(NULL, MDITILE_SKIPDISABLED, NULL, 0, NULL);
712451a9c6fSKatayama Hirofumi MZ             appbar_notify_all(NULL, ABN_WINDOWARRANGE, NULL, FALSE);
713be970d8dSTuur Martens             g_Arrangement = CASCADED;
714c2c66affSColin Finck             break;
715c2c66affSColin Finck 
716c2c66affSColin Finck         case ID_SHELL_CMD_CUST_NOTIF:
717c2c66affSColin Finck             ShowCustomizeNotifyIcons(hExplorerInstance, m_hWnd);
718c2c66affSColin Finck             break;
719c2c66affSColin Finck 
720c2c66affSColin Finck         case ID_SHELL_CMD_ADJUST_DAT:
721c2c66affSColin Finck             //FIXME: Use SHRunControlPanel
722c2c66affSColin Finck             ShellExecuteW(m_hWnd, NULL, L"timedate.cpl", NULL, NULL, SW_NORMAL);
723c2c66affSColin Finck             break;
724c2c66affSColin Finck 
72575b09f3fSKatayama Hirofumi MZ         case ID_SHELL_CMD_RESTORE_ALL:
72675b09f3fSKatayama Hirofumi MZ             RestoreAll();
72775b09f3fSKatayama Hirofumi MZ             break;
72875b09f3fSKatayama Hirofumi MZ 
729c2c66affSColin Finck         default:
730c2c66affSColin Finck             TRACE("ITrayWindow::ExecContextMenuCmd(%u): Unhandled Command ID!\n", uiCmd);
731c2c66affSColin Finck             return FALSE;
732c2c66affSColin Finck         }
733c2c66affSColin Finck 
734c2c66affSColin Finck         return TRUE;
735c2c66affSColin Finck     }
736c2c66affSColin Finck 
HideStartMenu()737802a87dfSKatayama Hirofumi MZ     VOID HideStartMenu()
738802a87dfSKatayama Hirofumi MZ     {
739802a87dfSKatayama Hirofumi MZ         m_StartMenuPopup->OnSelect(MPOS_CANCELLEVEL);
740802a87dfSKatayama Hirofumi MZ     }
741802a87dfSKatayama Hirofumi MZ 
HandleHotKey(DWORD id)742c2c66affSColin Finck     LRESULT HandleHotKey(DWORD id)
743c2c66affSColin Finck     {
744c2c66affSColin Finck         switch (id)
745c2c66affSColin Finck         {
746c2c66affSColin Finck         case IDHK_RUN:
747802a87dfSKatayama Hirofumi MZ             HideStartMenu();
748c2c66affSColin Finck             DisplayRunFileDlg();
749c2c66affSColin Finck             break;
750c2c66affSColin Finck         case IDHK_HELP:
751c2c66affSColin Finck             ExecResourceCmd(IDS_HELP_COMMAND);
752c2c66affSColin Finck             break;
753c2c66affSColin Finck         case IDHK_EXPLORE:
754c2c66affSColin Finck             //FIXME: We don't support this yet:
755c2c66affSColin Finck             //ShellExecuteW(0, L"explore", NULL, NULL, NULL, 1);
7564b6d929bSGiannis Adamopoulos             ShellExecuteW(0, NULL, L"explorer.exe", L"/e ,", NULL, 1);
757c2c66affSColin Finck             break;
758c2c66affSColin Finck         case IDHK_FIND:
759c2c66affSColin Finck             SHFindFiles(NULL, NULL);
760c2c66affSColin Finck             break;
761c2c66affSColin Finck         case IDHK_FIND_COMPUTER:
762c2c66affSColin Finck             SHFindComputer(NULL, NULL);
763c2c66affSColin Finck             break;
764c2c66affSColin Finck         case IDHK_SYS_PROPERTIES:
765c2c66affSColin Finck             //FIXME: Use SHRunControlPanel
766c2c66affSColin Finck             ShellExecuteW(m_hWnd, NULL, L"sysdm.cpl", NULL, NULL, SW_NORMAL);
767c2c66affSColin Finck             break;
768c2c66affSColin Finck         case IDHK_NEXT_TASK:
769c2c66affSColin Finck             break;
770c2c66affSColin Finck         case IDHK_PREV_TASK:
771c2c66affSColin Finck             break;
772c2c66affSColin Finck         case IDHK_MINIMIZE_ALL:
77375b09f3fSKatayama Hirofumi MZ             MinimizeAll();
774c2c66affSColin Finck             break;
775c2c66affSColin Finck         case IDHK_RESTORE_ALL:
77675b09f3fSKatayama Hirofumi MZ             RestoreAll();
777c2c66affSColin Finck             break;
778c2c66affSColin Finck         case IDHK_DESKTOP:
77975b09f3fSKatayama Hirofumi MZ             ToggleDesktop();
780c2c66affSColin Finck             break;
781c2c66affSColin Finck         case IDHK_PAGER:
782c2c66affSColin Finck             break;
783c2c66affSColin Finck         }
784c2c66affSColin Finck 
785c2c66affSColin Finck         return 0;
786c2c66affSColin Finck     }
787c2c66affSColin Finck 
HandleCommand(UINT uCommand)788c2c66affSColin Finck     LRESULT HandleCommand(UINT uCommand)
789c2c66affSColin Finck     {
790c2c66affSColin Finck         switch (uCommand)
791c2c66affSColin Finck         {
79275b09f3fSKatayama Hirofumi MZ             case TRAYCMD_STARTMENU:
79375b09f3fSKatayama Hirofumi MZ                 // TODO:
794c2c66affSColin Finck                 break;
79575b09f3fSKatayama Hirofumi MZ             case TRAYCMD_RUN_DIALOG:
796802a87dfSKatayama Hirofumi MZ                 HideStartMenu();
797c2c66affSColin Finck                 DisplayRunFileDlg();
798c2c66affSColin Finck                 break;
79975b09f3fSKatayama Hirofumi MZ             case TRAYCMD_LOGOFF_DIALOG:
800802dc971SWhindmar Saksit                 SaveState();
801c2c66affSColin Finck                 LogoffWindowsDialog(m_hWnd); // FIXME: Maybe handle it in a similar way as DoExitWindows?
802c2c66affSColin Finck                 break;
80375b09f3fSKatayama Hirofumi MZ             case TRAYCMD_CASCADE:
80475b09f3fSKatayama Hirofumi MZ                 CascadeWindows(NULL, MDITILE_SKIPDISABLED, NULL, 0, NULL);
80575b09f3fSKatayama Hirofumi MZ                 break;
80675b09f3fSKatayama Hirofumi MZ             case TRAYCMD_TILE_H:
80775b09f3fSKatayama Hirofumi MZ                 TileWindows(NULL, MDITILE_HORIZONTAL, NULL, 0, NULL);
80875b09f3fSKatayama Hirofumi MZ                 break;
80975b09f3fSKatayama Hirofumi MZ             case TRAYCMD_TILE_V:
81075b09f3fSKatayama Hirofumi MZ                 TileWindows(NULL, MDITILE_VERTICAL, NULL, 0, NULL);
81175b09f3fSKatayama Hirofumi MZ                 break;
81275b09f3fSKatayama Hirofumi MZ             case TRAYCMD_TOGGLE_DESKTOP:
81375b09f3fSKatayama Hirofumi MZ                 ToggleDesktop();
81475b09f3fSKatayama Hirofumi MZ                 break;
81575b09f3fSKatayama Hirofumi MZ             case TRAYCMD_DATE_AND_TIME:
81675b09f3fSKatayama Hirofumi MZ                 ShellExecuteW(m_hWnd, NULL, L"timedate.cpl", NULL, NULL, SW_NORMAL);
81775b09f3fSKatayama Hirofumi MZ                 break;
81875b09f3fSKatayama Hirofumi MZ             case TRAYCMD_TASKBAR_PROPERTIES:
81975b09f3fSKatayama Hirofumi MZ                 DisplayProperties();
82075b09f3fSKatayama Hirofumi MZ                 break;
82175b09f3fSKatayama Hirofumi MZ             case TRAYCMD_MINIMIZE_ALL:
82275b09f3fSKatayama Hirofumi MZ                 MinimizeAll();
82375b09f3fSKatayama Hirofumi MZ                 break;
82475b09f3fSKatayama Hirofumi MZ             case TRAYCMD_RESTORE_ALL:
82575b09f3fSKatayama Hirofumi MZ                 RestoreAll();
82675b09f3fSKatayama Hirofumi MZ                 break;
82775b09f3fSKatayama Hirofumi MZ             case TRAYCMD_SHOW_DESKTOP:
82875b09f3fSKatayama Hirofumi MZ                 ShowDesktop();
82975b09f3fSKatayama Hirofumi MZ                 break;
83075b09f3fSKatayama Hirofumi MZ             case TRAYCMD_SHOW_TASK_MGR:
83175b09f3fSKatayama Hirofumi MZ                 OpenTaskManager(m_hWnd);
83275b09f3fSKatayama Hirofumi MZ                 break;
83375b09f3fSKatayama Hirofumi MZ             case TRAYCMD_CUSTOMIZE_TASKBAR:
83475b09f3fSKatayama Hirofumi MZ                 break;
83575b09f3fSKatayama Hirofumi MZ             case TRAYCMD_LOCK_TASKBAR:
83675b09f3fSKatayama Hirofumi MZ                 if (SHRestricted(REST_CLASSICSHELL) == 0)
83775b09f3fSKatayama Hirofumi MZ                 {
83875b09f3fSKatayama Hirofumi MZ                     Lock(!g_TaskbarSettings.bLock);
8397fafeb63SCarl J. Bialorucki                     g_TaskbarSettings.Save();
84075b09f3fSKatayama Hirofumi MZ                 }
84175b09f3fSKatayama Hirofumi MZ                 break;
84275b09f3fSKatayama Hirofumi MZ             case TRAYCMD_HELP_AND_SUPPORT:
84375b09f3fSKatayama Hirofumi MZ                 ExecResourceCmd(IDS_HELP_COMMAND);
84475b09f3fSKatayama Hirofumi MZ                 break;
84575b09f3fSKatayama Hirofumi MZ             case TRAYCMD_CONTROL_PANEL:
84675b09f3fSKatayama Hirofumi MZ                 // TODO:
84775b09f3fSKatayama Hirofumi MZ                 break;
84875b09f3fSKatayama Hirofumi MZ             case TRAYCMD_SHUTDOWN_DIALOG:
849c2c66affSColin Finck                 DoExitWindows();
850c2c66affSColin Finck                 break;
85175b09f3fSKatayama Hirofumi MZ             case TRAYCMD_PRINTERS_AND_FAXES:
85275b09f3fSKatayama Hirofumi MZ                 // TODO:
85375b09f3fSKatayama Hirofumi MZ                 break;
85475b09f3fSKatayama Hirofumi MZ             case TRAYCMD_LOCK_DESKTOP:
85575b09f3fSKatayama Hirofumi MZ                 // TODO:
85675b09f3fSKatayama Hirofumi MZ                 break;
85775b09f3fSKatayama Hirofumi MZ             case TRAYCMD_SWITCH_USER_DIALOG:
85875b09f3fSKatayama Hirofumi MZ                 // TODO:
85975b09f3fSKatayama Hirofumi MZ                 break;
8604d097cf8SBrock Mammen             case IDM_SEARCH:
86175b09f3fSKatayama Hirofumi MZ             case TRAYCMD_SEARCH_FILES:
86275b09f3fSKatayama Hirofumi MZ                 SHFindFiles(NULL, NULL);
86375b09f3fSKatayama Hirofumi MZ                 break;
86475b09f3fSKatayama Hirofumi MZ             case TRAYCMD_SEARCH_COMPUTERS:
86575b09f3fSKatayama Hirofumi MZ                 SHFindComputer(NULL, NULL);
86675b09f3fSKatayama Hirofumi MZ                 break;
86775b09f3fSKatayama Hirofumi MZ 
86875b09f3fSKatayama Hirofumi MZ             default:
86975b09f3fSKatayama Hirofumi MZ                 break;
870c2c66affSColin Finck         }
871c2c66affSColin Finck 
872c2c66affSColin Finck         return FALSE;
873c2c66affSColin Finck     }
874c2c66affSColin Finck 
875c2c66affSColin Finck 
TrackMenu(IN HMENU hMenu,IN POINT * ppt OPTIONAL,IN HWND hwndExclude OPTIONAL,IN BOOL TrackUp,IN BOOL IsContextMenu)876c2c66affSColin Finck     UINT TrackMenu(
877c2c66affSColin Finck         IN HMENU hMenu,
878c2c66affSColin Finck         IN POINT *ppt OPTIONAL,
879c2c66affSColin Finck         IN HWND hwndExclude OPTIONAL,
880c2c66affSColin Finck         IN BOOL TrackUp,
881c2c66affSColin Finck         IN BOOL IsContextMenu)
882c2c66affSColin Finck     {
883c2c66affSColin Finck         TPMPARAMS tmp, *ptmp = NULL;
884c2c66affSColin Finck         POINT pt;
885c2c66affSColin Finck         UINT cmdId;
886c2c66affSColin Finck         UINT fuFlags;
887c2c66affSColin Finck 
888c2c66affSColin Finck         if (hwndExclude != NULL)
889c2c66affSColin Finck         {
890c2c66affSColin Finck             /* Get the client rectangle and map it to screen coordinates */
891c2c66affSColin Finck             if (::GetClientRect(hwndExclude,
892c2c66affSColin Finck                 &tmp.rcExclude) &&
893c2c66affSColin Finck                 ::MapWindowPoints(hwndExclude,
894c2c66affSColin Finck                 NULL,
895c2c66affSColin Finck                 (LPPOINT) &tmp.rcExclude,
896c2c66affSColin Finck                 2) != 0)
897c2c66affSColin Finck             {
898c2c66affSColin Finck                 ptmp = &tmp;
899c2c66affSColin Finck             }
900c2c66affSColin Finck         }
901c2c66affSColin Finck 
902c2c66affSColin Finck         if (ppt == NULL)
903c2c66affSColin Finck         {
904c2c66affSColin Finck             if (ptmp == NULL &&
905c2c66affSColin Finck                 GetClientRect(&tmp.rcExclude) &&
906c2c66affSColin Finck                 MapWindowPoints(
907c2c66affSColin Finck                 NULL,
908c2c66affSColin Finck                 (LPPOINT) &tmp.rcExclude,
909c2c66affSColin Finck                 2) != 0)
910c2c66affSColin Finck             {
911c2c66affSColin Finck                 ptmp = &tmp;
912c2c66affSColin Finck             }
913c2c66affSColin Finck 
914c2c66affSColin Finck             if (ptmp != NULL)
915c2c66affSColin Finck             {
916c2c66affSColin Finck                 /* NOTE: TrackPopupMenuEx will eventually align the track position
917c2c66affSColin Finck                          for us, no need to take care of it here as long as the
918c2c66affSColin Finck                          coordinates are somewhere within the exclusion rectangle */
919c2c66affSColin Finck                 pt.x = ptmp->rcExclude.left;
920c2c66affSColin Finck                 pt.y = ptmp->rcExclude.top;
921c2c66affSColin Finck             }
922c2c66affSColin Finck             else
923c2c66affSColin Finck                 pt.x = pt.y = 0;
924c2c66affSColin Finck         }
925c2c66affSColin Finck         else
926c2c66affSColin Finck             pt = *ppt;
927c2c66affSColin Finck 
928c2c66affSColin Finck         tmp.cbSize = sizeof(tmp);
929c2c66affSColin Finck 
930c2c66affSColin Finck         fuFlags = TPM_RETURNCMD | TPM_VERTICAL;
931c2c66affSColin Finck         fuFlags |= (TrackUp ? TPM_BOTTOMALIGN : TPM_TOPALIGN);
932c2c66affSColin Finck         if (IsContextMenu)
933c2c66affSColin Finck             fuFlags |= TPM_RIGHTBUTTON;
934c2c66affSColin Finck         else
935c2c66affSColin Finck             fuFlags |= (TrackUp ? TPM_VERNEGANIMATION : TPM_VERPOSANIMATION);
936c2c66affSColin Finck 
937c2c66affSColin Finck         cmdId = TrackPopupMenuEx(hMenu,
938c2c66affSColin Finck                                  fuFlags,
939c2c66affSColin Finck                                  pt.x,
940c2c66affSColin Finck                                  pt.y,
941c2c66affSColin Finck                                  m_hWnd,
942c2c66affSColin Finck                                  ptmp);
943c2c66affSColin Finck 
944c2c66affSColin Finck         return cmdId;
945c2c66affSColin Finck     }
946c2c66affSColin Finck 
TrackCtxMenu(IN IContextMenu * contextMenu,IN POINT * ppt OPTIONAL,IN HWND hwndExclude OPTIONAL,IN BOOL TrackUp,IN PVOID Context OPTIONAL)947c2c66affSColin Finck     HRESULT TrackCtxMenu(
948c2c66affSColin Finck         IN IContextMenu * contextMenu,
949c2c66affSColin Finck         IN POINT *ppt OPTIONAL,
950c2c66affSColin Finck         IN HWND hwndExclude OPTIONAL,
951c2c66affSColin Finck         IN BOOL TrackUp,
952c2c66affSColin Finck         IN PVOID Context OPTIONAL)
953c2c66affSColin Finck     {
95458825de8SKatayama Hirofumi MZ         POINT pt;
95558825de8SKatayama Hirofumi MZ         TPMPARAMS params;
95658825de8SKatayama Hirofumi MZ         RECT rc;
957c2c66affSColin Finck         HRESULT hr;
958c2c66affSColin Finck         UINT uCommand;
959c2c66affSColin Finck         HMENU popup = CreatePopupMenu();
960c2c66affSColin Finck 
961c2c66affSColin Finck         if (popup == NULL)
962c2c66affSColin Finck             return E_FAIL;
963c2c66affSColin Finck 
96458825de8SKatayama Hirofumi MZ         if (ppt)
96558825de8SKatayama Hirofumi MZ         {
96658825de8SKatayama Hirofumi MZ             pt = *ppt;
96758825de8SKatayama Hirofumi MZ         }
96858825de8SKatayama Hirofumi MZ         else
96958825de8SKatayama Hirofumi MZ         {
97058825de8SKatayama Hirofumi MZ             ::GetWindowRect(m_hWnd, &rc);
97158825de8SKatayama Hirofumi MZ             pt.x = rc.left;
97258825de8SKatayama Hirofumi MZ             pt.y = rc.top;
97358825de8SKatayama Hirofumi MZ         }
97458825de8SKatayama Hirofumi MZ 
975c2c66affSColin Finck         TRACE("Before Query\n");
976c2c66affSColin Finck         hr = contextMenu->QueryContextMenu(popup, 0, 0, UINT_MAX, CMF_NORMAL);
977c2c66affSColin Finck         if (FAILED_UNEXPECTEDLY(hr))
978c2c66affSColin Finck         {
979c2c66affSColin Finck             TRACE("Query failed\n");
980c2c66affSColin Finck             DestroyMenu(popup);
981c2c66affSColin Finck             return hr;
982c2c66affSColin Finck         }
983c2c66affSColin Finck 
984c2c66affSColin Finck         TRACE("Before Tracking\n");
98558825de8SKatayama Hirofumi MZ         ::SetForegroundWindow(m_hWnd);
98658825de8SKatayama Hirofumi MZ         if (hwndExclude)
98758825de8SKatayama Hirofumi MZ         {
98858825de8SKatayama Hirofumi MZ             ::GetWindowRect(hwndExclude, &rc);
98958825de8SKatayama Hirofumi MZ             ZeroMemory(&params, sizeof(params));
99058825de8SKatayama Hirofumi MZ             params.cbSize = sizeof(params);
99158825de8SKatayama Hirofumi MZ             params.rcExclude = rc;
99258825de8SKatayama Hirofumi MZ             uCommand = ::TrackPopupMenuEx(popup, TPM_RETURNCMD, pt.x, pt.y, m_hWnd, &params);
99358825de8SKatayama Hirofumi MZ         }
99458825de8SKatayama Hirofumi MZ         else
99558825de8SKatayama Hirofumi MZ         {
99658825de8SKatayama Hirofumi MZ             uCommand = ::TrackPopupMenuEx(popup, TPM_RETURNCMD, pt.x, pt.y, m_hWnd, NULL);
99758825de8SKatayama Hirofumi MZ         }
99858825de8SKatayama Hirofumi MZ         ::PostMessage(m_hWnd, WM_NULL, 0, 0);
999c2c66affSColin Finck 
1000c2c66affSColin Finck         if (uCommand != 0)
1001c2c66affSColin Finck         {
1002c2c66affSColin Finck             TRACE("Before InvokeCommand\n");
1003c2c66affSColin Finck             CMINVOKECOMMANDINFO cmi = { 0 };
1004c2c66affSColin Finck             cmi.cbSize = sizeof(cmi);
1005c2c66affSColin Finck             cmi.lpVerb = MAKEINTRESOURCEA(uCommand);
1006c2c66affSColin Finck             cmi.hwnd = m_hWnd;
1007c2c66affSColin Finck             hr = contextMenu->InvokeCommand(&cmi);
1008c2c66affSColin Finck         }
1009c2c66affSColin Finck         else
1010c2c66affSColin Finck         {
1011c2c66affSColin Finck             TRACE("TrackPopupMenu failed. Code=%d, LastError=%d\n", uCommand, GetLastError());
1012c2c66affSColin Finck             hr = S_FALSE;
1013c2c66affSColin Finck         }
1014c2c66affSColin Finck 
1015c2c66affSColin Finck         DestroyMenu(popup);
1016c2c66affSColin Finck         return hr;
1017c2c66affSColin Finck     }
1018c2c66affSColin Finck 
1019c2c66affSColin Finck 
1020c2c66affSColin Finck 
1021c2c66affSColin Finck 
1022c2c66affSColin Finck 
1023c2c66affSColin Finck     /**********************************************************
1024c2c66affSColin Finck      *    ##### moving and sizing handling #####
1025c2c66affSColin Finck      */
1026c2c66affSColin Finck 
UpdateFonts()1027c2c66affSColin Finck     void UpdateFonts()
1028c2c66affSColin Finck     {
1029c2c66affSColin Finck         /* There is nothing to do if themes are enabled */
1030c2c66affSColin Finck         if (m_Theme)
1031c2c66affSColin Finck             return;
1032c2c66affSColin Finck 
1033c2c66affSColin Finck         m_StartButton.UpdateFont();
1034c2c66affSColin Finck 
1035c2c66affSColin Finck         NONCLIENTMETRICS ncm = {sizeof(ncm)};
1036c2c66affSColin Finck         if (!SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, FALSE))
1037c2c66affSColin Finck         {
1038c2c66affSColin Finck             ERR("SPI_GETNONCLIENTMETRICS failed\n");
1039c2c66affSColin Finck             return;
1040c2c66affSColin Finck         }
1041c2c66affSColin Finck 
1042c2c66affSColin Finck         if (m_Font != NULL)
1043c2c66affSColin Finck             DeleteObject(m_Font);
1044c2c66affSColin Finck 
1045c2c66affSColin Finck         ncm.lfCaptionFont.lfWeight = FW_NORMAL;
1046c2c66affSColin Finck         m_Font = CreateFontIndirect(&ncm.lfCaptionFont);
1047c2c66affSColin Finck         if (!m_Font)
1048c2c66affSColin Finck         {
1049c2c66affSColin Finck             ERR("CreateFontIndirect failed\n");
1050c2c66affSColin Finck             return;
1051c2c66affSColin Finck         }
1052c2c66affSColin Finck 
1053c2c66affSColin Finck         SendMessage(m_Rebar, WM_SETFONT, (WPARAM) m_Font, TRUE);
1054c2c66affSColin Finck         SendMessage(m_TaskSwitch, WM_SETFONT, (WPARAM) m_Font, TRUE);
1055c2c66affSColin Finck         SendMessage(m_TrayNotify, WM_SETFONT, (WPARAM) m_Font, TRUE);
1056c2c66affSColin Finck     }
1057c2c66affSColin Finck 
GetScreenRectFromRect(IN OUT RECT * pRect,IN DWORD dwFlags)1058c2c66affSColin Finck     HMONITOR GetScreenRectFromRect(
1059c2c66affSColin Finck         IN OUT RECT *pRect,
1060c2c66affSColin Finck         IN DWORD dwFlags)
1061c2c66affSColin Finck     {
1062c2c66affSColin Finck         MONITORINFO mi;
1063c2c66affSColin Finck         HMONITOR hMon;
1064c2c66affSColin Finck 
1065c2c66affSColin Finck         mi.cbSize = sizeof(mi);
1066c2c66affSColin Finck         hMon = MonitorFromRect(pRect, dwFlags);
1067c2c66affSColin Finck         if (hMon != NULL &&
1068c2c66affSColin Finck             GetMonitorInfo(hMon, &mi))
1069c2c66affSColin Finck         {
1070c2c66affSColin Finck             *pRect = mi.rcMonitor;
1071c2c66affSColin Finck         }
1072c2c66affSColin Finck         else
1073c2c66affSColin Finck         {
1074c2c66affSColin Finck             pRect->left = 0;
1075c2c66affSColin Finck             pRect->top = 0;
1076c2c66affSColin Finck             pRect->right = GetSystemMetrics(SM_CXSCREEN);
1077c2c66affSColin Finck             pRect->bottom = GetSystemMetrics(SM_CYSCREEN);
1078c2c66affSColin Finck 
1079c2c66affSColin Finck             hMon = NULL;
1080c2c66affSColin Finck         }
1081c2c66affSColin Finck 
1082c2c66affSColin Finck         return hMon;
1083c2c66affSColin Finck     }
1084c2c66affSColin Finck 
GetMonitorFromRect(IN const RECT * pRect)1085c2c66affSColin Finck     HMONITOR GetMonitorFromRect(
1086c2c66affSColin Finck         IN const RECT *pRect)
1087c2c66affSColin Finck     {
1088c2c66affSColin Finck         HMONITOR hMon;
1089c2c66affSColin Finck 
1090c2c66affSColin Finck         /* In case the monitor sizes or saved sizes differ a bit (probably
1091c2c66affSColin Finck            not a lot, only so the tray window overlaps into another monitor
1092c2c66affSColin Finck            now), minimize the risk that we determine a wrong monitor by
1093c2c66affSColin Finck            using the center point of the tray window if we can't determine
1094c2c66affSColin Finck            it using the rectangle. */
1095c2c66affSColin Finck         hMon = MonitorFromRect(pRect, MONITOR_DEFAULTTONULL);
1096c2c66affSColin Finck         if (hMon == NULL)
1097c2c66affSColin Finck         {
1098c2c66affSColin Finck             POINT pt;
1099c2c66affSColin Finck 
1100c2c66affSColin Finck             pt.x = pRect->left + ((pRect->right - pRect->left) / 2);
1101c2c66affSColin Finck             pt.y = pRect->top + ((pRect->bottom - pRect->top) / 2);
1102c2c66affSColin Finck 
1103c2c66affSColin Finck             /* be less error-prone, find the nearest monitor */
1104c2c66affSColin Finck             hMon = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST);
1105c2c66affSColin Finck         }
1106c2c66affSColin Finck 
1107c2c66affSColin Finck         return hMon;
1108c2c66affSColin Finck     }
1109c2c66affSColin Finck 
GetScreenRect(IN HMONITOR hMonitor,IN OUT RECT * pRect)1110c2c66affSColin Finck     HMONITOR GetScreenRect(
1111c2c66affSColin Finck         IN HMONITOR hMonitor,
1112c2c66affSColin Finck         IN OUT RECT *pRect)
1113c2c66affSColin Finck     {
1114c2c66affSColin Finck         HMONITOR hMon = NULL;
1115c2c66affSColin Finck 
1116c2c66affSColin Finck         if (hMonitor != NULL)
1117c2c66affSColin Finck         {
1118c2c66affSColin Finck             MONITORINFO mi;
1119c2c66affSColin Finck 
1120c2c66affSColin Finck             mi.cbSize = sizeof(mi);
1121c2c66affSColin Finck             if (!GetMonitorInfo(hMonitor, &mi))
1122c2c66affSColin Finck             {
1123c2c66affSColin Finck                 /* Hm, the monitor is gone? Try to find a monitor where it
1124c2c66affSColin Finck                    could be located now */
1125c2c66affSColin Finck                 hMon = GetMonitorFromRect(pRect);
1126c2c66affSColin Finck                 if (hMon == NULL ||
1127c2c66affSColin Finck                     !GetMonitorInfo(hMon, &mi))
1128c2c66affSColin Finck                 {
1129c2c66affSColin Finck                     hMon = NULL;
1130c2c66affSColin Finck                     goto GetPrimaryRect;
1131c2c66affSColin Finck                 }
1132c2c66affSColin Finck             }
1133c2c66affSColin Finck 
1134c2c66affSColin Finck             *pRect = mi.rcMonitor;
1135c2c66affSColin Finck         }
1136c2c66affSColin Finck         else
1137c2c66affSColin Finck         {
1138c2c66affSColin Finck GetPrimaryRect:
1139c2c66affSColin Finck             pRect->left = 0;
1140c2c66affSColin Finck             pRect->top = 0;
1141c2c66affSColin Finck             pRect->right = GetSystemMetrics(SM_CXSCREEN);
1142c2c66affSColin Finck             pRect->bottom = GetSystemMetrics(SM_CYSCREEN);
1143c2c66affSColin Finck         }
1144c2c66affSColin Finck 
1145c2c66affSColin Finck         return hMon;
1146c2c66affSColin Finck     }
1147c2c66affSColin Finck 
AdjustSizerRect(RECT * rc,DWORD pos)1148c2c66affSColin Finck     VOID AdjustSizerRect(RECT *rc, DWORD pos)
1149c2c66affSColin Finck     {
1150c2c66affSColin Finck         int iSizerPart[4] = {TBP_SIZINGBARLEFT, TBP_SIZINGBARTOP, TBP_SIZINGBARRIGHT, TBP_SIZINGBARBOTTOM};
1151c2c66affSColin Finck         SIZE size;
1152c2c66affSColin Finck 
1153c2c66affSColin Finck         if (pos > ABE_BOTTOM)
1154c2c66affSColin Finck             pos = ABE_BOTTOM;
1155c2c66affSColin Finck 
1156c2c66affSColin Finck         HRESULT hr = GetThemePartSize(m_Theme, NULL, iSizerPart[pos], 0, NULL, TS_TRUE, &size);
1157c2c66affSColin Finck         if (FAILED_UNEXPECTEDLY(hr))
1158c2c66affSColin Finck             return;
1159c2c66affSColin Finck 
1160c2c66affSColin Finck         switch (pos)
1161c2c66affSColin Finck         {
1162c2c66affSColin Finck             case ABE_TOP:
1163c2c66affSColin Finck                 rc->bottom -= size.cy;
1164c2c66affSColin Finck                 break;
1165c2c66affSColin Finck             case ABE_BOTTOM:
1166c2c66affSColin Finck                 rc->top += size.cy;
1167c2c66affSColin Finck                 break;
1168c2c66affSColin Finck             case ABE_LEFT:
1169c2c66affSColin Finck                 rc->right -= size.cx;
1170c2c66affSColin Finck                 break;
1171c2c66affSColin Finck             case ABE_RIGHT:
1172c2c66affSColin Finck                 rc->left += size.cx;
1173c2c66affSColin Finck                 break;
1174c2c66affSColin Finck         }
1175c2c66affSColin Finck     }
1176c2c66affSColin Finck 
MakeTrayRectWithSize(IN DWORD Position,IN const SIZE * pTraySize,IN OUT RECT * pRect)1177c2c66affSColin Finck     VOID MakeTrayRectWithSize(IN DWORD Position,
1178c2c66affSColin Finck                               IN const SIZE *pTraySize,
1179c2c66affSColin Finck                               IN OUT RECT *pRect)
1180c2c66affSColin Finck     {
1181c2c66affSColin Finck         switch (Position)
1182c2c66affSColin Finck         {
1183c2c66affSColin Finck         case ABE_LEFT:
1184c2c66affSColin Finck             pRect->right = pRect->left + pTraySize->cx;
1185c2c66affSColin Finck             break;
1186c2c66affSColin Finck 
1187c2c66affSColin Finck         case ABE_TOP:
1188c2c66affSColin Finck             pRect->bottom = pRect->top + pTraySize->cy;
1189c2c66affSColin Finck             break;
1190c2c66affSColin Finck 
1191c2c66affSColin Finck         case ABE_RIGHT:
1192c2c66affSColin Finck             pRect->left = pRect->right - pTraySize->cx;
1193c2c66affSColin Finck             break;
1194c2c66affSColin Finck 
1195c2c66affSColin Finck         case ABE_BOTTOM:
1196c2c66affSColin Finck         default:
1197c2c66affSColin Finck             pRect->top = pRect->bottom - pTraySize->cy;
1198c2c66affSColin Finck             break;
1199c2c66affSColin Finck         }
1200c2c66affSColin Finck     }
1201c2c66affSColin Finck 
GetTrayRectFromScreenRect(IN DWORD Position,IN const RECT * pScreen,IN const SIZE * pTraySize OPTIONAL,OUT RECT * pRect)1202c2c66affSColin Finck     VOID GetTrayRectFromScreenRect(IN DWORD Position,
1203c2c66affSColin Finck                                    IN const RECT *pScreen,
1204c2c66affSColin Finck                                    IN const SIZE *pTraySize OPTIONAL,
1205c2c66affSColin Finck                                    OUT RECT *pRect)
1206c2c66affSColin Finck     {
1207c2c66affSColin Finck         if (pTraySize == NULL)
1208c2c66affSColin Finck             pTraySize = &m_TraySize;
1209c2c66affSColin Finck 
1210c2c66affSColin Finck         *pRect = *pScreen;
1211c2c66affSColin Finck 
1212c2c66affSColin Finck         if(!m_Theme)
1213c2c66affSColin Finck         {
1214c2c66affSColin Finck             /* Move the border outside of the screen */
1215c2c66affSColin Finck             InflateRect(pRect,
1216c2c66affSColin Finck                         GetSystemMetrics(SM_CXEDGE),
1217c2c66affSColin Finck                         GetSystemMetrics(SM_CYEDGE));
1218c2c66affSColin Finck         }
1219c2c66affSColin Finck 
1220c2c66affSColin Finck         MakeTrayRectWithSize(Position, pTraySize, pRect);
1221c2c66affSColin Finck     }
1222c2c66affSColin Finck 
IsPosHorizontal()1223c2c66affSColin Finck     BOOL IsPosHorizontal()
1224c2c66affSColin Finck     {
1225c2c66affSColin Finck         return m_Position == ABE_TOP || m_Position == ABE_BOTTOM;
1226c2c66affSColin Finck     }
1227c2c66affSColin Finck 
CalculateValidSize(IN DWORD Position,IN OUT RECT * pRect)1228c2c66affSColin Finck     HMONITOR CalculateValidSize(
1229c2c66affSColin Finck         IN DWORD Position,
1230c2c66affSColin Finck         IN OUT RECT *pRect)
1231c2c66affSColin Finck     {
1232c2c66affSColin Finck         RECT rcScreen;
1233c2c66affSColin Finck         //BOOL Horizontal;
1234c2c66affSColin Finck         HMONITOR hMon;
1235c2c66affSColin Finck         SIZE szMax, szWnd;
1236c2c66affSColin Finck 
1237c2c66affSColin Finck         //Horizontal = IsPosHorizontal();
1238c2c66affSColin Finck 
1239c2c66affSColin Finck         szWnd.cx = pRect->right - pRect->left;
1240c2c66affSColin Finck         szWnd.cy = pRect->bottom - pRect->top;
1241c2c66affSColin Finck 
1242c2c66affSColin Finck         rcScreen = *pRect;
1243c2c66affSColin Finck         hMon = GetScreenRectFromRect(
1244c2c66affSColin Finck             &rcScreen,
1245c2c66affSColin Finck             MONITOR_DEFAULTTONEAREST);
1246c2c66affSColin Finck 
1247c2c66affSColin Finck         /* Calculate the maximum size of the tray window and limit the window
1248c2c66affSColin Finck            size to half of the screen's size. */
1249c2c66affSColin Finck         szMax.cx = (rcScreen.right - rcScreen.left) / 2;
1250c2c66affSColin Finck         szMax.cy = (rcScreen.bottom - rcScreen.top) / 2;
1251c2c66affSColin Finck         if (szWnd.cx > szMax.cx)
1252c2c66affSColin Finck             szWnd.cx = szMax.cx;
1253c2c66affSColin Finck         if (szWnd.cy > szMax.cy)
1254c2c66affSColin Finck             szWnd.cy = szMax.cy;
1255c2c66affSColin Finck 
1256c2c66affSColin Finck         /* FIXME - calculate */
1257c2c66affSColin Finck 
1258c2c66affSColin Finck         GetTrayRectFromScreenRect(Position,
1259c2c66affSColin Finck                                   &rcScreen,
1260c2c66affSColin Finck                                   &szWnd,
1261c2c66affSColin Finck                                   pRect);
1262c2c66affSColin Finck 
1263c2c66affSColin Finck         return hMon;
1264c2c66affSColin Finck     }
1265c2c66affSColin Finck 
1266c2c66affSColin Finck #if 0
1267c2c66affSColin Finck     VOID
1268c2c66affSColin Finck         GetMinimumWindowSize(
1269c2c66affSColin Finck         OUT RECT *pRect)
1270c2c66affSColin Finck     {
1271c2c66affSColin Finck         RECT rcMin = {0};
1272c2c66affSColin Finck 
1273c2c66affSColin Finck         AdjustWindowRectEx(&rcMin,
1274c2c66affSColin Finck                            GetWindowLong(m_hWnd,
1275c2c66affSColin Finck                            GWL_STYLE),
1276c2c66affSColin Finck                            FALSE,
1277c2c66affSColin Finck                            GetWindowLong(m_hWnd,
1278c2c66affSColin Finck                            GWL_EXSTYLE));
1279c2c66affSColin Finck 
1280c2c66affSColin Finck         *pRect = rcMin;
1281c2c66affSColin Finck     }
1282c2c66affSColin Finck #endif
1283c2c66affSColin Finck 
1284c2c66affSColin Finck 
GetDraggingRectFromPt(IN POINT pt,OUT RECT * pRect,OUT HMONITOR * phMonitor)1285c2c66affSColin Finck     DWORD GetDraggingRectFromPt(
1286c2c66affSColin Finck         IN POINT pt,
1287c2c66affSColin Finck         OUT RECT *pRect,
1288c2c66affSColin Finck         OUT HMONITOR *phMonitor)
1289c2c66affSColin Finck     {
1290c2c66affSColin Finck         HMONITOR hMon, hMonNew;
1291c2c66affSColin Finck         DWORD PosH, PosV, Pos;
1292c2c66affSColin Finck         SIZE DeltaPt, ScreenOffset;
1293c2c66affSColin Finck         RECT rcScreen;
1294c2c66affSColin Finck 
1295c2c66affSColin Finck         rcScreen.left = 0;
1296c2c66affSColin Finck         rcScreen.top = 0;
1297c2c66affSColin Finck 
1298c2c66affSColin Finck         /* Determine the screen rectangle */
1299c2c66affSColin Finck         hMon = MonitorFromPoint(pt, MONITOR_DEFAULTTONULL);
1300c2c66affSColin Finck         if (hMon != NULL)
1301c2c66affSColin Finck         {
1302c2c66affSColin Finck             MONITORINFO mi;
1303c2c66affSColin Finck 
1304c2c66affSColin Finck             mi.cbSize = sizeof(mi);
1305c2c66affSColin Finck             if (!GetMonitorInfo(hMon, &mi))
1306c2c66affSColin Finck             {
1307c2c66affSColin Finck                 hMon = NULL;
1308c2c66affSColin Finck                 goto GetPrimaryScreenRect;
1309c2c66affSColin Finck             }
1310c2c66affSColin Finck 
1311c2c66affSColin Finck             /* make left top corner of the screen zero based to
1312c2c66affSColin Finck                make calculations easier */
1313c2c66affSColin Finck             pt.x -= mi.rcMonitor.left;
1314c2c66affSColin Finck             pt.y -= mi.rcMonitor.top;
1315c2c66affSColin Finck 
1316c2c66affSColin Finck             ScreenOffset.cx = mi.rcMonitor.left;
1317c2c66affSColin Finck             ScreenOffset.cy = mi.rcMonitor.top;
1318c2c66affSColin Finck             rcScreen.right = mi.rcMonitor.right - mi.rcMonitor.left;
1319c2c66affSColin Finck             rcScreen.bottom = mi.rcMonitor.bottom - mi.rcMonitor.top;
1320c2c66affSColin Finck         }
1321c2c66affSColin Finck         else
1322c2c66affSColin Finck         {
1323c2c66affSColin Finck GetPrimaryScreenRect:
1324c2c66affSColin Finck             ScreenOffset.cx = 0;
1325c2c66affSColin Finck             ScreenOffset.cy = 0;
1326c2c66affSColin Finck             rcScreen.right = GetSystemMetrics(SM_CXSCREEN);
1327c2c66affSColin Finck             rcScreen.bottom = GetSystemMetrics(SM_CYSCREEN);
1328c2c66affSColin Finck         }
1329c2c66affSColin Finck 
1330c2c66affSColin Finck         /* Calculate the nearest screen border */
1331c2c66affSColin Finck         if (pt.x < rcScreen.right / 2)
1332c2c66affSColin Finck         {
1333c2c66affSColin Finck             DeltaPt.cx = pt.x;
1334c2c66affSColin Finck             PosH = ABE_LEFT;
1335c2c66affSColin Finck         }
1336c2c66affSColin Finck         else
1337c2c66affSColin Finck         {
1338c2c66affSColin Finck             DeltaPt.cx = rcScreen.right - pt.x;
1339c2c66affSColin Finck             PosH = ABE_RIGHT;
1340c2c66affSColin Finck         }
1341c2c66affSColin Finck 
1342c2c66affSColin Finck         if (pt.y < rcScreen.bottom / 2)
1343c2c66affSColin Finck         {
1344c2c66affSColin Finck             DeltaPt.cy = pt.y;
1345c2c66affSColin Finck             PosV = ABE_TOP;
1346c2c66affSColin Finck         }
1347c2c66affSColin Finck         else
1348c2c66affSColin Finck         {
1349c2c66affSColin Finck             DeltaPt.cy = rcScreen.bottom - pt.y;
1350c2c66affSColin Finck             PosV = ABE_BOTTOM;
1351c2c66affSColin Finck         }
1352c2c66affSColin Finck 
1353c2c66affSColin Finck         Pos = (DeltaPt.cx * rcScreen.bottom < DeltaPt.cy * rcScreen.right) ? PosH : PosV;
1354c2c66affSColin Finck 
1355c2c66affSColin Finck         /* Fix the screen origin to be relative to the primary monitor again */
1356c2c66affSColin Finck         OffsetRect(&rcScreen,
1357c2c66affSColin Finck                    ScreenOffset.cx,
1358c2c66affSColin Finck                    ScreenOffset.cy);
1359c2c66affSColin Finck 
1360c2c66affSColin Finck         RECT rcPos = m_TrayRects[Pos];
1361c2c66affSColin Finck 
1362c2c66affSColin Finck         hMonNew = GetMonitorFromRect(&rcPos);
1363c2c66affSColin Finck         if (hMon != hMonNew)
1364c2c66affSColin Finck         {
1365c2c66affSColin Finck             SIZE szTray;
1366c2c66affSColin Finck 
1367c2c66affSColin Finck             /* Recalculate the rectangle, we're dragging to another monitor.
1368c2c66affSColin Finck                We don't need to recalculate the rect on single monitor systems. */
1369c2c66affSColin Finck             szTray.cx = rcPos.right - rcPos.left;
1370c2c66affSColin Finck             szTray.cy = rcPos.bottom - rcPos.top;
1371c2c66affSColin Finck 
1372c2c66affSColin Finck             GetTrayRectFromScreenRect(Pos, &rcScreen, &szTray, pRect);
1373c2c66affSColin Finck             hMon = hMonNew;
1374c2c66affSColin Finck         }
1375c2c66affSColin Finck         else
1376c2c66affSColin Finck         {
1377c2c66affSColin Finck             /* The user is dragging the tray window on the same monitor. We don't need
1378c2c66affSColin Finck                to recalculate the rectangle */
1379c2c66affSColin Finck             *pRect = rcPos;
1380c2c66affSColin Finck         }
1381c2c66affSColin Finck 
1382c2c66affSColin Finck         *phMonitor = hMon;
1383c2c66affSColin Finck 
1384c2c66affSColin Finck         return Pos;
1385c2c66affSColin Finck     }
1386c2c66affSColin Finck 
GetDraggingRectFromRect(IN OUT RECT * pRect,OUT HMONITOR * phMonitor)1387c2c66affSColin Finck     DWORD GetDraggingRectFromRect(
1388c2c66affSColin Finck         IN OUT RECT *pRect,
1389c2c66affSColin Finck         OUT HMONITOR *phMonitor)
1390c2c66affSColin Finck     {
1391c2c66affSColin Finck         POINT pt;
1392c2c66affSColin Finck 
1393c2c66affSColin Finck         /* Calculate the center of the rectangle. We call
1394c2c66affSColin Finck            GetDraggingRectFromPt to calculate a valid
1395c2c66affSColin Finck            dragging rectangle */
1396c2c66affSColin Finck         pt.x = pRect->left + ((pRect->right - pRect->left) / 2);
1397c2c66affSColin Finck         pt.y = pRect->top + ((pRect->bottom - pRect->top) / 2);
1398c2c66affSColin Finck 
1399c2c66affSColin Finck         return GetDraggingRectFromPt(
1400c2c66affSColin Finck             pt,
1401c2c66affSColin Finck             pRect,
1402c2c66affSColin Finck             phMonitor);
1403c2c66affSColin Finck     }
1404c2c66affSColin Finck 
ChangingWinPos(IN OUT LPWINDOWPOS pwp)1405c2c66affSColin Finck     VOID ChangingWinPos(IN OUT LPWINDOWPOS pwp)
1406c2c66affSColin Finck     {
1407c2c66affSColin Finck         RECT rcTray;
1408c2c66affSColin Finck 
1409c2c66affSColin Finck         if (IsDragging)
1410c2c66affSColin Finck         {
1411c2c66affSColin Finck             rcTray.left = pwp->x;
1412c2c66affSColin Finck             rcTray.top = pwp->y;
1413c2c66affSColin Finck             rcTray.right = rcTray.left + pwp->cx;
1414c2c66affSColin Finck             rcTray.bottom = rcTray.top + pwp->cy;
1415c2c66affSColin Finck 
1416c2c66affSColin Finck             if (!EqualRect(&rcTray,
1417c2c66affSColin Finck                 &m_TrayRects[m_DraggingPosition]))
1418c2c66affSColin Finck             {
1419c2c66affSColin Finck                 /* Recalculate the rectangle, the user dragged the tray
1420c2c66affSColin Finck                    window to another monitor or the window was somehow else
1421c2c66affSColin Finck                    moved or resized */
1422c2c66affSColin Finck                 m_DraggingPosition = GetDraggingRectFromRect(
1423c2c66affSColin Finck                     &rcTray,
1424c2c66affSColin Finck                     &m_DraggingMonitor);
1425c2c66affSColin Finck                 //m_TrayRects[DraggingPosition] = rcTray;
1426c2c66affSColin Finck             }
1427c2c66affSColin Finck 
1428c2c66affSColin Finck             //Monitor = CalculateValidSize(DraggingPosition,
1429c2c66affSColin Finck             //                             &rcTray);
1430c2c66affSColin Finck 
1431c2c66affSColin Finck             m_Monitor = m_DraggingMonitor;
1432c2c66affSColin Finck             m_Position = m_DraggingPosition;
14337fafeb63SCarl J. Bialorucki             g_TaskbarSettings.sr.Position = m_Position;
14347fafeb63SCarl J. Bialorucki             g_TaskbarSettings.Save();
1435c2c66affSColin Finck             IsDragging = FALSE;
1436c2c66affSColin Finck 
1437c2c66affSColin Finck             m_TrayRects[m_Position] = rcTray;
1438c2c66affSColin Finck             goto ChangePos;
1439c2c66affSColin Finck         }
1440c2c66affSColin Finck         else if (GetWindowRect(&rcTray))
1441c2c66affSColin Finck         {
1442c2c66affSColin Finck             if (InSizeMove)
1443c2c66affSColin Finck             {
1444c2c66affSColin Finck                 if (!(pwp->flags & SWP_NOMOVE))
1445c2c66affSColin Finck                 {
1446c2c66affSColin Finck                     rcTray.left = pwp->x;
1447c2c66affSColin Finck                     rcTray.top = pwp->y;
1448c2c66affSColin Finck                 }
1449c2c66affSColin Finck 
1450c2c66affSColin Finck                 if (!(pwp->flags & SWP_NOSIZE))
1451c2c66affSColin Finck                 {
1452c2c66affSColin Finck                     rcTray.right = rcTray.left + pwp->cx;
1453c2c66affSColin Finck                     rcTray.bottom = rcTray.top + pwp->cy;
1454c2c66affSColin Finck                 }
1455c2c66affSColin Finck 
1456c2c66affSColin Finck                 m_Position = GetDraggingRectFromRect(&rcTray, &m_Monitor);
1457c2c66affSColin Finck 
1458c2c66affSColin Finck                 if (!(pwp->flags & (SWP_NOMOVE | SWP_NOSIZE)))
1459c2c66affSColin Finck                 {
1460c2c66affSColin Finck                     SIZE szWnd;
1461c2c66affSColin Finck 
1462c2c66affSColin Finck                     szWnd.cx = pwp->cx;
1463c2c66affSColin Finck                     szWnd.cy = pwp->cy;
1464c2c66affSColin Finck 
1465c2c66affSColin Finck                     MakeTrayRectWithSize(m_Position, &szWnd, &rcTray);
1466c2c66affSColin Finck                 }
1467c2c66affSColin Finck 
1468c2c66affSColin Finck                 m_TrayRects[m_Position] = rcTray;
1469c2c66affSColin Finck             }
1470ce537f1aSTimo Kreuzer             else if (m_Position != (DWORD)-1)
1471c2c66affSColin Finck             {
1472c2c66affSColin Finck                 /* If the user isn't resizing the tray window we need to make sure the
1473c2c66affSColin Finck                    new size or position is valid. this is to prevent changes to the window
1474c2c66affSColin Finck                    without user interaction. */
1475c2c66affSColin Finck                 rcTray = m_TrayRects[m_Position];
1476c2c66affSColin Finck 
14772ed535daSGiannis Adamopoulos                 if (g_TaskbarSettings.sr.AutoHide)
1478c2c66affSColin Finck                 {
1479c2c66affSColin Finck                     rcTray.left += m_AutoHideOffset.cx;
1480c2c66affSColin Finck                     rcTray.right += m_AutoHideOffset.cx;
1481c2c66affSColin Finck                     rcTray.top += m_AutoHideOffset.cy;
1482c2c66affSColin Finck                     rcTray.bottom += m_AutoHideOffset.cy;
1483c2c66affSColin Finck                 }
1484c2c66affSColin Finck 
14854238f223SGiannis Adamopoulos             }
14864238f223SGiannis Adamopoulos 
14874238f223SGiannis Adamopoulos ChangePos:
14884238f223SGiannis Adamopoulos             m_TraySize.cx = rcTray.right - rcTray.left;
14894238f223SGiannis Adamopoulos             m_TraySize.cy = rcTray.bottom - rcTray.top;
14904238f223SGiannis Adamopoulos 
1491c2c66affSColin Finck             pwp->flags &= ~(SWP_NOMOVE | SWP_NOSIZE);
1492c2c66affSColin Finck             pwp->x = rcTray.left;
1493c2c66affSColin Finck             pwp->y = rcTray.top;
1494c2c66affSColin Finck             pwp->cx = m_TraySize.cx;
1495c2c66affSColin Finck             pwp->cy = m_TraySize.cy;
1496c2c66affSColin Finck         }
1497c2c66affSColin Finck     }
1498c2c66affSColin Finck 
ApplyClipping(IN BOOL Clip)1499c2c66affSColin Finck     VOID ApplyClipping(IN BOOL Clip)
1500c2c66affSColin Finck     {
1501c2c66affSColin Finck         RECT rcClip, rcWindow;
1502c2c66affSColin Finck         HRGN hClipRgn;
1503c2c66affSColin Finck 
1504c2c66affSColin Finck         if (GetWindowRect(&rcWindow))
1505c2c66affSColin Finck         {
1506c2c66affSColin Finck             /* Disable clipping on systems with only one monitor */
1507c2c66affSColin Finck             if (GetSystemMetrics(SM_CMONITORS) <= 1)
1508c2c66affSColin Finck                 Clip = FALSE;
1509c2c66affSColin Finck 
1510c2c66affSColin Finck             if (Clip)
1511c2c66affSColin Finck             {
1512c2c66affSColin Finck                 rcClip = rcWindow;
1513c2c66affSColin Finck 
1514c2c66affSColin Finck                 GetScreenRect(m_Monitor, &rcClip);
1515c2c66affSColin Finck 
1516c2c66affSColin Finck                 if (!IntersectRect(&rcClip, &rcClip, &rcWindow))
1517c2c66affSColin Finck                 {
1518c2c66affSColin Finck                     rcClip = rcWindow;
1519c2c66affSColin Finck                 }
1520c2c66affSColin Finck 
1521c2c66affSColin Finck                 OffsetRect(&rcClip,
1522c2c66affSColin Finck                            -rcWindow.left,
1523c2c66affSColin Finck                            -rcWindow.top);
1524c2c66affSColin Finck 
1525c2c66affSColin Finck                 hClipRgn = CreateRectRgnIndirect(&rcClip);
1526c2c66affSColin Finck             }
1527c2c66affSColin Finck             else
1528c2c66affSColin Finck                 hClipRgn = NULL;
1529c2c66affSColin Finck 
1530c2c66affSColin Finck             /* Set the clipping region or make sure the window isn't clipped
1531c2c66affSColin Finck                by disabling it explicitly. */
1532c2c66affSColin Finck             SetWindowRgn(hClipRgn, TRUE);
1533c2c66affSColin Finck         }
1534c2c66affSColin Finck     }
1535c2c66affSColin Finck 
ResizeWorkArea()1536c2c66affSColin Finck     VOID ResizeWorkArea()
1537c2c66affSColin Finck     {
1538c2c66affSColin Finck #if !WIN7_DEBUG_MODE
1539c2c66affSColin Finck         RECT rcTray, rcWorkArea;
1540c2c66affSColin Finck 
1541c2c66affSColin Finck         /* If monitor has changed then fix the previous monitors work area */
1542c2c66affSColin Finck         if (m_PreviousMonitor != m_Monitor)
1543c2c66affSColin Finck         {
1544c2c66affSColin Finck             GetScreenRect(m_PreviousMonitor, &rcWorkArea);
1545c2c66affSColin Finck             SystemParametersInfoW(SPI_SETWORKAREA,
1546c2c66affSColin Finck                                   1,
1547c2c66affSColin Finck                                   &rcWorkArea,
1548c2c66affSColin Finck                                   SPIF_SENDCHANGE);
1549c2c66affSColin Finck         }
1550c2c66affSColin Finck 
1551c2c66affSColin Finck         rcTray = m_TrayRects[m_Position];
1552c2c66affSColin Finck 
1553c2c66affSColin Finck         GetScreenRect(m_Monitor, &rcWorkArea);
1554c2c66affSColin Finck         m_PreviousMonitor = m_Monitor;
1555c2c66affSColin Finck 
1556c2c66affSColin Finck         /* If AutoHide is false then change the workarea to exclude
1557c2c66affSColin Finck            the area that the taskbar covers. */
15582ed535daSGiannis Adamopoulos         if (!g_TaskbarSettings.sr.AutoHide)
1559c2c66affSColin Finck         {
1560c2c66affSColin Finck             switch (m_Position)
1561c2c66affSColin Finck             {
1562c2c66affSColin Finck             case ABE_TOP:
1563c2c66affSColin Finck                 rcWorkArea.top = rcTray.bottom;
1564c2c66affSColin Finck                 break;
1565c2c66affSColin Finck             case ABE_LEFT:
1566c2c66affSColin Finck                 rcWorkArea.left = rcTray.right;
1567c2c66affSColin Finck                 break;
1568c2c66affSColin Finck             case ABE_RIGHT:
1569c2c66affSColin Finck                 rcWorkArea.right = rcTray.left;
1570c2c66affSColin Finck                 break;
1571c2c66affSColin Finck             case ABE_BOTTOM:
1572c2c66affSColin Finck                 rcWorkArea.bottom = rcTray.top;
1573c2c66affSColin Finck                 break;
1574c2c66affSColin Finck             }
1575c2c66affSColin Finck         }
1576c2c66affSColin Finck 
1577c2c66affSColin Finck         /*
1578c2c66affSColin Finck          * Resize the current monitor work area. Win32k will also send
1579c2c66affSColin Finck          * a WM_SIZE message to automatically resize the desktop.
1580c2c66affSColin Finck          */
1581c2c66affSColin Finck         SystemParametersInfoW(SPI_SETWORKAREA,
1582c2c66affSColin Finck                               1,
1583c2c66affSColin Finck                               &rcWorkArea,
1584c2c66affSColin Finck                               SPIF_SENDCHANGE);
1585c2c66affSColin Finck #endif
1586c2c66affSColin Finck     }
1587c2c66affSColin Finck 
CheckTrayWndPosition()1588c2c66affSColin Finck     VOID CheckTrayWndPosition()
1589c2c66affSColin Finck     {
15904238f223SGiannis Adamopoulos         /* Force the rebar bands to resize */
1591c2c66affSColin Finck         IUnknown_Exec(m_TrayBandSite,
1592c2c66affSColin Finck                       IID_IDeskBand,
1593c2c66affSColin Finck                       DBID_BANDINFOCHANGED,
1594c2c66affSColin Finck                       0,
1595c2c66affSColin Finck                       NULL,
1596c2c66affSColin Finck                       NULL);
1597c2c66affSColin Finck 
15984238f223SGiannis Adamopoulos         /* Calculate the size of the taskbar based on the rebar */
15994238f223SGiannis Adamopoulos         FitToRebar(&m_TrayRects[m_Position]);
1600c2c66affSColin Finck 
1601c2c66affSColin Finck         /* Move the tray window */
16024238f223SGiannis Adamopoulos         /* The handler of WM_WINDOWPOSCHANGING will override whatever size
16034238f223SGiannis Adamopoulos          * and position we use here with m_TrayRects */
16044238f223SGiannis Adamopoulos         SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOACTIVATE);
1605c2c66affSColin Finck         ResizeWorkArea();
1606c2c66affSColin Finck         ApplyClipping(TRUE);
160770d7009aSEthan Rodensky         RedrawWindow(NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INTERNALPAINT | RDW_INVALIDATE | RDW_ALLCHILDREN);
1608c2c66affSColin Finck     }
1609c2c66affSColin Finck 
RegLoadSettings()1610c2c66affSColin Finck     VOID RegLoadSettings()
1611c2c66affSColin Finck     {
1612c2c66affSColin Finck         DWORD Pos;
1613c2c66affSColin Finck         RECT rcScreen;
1614c2c66affSColin Finck         SIZE WndSize, EdgeSize, DlgFrameSize;
1615c2c66affSColin Finck         SIZE StartBtnSize = m_StartButton.GetSize();
1616c2c66affSColin Finck 
1617c2c66affSColin Finck         EdgeSize.cx = GetSystemMetrics(SM_CXEDGE);
1618c2c66affSColin Finck         EdgeSize.cy = GetSystemMetrics(SM_CYEDGE);
1619c2c66affSColin Finck         DlgFrameSize.cx = GetSystemMetrics(SM_CXDLGFRAME);
1620c2c66affSColin Finck         DlgFrameSize.cy = GetSystemMetrics(SM_CYDLGFRAME);
1621c2c66affSColin Finck 
16222ed535daSGiannis Adamopoulos         m_Position = g_TaskbarSettings.sr.Position;
16232ed535daSGiannis Adamopoulos         rcScreen = g_TaskbarSettings.sr.Rect;
16242ed535daSGiannis Adamopoulos         GetScreenRectFromRect(&rcScreen, MONITOR_DEFAULTTONEAREST);
16252ed535daSGiannis Adamopoulos 
16262ed535daSGiannis Adamopoulos         if (!g_TaskbarSettings.sr.Size.cx || !g_TaskbarSettings.sr.Size.cy)
1627c2c66affSColin Finck         {
1628c2c66affSColin Finck             /* Use the minimum size of the taskbar, we'll use the start
1629c2c66affSColin Finck                button as a minimum for now. Make sure we calculate the
1630c2c66affSColin Finck                entire window size, not just the client size. However, we
1631c2c66affSColin Finck                use a thinner border than a standard thick border, so that
1632c2c66affSColin Finck                the start button and bands are not stuck to the screen border. */
1633c2c66affSColin Finck             if(!m_Theme)
1634c2c66affSColin Finck             {
16352ed535daSGiannis Adamopoulos                 g_TaskbarSettings.sr.Size.cx = StartBtnSize.cx + (2 * (EdgeSize.cx + DlgFrameSize.cx));
16362ed535daSGiannis Adamopoulos                 g_TaskbarSettings.sr.Size.cy = StartBtnSize.cy + (2 * (EdgeSize.cy + DlgFrameSize.cy));
1637c2c66affSColin Finck             }
1638c2c66affSColin Finck             else
1639c2c66affSColin Finck             {
16402ed535daSGiannis Adamopoulos                 g_TaskbarSettings.sr.Size.cx = StartBtnSize.cx - EdgeSize.cx;
16412ed535daSGiannis Adamopoulos                 g_TaskbarSettings.sr.Size.cy = StartBtnSize.cy - EdgeSize.cy;
16422ed535daSGiannis Adamopoulos                 if(!g_TaskbarSettings.bLock)
16432ed535daSGiannis Adamopoulos                     g_TaskbarSettings.sr.Size.cy += GetSystemMetrics(SM_CYSIZEFRAME);
1644c2c66affSColin Finck             }
1645c2c66affSColin Finck         }
1646c2c66affSColin Finck         /* Determine a minimum tray window rectangle. The "client" height is
1647c2c66affSColin Finck            zero here since we cannot determine an optimal minimum width when
1648c2c66affSColin Finck            loaded as a vertical tray window. We just need to make sure the values
1649c2c66affSColin Finck            loaded from the registry are at least. The windows explorer behaves
1650c2c66affSColin Finck            the same way, it allows the user to save a zero width vertical tray
1651c2c66affSColin Finck            window, but not a zero height horizontal tray window. */
1652c2c66affSColin Finck         if(!m_Theme)
1653c2c66affSColin Finck         {
1654c2c66affSColin Finck             WndSize.cx = 2 * (EdgeSize.cx + DlgFrameSize.cx);
1655c2c66affSColin Finck             WndSize.cy = StartBtnSize.cy + (2 * (EdgeSize.cy + DlgFrameSize.cy));
1656c2c66affSColin Finck         }
1657c2c66affSColin Finck         else
1658c2c66affSColin Finck         {
1659c2c66affSColin Finck             WndSize.cx = StartBtnSize.cx;
166067ad4e7fSDoug Lyons             WndSize.cy = StartBtnSize.cy - EdgeSize.cy;
1661c2c66affSColin Finck         }
1662c2c66affSColin Finck 
16632ed535daSGiannis Adamopoulos         if (WndSize.cx < g_TaskbarSettings.sr.Size.cx)
16642ed535daSGiannis Adamopoulos             WndSize.cx = g_TaskbarSettings.sr.Size.cx;
16652ed535daSGiannis Adamopoulos         if (WndSize.cy < g_TaskbarSettings.sr.Size.cy)
16662ed535daSGiannis Adamopoulos             WndSize.cy = g_TaskbarSettings.sr.Size.cy;
1667c2c66affSColin Finck 
1668c2c66affSColin Finck         /* Save the calculated size */
1669c2c66affSColin Finck         m_TraySize = WndSize;
1670c2c66affSColin Finck 
1671c2c66affSColin Finck         /* Calculate all docking rectangles. We need to do this here so they're
1672c2c66affSColin Finck            initialized and dragging the tray window to another position gives
1673c2c66affSColin Finck            usable results */
1674c2c66affSColin Finck         for (Pos = ABE_LEFT; Pos <= ABE_BOTTOM; Pos++)
1675c2c66affSColin Finck         {
1676c2c66affSColin Finck             GetTrayRectFromScreenRect(Pos,
1677c2c66affSColin Finck                                       &rcScreen,
1678c2c66affSColin Finck                                       &m_TraySize,
1679c2c66affSColin Finck                                       &m_TrayRects[Pos]);
1680c2c66affSColin 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);
1681c2c66affSColin Finck         }
1682c2c66affSColin Finck 
1683c2c66affSColin Finck         /* Determine which monitor we are on. It shouldn't matter which docked
1684c2c66affSColin Finck            position rectangle we use */
1685c2c66affSColin Finck         m_Monitor = GetMonitorFromRect(&m_TrayRects[ABE_LEFT]);
1686c2c66affSColin Finck     }
1687c2c66affSColin Finck 
AlignControls(IN PRECT prcClient OPTIONAL)1688c2c66affSColin Finck     VOID AlignControls(IN PRECT prcClient OPTIONAL)
1689c2c66affSColin Finck     {
1690c2c66affSColin Finck         RECT rcClient;
1691c2c66affSColin Finck         SIZE TraySize, StartSize;
1692c2c66affSColin Finck         POINT ptTrayNotify = { 0, 0 };
1693c2c66affSColin Finck         BOOL Horizontal;
1694c2c66affSColin Finck         HDWP dwp;
1695c2c66affSColin Finck 
1696c2c66affSColin Finck         m_StartButton.UpdateSize();
1697c2c66affSColin Finck         if (prcClient != NULL)
1698c2c66affSColin Finck         {
1699c2c66affSColin Finck             rcClient = *prcClient;
1700c2c66affSColin Finck         }
1701c2c66affSColin Finck         else
1702c2c66affSColin Finck         {
1703c2c66affSColin Finck             if (!GetClientRect(&rcClient))
1704c2c66affSColin Finck             {
1705c2c66affSColin Finck                 ERR("Could not get client rect lastErr=%d\n", GetLastError());
1706c2c66affSColin Finck                 return;
1707c2c66affSColin Finck             }
1708c2c66affSColin Finck         }
1709c2c66affSColin Finck 
1710c2c66affSColin Finck         Horizontal = IsPosHorizontal();
1711c2c66affSColin Finck 
1712c2c66affSColin Finck         /* We're about to resize/move the start button, the rebar control and
1713c2c66affSColin Finck            the tray notification control */
171426efda4dSKatayama Hirofumi MZ         dwp = BeginDeferWindowPos(4);
1715c2c66affSColin Finck         if (dwp == NULL)
1716c2c66affSColin Finck         {
1717c2c66affSColin Finck             ERR("BeginDeferWindowPos failed. lastErr=%d\n", GetLastError());
1718c2c66affSColin Finck             return;
1719c2c66affSColin Finck         }
1720c2c66affSColin Finck 
1721c2c66affSColin Finck         /* Limit the Start button width to the client width, if necessary */
1722c2c66affSColin Finck         StartSize = m_StartButton.GetSize();
1723c2c66affSColin Finck         if (StartSize.cx > rcClient.right)
1724c2c66affSColin Finck             StartSize.cx = rcClient.right;
1725c2c66affSColin Finck 
1726c2c66affSColin Finck         HWND hwndTaskToolbar = ::GetWindow(m_TaskSwitch, GW_CHILD);
1727c2c66affSColin Finck         if (hwndTaskToolbar)
1728c2c66affSColin Finck         {
1729c2c66affSColin Finck             DWORD size = SendMessageW(hwndTaskToolbar, TB_GETBUTTONSIZE, 0, 0);
173067ad4e7fSDoug Lyons 
173167ad4e7fSDoug Lyons             /* Themed button covers Edge area as well */
173267ad4e7fSDoug Lyons             StartSize.cy = HIWORD(size) + (m_Theme ? GetSystemMetrics(SM_CYEDGE) : 0);
1733c2c66affSColin Finck         }
1734c2c66affSColin Finck 
1735c2c66affSColin Finck         if (m_StartButton.m_hWnd != NULL)
1736c2c66affSColin Finck         {
1737c2c66affSColin Finck             /* Resize and reposition the button */
1738c2c66affSColin Finck             dwp = m_StartButton.DeferWindowPos(dwp,
1739c2c66affSColin Finck                                                NULL,
1740c2c66affSColin Finck                                                0,
1741c2c66affSColin Finck                                                0,
1742c2c66affSColin Finck                                                StartSize.cx,
1743c2c66affSColin Finck                                                StartSize.cy,
1744c2c66affSColin Finck                                                SWP_NOZORDER | SWP_NOACTIVATE);
1745c2c66affSColin Finck             if (dwp == NULL)
1746c2c66affSColin Finck             {
1747c2c66affSColin Finck                 ERR("DeferWindowPos for start button failed. lastErr=%d\n", GetLastError());
1748c2c66affSColin Finck                 return;
1749c2c66affSColin Finck             }
1750c2c66affSColin Finck         }
1751c2c66affSColin Finck 
1752c2c66affSColin Finck         /* Determine the size that the tray notification window needs */
1753c2c66affSColin Finck         if (Horizontal)
1754c2c66affSColin Finck         {
1755c2c66affSColin Finck             TraySize.cx = 0;
1756c2c66affSColin Finck             TraySize.cy = rcClient.bottom;
1757c2c66affSColin Finck         }
1758c2c66affSColin Finck         else
1759c2c66affSColin Finck         {
1760c2c66affSColin Finck             TraySize.cx = rcClient.right;
1761c2c66affSColin Finck             TraySize.cy = 0;
1762c2c66affSColin Finck         }
1763c2c66affSColin Finck 
1764c2c66affSColin Finck         if (m_TrayNotify != NULL &&
1765c2c66affSColin Finck             SendMessage(m_TrayNotify,
1766c2c66affSColin Finck                         TNWM_GETMINIMUMSIZE,
1767c2c66affSColin Finck                         (WPARAM)Horizontal,
1768c2c66affSColin Finck                         (LPARAM)&TraySize))
1769c2c66affSColin Finck         {
1770c2c66affSColin Finck             /* Move the tray notification window to the desired location */
1771c2c66affSColin Finck             if (Horizontal)
1772c2c66affSColin Finck                 ptTrayNotify.x = rcClient.right - TraySize.cx;
1773c2c66affSColin Finck             else
1774c2c66affSColin Finck                 ptTrayNotify.y = rcClient.bottom - TraySize.cy;
1775c2c66affSColin Finck 
1776c2c66affSColin Finck             dwp = ::DeferWindowPos(dwp,
1777c2c66affSColin Finck                                    m_TrayNotify,
1778c2c66affSColin Finck                                    NULL,
1779c2c66affSColin Finck                                    ptTrayNotify.x,
1780c2c66affSColin Finck                                    ptTrayNotify.y,
1781c2c66affSColin Finck                                    TraySize.cx,
1782c2c66affSColin Finck                                    TraySize.cy,
1783c2c66affSColin Finck                                    SWP_NOZORDER | SWP_NOACTIVATE);
1784c2c66affSColin Finck             if (dwp == NULL)
1785c2c66affSColin Finck             {
1786c2c66affSColin Finck                 ERR("DeferWindowPos for notification area failed. lastErr=%d\n", GetLastError());
1787c2c66affSColin Finck                 return;
1788c2c66affSColin Finck             }
1789c2c66affSColin Finck         }
1790c2c66affSColin Finck 
1791c2c66affSColin Finck         /* Resize/Move the rebar control */
1792c2c66affSColin Finck         if (m_Rebar != NULL)
1793c2c66affSColin Finck         {
1794c2c66affSColin Finck             POINT ptRebar = { 0, 0 };
1795c2c66affSColin Finck             SIZE szRebar;
1796c2c66affSColin Finck 
1797c2c66affSColin Finck             SetWindowStyle(m_Rebar, CCS_VERT, Horizontal ? 0 : CCS_VERT);
1798c2c66affSColin Finck 
1799c2c66affSColin Finck             if (Horizontal)
1800c2c66affSColin Finck             {
1801c2c66affSColin Finck                 ptRebar.x = StartSize.cx + GetSystemMetrics(SM_CXSIZEFRAME);
1802c2c66affSColin Finck                 szRebar.cx = ptTrayNotify.x - ptRebar.x;
1803c2c66affSColin Finck                 szRebar.cy = rcClient.bottom;
1804c2c66affSColin Finck             }
1805c2c66affSColin Finck             else
1806c2c66affSColin Finck             {
1807c2c66affSColin Finck                 ptRebar.y = StartSize.cy + GetSystemMetrics(SM_CYSIZEFRAME);
1808c2c66affSColin Finck                 szRebar.cx = rcClient.right;
1809c2c66affSColin Finck                 szRebar.cy = ptTrayNotify.y - ptRebar.y;
1810c2c66affSColin Finck             }
1811c2c66affSColin Finck 
1812c2c66affSColin Finck             dwp = ::DeferWindowPos(dwp,
1813c2c66affSColin Finck                                    m_Rebar,
1814c2c66affSColin Finck                                    NULL,
1815c2c66affSColin Finck                                    ptRebar.x,
1816c2c66affSColin Finck                                    ptRebar.y,
1817c2c66affSColin Finck                                    szRebar.cx,
1818c2c66affSColin Finck                                    szRebar.cy,
1819c2c66affSColin Finck                                    SWP_NOZORDER | SWP_NOACTIVATE);
1820c2c66affSColin Finck         }
1821c2c66affSColin Finck 
1822c2c66affSColin Finck         if (dwp != NULL)
1823c2c66affSColin Finck             EndDeferWindowPos(dwp);
1824c2c66affSColin Finck 
1825c2c66affSColin Finck         if (m_TaskSwitch != NULL)
1826c2c66affSColin Finck         {
1827c2c66affSColin Finck             /* Update the task switch window configuration */
1828c2c66affSColin Finck             SendMessage(m_TaskSwitch, TSWM_UPDATETASKBARPOS, 0, 0);
1829c2c66affSColin Finck         }
1830c2c66affSColin Finck     }
1831c2c66affSColin Finck 
FitToRebar(PRECT pRect)1832c2c66affSColin Finck     void FitToRebar(PRECT pRect)
1833c2c66affSColin Finck     {
1834c2c66affSColin Finck         /* Get the rect of the rebar */
1835c2c66affSColin Finck         RECT rebarRect, taskbarRect, clientRect;
1836c2c66affSColin Finck         ::GetWindowRect(m_Rebar, &rebarRect);
1837c2c66affSColin Finck         ::GetWindowRect(m_hWnd, &taskbarRect);
1838c2c66affSColin Finck         ::GetClientRect(m_hWnd, &clientRect);
1839c2c66affSColin Finck         OffsetRect(&rebarRect, -taskbarRect.left, -taskbarRect.top);
1840c2c66affSColin Finck 
1841c2c66affSColin Finck         /* Calculate the difference of size of the taskbar and the rebar */
1842c2c66affSColin Finck         SIZE margins;
1843c2c66affSColin Finck         margins.cx = taskbarRect.right - taskbarRect.left - clientRect.right + clientRect.left;
1844c2c66affSColin Finck         margins.cy = taskbarRect.bottom - taskbarRect.top - clientRect.bottom + clientRect.top;
1845c2c66affSColin Finck 
1846c2c66affSColin Finck         /* Calculate the new size of the rebar and make it resize, then change the new taskbar size */
1847c2c66affSColin Finck         switch (m_Position)
1848c2c66affSColin Finck         {
1849c2c66affSColin Finck         case ABE_TOP:
1850c2c66affSColin Finck             rebarRect.bottom = rebarRect.top + pRect->bottom - pRect->top - margins.cy;
1851c2c66affSColin Finck             ::SendMessageW(m_Rebar, RB_SIZETORECT, RBSTR_CHANGERECT,  (LPARAM)&rebarRect);
1852c2c66affSColin Finck             pRect->bottom = pRect->top + rebarRect.bottom - rebarRect.top + margins.cy;
1853c2c66affSColin Finck             break;
1854c2c66affSColin Finck         case ABE_BOTTOM:
1855c2c66affSColin Finck             rebarRect.top = rebarRect.bottom - (pRect->bottom - pRect->top - margins.cy);
1856c2c66affSColin Finck             ::SendMessageW(m_Rebar, RB_SIZETORECT, RBSTR_CHANGERECT,  (LPARAM)&rebarRect);
1857c2c66affSColin Finck             pRect->top = pRect->bottom - (rebarRect.bottom - rebarRect.top + margins.cy);
1858c2c66affSColin Finck             break;
1859c2c66affSColin Finck         case ABE_LEFT:
1860c2c66affSColin Finck             rebarRect.right = rebarRect.left + (pRect->right - pRect->left - margins.cx);
1861c2c66affSColin Finck             ::SendMessageW(m_Rebar, RB_SIZETORECT, RBSTR_CHANGERECT,  (LPARAM)&rebarRect);
1862c2c66affSColin Finck             pRect->right = pRect->left + (rebarRect.right - rebarRect.left + margins.cx);
1863c2c66affSColin Finck             break;
1864c2c66affSColin Finck         case ABE_RIGHT:
1865c2c66affSColin Finck             rebarRect.left = rebarRect.right - (pRect->right - pRect->left - margins.cx);
1866c2c66affSColin Finck             ::SendMessageW(m_Rebar, RB_SIZETORECT, RBSTR_CHANGERECT,  (LPARAM)&rebarRect);
1867c2c66affSColin Finck             pRect->left = pRect->right - (rebarRect.right - rebarRect.left + margins.cx);
1868c2c66affSColin Finck             break;
1869c2c66affSColin Finck         }
1870c2c66affSColin Finck 
1871c2c66affSColin Finck         CalculateValidSize(m_Position, pRect);
1872c2c66affSColin Finck     }
1873c2c66affSColin Finck 
PopupStartMenu()1874c2c66affSColin Finck     void PopupStartMenu()
1875c2c66affSColin Finck     {
1876c2c66affSColin Finck         if (m_StartMenuPopup != NULL)
1877c2c66affSColin Finck         {
1878c2c66affSColin Finck             POINTL pt;
1879c2c66affSColin Finck             RECTL rcExclude;
1880c2c66affSColin Finck             DWORD dwFlags = 0;
1881c2c66affSColin Finck 
1882c2c66affSColin Finck             if (m_StartButton.GetWindowRect((RECT*) &rcExclude))
1883c2c66affSColin Finck             {
1884c2c66affSColin Finck                 switch (m_Position)
1885c2c66affSColin Finck                 {
1886c2c66affSColin Finck                 case ABE_BOTTOM:
1887c2c66affSColin Finck                     pt.x = rcExclude.left;
1888c2c66affSColin Finck                     pt.y = rcExclude.top;
1889c2c66affSColin Finck                     dwFlags |= MPPF_TOP;
1890c2c66affSColin Finck                     break;
1891c2c66affSColin Finck                 case ABE_TOP:
1892c2c66affSColin Finck                     pt.x = rcExclude.left;
1893c2c66affSColin Finck                     pt.y = rcExclude.bottom;
1894c2c66affSColin Finck                     dwFlags |= MPPF_BOTTOM;
1895c2c66affSColin Finck                     break;
1896c2c66affSColin Finck                 case ABE_LEFT:
1897c2c66affSColin Finck                     pt.x = rcExclude.right;
1898c2c66affSColin Finck                     pt.y = rcExclude.top;
1899c2c66affSColin Finck                     dwFlags |= MPPF_RIGHT;
1900c2c66affSColin Finck                     break;
1901c2c66affSColin Finck                 case ABE_RIGHT:
1902c2c66affSColin Finck                     pt.x = rcExclude.left;
1903c2c66affSColin Finck                     pt.y = rcExclude.top;
1904c2c66affSColin Finck                     dwFlags |= MPPF_LEFT;
1905c2c66affSColin Finck                     break;
1906c2c66affSColin Finck                 }
1907c2c66affSColin Finck 
1908c2c66affSColin Finck                 m_StartMenuPopup->Popup(&pt, &rcExclude, dwFlags);
1909c2c66affSColin Finck 
1910c2c66affSColin Finck                 m_StartButton.SendMessageW(BM_SETSTATE, TRUE, 0);
1911c2c66affSColin Finck             }
1912c2c66affSColin Finck         }
1913c2c66affSColin Finck     }
1914c2c66affSColin Finck 
ProcessMouseTracking()1915c2c66affSColin Finck     void ProcessMouseTracking()
1916c2c66affSColin Finck     {
1917c2c66affSColin Finck         RECT rcCurrent;
1918c2c66affSColin Finck         POINT pt;
1919c2c66affSColin Finck         BOOL over;
1920c2c66affSColin Finck         UINT state = m_AutoHideState;
1921c2c66affSColin Finck 
1922c2c66affSColin Finck         GetCursorPos(&pt);
1923c2c66affSColin Finck         GetWindowRect(&rcCurrent);
1924c2c66affSColin Finck         over = PtInRect(&rcCurrent, pt);
1925c2c66affSColin Finck 
1926c2c66affSColin Finck         if (m_StartButton.SendMessage( BM_GETSTATE, 0, 0) != BST_UNCHECKED)
1927c2c66affSColin Finck         {
1928c2c66affSColin Finck             over = TRUE;
1929c2c66affSColin Finck         }
1930c2c66affSColin Finck 
1931c2c66affSColin Finck         if (over)
1932c2c66affSColin Finck         {
1933c2c66affSColin Finck             if (state == AUTOHIDE_HIDING)
1934c2c66affSColin Finck             {
1935c2c66affSColin Finck                 TRACE("AutoHide cancelling hide.\n");
1936c2c66affSColin Finck                 m_AutoHideState = AUTOHIDE_SHOWING;
1937c2c66affSColin Finck                 SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_INTERVAL_ANIMATING, NULL);
1938c2c66affSColin Finck             }
1939c2c66affSColin Finck             else if (state == AUTOHIDE_HIDDEN)
1940c2c66affSColin Finck             {
1941c2c66affSColin Finck                 TRACE("AutoHide starting show.\n");
1942c2c66affSColin Finck                 m_AutoHideState = AUTOHIDE_SHOWING;
1943c2c66affSColin Finck                 SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_DELAY_SHOW, NULL);
1944c2c66affSColin Finck             }
1945c2c66affSColin Finck         }
1946c2c66affSColin Finck         else
1947c2c66affSColin Finck         {
1948c2c66affSColin Finck             if (state == AUTOHIDE_SHOWING)
1949c2c66affSColin Finck             {
1950c2c66affSColin Finck                 TRACE("AutoHide cancelling show.\n");
1951c2c66affSColin Finck                 m_AutoHideState = AUTOHIDE_HIDING;
1952c2c66affSColin Finck                 SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_INTERVAL_ANIMATING, NULL);
1953c2c66affSColin Finck             }
1954c2c66affSColin Finck             else if (state == AUTOHIDE_SHOWN)
1955c2c66affSColin Finck             {
1956c2c66affSColin Finck                 TRACE("AutoHide starting hide.\n");
1957c2c66affSColin Finck                 m_AutoHideState = AUTOHIDE_HIDING;
1958c2c66affSColin Finck                 SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_DELAY_HIDE, NULL);
1959c2c66affSColin Finck             }
1960c2c66affSColin Finck 
1961c2c66affSColin Finck             KillTimer(TIMER_ID_MOUSETRACK);
1962c2c66affSColin Finck         }
1963c2c66affSColin Finck     }
1964c2c66affSColin Finck 
ProcessAutoHide()1965c2c66affSColin Finck     void ProcessAutoHide()
1966c2c66affSColin Finck     {
19674ed752e2SKatayama Hirofumi MZ         INT w = m_TraySize.cx - GetSystemMetrics(SM_CXSIZEFRAME);
19684ed752e2SKatayama Hirofumi MZ         INT h = m_TraySize.cy - GetSystemMetrics(SM_CYSIZEFRAME);
1969c2c66affSColin Finck 
1970c2c66affSColin Finck         switch (m_AutoHideState)
1971c2c66affSColin Finck         {
1972c2c66affSColin Finck         case AUTOHIDE_HIDING:
1973c2c66affSColin Finck             switch (m_Position)
1974c2c66affSColin Finck             {
1975c2c66affSColin Finck             case ABE_LEFT:
1976c2c66affSColin Finck                 m_AutoHideOffset.cy = 0;
1977c2c66affSColin Finck                 m_AutoHideOffset.cx -= AUTOHIDE_SPEED_HIDE;
1978c2c66affSColin Finck                 if (m_AutoHideOffset.cx < -w)
1979c3a4309dSJose Carlos Jesus                     m_AutoHideOffset.cx = w;
1980c2c66affSColin Finck                 break;
1981c2c66affSColin Finck             case ABE_TOP:
1982c2c66affSColin Finck                 m_AutoHideOffset.cx = 0;
1983c2c66affSColin Finck                 m_AutoHideOffset.cy -= AUTOHIDE_SPEED_HIDE;
1984c2c66affSColin Finck                 if (m_AutoHideOffset.cy < -h)
1985c3a4309dSJose Carlos Jesus                     m_AutoHideOffset.cy = h;
1986c2c66affSColin Finck                 break;
1987c2c66affSColin Finck             case ABE_RIGHT:
1988c2c66affSColin Finck                 m_AutoHideOffset.cy = 0;
1989c2c66affSColin Finck                 m_AutoHideOffset.cx += AUTOHIDE_SPEED_HIDE;
1990c2c66affSColin Finck                 if (m_AutoHideOffset.cx > w)
1991c2c66affSColin Finck                     m_AutoHideOffset.cx = w;
1992c2c66affSColin Finck                 break;
1993c2c66affSColin Finck             case ABE_BOTTOM:
1994c2c66affSColin Finck                 m_AutoHideOffset.cx = 0;
1995c2c66affSColin Finck                 m_AutoHideOffset.cy += AUTOHIDE_SPEED_HIDE;
1996c2c66affSColin Finck                 if (m_AutoHideOffset.cy > h)
1997c2c66affSColin Finck                     m_AutoHideOffset.cy = h;
1998c2c66affSColin Finck                 break;
1999c2c66affSColin Finck             }
2000c2c66affSColin Finck 
2001c2c66affSColin Finck             if (m_AutoHideOffset.cx != w && m_AutoHideOffset.cy != h)
2002c2c66affSColin Finck             {
2003c2c66affSColin Finck                 SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_INTERVAL_ANIMATING, NULL);
2004c2c66affSColin Finck                 break;
2005c2c66affSColin Finck             }
2006c2c66affSColin Finck 
2007c2c66affSColin Finck             /* fallthrough */
2008c2c66affSColin Finck         case AUTOHIDE_HIDDEN:
2009c2c66affSColin Finck 
2010c2c66affSColin Finck             switch (m_Position)
2011c2c66affSColin Finck             {
2012c2c66affSColin Finck             case ABE_LEFT:
2013c2c66affSColin Finck                 m_AutoHideOffset.cx = -w;
2014c2c66affSColin Finck                 m_AutoHideOffset.cy = 0;
2015c2c66affSColin Finck                 break;
2016c2c66affSColin Finck             case ABE_TOP:
2017c2c66affSColin Finck                 m_AutoHideOffset.cx = 0;
2018c2c66affSColin Finck                 m_AutoHideOffset.cy = -h;
2019c2c66affSColin Finck                 break;
2020c2c66affSColin Finck             case ABE_RIGHT:
2021c2c66affSColin Finck                 m_AutoHideOffset.cx = w;
2022c2c66affSColin Finck                 m_AutoHideOffset.cy = 0;
2023c2c66affSColin Finck                 break;
2024c2c66affSColin Finck             case ABE_BOTTOM:
2025c2c66affSColin Finck                 m_AutoHideOffset.cx = 0;
2026c2c66affSColin Finck                 m_AutoHideOffset.cy = h;
2027c2c66affSColin Finck                 break;
2028c2c66affSColin Finck             }
2029c2c66affSColin Finck 
2030c2c66affSColin Finck             KillTimer(TIMER_ID_AUTOHIDE);
2031c2c66affSColin Finck             m_AutoHideState = AUTOHIDE_HIDDEN;
2032c2c66affSColin Finck             break;
2033c2c66affSColin Finck 
2034c2c66affSColin Finck         case AUTOHIDE_SHOWING:
2035c2c66affSColin Finck             if (m_AutoHideOffset.cx >= AUTOHIDE_SPEED_SHOW)
2036c2c66affSColin Finck             {
2037c2c66affSColin Finck                 m_AutoHideOffset.cx -= AUTOHIDE_SPEED_SHOW;
2038c2c66affSColin Finck             }
2039c2c66affSColin Finck             else if (m_AutoHideOffset.cx <= -AUTOHIDE_SPEED_SHOW)
2040c2c66affSColin Finck             {
2041c2c66affSColin Finck                 m_AutoHideOffset.cx += AUTOHIDE_SPEED_SHOW;
2042c2c66affSColin Finck             }
2043c2c66affSColin Finck             else
2044c2c66affSColin Finck             {
2045c2c66affSColin Finck                 m_AutoHideOffset.cx = 0;
2046c2c66affSColin Finck             }
2047c2c66affSColin Finck 
2048c2c66affSColin Finck             if (m_AutoHideOffset.cy >= AUTOHIDE_SPEED_SHOW)
2049c2c66affSColin Finck             {
2050c2c66affSColin Finck                 m_AutoHideOffset.cy -= AUTOHIDE_SPEED_SHOW;
2051c2c66affSColin Finck             }
2052c2c66affSColin Finck             else if (m_AutoHideOffset.cy <= -AUTOHIDE_SPEED_SHOW)
2053c2c66affSColin Finck             {
2054c2c66affSColin Finck                 m_AutoHideOffset.cy += AUTOHIDE_SPEED_SHOW;
2055c2c66affSColin Finck             }
2056c2c66affSColin Finck             else
2057c2c66affSColin Finck             {
2058c2c66affSColin Finck                 m_AutoHideOffset.cy = 0;
2059c2c66affSColin Finck             }
2060c2c66affSColin Finck 
2061c2c66affSColin Finck             if (m_AutoHideOffset.cx != 0 || m_AutoHideOffset.cy != 0)
2062c2c66affSColin Finck             {
2063c2c66affSColin Finck                 SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_INTERVAL_ANIMATING, NULL);
2064c2c66affSColin Finck                 break;
2065c2c66affSColin Finck             }
2066c2c66affSColin Finck 
2067c2c66affSColin Finck             /* fallthrough */
2068c2c66affSColin Finck         case AUTOHIDE_SHOWN:
2069c2c66affSColin Finck 
2070c2c66affSColin Finck             KillTimer(TIMER_ID_AUTOHIDE);
2071c2c66affSColin Finck             m_AutoHideState = AUTOHIDE_SHOWN;
2072c2c66affSColin Finck             break;
2073c2c66affSColin Finck         }
2074c2c66affSColin Finck 
20754238f223SGiannis Adamopoulos         SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOZORDER);
2076c2c66affSColin Finck     }
2077c2c66affSColin Finck 
2078c2c66affSColin Finck 
2079c2c66affSColin Finck 
2080c2c66affSColin Finck 
2081c2c66affSColin Finck 
2082c2c66affSColin Finck     /**********************************************************
2083c2c66affSColin Finck      *    ##### taskbar drawing #####
2084c2c66affSColin Finck      */
2085c2c66affSColin Finck 
EraseBackgroundWithTheme(HDC hdc)2086c2c66affSColin Finck     LRESULT EraseBackgroundWithTheme(HDC hdc)
2087c2c66affSColin Finck     {
2088c2c66affSColin Finck         RECT rect;
2089c2c66affSColin Finck         int iSBkgndPart[4] = {TBP_BACKGROUNDLEFT, TBP_BACKGROUNDTOP, TBP_BACKGROUNDRIGHT, TBP_BACKGROUNDBOTTOM};
2090c2c66affSColin Finck 
2091c2c66affSColin Finck         ASSERT(m_Position <= ABE_BOTTOM);
2092c2c66affSColin Finck 
2093c2c66affSColin Finck         if (m_Theme)
2094c2c66affSColin Finck         {
2095c2c66affSColin Finck             GetClientRect(&rect);
2096c2c66affSColin Finck             DrawThemeBackground(m_Theme, hdc, iSBkgndPart[m_Position], 0, &rect, 0);
2097c2c66affSColin Finck         }
2098c2c66affSColin Finck 
2099c2c66affSColin Finck         return 0;
2100c2c66affSColin Finck     }
2101c2c66affSColin Finck 
DrawSizerWithTheme(IN HRGN hRgn)2102c2c66affSColin Finck     int DrawSizerWithTheme(IN HRGN hRgn)
2103c2c66affSColin Finck     {
2104c2c66affSColin Finck         HDC hdc;
2105c2c66affSColin Finck         RECT rect;
2106c2c66affSColin Finck         int iSizerPart[4] = {TBP_SIZINGBARLEFT, TBP_SIZINGBARTOP, TBP_SIZINGBARRIGHT, TBP_SIZINGBARBOTTOM};
2107c2c66affSColin Finck         SIZE size;
2108c2c66affSColin Finck 
2109c2c66affSColin Finck         ASSERT(m_Position <= ABE_BOTTOM);
2110c2c66affSColin Finck 
2111c2c66affSColin Finck         HRESULT hr = GetThemePartSize(m_Theme, NULL, iSizerPart[m_Position], 0, NULL, TS_TRUE, &size);
2112c2c66affSColin Finck         if (FAILED_UNEXPECTEDLY(hr))
2113c2c66affSColin Finck             return 0;
2114c2c66affSColin Finck 
2115c2c66affSColin Finck         GetWindowRect(&rect);
2116c2c66affSColin Finck         OffsetRect(&rect, -rect.left, -rect.top);
2117c2c66affSColin Finck 
2118c2c66affSColin Finck         hdc = GetWindowDC();
2119c2c66affSColin Finck 
2120c2c66affSColin Finck         switch (m_Position)
2121c2c66affSColin Finck         {
2122c2c66affSColin Finck         case ABE_LEFT:
2123c2c66affSColin Finck             rect.left = rect.right - size.cx;
2124c2c66affSColin Finck             break;
2125c2c66affSColin Finck         case ABE_TOP:
2126c2c66affSColin Finck             rect.top = rect.bottom - size.cy;
2127c2c66affSColin Finck             break;
2128c2c66affSColin Finck         case ABE_RIGHT:
2129c2c66affSColin Finck             rect.right = rect.left + size.cx;
2130c2c66affSColin Finck             break;
2131c2c66affSColin Finck         case ABE_BOTTOM:
2132c2c66affSColin Finck         default:
2133c2c66affSColin Finck             rect.bottom = rect.top + size.cy;
2134c2c66affSColin Finck             break;
2135c2c66affSColin Finck         }
2136c2c66affSColin Finck 
2137c2c66affSColin Finck         DrawThemeBackground(m_Theme, hdc, iSizerPart[m_Position], 0, &rect, 0);
2138c2c66affSColin Finck 
2139c2c66affSColin Finck         ReleaseDC(hdc);
2140c2c66affSColin Finck         return 0;
2141c2c66affSColin Finck     }
2142c2c66affSColin Finck 
2143c2c66affSColin Finck 
2144c2c66affSColin Finck 
2145c2c66affSColin Finck 
2146c2c66affSColin Finck 
2147c2c66affSColin Finck     /*
2148c2c66affSColin Finck      * ITrayWindow
2149c2c66affSColin Finck      */
Open()2150c2c66affSColin Finck     HRESULT STDMETHODCALLTYPE Open()
2151c2c66affSColin Finck     {
2152c2c66affSColin Finck         RECT rcWnd;
2153c2c66affSColin Finck 
2154c2c66affSColin Finck         /* Check if there's already a window created and try to show it.
2155c2c66affSColin Finck            If it was somehow destroyed just create a new tray window. */
2156c2c66affSColin Finck         if (m_hWnd != NULL && IsWindow())
2157c2c66affSColin Finck         {
2158c2c66affSColin Finck             return S_OK;
2159c2c66affSColin Finck         }
2160c2c66affSColin Finck 
2161c2c66affSColin Finck         DWORD dwExStyle = WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE;
21622ed535daSGiannis Adamopoulos         if (g_TaskbarSettings.sr.AlwaysOnTop)
2163c2c66affSColin Finck             dwExStyle |= WS_EX_TOPMOST;
2164c2c66affSColin Finck 
2165c2c66affSColin Finck         DWORD dwStyle = WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
2166c2c66affSColin Finck         if(!m_Theme)
2167c2c66affSColin Finck         {
2168c2c66affSColin Finck             dwStyle |= WS_THICKFRAME | WS_BORDER;
2169c2c66affSColin Finck         }
2170c2c66affSColin Finck 
2171c2c66affSColin Finck         ZeroMemory(&rcWnd, sizeof(rcWnd));
2172c2c66affSColin Finck         if (m_Position != (DWORD) -1)
2173c2c66affSColin Finck             rcWnd = m_TrayRects[m_Position];
2174c2c66affSColin Finck 
2175c2c66affSColin Finck         if (!Create(NULL, rcWnd, NULL, dwStyle, dwExStyle))
2176c2c66affSColin Finck             return E_FAIL;
2177c2c66affSColin Finck 
2178c2c66affSColin Finck         /* Align all controls on the tray window */
2179c2c66affSColin Finck         AlignControls(NULL);
2180c2c66affSColin Finck 
2181c2c66affSColin Finck         /* Move the tray window to the right position and resize it if necessary */
2182c2c66affSColin Finck         CheckTrayWndPosition();
2183c2c66affSColin Finck 
2184c2c66affSColin Finck         return S_OK;
2185c2c66affSColin Finck     }
2186c2c66affSColin Finck 
Close()2187c2c66affSColin Finck     HRESULT STDMETHODCALLTYPE Close()
2188c2c66affSColin Finck     {
2189c2c66affSColin Finck         if (m_hWnd != NULL)
2190c2c66affSColin Finck         {
2191c2c66affSColin Finck             SendMessage(m_hWnd,
2192c2c66affSColin Finck                         WM_APP_TRAYDESTROY,
2193c2c66affSColin Finck                         0,
2194c2c66affSColin Finck                         0);
2195c2c66affSColin Finck         }
2196c2c66affSColin Finck 
2197c2c66affSColin Finck         return S_OK;
2198c2c66affSColin Finck     }
2199c2c66affSColin Finck 
GetHWND()2200c2c66affSColin Finck     HWND STDMETHODCALLTYPE GetHWND()
2201c2c66affSColin Finck     {
2202c2c66affSColin Finck         return m_hWnd;
2203c2c66affSColin Finck     }
2204c2c66affSColin Finck 
IsSpecialHWND(IN HWND hWnd)2205c2c66affSColin Finck     BOOL STDMETHODCALLTYPE IsSpecialHWND(IN HWND hWnd)
2206c2c66affSColin Finck     {
2207c2c66affSColin Finck         return (m_hWnd == hWnd ||
2208c2c66affSColin Finck                 (m_DesktopWnd != NULL && m_hWnd == m_DesktopWnd));
2209c2c66affSColin Finck     }
2210c2c66affSColin Finck 
IsHorizontal()2211c2c66affSColin Finck     BOOL STDMETHODCALLTYPE IsHorizontal()
2212c2c66affSColin Finck     {
2213c2c66affSColin Finck         return IsPosHorizontal();
2214c2c66affSColin Finck     }
2215c2c66affSColin Finck 
Lock(IN BOOL bLock)2216c2c66affSColin Finck     BOOL STDMETHODCALLTYPE Lock(IN BOOL bLock)
2217c2c66affSColin Finck     {
22182ed535daSGiannis Adamopoulos         BOOL bPrevLock = g_TaskbarSettings.bLock;
2219c2c66affSColin Finck 
22202ed535daSGiannis Adamopoulos         if (g_TaskbarSettings.bLock != bLock)
2221c2c66affSColin Finck         {
22222ed535daSGiannis Adamopoulos             g_TaskbarSettings.bLock = bLock;
2223c2c66affSColin Finck 
2224c2c66affSColin Finck             if (m_TrayBandSite != NULL)
2225c2c66affSColin Finck             {
2226c2c66affSColin Finck                 if (!SUCCEEDED(m_TrayBandSite->Lock(bLock)))
2227c2c66affSColin Finck                 {
2228c2c66affSColin Finck                     /* Reset?? */
22292ed535daSGiannis Adamopoulos                     g_TaskbarSettings.bLock = bPrevLock;
2230c2c66affSColin Finck                     return bPrevLock;
2231c2c66affSColin Finck                 }
2232c2c66affSColin Finck             }
2233c2c66affSColin Finck 
2234c2c66affSColin Finck             if (m_Theme)
2235c2c66affSColin Finck             {
2236c2c66affSColin Finck                 /* Update cached tray sizes */
2237c2c66affSColin Finck                 for(DWORD Pos = ABE_LEFT; Pos <= ABE_BOTTOM; Pos++)
2238c2c66affSColin Finck                 {
2239c2c66affSColin Finck                     RECT rcGripper = {0};
2240c2c66affSColin Finck                     AdjustSizerRect(&rcGripper, Pos);
2241c2c66affSColin Finck 
22422ed535daSGiannis Adamopoulos                     if(g_TaskbarSettings.bLock)
2243c2c66affSColin Finck                     {
2244c2c66affSColin Finck                         m_TrayRects[Pos].top += rcGripper.top;
2245c2c66affSColin Finck                         m_TrayRects[Pos].left += rcGripper.left;
2246c2c66affSColin Finck                         m_TrayRects[Pos].bottom += rcGripper.bottom;
2247c2c66affSColin Finck                         m_TrayRects[Pos].right += rcGripper.right;
2248c2c66affSColin Finck                     }
2249c2c66affSColin Finck                     else
2250c2c66affSColin Finck                     {
2251c2c66affSColin Finck                         m_TrayRects[Pos].top -= rcGripper.top;
2252c2c66affSColin Finck                         m_TrayRects[Pos].left -= rcGripper.left;
2253c2c66affSColin Finck                         m_TrayRects[Pos].bottom -= rcGripper.bottom;
2254c2c66affSColin Finck                         m_TrayRects[Pos].right -= rcGripper.right;
2255c2c66affSColin Finck                     }
2256c2c66affSColin Finck                 }
2257c2c66affSColin Finck             }
2258c2c66affSColin Finck             SetWindowPos(NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER);
2259c2c66affSColin Finck             ResizeWorkArea();
2260c2c66affSColin Finck             ApplyClipping(TRUE);
2261c2c66affSColin Finck         }
2262c2c66affSColin Finck 
2263c2c66affSColin Finck         return bPrevLock;
2264c2c66affSColin Finck     }
2265c2c66affSColin Finck 
2266e6bced7aSKatayama Hirofumi MZ     /* The task window is visible and non-WS_EX_TOOLWINDOW and
2267e6bced7aSKatayama Hirofumi MZ        { has WS_EX_APPWINDOW style or has no owner } and is none of explorer's
2268e6bced7aSKatayama Hirofumi MZ        special windows (such as the desktop or the tray window) */
IsTaskWnd(HWND hWnd)2269e6bced7aSKatayama Hirofumi MZ     BOOL STDMETHODCALLTYPE IsTaskWnd(HWND hWnd)
2270e6bced7aSKatayama Hirofumi MZ     {
2271e6bced7aSKatayama Hirofumi MZ         if (::IsWindow(hWnd) && ::IsWindowVisible(hWnd) && !IsSpecialHWND(hWnd))
2272e6bced7aSKatayama Hirofumi MZ         {
2273e6bced7aSKatayama Hirofumi MZ             DWORD exStyle = (DWORD)::GetWindowLongPtr(hWnd, GWL_EXSTYLE);
2274e6bced7aSKatayama Hirofumi MZ             if (((exStyle & WS_EX_APPWINDOW) || ::GetWindow(hWnd, GW_OWNER) == NULL) &&
2275e6bced7aSKatayama Hirofumi MZ                 !(exStyle & WS_EX_TOOLWINDOW))
2276e6bced7aSKatayama Hirofumi MZ             {
2277e6bced7aSKatayama Hirofumi MZ                 return TRUE;
2278e6bced7aSKatayama Hirofumi MZ             }
2279e6bced7aSKatayama Hirofumi MZ         }
2280e6bced7aSKatayama Hirofumi MZ         return FALSE;
2281e6bced7aSKatayama Hirofumi MZ     }
2282c2c66affSColin Finck 
2283c2c66affSColin Finck     /*
2284c2c66affSColin Finck      *  IContextMenu
2285c2c66affSColin Finck      */
QueryContextMenu(HMENU hPopup,UINT indexMenu,UINT idCmdFirst,UINT idCmdLast,UINT uFlags)2286c2c66affSColin Finck     HRESULT STDMETHODCALLTYPE QueryContextMenu(HMENU hPopup,
2287c2c66affSColin Finck                                                UINT indexMenu,
2288c2c66affSColin Finck                                                UINT idCmdFirst,
2289c2c66affSColin Finck                                                UINT idCmdLast,
2290c2c66affSColin Finck                                                UINT uFlags)
2291c2c66affSColin Finck     {
2292c2c66affSColin Finck         if (!m_ContextMenu)
2293c2c66affSColin Finck         {
2294c2c66affSColin Finck             HRESULT hr = TrayWindowCtxMenuCreator(this, m_hWnd, &m_ContextMenu);
2295c2c66affSColin Finck             if (FAILED_UNEXPECTEDLY(hr))
2296c2c66affSColin Finck                 return hr;
2297c2c66affSColin Finck         }
2298c2c66affSColin Finck 
2299c2c66affSColin Finck         return m_ContextMenu->QueryContextMenu(hPopup, indexMenu, idCmdFirst, idCmdLast, uFlags);
2300c2c66affSColin Finck     }
2301c2c66affSColin Finck 
InvokeCommand(LPCMINVOKECOMMANDINFO lpici)2302c2c66affSColin Finck     HRESULT STDMETHODCALLTYPE InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
2303c2c66affSColin Finck     {
2304c2c66affSColin Finck         if (!m_ContextMenu)
2305c2c66affSColin Finck             return E_INVALIDARG;
2306c2c66affSColin Finck 
2307c2c66affSColin Finck         return m_ContextMenu->InvokeCommand(lpici);
2308c2c66affSColin Finck     }
2309c2c66affSColin Finck 
GetCommandString(UINT_PTR idCmd,UINT uType,UINT * pwReserved,LPSTR pszName,UINT cchMax)2310c2c66affSColin Finck     HRESULT STDMETHODCALLTYPE GetCommandString(UINT_PTR idCmd,
2311c2c66affSColin Finck                                                UINT uType,
2312c2c66affSColin Finck                                                UINT *pwReserved,
2313c2c66affSColin Finck                                                LPSTR pszName,
2314c2c66affSColin Finck                                                UINT cchMax)
2315c2c66affSColin Finck     {
2316c2c66affSColin Finck         if (!m_ContextMenu)
2317c2c66affSColin Finck             return E_INVALIDARG;
2318c2c66affSColin Finck 
2319c2c66affSColin Finck         return m_ContextMenu->GetCommandString(idCmd, uType, pwReserved, pszName, cchMax);
2320c2c66affSColin Finck     }
2321c2c66affSColin Finck 
2322c2c66affSColin Finck     /**********************************************************
2323c2c66affSColin Finck      *    ##### message handling #####
2324c2c66affSColin Finck      */
2325c2c66affSColin Finck 
OnCreate(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)2326c2c66affSColin Finck     LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2327c2c66affSColin Finck     {
2328c2c66affSColin Finck         HRESULT hRet;
2329c2c66affSColin Finck 
2330c2c66affSColin Finck         ((ITrayWindow*)this)->AddRef();
2331c2c66affSColin Finck 
2332c2c66affSColin Finck         SetWindowTheme(m_hWnd, L"TaskBar", NULL);
2333c2c66affSColin Finck 
2334c2c66affSColin Finck         /* Create the Start button */
2335c2c66affSColin Finck         m_StartButton.Create(m_hWnd);
2336c2c66affSColin Finck 
2337c2c66affSColin Finck         /* Load the saved tray window settings */
2338c2c66affSColin Finck         RegLoadSettings();
2339c2c66affSColin Finck 
2340c2c66affSColin Finck         /* Create and initialize the start menu */
2341c2c66affSColin Finck         HBITMAP hbmBanner = LoadBitmapW(hExplorerInstance, MAKEINTRESOURCEW(IDB_STARTMENU));
234217b0623cSKatayama Hirofumi MZ         m_StartMenuPopup = CreateStartMenu(this, &m_StartMenuBand, hbmBanner,
234317b0623cSKatayama Hirofumi MZ                                            g_TaskbarSettings.sr.SmSmallIcons);
2344c2c66affSColin Finck 
2345c2c66affSColin Finck         /* Create the task band */
2346c2c66affSColin Finck         hRet = CTaskBand_CreateInstance(this, m_StartButton.m_hWnd, IID_PPV_ARG(IDeskBand, &m_TaskBand));
2347c2c66affSColin Finck         if (FAILED_UNEXPECTEDLY(hRet))
2348c2c66affSColin Finck             return FALSE;
2349c2c66affSColin Finck 
2350c2c66affSColin Finck         /* Create the rebar band site. This actually creates the rebar and the tasks toolbar. */
2351c2c66affSColin Finck         hRet = CTrayBandSite_CreateInstance(this, m_TaskBand, &m_TrayBandSite);
2352c2c66affSColin Finck         if (FAILED_UNEXPECTEDLY(hRet))
2353c2c66affSColin Finck             return FALSE;
2354c2c66affSColin Finck 
2355455bce68SGiannis Adamopoulos         /* Create the tray notification window */
2356455bce68SGiannis Adamopoulos         hRet = CTrayNotifyWnd_CreateInstance(m_hWnd, IID_PPV_ARG(IUnknown, &m_TrayNotifyInstance));
2357455bce68SGiannis Adamopoulos         if (FAILED_UNEXPECTEDLY(hRet))
2358455bce68SGiannis Adamopoulos             return FALSE;
2359455bce68SGiannis Adamopoulos 
2360c2c66affSColin Finck         /* Get the hwnd of the rebar */
2361c2c66affSColin Finck         hRet = IUnknown_GetWindow(m_TrayBandSite, &m_Rebar);
2362c2c66affSColin Finck         if (FAILED_UNEXPECTEDLY(hRet))
2363c2c66affSColin Finck             return FALSE;
2364c2c66affSColin Finck 
2365c2c66affSColin Finck         /* Get the hwnd of the tasks toolbar */
2366c2c66affSColin Finck         hRet = IUnknown_GetWindow(m_TaskBand, &m_TaskSwitch);
2367c2c66affSColin Finck         if (FAILED_UNEXPECTEDLY(hRet))
2368c2c66affSColin Finck             return FALSE;
2369c2c66affSColin Finck 
2370455bce68SGiannis Adamopoulos         /* Get the hwnd of the tray notification window */
2371455bce68SGiannis Adamopoulos         hRet = IUnknown_GetWindow(m_TrayNotifyInstance, &m_TrayNotify);
2372455bce68SGiannis Adamopoulos         if (FAILED_UNEXPECTEDLY(hRet))
2373455bce68SGiannis Adamopoulos             return FALSE;
2374c2c66affSColin Finck 
237570d7009aSEthan Rodensky         ::SendMessage(m_TrayNotify, TNWM_GETSHOWDESKTOPBUTTON, (WPARAM)&m_pShowDesktopButton, 0);
237670d7009aSEthan Rodensky         if (!m_pShowDesktopButton)
237770d7009aSEthan Rodensky             return FALSE;
237870d7009aSEthan Rodensky 
2379455bce68SGiannis Adamopoulos         SetWindowTheme(m_Rebar, L"TaskBar", NULL);
2380c2c66affSColin Finck 
2381c2c66affSColin Finck         UpdateFonts();
2382c2c66affSColin Finck 
2383c2c66affSColin Finck         InitShellServices(&m_ShellServices);
2384c2c66affSColin Finck 
23852ed535daSGiannis Adamopoulos         if (g_TaskbarSettings.sr.AutoHide)
2386c2c66affSColin Finck         {
2387c2c66affSColin Finck             m_AutoHideState = AUTOHIDE_HIDING;
2388c2c66affSColin Finck             SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_DELAY_HIDE, NULL);
2389c2c66affSColin Finck         }
2390c2c66affSColin Finck 
2391b95fff5bSGiannis Adamopoulos         /* Set the initial lock state in the band site */
2392b95fff5bSGiannis Adamopoulos         m_TrayBandSite->Lock(g_TaskbarSettings.bLock);
2393b95fff5bSGiannis Adamopoulos 
2394c2c66affSColin Finck         RegisterHotKey(m_hWnd, IDHK_RUN, MOD_WIN, 'R');
2395c2c66affSColin Finck         RegisterHotKey(m_hWnd, IDHK_MINIMIZE_ALL, MOD_WIN, 'M');
2396c2c66affSColin Finck         RegisterHotKey(m_hWnd, IDHK_RESTORE_ALL, MOD_WIN|MOD_SHIFT, 'M');
2397c2c66affSColin Finck         RegisterHotKey(m_hWnd, IDHK_HELP, MOD_WIN, VK_F1);
2398c2c66affSColin Finck         RegisterHotKey(m_hWnd, IDHK_EXPLORE, MOD_WIN, 'E');
2399c2c66affSColin Finck         RegisterHotKey(m_hWnd, IDHK_FIND, MOD_WIN, 'F');
2400c2c66affSColin Finck         RegisterHotKey(m_hWnd, IDHK_FIND_COMPUTER, MOD_WIN|MOD_CONTROL, 'F');
2401c2c66affSColin Finck         RegisterHotKey(m_hWnd, IDHK_NEXT_TASK, MOD_WIN, VK_TAB);
2402c2c66affSColin Finck         RegisterHotKey(m_hWnd, IDHK_PREV_TASK, MOD_WIN|MOD_SHIFT, VK_TAB);
2403c2c66affSColin Finck         RegisterHotKey(m_hWnd, IDHK_SYS_PROPERTIES, MOD_WIN, VK_PAUSE);
2404c2c66affSColin Finck         RegisterHotKey(m_hWnd, IDHK_DESKTOP, MOD_WIN, 'D');
2405c2c66affSColin Finck         RegisterHotKey(m_hWnd, IDHK_PAGER, MOD_WIN, 'B');
2406c2c66affSColin Finck 
2407c2c66affSColin Finck         return TRUE;
2408c2c66affSColin Finck     }
2409c2c66affSColin Finck 
2410e6bced7aSKatayama Hirofumi MZ #define TIMER_ID_IGNOREPULSERESET 888
2411e6bced7aSKatayama Hirofumi MZ #define TIMER_IGNOREPULSERESET_TIMEOUT 200
2412e6bced7aSKatayama Hirofumi MZ 
OnDestroy(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)2413e6bced7aSKatayama Hirofumi MZ     LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2414e6bced7aSKatayama Hirofumi MZ     {
2415e6bced7aSKatayama Hirofumi MZ         KillTimer(TIMER_ID_IGNOREPULSERESET);
2416e6bced7aSKatayama Hirofumi MZ         return 0;
2417e6bced7aSKatayama Hirofumi MZ     }
2418e6bced7aSKatayama Hirofumi MZ 
OnEndSession(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)2419802dc971SWhindmar Saksit     LRESULT OnEndSession(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2420802dc971SWhindmar Saksit     {
2421802dc971SWhindmar Saksit         if (wParam)
2422802dc971SWhindmar Saksit             SaveState();
2423802dc971SWhindmar Saksit         return 0;
2424802dc971SWhindmar Saksit     }
2425802dc971SWhindmar Saksit 
OnThemeChanged(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)2426c2c66affSColin Finck     LRESULT OnThemeChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2427c2c66affSColin Finck     {
2428c2c66affSColin Finck         if (m_Theme)
2429c2c66affSColin Finck             CloseThemeData(m_Theme);
2430c2c66affSColin Finck 
2431c2c66affSColin Finck         m_Theme = OpenThemeData(m_hWnd, L"TaskBar");
2432c2c66affSColin Finck 
2433c2c66affSColin Finck         if (m_Theme)
2434c2c66affSColin Finck         {
2435c2c66affSColin Finck             SetWindowStyle(m_hWnd, WS_THICKFRAME | WS_BORDER, 0);
2436c2c66affSColin Finck         }
2437c2c66affSColin Finck         else
2438c2c66affSColin Finck         {
2439c2c66affSColin Finck             SetWindowStyle(m_hWnd, WS_THICKFRAME | WS_BORDER, WS_THICKFRAME | WS_BORDER);
2440c2c66affSColin Finck         }
2441c2c66affSColin Finck         SetWindowPos(NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER);
2442c2c66affSColin Finck 
2443c2c66affSColin Finck         return TRUE;
2444c2c66affSColin Finck     }
2445c2c66affSColin Finck 
OnSettingChanged(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)2446c2c66affSColin Finck     LRESULT OnSettingChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2447c2c66affSColin Finck     {
2448c2c66affSColin Finck         if (wParam == SPI_SETNONCLIENTMETRICS)
2449c2c66affSColin Finck         {
2450c2c66affSColin Finck             SendMessage(m_TrayNotify, uMsg, wParam, lParam);
2451c2c66affSColin Finck             SendMessage(m_TaskSwitch, uMsg, wParam, lParam);
2452c2c66affSColin Finck             UpdateFonts();
2453c2c66affSColin Finck             AlignControls(NULL);
2454c2c66affSColin Finck             CheckTrayWndPosition();
2455c2c66affSColin Finck         }
2456c2c66affSColin Finck 
2457d1ac33a9SKatayama Hirofumi MZ         if (m_StartMenuPopup && lstrcmpiW((LPCWSTR)lParam, L"TraySettings") == 0)
2458d1ac33a9SKatayama Hirofumi MZ         {
2459d1ac33a9SKatayama Hirofumi MZ             HideStartMenu();
2460ad748b0bSKatayama Hirofumi MZ 
2461d1ac33a9SKatayama Hirofumi MZ             HBITMAP hbmBanner = LoadBitmapW(hExplorerInstance, MAKEINTRESOURCEW(IDB_STARTMENU));
246217b0623cSKatayama Hirofumi MZ #if 1 // FIXME: Please re-use the start menu
246317b0623cSKatayama Hirofumi MZ             /* Re-create the start menu */
246417b0623cSKatayama Hirofumi MZ             m_StartMenuBand.Release();
246517b0623cSKatayama Hirofumi MZ             m_StartMenuPopup = CreateStartMenu(this, &m_StartMenuBand, hbmBanner,
246617b0623cSKatayama Hirofumi MZ                                                g_TaskbarSettings.sr.SmSmallIcons);
246717b0623cSKatayama Hirofumi MZ             FIXME("Use UpdateStartMenu\n");
246817b0623cSKatayama Hirofumi MZ #else
246917b0623cSKatayama Hirofumi MZ             // Update the start menu
247017b0623cSKatayama Hirofumi MZ             UpdateStartMenu(m_StartMenuPopup, hbmBanner, g_TaskbarSettings.sr.SmSmallIcons, TRUE);
247117b0623cSKatayama Hirofumi MZ #endif
2472d1ac33a9SKatayama Hirofumi MZ         }
2473d1ac33a9SKatayama Hirofumi MZ 
2474c2c66affSColin Finck         return 0;
2475c2c66affSColin Finck     }
2476c2c66affSColin Finck 
OnEraseBackground(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)2477c2c66affSColin Finck     LRESULT OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2478c2c66affSColin Finck     {
2479c2c66affSColin Finck         HDC hdc = (HDC) wParam;
2480c2c66affSColin Finck 
2481c2c66affSColin Finck         if (!m_Theme)
2482c2c66affSColin Finck         {
2483c2c66affSColin Finck             bHandled = FALSE;
2484c2c66affSColin Finck             return 0;
2485c2c66affSColin Finck         }
2486c2c66affSColin Finck 
2487c2c66affSColin Finck         return EraseBackgroundWithTheme(hdc);
2488c2c66affSColin Finck     }
2489c2c66affSColin Finck 
OnDisplayChange(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)2490c2c66affSColin Finck     LRESULT OnDisplayChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2491c2c66affSColin Finck     {
2492c2c66affSColin Finck         /* Load the saved tray window settings */
2493c2c66affSColin Finck         RegLoadSettings();
2494c2c66affSColin Finck 
2495c2c66affSColin Finck         /* Move the tray window to the right position and resize it if necessary */
2496c2c66affSColin Finck         CheckTrayWndPosition();
2497c2c66affSColin Finck 
2498c2c66affSColin Finck         return TRUE;
2499c2c66affSColin Finck     }
2500c2c66affSColin Finck 
OnCopyData(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)2501c2c66affSColin Finck     LRESULT OnCopyData(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2502c2c66affSColin Finck     {
250322ab8c81SKatayama Hirofumi MZ         COPYDATASTRUCT *pCopyData = (COPYDATASTRUCT *)lParam;
25041c400705SKatayama Hirofumi MZ         switch (pCopyData->dwData)
25051c400705SKatayama Hirofumi MZ         {
25061c400705SKatayama Hirofumi MZ             case TABDMC_APPBAR:
25071c400705SKatayama Hirofumi MZ                 return appbar_message(pCopyData);
25081c400705SKatayama Hirofumi MZ             case TABDMC_NOTIFY:
25091c400705SKatayama Hirofumi MZ             case TABDMC_LOADINPROC:
25101c400705SKatayama Hirofumi MZ                 return ::SendMessageW(m_TrayNotify, uMsg, wParam, lParam);
25111c400705SKatayama Hirofumi MZ         }
25121c400705SKatayama Hirofumi MZ         return FALSE;
2513c2c66affSColin Finck     }
2514c2c66affSColin Finck 
251526efda4dSKatayama Hirofumi MZ     // We have to draw non-client area because the 'Show Desktop' button is beyond client area.
DrawShowDesktopButton()251626efda4dSKatayama Hirofumi MZ     void DrawShowDesktopButton()
251726efda4dSKatayama Hirofumi MZ     {
251870d7009aSEthan Rodensky         if (!m_pShowDesktopButton || !m_pShowDesktopButton->IsWindow())
2519ba2cead8SKatayama Hirofumi MZ             return;
252070d7009aSEthan Rodensky         ::RedrawWindow(m_TrayNotify, NULL, NULL, RDW_INVALIDATE | RDW_ERASENOW | RDW_UPDATENOW);
252126efda4dSKatayama Hirofumi MZ     }
252226efda4dSKatayama Hirofumi MZ 
OnNcPaint(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)2523c2c66affSColin Finck     LRESULT OnNcPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2524c2c66affSColin Finck     {
252526efda4dSKatayama Hirofumi MZ         DefWindowProc(uMsg, wParam, lParam);
252626efda4dSKatayama Hirofumi MZ         bHandled = TRUE;
252726efda4dSKatayama Hirofumi MZ 
252826efda4dSKatayama Hirofumi MZ         if (!m_Theme || g_TaskbarSettings.bLock)
2529c2c66affSColin Finck         {
253026efda4dSKatayama Hirofumi MZ             DrawShowDesktopButton(); // We have to draw non-client area
2531c54c5ebbSGiannis Adamopoulos             return 0;
2532c54c5ebbSGiannis Adamopoulos         }
2533c2c66affSColin Finck 
253426efda4dSKatayama Hirofumi MZ         DrawSizerWithTheme((HRGN) wParam);
253526efda4dSKatayama Hirofumi MZ         DrawShowDesktopButton(); // We have to draw non-client area
253626efda4dSKatayama Hirofumi MZ         return 0;
2537c2c66affSColin Finck     }
2538c2c66affSColin Finck 
OnCtlColorBtn(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)2539c2c66affSColin Finck     LRESULT OnCtlColorBtn(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2540c2c66affSColin Finck     {
2541c2c66affSColin Finck         SetBkMode((HDC) wParam, TRANSPARENT);
2542c2c66affSColin Finck         return (LRESULT) GetStockObject(HOLLOW_BRUSH);
2543c2c66affSColin Finck     }
2544c2c66affSColin Finck 
OnSysColorChange(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)2545*751641c2SWhindmar Saksit     LRESULT OnSysColorChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2546*751641c2SWhindmar Saksit     {
2547*751641c2SWhindmar Saksit         return SendMessageW(m_Rebar, uMsg, wParam, lParam);
2548*751641c2SWhindmar Saksit     }
2549*751641c2SWhindmar Saksit 
OnNcHitTest(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)2550c2c66affSColin Finck     LRESULT OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2551c2c66affSColin Finck     {
2552c2c66affSColin Finck         RECT rcClient;
2553c2c66affSColin Finck         POINT pt;
2554c2c66affSColin Finck 
25552ed535daSGiannis Adamopoulos         if (g_TaskbarSettings.bLock)
2556c2c66affSColin Finck         {
2557c2c66affSColin Finck             /* The user may not be able to resize the tray window.
2558c2c66affSColin Finck             Pretend like the window is not sizeable when the user
2559c2c66affSColin Finck             clicks on the border. */
2560c2c66affSColin Finck             return HTBORDER;
2561c2c66affSColin Finck         }
2562c2c66affSColin Finck 
2563c2c66affSColin Finck         SetLastError(ERROR_SUCCESS);
2564c2c66affSColin Finck         if (GetClientRect(&rcClient) &&
2565c2c66affSColin Finck             (MapWindowPoints(NULL, (LPPOINT) &rcClient, 2) != 0 || GetLastError() == ERROR_SUCCESS))
2566c2c66affSColin Finck         {
256770d7009aSEthan Rodensky             pt.x = GET_X_LPARAM(lParam);
256870d7009aSEthan Rodensky             pt.y = GET_Y_LPARAM(lParam);
256970d7009aSEthan Rodensky 
257070d7009aSEthan Rodensky             if (m_pShowDesktopButton && ::IsWindow(m_pShowDesktopButton->m_hWnd) && m_pShowDesktopButton->PtInButton(&pt))
257170d7009aSEthan Rodensky                 return HTBORDER;
2572c2c66affSColin Finck 
2573eff4c213SHermès Bélusca-Maïto             if (PtInRect(&rcClient, pt))
2574c2c66affSColin Finck             {
2575c2c66affSColin Finck                 /* The user is trying to drag the tray window */
2576c2c66affSColin Finck                 return HTCAPTION;
2577c2c66affSColin Finck             }
2578c2c66affSColin Finck 
2579c2c66affSColin Finck             /* Depending on the position of the tray window, allow only
2580c2c66affSColin Finck             changing the border next to the monitor working area */
2581c2c66affSColin Finck             switch (m_Position)
2582c2c66affSColin Finck             {
2583c2c66affSColin Finck             case ABE_TOP:
2584c2c66affSColin Finck                 if (pt.y > rcClient.bottom)
2585c2c66affSColin Finck                     return HTBOTTOM;
2586c2c66affSColin Finck                 break;
2587c2c66affSColin Finck             case ABE_LEFT:
2588c2c66affSColin Finck                 if (pt.x > rcClient.right)
2589c2c66affSColin Finck                     return HTRIGHT;
2590c2c66affSColin Finck                 break;
2591c2c66affSColin Finck             case ABE_RIGHT:
2592c2c66affSColin Finck                 if (pt.x < rcClient.left)
2593c2c66affSColin Finck                     return HTLEFT;
2594c2c66affSColin Finck                 break;
2595c2c66affSColin Finck             case ABE_BOTTOM:
2596c2c66affSColin Finck             default:
2597c2c66affSColin Finck                 if (pt.y < rcClient.top)
2598c2c66affSColin Finck                     return HTTOP;
2599c2c66affSColin Finck                 break;
2600c2c66affSColin Finck             }
2601c2c66affSColin Finck         }
2602c2c66affSColin Finck         return HTBORDER;
2603c2c66affSColin Finck     }
2604c2c66affSColin Finck 
OnMoving(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)2605c2c66affSColin Finck     LRESULT OnMoving(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2606c2c66affSColin Finck     {
2607c2c66affSColin Finck         POINT ptCursor;
2608c2c66affSColin Finck         PRECT pRect = (PRECT) lParam;
2609c2c66affSColin Finck 
2610c2c66affSColin Finck         /* We need to ensure that an application can not accidently
2611c2c66affSColin Finck         move the tray window (using SetWindowPos). However, we still
2612c2c66affSColin Finck         need to be able to move the window in case the user wants to
2613c2c66affSColin Finck         drag the tray window to another position or in case the user
2614c2c66affSColin Finck         wants to resize the tray window. */
26152ed535daSGiannis Adamopoulos         if (!g_TaskbarSettings.bLock && GetCursorPos(&ptCursor))
2616c2c66affSColin Finck         {
2617c2c66affSColin Finck             IsDragging = TRUE;
2618c2c66affSColin Finck             m_DraggingPosition = GetDraggingRectFromPt(ptCursor, pRect, &m_DraggingMonitor);
2619c2c66affSColin Finck         }
2620c2c66affSColin Finck         else
2621c2c66affSColin Finck         {
2622c2c66affSColin Finck             *pRect = m_TrayRects[m_Position];
2623c2c66affSColin Finck         }
2624c2c66affSColin Finck         return TRUE;
2625c2c66affSColin Finck     }
2626c2c66affSColin Finck 
OnSizing(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)2627c2c66affSColin Finck     LRESULT OnSizing(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2628c2c66affSColin Finck     {
2629c2c66affSColin Finck         PRECT pRect = (PRECT) lParam;
2630c2c66affSColin Finck 
26312ed535daSGiannis Adamopoulos         if (!g_TaskbarSettings.bLock)
2632c2c66affSColin Finck         {
2633c2c66affSColin Finck             FitToRebar(pRect);
2634c2c66affSColin Finck         }
2635c2c66affSColin Finck         else
2636c2c66affSColin Finck         {
2637c2c66affSColin Finck             *pRect = m_TrayRects[m_Position];
2638c2c66affSColin Finck         }
2639c2c66affSColin Finck         return TRUE;
2640c2c66affSColin Finck     }
2641c2c66affSColin Finck 
OnWindowPosChanging(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)26424238f223SGiannis Adamopoulos     LRESULT OnWindowPosChanging(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2643c2c66affSColin Finck     {
2644c2c66affSColin Finck         ChangingWinPos((LPWINDOWPOS) lParam);
2645c2c66affSColin Finck         return TRUE;
2646c2c66affSColin Finck     }
2647c2c66affSColin Finck 
OnSize(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)2648c2c66affSColin Finck     LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2649c2c66affSColin Finck     {
2650c2c66affSColin Finck         RECT rcClient;
2651c2c66affSColin Finck         if (wParam == SIZE_RESTORED && lParam == 0)
2652c2c66affSColin Finck         {
2653c2c66affSColin Finck             ResizeWorkArea();
2654c2c66affSColin Finck             /* Clip the tray window on multi monitor systems so the edges can't
2655c2c66affSColin Finck             overlap into another monitor */
2656c2c66affSColin Finck             ApplyClipping(TRUE);
2657c2c66affSColin Finck 
2658c2c66affSColin Finck             if (!GetClientRect(&rcClient))
2659c2c66affSColin Finck             {
2660c2c66affSColin Finck                 return FALSE;
2661c2c66affSColin Finck             }
2662c2c66affSColin Finck         }
2663c2c66affSColin Finck         else
2664c2c66affSColin Finck         {
2665c2c66affSColin Finck             rcClient.left = rcClient.top = 0;
2666c2c66affSColin Finck             rcClient.right = LOWORD(lParam);
2667c2c66affSColin Finck             rcClient.bottom = HIWORD(lParam);
2668c2c66affSColin Finck         }
2669c2c66affSColin Finck 
2670c2c66affSColin Finck         AlignControls(&rcClient);
2671c2c66affSColin Finck         return TRUE;
2672c2c66affSColin Finck     }
2673c2c66affSColin Finck 
OnEnterSizeMove(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)2674c2c66affSColin Finck     LRESULT OnEnterSizeMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2675c2c66affSColin Finck     {
2676c2c66affSColin Finck         InSizeMove = TRUE;
2677c2c66affSColin Finck         IsDragging = FALSE;
26782ed535daSGiannis Adamopoulos         if (!g_TaskbarSettings.bLock)
2679c2c66affSColin Finck         {
2680c2c66affSColin Finck             /* Remove the clipping on multi monitor systems while dragging around */
2681c2c66affSColin Finck             ApplyClipping(FALSE);
2682c2c66affSColin Finck         }
2683c2c66affSColin Finck         return TRUE;
2684c2c66affSColin Finck     }
2685c2c66affSColin Finck 
OnExitSizeMove(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)2686c2c66affSColin Finck     LRESULT OnExitSizeMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2687c2c66affSColin Finck     {
2688c2c66affSColin Finck         InSizeMove = FALSE;
26892ed535daSGiannis Adamopoulos         if (!g_TaskbarSettings.bLock)
2690c2c66affSColin Finck         {
2691c2c66affSColin Finck             FitToRebar(&m_TrayRects[m_Position]);
2692c2c66affSColin Finck 
2693c2c66affSColin Finck             /* Apply clipping */
2694c2c66affSColin Finck             PostMessage(WM_SIZE, SIZE_RESTORED, 0);
2695c2c66affSColin Finck         }
2696c2c66affSColin Finck         return TRUE;
2697c2c66affSColin Finck     }
2698c2c66affSColin Finck 
OnSysChar(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)2699c2c66affSColin Finck     LRESULT OnSysChar(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2700c2c66affSColin Finck     {
2701c2c66affSColin Finck         switch (wParam)
2702c2c66affSColin Finck         {
2703c2c66affSColin Finck         case TEXT(' '):
2704c2c66affSColin Finck         {
2705c2c66affSColin Finck             /* The user pressed Alt+Space, this usually brings up the system menu of a window.
2706c2c66affSColin Finck             The tray window needs to handle this specially, since it normally doesn't have
2707c2c66affSColin Finck             a system menu. */
2708c2c66affSColin Finck 
2709c2c66affSColin Finck             static const UINT uidDisableItem [] = {
2710c2c66affSColin Finck                 SC_RESTORE,
2711c2c66affSColin Finck                 SC_MOVE,
2712c2c66affSColin Finck                 SC_SIZE,
2713c2c66affSColin Finck                 SC_MAXIMIZE,
2714c2c66affSColin Finck                 SC_MINIMIZE,
2715c2c66affSColin Finck             };
2716c2c66affSColin Finck             HMENU hSysMenu;
2717c2c66affSColin Finck             UINT i, uId;
2718c2c66affSColin Finck 
2719c2c66affSColin Finck             /* temporarily enable the system menu */
2720c2c66affSColin Finck             SetWindowStyle(m_hWnd, WS_SYSMENU, WS_SYSMENU);
2721c2c66affSColin Finck 
2722c2c66affSColin Finck             hSysMenu = GetSystemMenu(FALSE);
2723c2c66affSColin Finck             if (hSysMenu != NULL)
2724c2c66affSColin Finck             {
2725c2c66affSColin Finck                 /* Disable all items that are not relevant */
2726c2c66affSColin Finck                 for (i = 0; i < _countof(uidDisableItem); i++)
2727c2c66affSColin Finck                 {
2728c2c66affSColin Finck                     EnableMenuItem(hSysMenu,
2729c2c66affSColin Finck                                    uidDisableItem[i],
2730c2c66affSColin Finck                                    MF_BYCOMMAND | MF_GRAYED);
2731c2c66affSColin Finck                 }
2732c2c66affSColin Finck 
2733c2c66affSColin Finck                 EnableMenuItem(hSysMenu,
2734c2c66affSColin Finck                                SC_CLOSE,
2735c2c66affSColin Finck                                MF_BYCOMMAND |
2736c2c66affSColin Finck                                (SHRestricted(REST_NOCLOSE) ? MF_GRAYED : MF_ENABLED));
2737c2c66affSColin Finck 
2738c2c66affSColin Finck                 /* Display the system menu */
2739c2c66affSColin Finck                 uId = TrackMenu(
2740c2c66affSColin Finck                     hSysMenu,
2741c2c66affSColin Finck                     NULL,
2742c2c66affSColin Finck                     m_StartButton.m_hWnd,
2743c2c66affSColin Finck                     m_Position != ABE_TOP,
2744c2c66affSColin Finck                     FALSE);
2745c2c66affSColin Finck                 if (uId != 0)
2746c2c66affSColin Finck                 {
2747c2c66affSColin Finck                     SendMessage(m_hWnd, WM_SYSCOMMAND, (WPARAM) uId, 0);
2748c2c66affSColin Finck                 }
2749c2c66affSColin Finck             }
2750c2c66affSColin Finck 
2751c2c66affSColin Finck             /* revert the system menu window style */
2752c2c66affSColin Finck             SetWindowStyle(m_hWnd, WS_SYSMENU, 0);
2753c2c66affSColin Finck             break;
2754c2c66affSColin Finck         }
2755c2c66affSColin Finck 
2756c2c66affSColin Finck         default:
2757c2c66affSColin Finck             bHandled = FALSE;
2758c2c66affSColin Finck         }
2759c2c66affSColin Finck         return TRUE;
2760c2c66affSColin Finck     }
2761c2c66affSColin Finck 
IsPointWithinStartButton(LPPOINT ppt,LPRECT prcStartBtn,PWINDOWINFO pwi)276270d7009aSEthan Rodensky     BOOL IsPointWithinStartButton(LPPOINT ppt, LPRECT prcStartBtn, PWINDOWINFO pwi)
276370d7009aSEthan Rodensky     {
276470d7009aSEthan Rodensky         if (!ppt || !prcStartBtn || !pwi)
276570d7009aSEthan Rodensky             return FALSE;
276670d7009aSEthan Rodensky 
276770d7009aSEthan Rodensky         switch (m_Position)
276870d7009aSEthan Rodensky         {
276970d7009aSEthan Rodensky             case ABE_TOP:
277070d7009aSEthan Rodensky             case ABE_LEFT:
277170d7009aSEthan Rodensky             {
277270d7009aSEthan Rodensky                 if (ppt->x > prcStartBtn->right || ppt->y > prcStartBtn->bottom)
277370d7009aSEthan Rodensky                     return FALSE;
277470d7009aSEthan Rodensky                 break;
277570d7009aSEthan Rodensky             }
277670d7009aSEthan Rodensky             case ABE_RIGHT:
277770d7009aSEthan Rodensky             {
277870d7009aSEthan Rodensky                 if (ppt->x < prcStartBtn->left || ppt->y > prcStartBtn->bottom)
277970d7009aSEthan Rodensky                     return FALSE;
278070d7009aSEthan Rodensky 
278170d7009aSEthan Rodensky                 if (prcStartBtn->right + (int)pwi->cxWindowBorders * 2 + 1 < pwi->rcWindow.right &&
278270d7009aSEthan Rodensky                     ppt->x > prcStartBtn->right)
278370d7009aSEthan Rodensky                 {
278470d7009aSEthan Rodensky                     return FALSE;
278570d7009aSEthan Rodensky                 }
278670d7009aSEthan Rodensky                 break;
278770d7009aSEthan Rodensky             }
278870d7009aSEthan Rodensky             case ABE_BOTTOM:
278970d7009aSEthan Rodensky             {
279070d7009aSEthan Rodensky                 if (ppt->x > prcStartBtn->right || ppt->y < prcStartBtn->top)
279170d7009aSEthan Rodensky                     return FALSE;
279270d7009aSEthan Rodensky 
279370d7009aSEthan Rodensky                 if (prcStartBtn->bottom + (int)pwi->cyWindowBorders * 2 + 1 < pwi->rcWindow.bottom &&
279470d7009aSEthan Rodensky                     ppt->y > prcStartBtn->bottom)
279570d7009aSEthan Rodensky                 {
279670d7009aSEthan Rodensky                     return FALSE;
279770d7009aSEthan Rodensky                 }
279870d7009aSEthan Rodensky 
279970d7009aSEthan Rodensky                 break;
280070d7009aSEthan Rodensky             }
280170d7009aSEthan Rodensky         }
280270d7009aSEthan Rodensky         return TRUE;
280370d7009aSEthan Rodensky     }
280470d7009aSEthan Rodensky 
IsPointWithinShowDesktopButton(LPPOINT ppt,LPRECT prcShowDesktopBtn,PWINDOWINFO pwi)280570d7009aSEthan Rodensky     BOOL IsPointWithinShowDesktopButton(LPPOINT ppt, LPRECT prcShowDesktopBtn, PWINDOWINFO pwi)
280670d7009aSEthan Rodensky     {
280770d7009aSEthan Rodensky         if (!ppt || !prcShowDesktopBtn)
280870d7009aSEthan Rodensky             return FALSE;
280970d7009aSEthan Rodensky         UNREFERENCED_PARAMETER(pwi);
281070d7009aSEthan Rodensky 
281170d7009aSEthan Rodensky         switch (m_Position)
281270d7009aSEthan Rodensky         {
281370d7009aSEthan Rodensky             case ABE_LEFT:
281470d7009aSEthan Rodensky                 return !(ppt->x > prcShowDesktopBtn->right || ppt->y < prcShowDesktopBtn->top);
281570d7009aSEthan Rodensky             case ABE_TOP:
281670d7009aSEthan Rodensky                 return !(ppt->x < prcShowDesktopBtn->left || ppt->y > prcShowDesktopBtn->bottom);
281770d7009aSEthan Rodensky             case ABE_RIGHT:
281870d7009aSEthan Rodensky                 return !(ppt->x < prcShowDesktopBtn->left || ppt->y < prcShowDesktopBtn->top);
281970d7009aSEthan Rodensky             case ABE_BOTTOM:
282070d7009aSEthan Rodensky                 return !(ppt->x < prcShowDesktopBtn->left || ppt->y < prcShowDesktopBtn->top);
282170d7009aSEthan Rodensky         }
282270d7009aSEthan Rodensky         return FALSE;
282370d7009aSEthan Rodensky     }
282470d7009aSEthan Rodensky 
282570d7009aSEthan Rodensky     /**
282670d7009aSEthan Rodensky      * This handler implements the trick that makes the start button to
282770d7009aSEthan Rodensky      * get pressed when the user clicked left or below the button.
282870d7009aSEthan Rodensky      */
OnNcLButtonDown(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)2829c2c66affSColin Finck     LRESULT OnNcLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2830c2c66affSColin Finck     {
2831c2c66affSColin Finck         POINT pt = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
2832c2c66affSColin Finck         WINDOWINFO wi = {sizeof(WINDOWINFO)};
2833c2c66affSColin Finck 
2834c2c66affSColin Finck         bHandled = FALSE;
2835c2c66affSColin Finck 
283626efda4dSKatayama Hirofumi MZ         RECT rcStartBtn;
2837c2c66affSColin Finck         m_StartButton.GetWindowRect(&rcStartBtn);
2838c2c66affSColin Finck         GetWindowInfo(m_hWnd, &wi);
2839c2c66affSColin Finck 
284070d7009aSEthan Rodensky         if (IsPointWithinStartButton(&pt, &rcStartBtn, &wi))
2841c2c66affSColin Finck         {
2842c2c66affSColin Finck             bHandled = TRUE;
2843c2c66affSColin Finck             PopupStartMenu();
2844c2c66affSColin Finck             return 0;
2845c2c66affSColin Finck         }
2846c2c66affSColin Finck 
284770d7009aSEthan Rodensky         if (m_pShowDesktopButton && m_pShowDesktopButton->PtInButton(&pt))
284870d7009aSEthan Rodensky             m_pShowDesktopButton->OnLButtonDown(WM_LBUTTONDOWN, 0, 0, bHandled);
284970d7009aSEthan Rodensky 
285070d7009aSEthan Rodensky         return 0;
285170d7009aSEthan Rodensky     }
285270d7009aSEthan Rodensky 
OnNcRButtonUp(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)2853c2c66affSColin Finck     LRESULT OnNcRButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2854c2c66affSColin Finck     {
2855c2c66affSColin Finck         /* We want the user to be able to get a context menu even on the nonclient
2856c2c66affSColin Finck         area (including the sizing border)! */
2857c2c66affSColin Finck         uMsg = WM_CONTEXTMENU;
2858c2c66affSColin Finck         wParam = (WPARAM) m_hWnd;
2859c2c66affSColin Finck 
2860c2c66affSColin Finck         return OnContextMenu(uMsg, wParam, lParam, bHandled);
2861c2c66affSColin Finck     }
2862c2c66affSColin Finck 
OnContextMenu(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)2863c2c66affSColin Finck     LRESULT OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2864c2c66affSColin Finck     {
2865c2c66affSColin Finck         LRESULT Ret = FALSE;
2866c2c66affSColin Finck         POINT pt, *ppt = NULL;
2867c2c66affSColin Finck         HWND hWndExclude = NULL;
2868c2c66affSColin Finck 
2869c2c66affSColin Finck         /* Check if the administrator has forbidden access to context menus */
2870c2c66affSColin Finck         if (SHRestricted(REST_NOTRAYCONTEXTMENU))
2871c2c66affSColin Finck             return FALSE;
2872c2c66affSColin Finck 
2873c2c66affSColin Finck         pt.x = (SHORT) LOWORD(lParam);
2874c2c66affSColin Finck         pt.y = (SHORT) HIWORD(lParam);
2875c2c66affSColin Finck 
2876c2c66affSColin Finck         if (pt.x != -1 || pt.y != -1)
2877c2c66affSColin Finck             ppt = &pt;
2878c2c66affSColin Finck         else
2879c2c66affSColin Finck             hWndExclude = m_StartButton.m_hWnd;
2880c2c66affSColin Finck 
2881c2c66affSColin Finck         if ((HWND) wParam == m_StartButton.m_hWnd)
2882c2c66affSColin Finck         {
2883c2c66affSColin Finck             /* Make sure we can't track the context menu if the start
2884c2c66affSColin Finck             menu is currently being shown */
2885c2c66affSColin Finck             if (!(m_StartButton.SendMessage(BM_GETSTATE, 0, 0) & BST_PUSHED))
2886c2c66affSColin Finck             {
2887c2c66affSColin Finck                 CComPtr<IContextMenu> ctxMenu;
288884fa20ecSGiannis Adamopoulos                 CStartMenuBtnCtxMenu_CreateInstance(this, m_hWnd, &ctxMenu);
2889c2c66affSColin Finck                 TrackCtxMenu(ctxMenu, ppt, hWndExclude, m_Position == ABE_BOTTOM, this);
2890c2c66affSColin Finck             }
2891c2c66affSColin Finck         }
2892c2c66affSColin Finck         else
2893c2c66affSColin Finck         {
2894c2c66affSColin Finck             /* See if the context menu should be handled by the task band site */
2895c2c66affSColin Finck             if (ppt != NULL && m_TrayBandSite != NULL)
2896c2c66affSColin Finck             {
2897c2c66affSColin Finck                 HWND hWndAtPt;
2898c2c66affSColin Finck                 POINT ptClient = *ppt;
2899c2c66affSColin Finck 
2900c2c66affSColin Finck                 /* Convert the coordinates to client-coordinates */
2901c2c66affSColin Finck                 ::MapWindowPoints(NULL, m_hWnd, &ptClient, 1);
2902c2c66affSColin Finck 
2903c2c66affSColin Finck                 hWndAtPt = ChildWindowFromPoint(ptClient);
2904c2c66affSColin Finck                 if (hWndAtPt != NULL &&
2905c2c66affSColin Finck                     (hWndAtPt == m_Rebar || ::IsChild(m_Rebar, hWndAtPt)))
2906c2c66affSColin Finck                 {
2907c2c66affSColin Finck                     /* Check if the user clicked on the task switch window */
2908c2c66affSColin Finck                     ptClient = *ppt;
2909c2c66affSColin Finck                     ::MapWindowPoints(NULL, m_Rebar, &ptClient, 1);
2910c2c66affSColin Finck 
2911c2c66affSColin Finck                     hWndAtPt = ::ChildWindowFromPointEx(m_Rebar, ptClient, CWP_SKIPINVISIBLE | CWP_SKIPDISABLED);
2912c2c66affSColin Finck                     if (hWndAtPt == m_TaskSwitch)
2913c2c66affSColin Finck                         goto HandleTrayContextMenu;
2914c2c66affSColin Finck 
2915c2c66affSColin Finck                     /* Forward the message to the task band site */
2916c2c66affSColin Finck                     m_TrayBandSite->ProcessMessage(m_hWnd, uMsg, wParam, lParam, &Ret);
2917c2c66affSColin Finck                 }
2918c2c66affSColin Finck                 else
2919c2c66affSColin Finck                     goto HandleTrayContextMenu;
2920c2c66affSColin Finck             }
2921c2c66affSColin Finck             else
2922c2c66affSColin Finck             {
2923c2c66affSColin Finck HandleTrayContextMenu:
2924c2c66affSColin Finck                 /* Tray the default tray window context menu */
2925c2c66affSColin Finck                 TrackCtxMenu(this, ppt, NULL, FALSE, this);
2926c2c66affSColin Finck             }
2927c2c66affSColin Finck         }
2928c2c66affSColin Finck         return Ret;
2929c2c66affSColin Finck     }
2930c2c66affSColin Finck 
OnNotify(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)2931c2c66affSColin Finck     LRESULT OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2932c2c66affSColin Finck     {
2933c2c66affSColin Finck         LRESULT Ret = FALSE;
2934c2c66affSColin Finck         /* FIXME: We can't check with IsChild whether the hwnd is somewhere inside
2935c2c66affSColin Finck         the rebar control! But we shouldn't forward messages that the band
2936c2c66affSColin Finck         site doesn't handle, such as other controls (start button, tray window */
2937c2c66affSColin Finck 
2938c2c66affSColin Finck         HRESULT hr = E_FAIL;
2939c2c66affSColin Finck 
2940c2c66affSColin Finck         if (m_TrayBandSite)
2941c2c66affSColin Finck         {
2942c2c66affSColin Finck             hr = m_TrayBandSite->ProcessMessage(m_hWnd, uMsg, wParam, lParam, &Ret);
2943c2c66affSColin Finck             if (SUCCEEDED(hr))
2944c2c66affSColin Finck                 return Ret;
2945c2c66affSColin Finck         }
2946c2c66affSColin Finck 
2947c2c66affSColin Finck         if (m_TrayBandSite == NULL || FAILED(hr))
2948c2c66affSColin Finck         {
2949c2c66affSColin Finck             const NMHDR *nmh = (const NMHDR *) lParam;
2950c2c66affSColin Finck 
2951c2c66affSColin Finck             if (nmh->hwndFrom == m_TrayNotify)
2952c2c66affSColin Finck             {
2953c2c66affSColin Finck                 switch (nmh->code)
2954c2c66affSColin Finck                 {
2955c2c66affSColin Finck                 case NTNWM_REALIGN:
2956c2c66affSColin Finck                     /* Cause all controls to be aligned */
2957c2c66affSColin Finck                     PostMessage(WM_SIZE, SIZE_RESTORED, 0);
2958c2c66affSColin Finck                     break;
2959c2c66affSColin Finck                 }
2960c2c66affSColin Finck             }
2961c2c66affSColin Finck         }
2962c2c66affSColin Finck         return Ret;
2963c2c66affSColin Finck     }
2964c2c66affSColin Finck 
OnNcLButtonDblClick(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)2965c2c66affSColin Finck     LRESULT OnNcLButtonDblClick(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2966c2c66affSColin Finck     {
296772ea2d4cSAndrew Dent         /* Let the clock handle the double-click */
29687f35908aSGiannis Adamopoulos         ::SendMessageW(m_TrayNotify, uMsg, wParam, lParam);
29697f35908aSGiannis Adamopoulos 
2970c2c66affSColin Finck         /* We "handle" this message so users can't cause a weird maximize/restore
2971c2c66affSColin Finck         window animation when double-clicking the tray window! */
2972c2c66affSColin Finck         return TRUE;
2973c2c66affSColin Finck     }
2974c2c66affSColin Finck 
OnNcLButtonUp(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)297546de3a22SKatayama Hirofumi MZ     LRESULT OnNcLButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
297646de3a22SKatayama Hirofumi MZ     {
297770d7009aSEthan Rodensky         if (m_pShowDesktopButton && m_pShowDesktopButton->m_bPressed) // Did you click the button?
297870d7009aSEthan Rodensky         {
297970d7009aSEthan Rodensky             m_pShowDesktopButton->Click();
298070d7009aSEthan Rodensky             m_pShowDesktopButton->OnLButtonUp(WM_LBUTTONUP, 0, 0, bHandled);
298170d7009aSEthan Rodensky             bHandled = TRUE;
298270d7009aSEthan Rodensky         }
298370d7009aSEthan Rodensky 
298470d7009aSEthan Rodensky         return FALSE;
298570d7009aSEthan Rodensky     }
298670d7009aSEthan Rodensky 
OnLButtonUp(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)298770d7009aSEthan Rodensky     LRESULT OnLButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
298870d7009aSEthan Rodensky     {
298970d7009aSEthan Rodensky         if (m_pShowDesktopButton)
299070d7009aSEthan Rodensky             m_pShowDesktopButton->OnLButtonUp(uMsg, wParam, lParam, bHandled);
299163fa6747SJoachim Henze         return FALSE;
299246de3a22SKatayama Hirofumi MZ     }
299346de3a22SKatayama Hirofumi MZ 
OnAppTrayDestroy(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)2994c2c66affSColin Finck     LRESULT OnAppTrayDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2995c2c66affSColin Finck     {
2996c2c66affSColin Finck         DestroyWindow();
2997c2c66affSColin Finck         return TRUE;
2998c2c66affSColin Finck     }
2999c2c66affSColin Finck 
OnOpenStartMenu(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)3000c2c66affSColin Finck     LRESULT OnOpenStartMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
3001c2c66affSColin Finck     {
3002c2c66affSColin Finck         HWND hwndStartMenu;
3003c2c66affSColin Finck         HRESULT hr = IUnknown_GetWindow(m_StartMenuPopup, &hwndStartMenu);
3004c2c66affSColin Finck         if (FAILED_UNEXPECTEDLY(hr))
3005c2c66affSColin Finck             return FALSE;
3006c2c66affSColin Finck 
3007c2c66affSColin Finck         if (::IsWindowVisible(hwndStartMenu))
3008802a87dfSKatayama Hirofumi MZ             HideStartMenu();
3009c2c66affSColin Finck         else
3010c2c66affSColin Finck             PopupStartMenu();
3011c2c66affSColin Finck 
3012c2c66affSColin Finck         return TRUE;
3013c2c66affSColin Finck     }
3014c2c66affSColin Finck 
OnDoExitWindows(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)3015c2c66affSColin Finck     LRESULT OnDoExitWindows(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
3016c2c66affSColin Finck     {
3017c2c66affSColin Finck         /*
3018c2c66affSColin Finck          * TWM_DOEXITWINDOWS is send by the CDesktopBrowser to us
3019c2c66affSColin Finck          * to show the shutdown dialog. Also a WM_CLOSE message sent
3020c2c66affSColin Finck          * by apps should show the dialog.
3021c2c66affSColin Finck          */
3022c2c66affSColin Finck         return DoExitWindows();
3023c2c66affSColin Finck     }
3024c2c66affSColin Finck 
OnSysCommand(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)3025c2c66affSColin Finck     LRESULT OnSysCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
3026c2c66affSColin Finck     {
3027c2c66affSColin Finck         if (wParam == SC_CLOSE)
3028c2c66affSColin Finck         {
3029c2c66affSColin Finck             return DoExitWindows();
3030c2c66affSColin Finck         }
3031c2c66affSColin Finck 
3032c2c66affSColin Finck         bHandled = FALSE;
3033c2c66affSColin Finck         return TRUE;
3034c2c66affSColin Finck     }
3035c2c66affSColin Finck 
OnGetTaskSwitch(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)30366940d9fdSMark Jansen     LRESULT OnGetTaskSwitch(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
30376940d9fdSMark Jansen     {
30386940d9fdSMark Jansen         bHandled = TRUE;
30396940d9fdSMark Jansen         return (LRESULT)m_TaskSwitch;
30406940d9fdSMark Jansen     }
30416940d9fdSMark Jansen 
RestoreMinimizedNonTaskWnds(BOOL bDestroyed,HWND hwndActive)3042e6bced7aSKatayama Hirofumi MZ     void RestoreMinimizedNonTaskWnds(BOOL bDestroyed, HWND hwndActive)
3043e6bced7aSKatayama Hirofumi MZ     {
3044e6bced7aSKatayama Hirofumi MZ         for (INT i = g_MinimizedAll.GetSize() - 1; i >= 0; --i)
3045e6bced7aSKatayama Hirofumi MZ         {
3046e6bced7aSKatayama Hirofumi MZ             HWND hwnd = g_MinimizedAll[i].hwnd;
3047e6bced7aSKatayama Hirofumi MZ             if (!hwnd || hwndActive == hwnd)
3048e6bced7aSKatayama Hirofumi MZ                 continue;
3049e6bced7aSKatayama Hirofumi MZ 
3050e6bced7aSKatayama Hirofumi MZ             if (::IsWindowVisible(hwnd) && ::IsIconic(hwnd) &&
3051e6bced7aSKatayama Hirofumi MZ                 (!IsTaskWnd(hwnd) || !::IsWindowEnabled(hwnd)))
3052e6bced7aSKatayama Hirofumi MZ             {
3053e6bced7aSKatayama Hirofumi MZ                 ::SetWindowPlacement(hwnd, &g_MinimizedAll[i].wndpl); // Restore
3054e6bced7aSKatayama Hirofumi MZ             }
3055e6bced7aSKatayama Hirofumi MZ         }
3056e6bced7aSKatayama Hirofumi MZ 
3057045333e8SJose Carlos Jesus         if (bDestroyed)
3058e6bced7aSKatayama Hirofumi MZ             g_MinimizedAll.RemoveAll();
3059045333e8SJose Carlos Jesus         else
3060e6bced7aSKatayama Hirofumi MZ             ::SetForegroundWindow(hwndActive);
3061e6bced7aSKatayama Hirofumi MZ     }
3062e6bced7aSKatayama Hirofumi MZ 
OnPulse(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)3063e6bced7aSKatayama Hirofumi MZ     LRESULT OnPulse(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
3064e6bced7aSKatayama Hirofumi MZ     {
3065e6bced7aSKatayama Hirofumi MZ         if (IgnorePulse)
3066e6bced7aSKatayama Hirofumi MZ             return 0;
3067e6bced7aSKatayama Hirofumi MZ 
3068e6bced7aSKatayama Hirofumi MZ         KillTimer(TIMER_ID_IGNOREPULSERESET);
3069e6bced7aSKatayama Hirofumi MZ         IgnorePulse = TRUE;
3070e6bced7aSKatayama Hirofumi MZ         RestoreMinimizedNonTaskWnds((BOOL)wParam, (HWND)lParam);
3071e6bced7aSKatayama Hirofumi MZ         SetTimer(TIMER_ID_IGNOREPULSERESET, TIMER_IGNOREPULSERESET_TIMEOUT, NULL);
3072e6bced7aSKatayama Hirofumi MZ         return 0;
3073e6bced7aSKatayama Hirofumi MZ     }
3074e6bced7aSKatayama Hirofumi MZ 
OnHotkey(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)3075c2c66affSColin Finck     LRESULT OnHotkey(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
3076c2c66affSColin Finck     {
3077c2c66affSColin Finck         return HandleHotKey(wParam);
3078c2c66affSColin Finck     }
3079c2c66affSColin Finck 
308075b09f3fSKatayama Hirofumi MZ     struct MINIMIZE_INFO
308175b09f3fSKatayama Hirofumi MZ     {
308275b09f3fSKatayama Hirofumi MZ         HWND hwndDesktop;
308375b09f3fSKatayama Hirofumi MZ         HWND hTrayWnd;
308475b09f3fSKatayama Hirofumi MZ         HWND hwndProgman;
3085e6bced7aSKatayama Hirofumi MZ         CSimpleArray<MINWNDPOS> *pMinimizedAll;
308675b09f3fSKatayama Hirofumi MZ         BOOL bShowDesktop;
308775b09f3fSKatayama Hirofumi MZ     };
308875b09f3fSKatayama Hirofumi MZ 
IsDialog(HWND hwnd)308975b09f3fSKatayama Hirofumi MZ     static BOOL IsDialog(HWND hwnd)
309075b09f3fSKatayama Hirofumi MZ     {
309175b09f3fSKatayama Hirofumi MZ         WCHAR szClass[32];
309275b09f3fSKatayama Hirofumi MZ         GetClassNameW(hwnd, szClass, _countof(szClass));
309375b09f3fSKatayama Hirofumi MZ         return wcscmp(szClass, L"#32770") == 0;
309475b09f3fSKatayama Hirofumi MZ     }
309575b09f3fSKatayama Hirofumi MZ 
MinimizeWindowsProc(HWND hwnd,LPARAM lParam)309675b09f3fSKatayama Hirofumi MZ     static BOOL CALLBACK MinimizeWindowsProc(HWND hwnd, LPARAM lParam)
309775b09f3fSKatayama Hirofumi MZ     {
309875b09f3fSKatayama Hirofumi MZ         MINIMIZE_INFO *info = (MINIMIZE_INFO *)lParam;
3099e6bced7aSKatayama Hirofumi MZ         if (hwnd == info->hwndDesktop || hwnd == info->hTrayWnd || hwnd == info->hwndProgman)
3100e6bced7aSKatayama Hirofumi MZ             return TRUE; // Ignore special windows
3101e6bced7aSKatayama Hirofumi MZ 
310275b09f3fSKatayama Hirofumi MZ         if (!info->bShowDesktop)
310375b09f3fSKatayama Hirofumi MZ         {
310475b09f3fSKatayama Hirofumi MZ             if (!::IsWindowEnabled(hwnd) || IsDialog(hwnd))
310575b09f3fSKatayama Hirofumi MZ                 return TRUE;
310675b09f3fSKatayama Hirofumi MZ             HWND hwndOwner = ::GetWindow(hwnd, GW_OWNER);
310775b09f3fSKatayama Hirofumi MZ             if (hwndOwner && !::IsWindowEnabled(hwndOwner))
310875b09f3fSKatayama Hirofumi MZ                 return TRUE;
310975b09f3fSKatayama Hirofumi MZ         }
3110e6bced7aSKatayama Hirofumi MZ 
311122ab8c81SKatayama Hirofumi MZ         if (CanBeMinimized(hwnd))
311275b09f3fSKatayama Hirofumi MZ         {
311322ab8c81SKatayama Hirofumi MZ             MINWNDPOS mwp = { hwnd, { sizeof(mwp.wndpl) } };
311422ab8c81SKatayama Hirofumi MZ             if (::GetWindowPlacement(hwnd, &mwp.wndpl) && // Save the position and status
311522ab8c81SKatayama Hirofumi MZ                 ::ShowWindowAsync(hwnd, SW_SHOWMINNOACTIVE)) // Minimize
311622ab8c81SKatayama Hirofumi MZ             {
3117e6bced7aSKatayama Hirofumi MZ                 info->pMinimizedAll->Add(mwp);
311822ab8c81SKatayama Hirofumi MZ             }
311975b09f3fSKatayama Hirofumi MZ         }
3120e6bced7aSKatayama Hirofumi MZ 
312175b09f3fSKatayama Hirofumi MZ         return TRUE;
312275b09f3fSKatayama Hirofumi MZ     }
312375b09f3fSKatayama Hirofumi MZ 
MinimizeAll(BOOL bShowDesktop=FALSE)312475b09f3fSKatayama Hirofumi MZ     VOID MinimizeAll(BOOL bShowDesktop = FALSE)
312575b09f3fSKatayama Hirofumi MZ     {
3126e6bced7aSKatayama Hirofumi MZ         IgnorePulse = TRUE;
3127e6bced7aSKatayama Hirofumi MZ         KillTimer(TIMER_ID_IGNOREPULSERESET);
3128e6bced7aSKatayama Hirofumi MZ 
312975b09f3fSKatayama Hirofumi MZ         MINIMIZE_INFO info;
313075b09f3fSKatayama Hirofumi MZ         info.hwndDesktop = GetDesktopWindow();;
313175b09f3fSKatayama Hirofumi MZ         info.hTrayWnd = FindWindowW(L"Shell_TrayWnd", NULL);
313275b09f3fSKatayama Hirofumi MZ         info.hwndProgman = FindWindowW(L"Progman", NULL);
313375b09f3fSKatayama Hirofumi MZ         info.pMinimizedAll = &g_MinimizedAll;
313475b09f3fSKatayama Hirofumi MZ         info.bShowDesktop = bShowDesktop;
313575b09f3fSKatayama Hirofumi MZ         EnumWindows(MinimizeWindowsProc, (LPARAM)&info);
313675b09f3fSKatayama Hirofumi MZ 
313775b09f3fSKatayama Hirofumi MZ         ::SetForegroundWindow(m_DesktopWnd);
313875b09f3fSKatayama Hirofumi MZ         ::SetFocus(m_DesktopWnd);
3139e6bced7aSKatayama Hirofumi MZ         SetTimer(TIMER_ID_IGNOREPULSERESET, TIMER_IGNOREPULSERESET_TIMEOUT, NULL);
314075b09f3fSKatayama Hirofumi MZ     }
314175b09f3fSKatayama Hirofumi MZ 
ShowDesktop()314275b09f3fSKatayama Hirofumi MZ     VOID ShowDesktop()
314375b09f3fSKatayama Hirofumi MZ     {
314475b09f3fSKatayama Hirofumi MZ         MinimizeAll(TRUE);
314575b09f3fSKatayama Hirofumi MZ     }
314675b09f3fSKatayama Hirofumi MZ 
RestoreAll()314775b09f3fSKatayama Hirofumi MZ     VOID RestoreAll()
314875b09f3fSKatayama Hirofumi MZ     {
3149e6bced7aSKatayama Hirofumi MZ         IgnorePulse = TRUE;
3150e6bced7aSKatayama Hirofumi MZ         KillTimer(TIMER_ID_IGNOREPULSERESET);
3151e6bced7aSKatayama Hirofumi MZ 
315275b09f3fSKatayama Hirofumi MZ         for (INT i = g_MinimizedAll.GetSize() - 1; i >= 0; --i)
315375b09f3fSKatayama Hirofumi MZ         {
3154e6bced7aSKatayama Hirofumi MZ             HWND hwnd = g_MinimizedAll[i].hwnd;
315575b09f3fSKatayama Hirofumi MZ             if (::IsWindowVisible(hwnd) && ::IsIconic(hwnd))
3156e6bced7aSKatayama Hirofumi MZ                 ::SetWindowPlacement(hwnd, &g_MinimizedAll[i].wndpl);
315775b09f3fSKatayama Hirofumi MZ         }
3158e6bced7aSKatayama Hirofumi MZ 
315975b09f3fSKatayama Hirofumi MZ         g_MinimizedAll.RemoveAll();
3160e6bced7aSKatayama Hirofumi MZ         SetTimer(TIMER_ID_IGNOREPULSERESET, TIMER_IGNOREPULSERESET_TIMEOUT, NULL);
316175b09f3fSKatayama Hirofumi MZ     }
316275b09f3fSKatayama Hirofumi MZ 
OnCommand(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)3163c2c66affSColin Finck     LRESULT OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
3164c2c66affSColin Finck     {
3165c2c66affSColin Finck         LRESULT Ret = FALSE;
3166c2c66affSColin Finck 
3167c2c66affSColin Finck         if ((HWND) lParam == m_StartButton.m_hWnd)
3168c2c66affSColin Finck         {
3169c2c66affSColin Finck             return FALSE;
3170c2c66affSColin Finck         }
3171c2c66affSColin Finck 
3172c2c66affSColin Finck         if (m_TrayBandSite == NULL || FAILED_UNEXPECTEDLY(m_TrayBandSite->ProcessMessage(m_hWnd, uMsg, wParam, lParam, &Ret)))
3173c2c66affSColin Finck         {
3174c2c66affSColin Finck             return HandleCommand(LOWORD(wParam));
3175c2c66affSColin Finck         }
3176c2c66affSColin Finck         return Ret;
3177c2c66affSColin Finck     }
3178c2c66affSColin Finck 
OnMouseMove(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)3179c2c66affSColin Finck     LRESULT OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
3180c2c66affSColin Finck     {
318170d7009aSEthan Rodensky         SendMessage(m_TrayNotify, uMsg, wParam, lParam);
318226efda4dSKatayama Hirofumi MZ 
31832ed535daSGiannis Adamopoulos         if (g_TaskbarSettings.sr.AutoHide)
3184c2c66affSColin Finck         {
3185c2c66affSColin Finck             SetTimer(TIMER_ID_MOUSETRACK, MOUSETRACK_INTERVAL, NULL);
3186c2c66affSColin Finck         }
3187c2c66affSColin Finck 
3188c2c66affSColin Finck         return TRUE;
3189c2c66affSColin Finck     }
3190c2c66affSColin Finck 
OnTimer(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)3191c2c66affSColin Finck     LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
3192c2c66affSColin Finck     {
3193c2c66affSColin Finck         if (wParam == TIMER_ID_MOUSETRACK)
3194c2c66affSColin Finck         {
3195c2c66affSColin Finck             ProcessMouseTracking();
3196c2c66affSColin Finck         }
3197c2c66affSColin Finck         else if (wParam == TIMER_ID_AUTOHIDE)
3198c2c66affSColin Finck         {
3199c2c66affSColin Finck             ProcessAutoHide();
3200c2c66affSColin Finck         }
3201e6bced7aSKatayama Hirofumi MZ         else if (wParam == TIMER_ID_IGNOREPULSERESET)
3202e6bced7aSKatayama Hirofumi MZ         {
3203e6bced7aSKatayama Hirofumi MZ             KillTimer(TIMER_ID_IGNOREPULSERESET);
3204e6bced7aSKatayama Hirofumi MZ             IgnorePulse = FALSE;
3205e6bced7aSKatayama Hirofumi MZ         }
3206e6bced7aSKatayama Hirofumi MZ         return 0;
3207c2c66affSColin Finck     }
3208c2c66affSColin Finck 
OnNcActivate(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)320926efda4dSKatayama Hirofumi MZ     LRESULT OnNcActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
321026efda4dSKatayama Hirofumi MZ     {
3211ba2cead8SKatayama Hirofumi MZ         LRESULT ret = DefWindowProc(uMsg, wParam, lParam);
321226efda4dSKatayama Hirofumi MZ         DrawShowDesktopButton(); // We have to draw non-client area
321326efda4dSKatayama Hirofumi MZ         bHandled = TRUE;
3214ba2cead8SKatayama Hirofumi MZ         return ret;
321526efda4dSKatayama Hirofumi MZ     }
321626efda4dSKatayama Hirofumi MZ 
OnNcCalcSize(INT code,WPARAM wParam,LPARAM lParam,BOOL & bHandled)3217c2c66affSColin Finck     LRESULT OnNcCalcSize(INT code, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
3218c2c66affSColin Finck     {
3219c2c66affSColin Finck         RECT *rc = NULL;
3220c2c66affSColin Finck         /* Ignore WM_NCCALCSIZE if we are not themed or locked */
32212ed535daSGiannis Adamopoulos         if(!m_Theme || g_TaskbarSettings.bLock)
3222c2c66affSColin Finck         {
3223c2c66affSColin Finck             bHandled = FALSE;
3224c2c66affSColin Finck             return 0;
3225c2c66affSColin Finck         }
3226c2c66affSColin Finck         if(!wParam)
3227c2c66affSColin Finck         {
3228c2c66affSColin Finck             rc = (RECT*)wParam;
3229c2c66affSColin Finck         }
3230c2c66affSColin Finck         else
3231c2c66affSColin Finck         {
3232c2c66affSColin Finck             NCCALCSIZE_PARAMS *prms = (NCCALCSIZE_PARAMS*)lParam;
3233c2c66affSColin Finck             if(prms->lppos->flags & SWP_NOSENDCHANGING)
3234c2c66affSColin Finck             {
3235c2c66affSColin Finck                 bHandled = FALSE;
3236c2c66affSColin Finck                 return 0;
3237c2c66affSColin Finck             }
3238c2c66affSColin Finck             rc = &prms->rgrc[0];
3239c2c66affSColin Finck         }
3240c2c66affSColin Finck 
3241c2c66affSColin Finck         AdjustSizerRect(rc, m_Position);
3242c2c66affSColin Finck 
3243c2c66affSColin Finck         return 0;
3244c2c66affSColin Finck     }
3245c2c66affSColin Finck 
OnInitMenuPopup(INT code,WPARAM wParam,LPARAM lParam,BOOL & bHandled)324675b09f3fSKatayama Hirofumi MZ     LRESULT OnInitMenuPopup(INT code, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
324775b09f3fSKatayama Hirofumi MZ     {
324875b09f3fSKatayama Hirofumi MZ         HMENU hMenu = (HMENU)wParam;
324975b09f3fSKatayama Hirofumi MZ         if (::IsThereAnyEffectiveWindow(FALSE))
325075b09f3fSKatayama Hirofumi MZ         {
325175b09f3fSKatayama Hirofumi MZ             ::EnableMenuItem(hMenu, ID_SHELL_CMD_CASCADE_WND, MF_BYCOMMAND | MF_ENABLED);
325275b09f3fSKatayama Hirofumi MZ             ::EnableMenuItem(hMenu, ID_SHELL_CMD_TILE_WND_H, MF_BYCOMMAND | MF_ENABLED);
325375b09f3fSKatayama Hirofumi MZ             ::EnableMenuItem(hMenu, ID_SHELL_CMD_TILE_WND_V, MF_BYCOMMAND | MF_ENABLED);
3254be970d8dSTuur Martens             if (g_Arrangement != NONE)
3255be970d8dSTuur Martens             {
3256be970d8dSTuur Martens                 CStringW strCaption((g_Arrangement == TILED) ? MAKEINTRESOURCEW(IDS_TRAYWND_UNDO_TILE)
3257be970d8dSTuur Martens                                                              : MAKEINTRESOURCEW(IDS_TRAYWND_UNDO_CASCADE));
3258be970d8dSTuur Martens                 MENUITEMINFOW mii = { sizeof(mii) };
3259be970d8dSTuur Martens                 ::GetMenuItemInfoW(hMenu, ID_SHELL_CMD_UNDO_ACTION, FALSE, &mii);
3260be970d8dSTuur Martens                 mii.fMask = MIIM_TYPE;
3261be970d8dSTuur Martens                 mii.fType = MFT_STRING;
3262be970d8dSTuur Martens                 mii.dwTypeData = const_cast<LPWSTR>(&strCaption[0]);
3263be970d8dSTuur Martens                 ::SetMenuItemInfoW(hMenu, ID_SHELL_CMD_UNDO_ACTION, FALSE, &mii);
3264be970d8dSTuur Martens             }
3265be970d8dSTuur Martens             else
3266be970d8dSTuur Martens             {
3267be970d8dSTuur Martens                 ::DeleteMenu(hMenu, ID_SHELL_CMD_UNDO_ACTION, MF_BYCOMMAND);
3268be970d8dSTuur Martens             }
326975b09f3fSKatayama Hirofumi MZ         }
327075b09f3fSKatayama Hirofumi MZ         else
327175b09f3fSKatayama Hirofumi MZ         {
327275b09f3fSKatayama Hirofumi MZ             ::EnableMenuItem(hMenu, ID_SHELL_CMD_CASCADE_WND, MF_BYCOMMAND | MF_GRAYED);
327375b09f3fSKatayama Hirofumi MZ             ::EnableMenuItem(hMenu, ID_SHELL_CMD_TILE_WND_H, MF_BYCOMMAND | MF_GRAYED);
327475b09f3fSKatayama Hirofumi MZ             ::EnableMenuItem(hMenu, ID_SHELL_CMD_TILE_WND_V, MF_BYCOMMAND | MF_GRAYED);
3275be970d8dSTuur Martens             ::DeleteMenu(hMenu, ID_SHELL_CMD_UNDO_ACTION, MF_BYCOMMAND);
3276be970d8dSTuur Martens             g_Arrangement = NONE;
3277be970d8dSTuur Martens             g_WindowPosBackup.RemoveAll();
327875b09f3fSKatayama Hirofumi MZ         }
327975b09f3fSKatayama Hirofumi MZ         return 0;
328075b09f3fSKatayama Hirofumi MZ     }
328175b09f3fSKatayama Hirofumi MZ 
OnRebarAutoSize(INT code,LPNMHDR nmhdr,BOOL & bHandled)3282c2c66affSColin Finck     LRESULT OnRebarAutoSize(INT code, LPNMHDR nmhdr, BOOL& bHandled)
3283c2c66affSColin Finck     {
3284c2c66affSColin Finck #if 0
3285c2c66affSColin Finck         LPNMRBAUTOSIZE as = (LPNMRBAUTOSIZE) nmhdr;
3286c2c66affSColin Finck 
3287c2c66affSColin Finck         if (!as->fChanged)
3288c2c66affSColin Finck             return 0;
3289c2c66affSColin Finck 
3290c2c66affSColin Finck         RECT rc;
3291c2c66affSColin Finck         ::GetWindowRect(m_hWnd, &rc);
3292c2c66affSColin Finck 
3293c2c66affSColin Finck         SIZE szWindow = {
3294c2c66affSColin Finck             rc.right - rc.left,
3295c2c66affSColin Finck             rc.bottom - rc.top };
3296c2c66affSColin Finck         SIZE szTarget = {
3297c2c66affSColin Finck             as->rcTarget.right - as->rcTarget.left,
3298c2c66affSColin Finck             as->rcTarget.bottom - as->rcTarget.top };
3299c2c66affSColin Finck         SIZE szActual = {
3300c2c66affSColin Finck             as->rcActual.right - as->rcActual.left,
3301c2c66affSColin Finck             as->rcActual.bottom - as->rcActual.top };
3302c2c66affSColin Finck 
3303c2c66affSColin Finck         SIZE borders = {
3304c2c66affSColin Finck             szWindow.cx - szTarget.cx,
3305c2c66affSColin Finck             szWindow.cy - szTarget.cx,
3306c2c66affSColin Finck         };
3307c2c66affSColin Finck 
3308c2c66affSColin Finck         switch (m_Position)
3309c2c66affSColin Finck         {
3310c2c66affSColin Finck         case ABE_LEFT:
3311c2c66affSColin Finck             szWindow.cx = szActual.cx + borders.cx;
3312c2c66affSColin Finck             break;
3313c2c66affSColin Finck         case ABE_TOP:
3314c2c66affSColin Finck             szWindow.cy = szActual.cy + borders.cy;
3315c2c66affSColin Finck             break;
3316c2c66affSColin Finck         case ABE_RIGHT:
3317c2c66affSColin Finck             szWindow.cx = szActual.cx + borders.cx;
3318c2c66affSColin Finck             rc.left = rc.right - szWindow.cy;
3319c2c66affSColin Finck             break;
3320c2c66affSColin Finck         case ABE_BOTTOM:
3321c2c66affSColin Finck             szWindow.cy = szActual.cy + borders.cy;
3322c2c66affSColin Finck             rc.top = rc.bottom - szWindow.cy;
3323c2c66affSColin Finck             break;
3324c2c66affSColin Finck         }
3325c2c66affSColin Finck 
3326c2c66affSColin Finck         SetWindowPos(NULL, rc.left, rc.top, szWindow.cx, szWindow.cy, SWP_NOACTIVATE | SWP_NOZORDER);
3327c2c66affSColin Finck #else
3328c2c66affSColin Finck         bHandled = FALSE;
3329c2c66affSColin Finck #endif
3330c2c66affSColin Finck         return 0;
3331c2c66affSColin Finck     }
3332c2c66affSColin Finck 
OnTaskbarSettingsChanged(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)33332ed535daSGiannis Adamopoulos     LRESULT OnTaskbarSettingsChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
33342ed535daSGiannis Adamopoulos     {
33352ed535daSGiannis Adamopoulos         TaskbarSettings* newSettings = (TaskbarSettings*)lParam;
33362ed535daSGiannis Adamopoulos 
33372ed535daSGiannis Adamopoulos         /* Propagate the new settings to the children */
33382ed535daSGiannis Adamopoulos         ::SendMessageW(m_TaskSwitch, uMsg, wParam, lParam);
33392ed535daSGiannis Adamopoulos         ::SendMessageW(m_TrayNotify, uMsg, wParam, lParam);
33402ed535daSGiannis Adamopoulos 
33412ed535daSGiannis Adamopoulos         /* Toggle autohide */
33422ed535daSGiannis Adamopoulos         if (newSettings->sr.AutoHide != g_TaskbarSettings.sr.AutoHide)
33432ed535daSGiannis Adamopoulos         {
33442ed535daSGiannis Adamopoulos             g_TaskbarSettings.sr.AutoHide = newSettings->sr.AutoHide;
33452ed535daSGiannis Adamopoulos             memset(&m_AutoHideOffset, 0, sizeof(m_AutoHideOffset));
33462ed535daSGiannis Adamopoulos             m_AutoHideState = AUTOHIDE_SHOWN;
33472ed535daSGiannis Adamopoulos             if (!newSettings->sr.AutoHide)
33482ed535daSGiannis Adamopoulos                 SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOZORDER);
33492ed535daSGiannis Adamopoulos             else
33502ed535daSGiannis Adamopoulos                 SetTimer(TIMER_ID_MOUSETRACK, MOUSETRACK_INTERVAL, NULL);
33512ed535daSGiannis Adamopoulos         }
33522ed535daSGiannis Adamopoulos 
33532ed535daSGiannis Adamopoulos         /* Toggle lock state */
33542ed535daSGiannis Adamopoulos         Lock(newSettings->bLock);
33552ed535daSGiannis Adamopoulos 
33562ed535daSGiannis Adamopoulos         /* Toggle OnTop state */
33572ed535daSGiannis Adamopoulos         if (newSettings->sr.AlwaysOnTop != g_TaskbarSettings.sr.AlwaysOnTop)
33582ed535daSGiannis Adamopoulos         {
33592ed535daSGiannis Adamopoulos             g_TaskbarSettings.sr.AlwaysOnTop = newSettings->sr.AlwaysOnTop;
33602ed535daSGiannis Adamopoulos             HWND hWndInsertAfter = newSettings->sr.AlwaysOnTop ? HWND_TOPMOST : HWND_BOTTOM;
33612ed535daSGiannis Adamopoulos             SetWindowPos(hWndInsertAfter, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
33622ed535daSGiannis Adamopoulos         }
33632ed535daSGiannis Adamopoulos 
336428ae9fb7SCarl J. Bialorucki         /* Adjust taskbar size */
336528ae9fb7SCarl J. Bialorucki         CheckTrayWndPosition();
336628ae9fb7SCarl J. Bialorucki 
33672ed535daSGiannis Adamopoulos         g_TaskbarSettings.Save();
33682ed535daSGiannis Adamopoulos         return 0;
33692ed535daSGiannis Adamopoulos     }
33702ed535daSGiannis Adamopoulos 
3371c2c66affSColin Finck     DECLARE_WND_CLASS_EX(szTrayWndClass, CS_DBLCLKS, COLOR_3DFACE)
3372c2c66affSColin Finck 
3373c2c66affSColin Finck     BEGIN_MSG_MAP(CTrayWindow)
3374c2c66affSColin Finck         if (m_StartMenuBand != NULL)
3375c2c66affSColin Finck         {
3376c2c66affSColin Finck             MSG Msg;
3377c2c66affSColin Finck             LRESULT lRet;
3378c2c66affSColin Finck 
3379c2c66affSColin Finck             Msg.hwnd = m_hWnd;
3380c2c66affSColin Finck             Msg.message = uMsg;
3381c2c66affSColin Finck             Msg.wParam = wParam;
3382c2c66affSColin Finck             Msg.lParam = lParam;
3383c2c66affSColin Finck 
3384c2c66affSColin Finck             if (m_StartMenuBand->TranslateMenuMessage(&Msg, &lRet) == S_OK)
3385c2c66affSColin Finck             {
3386c2c66affSColin Finck                 return lRet;
3387c2c66affSColin Finck             }
3388c2c66affSColin Finck 
3389c2c66affSColin Finck             wParam = Msg.wParam;
3390c2c66affSColin Finck             lParam = Msg.lParam;
3391c2c66affSColin Finck         }
MESSAGE_HANDLER(WM_THEMECHANGED,OnThemeChanged)3392c2c66affSColin Finck         MESSAGE_HANDLER(WM_THEMECHANGED, OnThemeChanged)
3393c2c66affSColin Finck         MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChanged)
3394c2c66affSColin Finck         NOTIFY_CODE_HANDLER(RBN_AUTOSIZE, OnRebarAutoSize) // Doesn't quite work ;P
3395c2c66affSColin Finck         MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
3396c2c66affSColin Finck         MESSAGE_HANDLER(WM_SIZE, OnSize)
3397c2c66affSColin Finck         MESSAGE_HANDLER(WM_CREATE, OnCreate)
3398e6bced7aSKatayama Hirofumi MZ         MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
3399802dc971SWhindmar Saksit         MESSAGE_HANDLER(WM_ENDSESSION, OnEndSession)
3400c2c66affSColin Finck         MESSAGE_HANDLER(WM_NCHITTEST, OnNcHitTest)
3401c2c66affSColin Finck         MESSAGE_HANDLER(WM_COMMAND, OnCommand)
3402c2c66affSColin Finck         MESSAGE_HANDLER(WM_SYSCOMMAND, OnSysCommand)
3403c2c66affSColin Finck         MESSAGE_HANDLER(WM_NOTIFY, OnNotify)
3404c2c66affSColin Finck         MESSAGE_HANDLER(WM_CONTEXTMENU, OnContextMenu)
3405c2c66affSColin Finck         MESSAGE_HANDLER(WM_TIMER, OnTimer)
3406c2c66affSColin Finck         MESSAGE_HANDLER(WM_DISPLAYCHANGE, OnDisplayChange)
3407c2c66affSColin Finck         MESSAGE_HANDLER(WM_COPYDATA, OnCopyData)
3408c2c66affSColin Finck         MESSAGE_HANDLER(WM_NCPAINT, OnNcPaint)
340926efda4dSKatayama Hirofumi MZ         MESSAGE_HANDLER(WM_NCACTIVATE, OnNcActivate)
3410c2c66affSColin Finck         MESSAGE_HANDLER(WM_CTLCOLORBTN, OnCtlColorBtn)
3411*751641c2SWhindmar Saksit         MESSAGE_HANDLER(WM_SYSCOLORCHANGE, OnSysColorChange)
3412c2c66affSColin Finck         MESSAGE_HANDLER(WM_MOVING, OnMoving)
3413c2c66affSColin Finck         MESSAGE_HANDLER(WM_SIZING, OnSizing)
34144238f223SGiannis Adamopoulos         MESSAGE_HANDLER(WM_WINDOWPOSCHANGING, OnWindowPosChanging)
3415c2c66affSColin Finck         MESSAGE_HANDLER(WM_ENTERSIZEMOVE, OnEnterSizeMove)
3416c2c66affSColin Finck         MESSAGE_HANDLER(WM_EXITSIZEMOVE, OnExitSizeMove)
3417c2c66affSColin Finck         MESSAGE_HANDLER(WM_NCLBUTTONDOWN, OnNcLButtonDown)
3418c2c66affSColin Finck         MESSAGE_HANDLER(WM_SYSCHAR, OnSysChar)
3419c2c66affSColin Finck         MESSAGE_HANDLER(WM_NCRBUTTONUP, OnNcRButtonUp)
3420c2c66affSColin Finck         MESSAGE_HANDLER(WM_NCLBUTTONDBLCLK, OnNcLButtonDblClick)
342170d7009aSEthan Rodensky         MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
342246de3a22SKatayama Hirofumi MZ         MESSAGE_HANDLER(WM_NCLBUTTONUP, OnNcLButtonUp)
3423c2c66affSColin Finck         MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
3424c2c66affSColin Finck         MESSAGE_HANDLER(WM_NCMOUSEMOVE, OnMouseMove)
3425c2c66affSColin Finck         MESSAGE_HANDLER(WM_APP_TRAYDESTROY, OnAppTrayDestroy)
3426c2c66affSColin Finck         MESSAGE_HANDLER(WM_CLOSE, OnDoExitWindows)
3427c2c66affSColin Finck         MESSAGE_HANDLER(WM_HOTKEY, OnHotkey)
3428c2c66affSColin Finck         MESSAGE_HANDLER(WM_NCCALCSIZE, OnNcCalcSize)
342975b09f3fSKatayama Hirofumi MZ         MESSAGE_HANDLER(WM_INITMENUPOPUP, OnInitMenuPopup)
34302ed535daSGiannis Adamopoulos         MESSAGE_HANDLER(TWM_SETTINGSCHANGED, OnTaskbarSettingsChanged)
3431a882ec7aSKatayama Hirofumi MZ         MESSAGE_HANDLER(TWM_OPENSTARTMENU, OnOpenStartMenu)
3432a882ec7aSKatayama Hirofumi MZ         MESSAGE_HANDLER(TWM_DOEXITWINDOWS, OnDoExitWindows)
34336940d9fdSMark Jansen         MESSAGE_HANDLER(TWM_GETTASKSWITCH, OnGetTaskSwitch)
3434e6bced7aSKatayama Hirofumi MZ         MESSAGE_HANDLER(TWM_PULSE, OnPulse)
3435c2c66affSColin Finck     ALT_MSG_MAP(1)
3436c2c66affSColin Finck     END_MSG_MAP()
3437c2c66affSColin Finck 
3438c2c66affSColin Finck     /*****************************************************************************/
3439c2c66affSColin Finck 
3440c2c66affSColin Finck     VOID TrayProcessMessages()
3441c2c66affSColin Finck     {
3442c2c66affSColin Finck         MSG Msg;
3443c2c66affSColin Finck 
3444c2c66affSColin Finck         /* FIXME: We should keep a reference here... */
3445c2c66affSColin Finck 
3446c2c66affSColin Finck         while (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))
3447c2c66affSColin Finck         {
3448c2c66affSColin Finck             if (Msg.message == WM_QUIT)
3449c2c66affSColin Finck                 break;
3450c2c66affSColin Finck 
3451c2c66affSColin Finck             if (m_StartMenuBand == NULL ||
3452c2c66affSColin Finck                 m_StartMenuBand->IsMenuMessage(&Msg) != S_OK)
3453c2c66affSColin Finck             {
3454c2c66affSColin Finck                 TranslateMessage(&Msg);
3455c2c66affSColin Finck                 DispatchMessage(&Msg);
3456c2c66affSColin Finck             }
3457c2c66affSColin Finck         }
3458c2c66affSColin Finck     }
3459c2c66affSColin Finck 
TrayMessageLoop()3460c2c66affSColin Finck     VOID TrayMessageLoop()
3461c2c66affSColin Finck     {
3462c2c66affSColin Finck         MSG Msg;
3463c2c66affSColin Finck         BOOL Ret;
3464c2c66affSColin Finck 
3465c2c66affSColin Finck         /* FIXME: We should keep a reference here... */
3466c2c66affSColin Finck 
3467c2c66affSColin Finck         while (true)
3468c2c66affSColin Finck         {
3469c2c66affSColin Finck             Ret = GetMessage(&Msg, NULL, 0, 0);
3470c2c66affSColin Finck 
3471c2c66affSColin Finck             if (!Ret || Ret == -1)
3472c2c66affSColin Finck                 break;
3473c2c66affSColin Finck 
3474c2c66affSColin Finck             if (m_StartMenuBand == NULL ||
3475c2c66affSColin Finck                 m_StartMenuBand->IsMenuMessage(&Msg) != S_OK)
3476c2c66affSColin Finck             {
3477c2c66affSColin Finck                 TranslateMessage(&Msg);
3478c2c66affSColin Finck                 DispatchMessage(&Msg);
3479c2c66affSColin Finck             }
3480c2c66affSColin Finck         }
3481c2c66affSColin Finck     }
3482c2c66affSColin Finck 
3483c2c66affSColin Finck     /*
3484c2c66affSColin Finck      * IShellDesktopTray
3485c2c66affSColin Finck      *
3486c2c66affSColin Finck      * NOTE: this is a very windows-specific COM interface used by SHCreateDesktop()!
3487c2c66affSColin Finck      *       These are the calls I observed, it may be wrong/incomplete/buggy!!!
3488c2c66affSColin Finck      *       The reason we implement it is because we have to use SHCreateDesktop() so
3489c2c66affSColin Finck      *       that the shell provides the desktop window and all the features that come
3490c2c66affSColin Finck      *       with it (especially positioning of desktop icons)
3491c2c66affSColin Finck      */
3492c2c66affSColin Finck 
GetState()3493c2c66affSColin Finck     virtual ULONG STDMETHODCALLTYPE GetState()
3494c2c66affSColin Finck     {
3495c2c66affSColin Finck         /* FIXME: Return ABS_ flags? */
3496c2c66affSColin Finck         TRACE("IShellDesktopTray::GetState() unimplemented!\n");
3497c2c66affSColin Finck         return 0;
3498c2c66affSColin Finck     }
3499c2c66affSColin Finck 
GetTrayWindow(OUT HWND * phWndTray)3500c2c66affSColin Finck     virtual HRESULT STDMETHODCALLTYPE GetTrayWindow(OUT HWND *phWndTray)
3501c2c66affSColin Finck     {
3502c2c66affSColin Finck         TRACE("IShellDesktopTray::GetTrayWindow(0x%p)\n", phWndTray);
3503c2c66affSColin Finck         *phWndTray = m_hWnd;
3504c2c66affSColin Finck         return S_OK;
3505c2c66affSColin Finck     }
3506c2c66affSColin Finck 
RegisterDesktopWindow(IN HWND hWndDesktop)3507c2c66affSColin Finck     virtual HRESULT STDMETHODCALLTYPE RegisterDesktopWindow(IN HWND hWndDesktop)
3508c2c66affSColin Finck     {
3509c2c66affSColin Finck         TRACE("IShellDesktopTray::RegisterDesktopWindow(0x%p)\n", hWndDesktop);
3510c2c66affSColin Finck 
3511c2c66affSColin Finck         m_DesktopWnd = hWndDesktop;
3512c2c66affSColin Finck         return S_OK;
3513c2c66affSColin Finck     }
3514c2c66affSColin Finck 
Unknown(IN DWORD dwUnknown1,IN DWORD dwUnknown2)3515c2c66affSColin Finck     virtual HRESULT STDMETHODCALLTYPE Unknown(IN DWORD dwUnknown1, IN DWORD dwUnknown2)
3516c2c66affSColin Finck     {
3517c2c66affSColin Finck         TRACE("IShellDesktopTray::Unknown(%u,%u) unimplemented!\n", dwUnknown1, dwUnknown2);
3518c2c66affSColin Finck         return S_OK;
3519c2c66affSColin Finck     }
3520c2c66affSColin Finck 
RaiseStartButton()3521c2c66affSColin Finck     virtual HRESULT RaiseStartButton()
3522c2c66affSColin Finck     {
3523c2c66affSColin Finck         m_StartButton.SendMessageW(BM_SETSTATE, FALSE, 0);
3524c2c66affSColin Finck         return S_OK;
3525c2c66affSColin Finck     }
3526c2c66affSColin Finck 
GetWindow(HWND * phwnd)3527c2c66affSColin Finck     HRESULT WINAPI GetWindow(HWND* phwnd)
3528c2c66affSColin Finck     {
3529c2c66affSColin Finck         if (!phwnd)
3530c2c66affSColin Finck             return E_INVALIDARG;
3531c2c66affSColin Finck         *phwnd = m_hWnd;
3532c2c66affSColin Finck         return S_OK;
3533c2c66affSColin Finck     }
3534c2c66affSColin Finck 
ContextSensitiveHelp(BOOL fEnterMode)3535c2c66affSColin Finck     HRESULT WINAPI ContextSensitiveHelp(BOOL fEnterMode)
3536c2c66affSColin Finck     {
3537c2c66affSColin Finck         return E_NOTIMPL;
3538c2c66affSColin Finck     }
3539c2c66affSColin Finck 
_Init()3540c2c66affSColin Finck     void _Init()
3541c2c66affSColin Finck     {
3542c2c66affSColin Finck         m_Position = (DWORD) -1;
3543c2c66affSColin Finck     }
3544c2c66affSColin Finck 
3545c2c66affSColin Finck     DECLARE_NOT_AGGREGATABLE(CTrayWindow)
3546c2c66affSColin Finck 
3547c2c66affSColin Finck     DECLARE_PROTECT_FINAL_CONSTRUCT()
3548c2c66affSColin Finck     BEGIN_COM_MAP(CTrayWindow)
3549c2c66affSColin Finck         /*COM_INTERFACE_ENTRY_IID(IID_ITrayWindow, ITrayWindow)*/
3550c2c66affSColin Finck         COM_INTERFACE_ENTRY_IID(IID_IShellDesktopTray, IShellDesktopTray)
3551c2c66affSColin Finck         COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
3552c2c66affSColin Finck         COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
3553c2c66affSColin Finck     END_COM_MAP()
3554c2c66affSColin Finck };
3555c2c66affSColin Finck 
3556c2c66affSColin Finck class CTrayWindowCtxMenu :
3557c2c66affSColin Finck     public CComCoClass<CTrayWindowCtxMenu>,
3558c2c66affSColin Finck     public CComObjectRootEx<CComMultiThreadModelNoCS>,
3559c2c66affSColin Finck     public IContextMenu
3560c2c66affSColin Finck {
3561c2c66affSColin Finck     HWND hWndOwner;
3562c2c66affSColin Finck     CComPtr<CTrayWindow> TrayWnd;
3563c2c66affSColin Finck     CComPtr<IContextMenu> pcm;
3564c2c66affSColin Finck     UINT m_idCmdCmFirst;
3565c2c66affSColin Finck 
3566c2c66affSColin Finck public:
Initialize(ITrayWindow * pTrayWnd,IN HWND hWndOwner)3567c2c66affSColin Finck     HRESULT Initialize(ITrayWindow * pTrayWnd, IN HWND hWndOwner)
3568c2c66affSColin Finck     {
3569c2c66affSColin Finck         this->TrayWnd = (CTrayWindow *) pTrayWnd;
3570c2c66affSColin Finck         this->hWndOwner = hWndOwner;
3571c2c66affSColin Finck         this->m_idCmdCmFirst = 0;
3572c2c66affSColin Finck         return S_OK;
3573c2c66affSColin Finck     }
3574c2c66affSColin Finck 
3575c2c66affSColin Finck     virtual HRESULT STDMETHODCALLTYPE
QueryContextMenu(HMENU hPopup,UINT indexMenu,UINT idCmdFirst,UINT idCmdLast,UINT uFlags)3576c2c66affSColin Finck         QueryContextMenu(HMENU hPopup,
3577c2c66affSColin Finck                          UINT indexMenu,
3578c2c66affSColin Finck                          UINT idCmdFirst,
3579c2c66affSColin Finck                          UINT idCmdLast,
3580c2c66affSColin Finck                          UINT uFlags)
3581c2c66affSColin Finck     {
358275b09f3fSKatayama Hirofumi MZ         HMENU hMenuBase;
358375b09f3fSKatayama Hirofumi MZ 
358475b09f3fSKatayama Hirofumi MZ         hMenuBase = LoadPopupMenu(hExplorerInstance, MAKEINTRESOURCEW(IDM_TRAYWND));
358543b3280fSWhindmar Saksit         if (!hMenuBase)
358643b3280fSWhindmar Saksit             return HResultFromWin32(GetLastError());
358775b09f3fSKatayama Hirofumi MZ 
358875b09f3fSKatayama Hirofumi MZ         if (g_MinimizedAll.GetSize() != 0 && !::IsThereAnyEffectiveWindow(TRUE))
358975b09f3fSKatayama Hirofumi MZ         {
359075b09f3fSKatayama Hirofumi MZ             CStringW strRestoreAll(MAKEINTRESOURCEW(IDS_RESTORE_ALL));
359175b09f3fSKatayama Hirofumi MZ             MENUITEMINFOW mii = { sizeof(mii) };
359275b09f3fSKatayama Hirofumi MZ             mii.fMask = MIIM_ID | MIIM_TYPE;
359375b09f3fSKatayama Hirofumi MZ             mii.wID = ID_SHELL_CMD_RESTORE_ALL;
359475b09f3fSKatayama Hirofumi MZ             mii.fType = MFT_STRING;
359575b09f3fSKatayama Hirofumi MZ             mii.dwTypeData = const_cast<LPWSTR>(&strRestoreAll[0]);
359675b09f3fSKatayama Hirofumi MZ             SetMenuItemInfoW(hMenuBase, ID_SHELL_CMD_SHOW_DESKTOP, FALSE, &mii);
359775b09f3fSKatayama Hirofumi MZ         }
359875b09f3fSKatayama Hirofumi MZ 
3599c2c66affSColin Finck         if (SHRestricted(REST_CLASSICSHELL) != 0)
3600c2c66affSColin Finck         {
3601c2c66affSColin Finck             DeleteMenu(hPopup,
3602c2c66affSColin Finck                        ID_LOCKTASKBAR,
3603c2c66affSColin Finck                        MF_BYCOMMAND);
3604c2c66affSColin Finck         }
3605c2c66affSColin Finck 
360675b09f3fSKatayama Hirofumi MZ         CheckMenuItem(hMenuBase,
3607c2c66affSColin Finck                       ID_LOCKTASKBAR,
36082ed535daSGiannis Adamopoulos                       MF_BYCOMMAND | (g_TaskbarSettings.bLock ? MF_CHECKED : MF_UNCHECKED));
3609c2c66affSColin Finck 
3610c2c66affSColin Finck         UINT idCmdNext;
361175b09f3fSKatayama Hirofumi MZ         idCmdNext = Shell_MergeMenus(hPopup, hMenuBase, indexMenu, idCmdFirst, idCmdLast, MM_SUBMENUSHAVEIDS | MM_ADDSEPARATOR);
3612c2c66affSColin Finck         m_idCmdCmFirst = idCmdNext - idCmdFirst;
3613c2c66affSColin Finck 
361475b09f3fSKatayama Hirofumi MZ         ::DestroyMenu(hMenuBase);
3615c2c66affSColin Finck 
3616c2c66affSColin Finck         if (TrayWnd->m_TrayBandSite != NULL)
3617c2c66affSColin Finck         {
3618d9589502SKatayama Hirofumi MZ             pcm.Release();
3619c2c66affSColin Finck             if (FAILED(TrayWnd->m_TrayBandSite->AddContextMenus(
3620c2c66affSColin Finck                 hPopup,
3621c2c66affSColin Finck                 indexMenu,
3622c2c66affSColin Finck                 idCmdNext,
3623c2c66affSColin Finck                 idCmdLast,
3624c2c66affSColin Finck                 CMF_NORMAL,
3625c2c66affSColin Finck                 &pcm)))
3626c2c66affSColin Finck             {
3627c2c66affSColin Finck                 WARN("AddContextMenus failed.\n");
3628d9589502SKatayama Hirofumi MZ                 pcm.Release();
3629c2c66affSColin Finck             }
3630c2c66affSColin Finck         }
3631c2c66affSColin Finck 
3632c2c66affSColin Finck         return S_OK;
3633c2c66affSColin Finck     }
3634c2c66affSColin Finck 
3635c2c66affSColin Finck     virtual HRESULT STDMETHODCALLTYPE
InvokeCommand(LPCMINVOKECOMMANDINFO lpici)3636c2c66affSColin Finck         InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
3637c2c66affSColin Finck     {
3638cf77354dSTimo Kreuzer         UINT uiCmdId = PtrToUlong(lpici->lpVerb);
3639c2c66affSColin Finck         if (uiCmdId != 0)
3640c2c66affSColin Finck         {
3641c2c66affSColin Finck             if (uiCmdId >= m_idCmdCmFirst)
3642c2c66affSColin Finck             {
3643c2c66affSColin Finck                 CMINVOKECOMMANDINFO cmici = { 0 };
3644c2c66affSColin Finck 
3645c2c66affSColin Finck                 if (pcm != NULL)
3646c2c66affSColin Finck                 {
3647c2c66affSColin Finck                     /* Setup and invoke the shell command */
3648c2c66affSColin Finck                     cmici.cbSize = sizeof(cmici);
3649c2c66affSColin Finck                     cmici.hwnd = hWndOwner;
3650c2c66affSColin Finck                     cmici.lpVerb = (LPCSTR) MAKEINTRESOURCEW(uiCmdId - m_idCmdCmFirst);
3651c2c66affSColin Finck                     cmici.nShow = SW_NORMAL;
3652c2c66affSColin Finck 
3653c2c66affSColin Finck                     pcm->InvokeCommand(&cmici);
3654c2c66affSColin Finck                 }
3655c2c66affSColin Finck             }
3656c2c66affSColin Finck             else
3657c2c66affSColin Finck             {
3658c2c66affSColin Finck                 TrayWnd->ExecContextMenuCmd(uiCmdId);
3659c2c66affSColin Finck             }
3660c2c66affSColin Finck         }
3661c2c66affSColin Finck 
3662c2c66affSColin Finck         return S_OK;
3663c2c66affSColin Finck     }
3664c2c66affSColin Finck 
3665c2c66affSColin Finck     virtual HRESULT STDMETHODCALLTYPE
GetCommandString(UINT_PTR idCmd,UINT uType,UINT * pwReserved,LPSTR pszName,UINT cchMax)3666c2c66affSColin Finck         GetCommandString(UINT_PTR idCmd,
3667c2c66affSColin Finck         UINT uType,
3668c2c66affSColin Finck         UINT *pwReserved,
3669c2c66affSColin Finck         LPSTR pszName,
3670c2c66affSColin Finck         UINT cchMax)
3671c2c66affSColin Finck     {
3672c2c66affSColin Finck         return E_NOTIMPL;
3673c2c66affSColin Finck     }
3674c2c66affSColin Finck 
CTrayWindowCtxMenu()3675c2c66affSColin Finck     CTrayWindowCtxMenu()
3676c2c66affSColin Finck     {
3677c2c66affSColin Finck     }
3678c2c66affSColin Finck 
~CTrayWindowCtxMenu()3679c2c66affSColin Finck     virtual ~CTrayWindowCtxMenu()
3680c2c66affSColin Finck     {
3681c2c66affSColin Finck     }
3682c2c66affSColin Finck 
3683c2c66affSColin Finck     BEGIN_COM_MAP(CTrayWindowCtxMenu)
3684c2c66affSColin Finck         COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
3685c2c66affSColin Finck     END_COM_MAP()
3686c2c66affSColin Finck };
3687c2c66affSColin Finck 
TrayWindowCtxMenuCreator(ITrayWindow * TrayWnd,IN HWND hWndOwner,IContextMenu ** ppCtxMenu)3688c2c66affSColin Finck HRESULT TrayWindowCtxMenuCreator(ITrayWindow * TrayWnd, IN HWND hWndOwner, IContextMenu ** ppCtxMenu)
3689c2c66affSColin Finck {
3690c2c66affSColin Finck     CTrayWindowCtxMenu * mnu = new CComObject<CTrayWindowCtxMenu>();
3691c2c66affSColin Finck     mnu->Initialize(TrayWnd, hWndOwner);
3692c2c66affSColin Finck     *ppCtxMenu = mnu;
3693c2c66affSColin Finck     return S_OK;
3694c2c66affSColin Finck }
3695c2c66affSColin Finck 
CreateTrayWindow(ITrayWindow ** ppTray)3696c2c66affSColin Finck HRESULT CreateTrayWindow(ITrayWindow ** ppTray)
3697c2c66affSColin Finck {
3698c2c66affSColin Finck     CComPtr<CTrayWindow> Tray = new CComObject<CTrayWindow>();
3699c2c66affSColin Finck     if (Tray == NULL)
3700c2c66affSColin Finck         return E_OUTOFMEMORY;
3701c2c66affSColin Finck 
3702c2c66affSColin Finck     Tray->_Init();
3703c2c66affSColin Finck     Tray->Open();
3704c2c66affSColin Finck 
3705c2c66affSColin Finck     *ppTray = (ITrayWindow *) Tray;
3706c2c66affSColin Finck 
3707c2c66affSColin Finck     return S_OK;
3708c2c66affSColin Finck }
3709c2c66affSColin Finck 
3710c2c66affSColin Finck HRESULT
Tray_OnStartMenuDismissed(ITrayWindow * Tray)3711c2c66affSColin Finck Tray_OnStartMenuDismissed(ITrayWindow* Tray)
3712c2c66affSColin Finck {
3713c2c66affSColin Finck     CTrayWindow * TrayWindow = static_cast<CTrayWindow *>(Tray);
3714c2c66affSColin Finck     return TrayWindow->RaiseStartButton();
3715c2c66affSColin Finck }
3716c2c66affSColin Finck 
TrayProcessMessages(ITrayWindow * Tray)3717c2c66affSColin Finck VOID TrayProcessMessages(ITrayWindow *Tray)
3718c2c66affSColin Finck {
3719c2c66affSColin Finck     CTrayWindow * TrayWindow = static_cast<CTrayWindow *>(Tray);
3720c2c66affSColin Finck     TrayWindow->TrayProcessMessages();
3721c2c66affSColin Finck }
3722c2c66affSColin Finck 
TrayMessageLoop(ITrayWindow * Tray)3723c2c66affSColin Finck VOID TrayMessageLoop(ITrayWindow *Tray)
3724c2c66affSColin Finck {
3725c2c66affSColin Finck     CTrayWindow * TrayWindow = static_cast<CTrayWindow *>(Tray);
3726c2c66affSColin Finck     TrayWindow->TrayMessageLoop();
3727c2c66affSColin Finck }
3728