1c2c66affSColin Finck /* 2c2c66affSColin Finck * ReactOS Explorer 3c2c66affSColin Finck * 4c2c66affSColin Finck * Copyright 2006 - 2007 Thomas Weidenmueller <w3seek@reactos.org> 5c2c66affSColin Finck * 6c2c66affSColin Finck * this library is free software; you can redistribute it and/or 7c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public 8c2c66affSColin Finck * License as published by the Free Software Foundation; either 9c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version. 10c2c66affSColin Finck * 11c2c66affSColin Finck * this library is distributed in the hope that it will be useful, 12c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of 13c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14c2c66affSColin Finck * Lesser General Public License for more details. 15c2c66affSColin Finck * 16c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public 17c2c66affSColin Finck * License along with this library; if not, write to the Free Software 18c2c66affSColin Finck * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19c2c66affSColin Finck */ 20c2c66affSColin Finck 21c2c66affSColin Finck #include "precomp.h" 22c2c66affSColin Finck #include <commoncontrols.h> 23c2c66affSColin Finck 24c2c66affSColin Finck HRESULT TrayWindowCtxMenuCreator(ITrayWindow * TrayWnd, IN HWND hWndOwner, IContextMenu ** ppCtxMenu); 25c2c66affSColin Finck 26c2c66affSColin Finck #define WM_APP_TRAYDESTROY (WM_APP + 0x100) 27c2c66affSColin Finck 28c2c66affSColin Finck #define TIMER_ID_AUTOHIDE 1 29c2c66affSColin Finck #define TIMER_ID_MOUSETRACK 2 30c2c66affSColin Finck #define MOUSETRACK_INTERVAL 100 31c2c66affSColin Finck #define AUTOHIDE_DELAY_HIDE 2000 32c2c66affSColin Finck #define AUTOHIDE_DELAY_SHOW 50 33c2c66affSColin Finck #define AUTOHIDE_INTERVAL_ANIMATING 10 34c2c66affSColin Finck 35c2c66affSColin Finck #define AUTOHIDE_SPEED_SHOW 10 36c2c66affSColin Finck #define AUTOHIDE_SPEED_HIDE 1 37c2c66affSColin Finck 38c2c66affSColin Finck #define AUTOHIDE_HIDDEN 0 39c2c66affSColin Finck #define AUTOHIDE_SHOWING 1 40c2c66affSColin Finck #define AUTOHIDE_SHOWN 2 41c2c66affSColin Finck #define AUTOHIDE_HIDING 3 42c2c66affSColin Finck 43c2c66affSColin Finck #define IDHK_RUN 0x1f4 44c2c66affSColin Finck #define IDHK_MINIMIZE_ALL 0x1f5 45c2c66affSColin Finck #define IDHK_RESTORE_ALL 0x1f6 46c2c66affSColin Finck #define IDHK_HELP 0x1f7 47c2c66affSColin Finck #define IDHK_EXPLORE 0x1f8 48c2c66affSColin Finck #define IDHK_FIND 0x1f9 49c2c66affSColin Finck #define IDHK_FIND_COMPUTER 0x1fa 50c2c66affSColin Finck #define IDHK_NEXT_TASK 0x1fb 51c2c66affSColin Finck #define IDHK_PREV_TASK 0x1fc 52c2c66affSColin Finck #define IDHK_SYS_PROPERTIES 0x1fd 53c2c66affSColin Finck #define IDHK_DESKTOP 0x1fe 54c2c66affSColin Finck #define IDHK_PAGER 0x1ff 55c2c66affSColin Finck 56c2c66affSColin Finck static const WCHAR szTrayWndClass[] = L"Shell_TrayWnd"; 57c2c66affSColin Finck 58c2c66affSColin Finck /* 59c2c66affSColin Finck * ITrayWindow 60c2c66affSColin Finck */ 61c2c66affSColin Finck 62c2c66affSColin Finck const GUID IID_IShellDesktopTray = { 0x213e2df9, 0x9a14, 0x4328, { 0x99, 0xb1, 0x69, 0x61, 0xf9, 0x14, 0x3c, 0xe9 } }; 63c2c66affSColin Finck 64c2c66affSColin Finck class CStartButton 65c2c66affSColin Finck : public CWindowImpl<CStartButton> 66c2c66affSColin Finck { 67c2c66affSColin Finck HIMAGELIST m_ImageList; 68c2c66affSColin Finck SIZE m_Size; 69c2c66affSColin Finck HFONT m_Font; 70c2c66affSColin Finck 71c2c66affSColin Finck public: 72c2c66affSColin Finck CStartButton() 73c2c66affSColin Finck : m_ImageList(NULL), 74c2c66affSColin Finck m_Font(NULL) 75c2c66affSColin Finck { 76c2c66affSColin Finck m_Size.cx = 0; 77c2c66affSColin Finck m_Size.cy = 0; 78c2c66affSColin Finck } 79c2c66affSColin Finck 80c2c66affSColin Finck virtual ~CStartButton() 81c2c66affSColin Finck { 82c2c66affSColin Finck if (m_ImageList != NULL) 83c2c66affSColin Finck ImageList_Destroy(m_ImageList); 84c2c66affSColin Finck 85c2c66affSColin Finck if (m_Font != NULL) 86c2c66affSColin Finck DeleteObject(m_Font); 87c2c66affSColin Finck } 88c2c66affSColin Finck 89c2c66affSColin Finck SIZE GetSize() 90c2c66affSColin Finck { 91c2c66affSColin Finck return m_Size; 92c2c66affSColin Finck } 93c2c66affSColin Finck 94c2c66affSColin Finck VOID UpdateSize() 95c2c66affSColin Finck { 96c2c66affSColin Finck SIZE Size = { 0, 0 }; 97c2c66affSColin Finck 98c2c66affSColin Finck if (m_ImageList == NULL || 99c2c66affSColin Finck !SendMessageW(BCM_GETIDEALSIZE, 0, (LPARAM) &Size)) 100c2c66affSColin Finck { 101c2c66affSColin Finck Size.cx = 2 * GetSystemMetrics(SM_CXEDGE) + GetSystemMetrics(SM_CYCAPTION) * 3; 102c2c66affSColin Finck } 103c2c66affSColin Finck 104c2c66affSColin Finck Size.cy = max(Size.cy, GetSystemMetrics(SM_CYCAPTION)); 105c2c66affSColin Finck 106c2c66affSColin Finck /* Save the size of the start button */ 107c2c66affSColin Finck m_Size = Size; 108c2c66affSColin Finck } 109c2c66affSColin Finck 110c2c66affSColin Finck VOID UpdateFont() 111c2c66affSColin Finck { 112c2c66affSColin Finck /* Get the system fonts, we use the caption font, always bold, though. */ 113c2c66affSColin Finck NONCLIENTMETRICS ncm = {sizeof(ncm)}; 114c2c66affSColin Finck if (!SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, FALSE)) 115c2c66affSColin Finck return; 116c2c66affSColin Finck 117c2c66affSColin Finck if (m_Font) 118c2c66affSColin Finck DeleteObject(m_Font); 119c2c66affSColin Finck 120c2c66affSColin Finck ncm.lfCaptionFont.lfWeight = FW_BOLD; 121c2c66affSColin Finck m_Font = CreateFontIndirect(&ncm.lfCaptionFont); 122c2c66affSColin Finck 123c2c66affSColin Finck SetFont(m_Font, FALSE); 124c2c66affSColin Finck } 125c2c66affSColin Finck 126c2c66affSColin Finck VOID Initialize() 127c2c66affSColin Finck { 128c2c66affSColin Finck SubclassWindow(m_hWnd); 129c2c66affSColin Finck SetWindowTheme(m_hWnd, L"Start", NULL); 130c2c66affSColin Finck 131c2c66affSColin Finck m_ImageList = ImageList_LoadImageW(hExplorerInstance, 132c2c66affSColin Finck MAKEINTRESOURCEW(IDB_START), 133c2c66affSColin Finck 0, 0, 0, 134c2c66affSColin Finck IMAGE_BITMAP, 135c2c66affSColin Finck LR_LOADTRANSPARENT | LR_CREATEDIBSECTION); 136c2c66affSColin Finck 137c2c66affSColin Finck BUTTON_IMAGELIST bil = {m_ImageList, {1,1,1,1}, BUTTON_IMAGELIST_ALIGN_LEFT}; 138c2c66affSColin Finck SendMessageW(BCM_SETIMAGELIST, 0, (LPARAM) &bil); 139c2c66affSColin Finck UpdateSize(); 140c2c66affSColin Finck } 141c2c66affSColin Finck 142c2c66affSColin Finck HWND Create(HWND hwndParent) 143c2c66affSColin Finck { 144c2c66affSColin Finck WCHAR szStartCaption[32]; 145c2c66affSColin Finck if (!LoadStringW(hExplorerInstance, 146c2c66affSColin Finck IDS_START, 147c2c66affSColin Finck szStartCaption, 148c2c66affSColin Finck _countof(szStartCaption))) 149c2c66affSColin Finck { 150c2c66affSColin Finck wcscpy(szStartCaption, L"Start"); 151c2c66affSColin Finck } 152c2c66affSColin Finck 153c2c66affSColin Finck DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | BS_PUSHBUTTON | BS_LEFT | BS_VCENTER; 154c2c66affSColin Finck 155c2c66affSColin Finck m_hWnd = CreateWindowEx( 156c2c66affSColin Finck 0, 157c2c66affSColin Finck WC_BUTTON, 158c2c66affSColin Finck szStartCaption, 159c2c66affSColin Finck dwStyle, 160c2c66affSColin Finck 0, 0, 0, 0, 161c2c66affSColin Finck hwndParent, 162c2c66affSColin Finck (HMENU) IDC_STARTBTN, 163c2c66affSColin Finck hExplorerInstance, 164c2c66affSColin Finck NULL); 165c2c66affSColin Finck 166c2c66affSColin Finck if (m_hWnd) 167c2c66affSColin Finck Initialize(); 168c2c66affSColin Finck 169c2c66affSColin Finck return m_hWnd; 170c2c66affSColin Finck } 171c2c66affSColin Finck 172c2c66affSColin Finck LRESULT OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 173c2c66affSColin Finck { 174c2c66affSColin Finck if (uMsg == WM_KEYUP && wParam != VK_SPACE) 175c2c66affSColin Finck return 0; 176c2c66affSColin Finck 177c2c66affSColin Finck GetParent().PostMessage(TWM_OPENSTARTMENU); 178c2c66affSColin Finck return 0; 179c2c66affSColin Finck } 180c2c66affSColin Finck 181c2c66affSColin Finck BEGIN_MSG_MAP(CStartButton) 182c2c66affSColin Finck MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown) 183c2c66affSColin Finck END_MSG_MAP() 184c2c66affSColin Finck 185c2c66affSColin Finck }; 186c2c66affSColin Finck 187c2c66affSColin Finck class CTrayWindow : 188c2c66affSColin Finck public CComCoClass<CTrayWindow>, 189c2c66affSColin Finck public CComObjectRootEx<CComMultiThreadModelNoCS>, 190c2c66affSColin Finck public CWindowImpl < CTrayWindow, CWindow, CControlWinTraits >, 191c2c66affSColin Finck public ITrayWindow, 192c2c66affSColin Finck public IShellDesktopTray, 193c2c66affSColin Finck public IOleWindow, 194c2c66affSColin Finck public IContextMenu 195c2c66affSColin Finck { 196c2c66affSColin Finck CStartButton m_StartButton; 197c2c66affSColin Finck 198c2c66affSColin Finck CComPtr<IMenuBand> m_StartMenuBand; 199c2c66affSColin Finck CComPtr<IMenuPopup> m_StartMenuPopup; 200c2c66affSColin Finck 201c2c66affSColin Finck CComPtr<IDeskBand> m_TaskBand; 202c2c66affSColin Finck CComPtr<IContextMenu> m_ContextMenu; 203c2c66affSColin Finck HTHEME m_Theme; 204c2c66affSColin Finck 205c2c66affSColin Finck HFONT m_Font; 206c2c66affSColin Finck 207c2c66affSColin Finck HWND m_DesktopWnd; 208c2c66affSColin Finck HWND m_Rebar; 209c2c66affSColin Finck HWND m_TaskSwitch; 210c2c66affSColin Finck HWND m_TrayNotify; 211c2c66affSColin Finck 212c2c66affSColin Finck CTrayNotifyWnd* m_TrayNotifyInstance; 213c2c66affSColin Finck 214c2c66affSColin Finck DWORD m_Position; 215c2c66affSColin Finck HMONITOR m_Monitor; 216c2c66affSColin Finck HMONITOR m_PreviousMonitor; 217c2c66affSColin Finck DWORD m_DraggingPosition; 218c2c66affSColin Finck HMONITOR m_DraggingMonitor; 219c2c66affSColin Finck 220c2c66affSColin Finck RECT m_TrayRects[4]; 221c2c66affSColin Finck SIZE m_TraySize; 222c2c66affSColin Finck 223c2c66affSColin Finck HWND m_TrayPropertiesOwner; 224c2c66affSColin Finck HWND m_RunFileDlgOwner; 225c2c66affSColin Finck 226c2c66affSColin Finck UINT m_AutoHideState; 227c2c66affSColin Finck SIZE m_AutoHideOffset; 228c2c66affSColin Finck TRACKMOUSEEVENT m_MouseTrackingInfo; 229c2c66affSColin Finck 230c2c66affSColin Finck HDPA m_ShellServices; 231c2c66affSColin Finck 232c2c66affSColin Finck public: 233c2c66affSColin Finck CComPtr<ITrayBandSite> m_TrayBandSite; 234c2c66affSColin Finck 235c2c66affSColin Finck union 236c2c66affSColin Finck { 237c2c66affSColin Finck DWORD Flags; 238c2c66affSColin Finck struct 239c2c66affSColin Finck { 240c2c66affSColin Finck /* UI Status */ 241c2c66affSColin Finck DWORD InSizeMove : 1; 242c2c66affSColin Finck DWORD IsDragging : 1; 243c2c66affSColin Finck DWORD NewPosSize : 1; 244c2c66affSColin Finck }; 245c2c66affSColin Finck }; 246c2c66affSColin Finck 247c2c66affSColin Finck public: 248c2c66affSColin Finck CTrayWindow() : 249c2c66affSColin Finck m_StartButton(), 250c2c66affSColin Finck m_Theme(NULL), 251c2c66affSColin Finck m_Font(NULL), 252c2c66affSColin Finck m_DesktopWnd(NULL), 253c2c66affSColin Finck m_Rebar(NULL), 254c2c66affSColin Finck m_TaskSwitch(NULL), 255c2c66affSColin Finck m_TrayNotify(NULL), 256c2c66affSColin Finck m_Position(0), 257c2c66affSColin Finck m_Monitor(NULL), 258c2c66affSColin Finck m_PreviousMonitor(NULL), 259c2c66affSColin Finck m_DraggingPosition(0), 260c2c66affSColin Finck m_DraggingMonitor(NULL), 261c2c66affSColin Finck m_TrayPropertiesOwner(NULL), 262c2c66affSColin Finck m_RunFileDlgOwner(NULL), 263c2c66affSColin Finck m_AutoHideState(NULL), 264c2c66affSColin Finck m_ShellServices(NULL), 265c2c66affSColin Finck Flags(0) 266c2c66affSColin Finck { 267c2c66affSColin Finck ZeroMemory(&m_TrayRects, sizeof(m_TrayRects)); 268c2c66affSColin Finck ZeroMemory(&m_TraySize, sizeof(m_TraySize)); 269c2c66affSColin Finck ZeroMemory(&m_AutoHideOffset, sizeof(m_AutoHideOffset)); 270c2c66affSColin Finck ZeroMemory(&m_MouseTrackingInfo, sizeof(m_MouseTrackingInfo)); 271c2c66affSColin Finck } 272c2c66affSColin Finck 273c2c66affSColin Finck virtual ~CTrayWindow() 274c2c66affSColin Finck { 275c2c66affSColin Finck if (m_ShellServices != NULL) 276c2c66affSColin Finck { 277c2c66affSColin Finck ShutdownShellServices(m_ShellServices); 278c2c66affSColin Finck m_ShellServices = NULL; 279c2c66affSColin Finck } 280c2c66affSColin Finck 281c2c66affSColin Finck if (m_Font != NULL) 282c2c66affSColin Finck { 283c2c66affSColin Finck DeleteObject(m_Font); 284c2c66affSColin Finck m_Font = NULL; 285c2c66affSColin Finck } 286c2c66affSColin Finck 287c2c66affSColin Finck if (m_Theme) 288c2c66affSColin Finck { 289c2c66affSColin Finck CloseThemeData(m_Theme); 290c2c66affSColin Finck m_Theme = NULL; 291c2c66affSColin Finck } 292c2c66affSColin Finck 293c2c66affSColin Finck PostQuitMessage(0); 294c2c66affSColin Finck } 295c2c66affSColin Finck 296c2c66affSColin Finck 297c2c66affSColin Finck 298c2c66affSColin Finck 299c2c66affSColin Finck 300c2c66affSColin Finck /********************************************************** 301c2c66affSColin Finck * ##### command handling ##### 302c2c66affSColin Finck */ 303c2c66affSColin Finck 304c2c66affSColin Finck HRESULT ExecResourceCmd(int id) 305c2c66affSColin Finck { 306c2c66affSColin Finck WCHAR szCommand[256]; 307c2c66affSColin Finck WCHAR *pszParameters; 308c2c66affSColin Finck 309c2c66affSColin Finck if (!LoadStringW(hExplorerInstance, 310c2c66affSColin Finck id, 311c2c66affSColin Finck szCommand, 312c2c66affSColin Finck _countof(szCommand))) 313c2c66affSColin Finck { 314c2c66affSColin Finck return E_FAIL; 315c2c66affSColin Finck } 316c2c66affSColin Finck 317c2c66affSColin Finck pszParameters = wcschr(szCommand, L'>'); 318c2c66affSColin Finck if (pszParameters) 319c2c66affSColin Finck { 320c2c66affSColin Finck *pszParameters = 0; 321c2c66affSColin Finck pszParameters++; 322c2c66affSColin Finck } 323c2c66affSColin Finck 324c2c66affSColin Finck ShellExecuteW(m_hWnd, NULL, szCommand, pszParameters, NULL, SW_SHOWNORMAL); 325c2c66affSColin Finck return S_OK; 326c2c66affSColin Finck } 327c2c66affSColin Finck 328c2c66affSColin Finck LRESULT DoExitWindows() 329c2c66affSColin Finck { 330c2c66affSColin Finck ExitWindowsDialog(m_hWnd); 331c2c66affSColin Finck return 0; 332c2c66affSColin Finck } 333c2c66affSColin Finck 334c2c66affSColin Finck DWORD WINAPI RunFileDlgThread() 335c2c66affSColin Finck { 336c2c66affSColin Finck HWND hwnd; 337c2c66affSColin Finck RECT posRect; 338c2c66affSColin Finck 339c2c66affSColin Finck m_StartButton.GetWindowRect(&posRect); 340c2c66affSColin Finck 341c2c66affSColin Finck hwnd = CreateWindowEx(0, 342c2c66affSColin Finck WC_STATIC, 343c2c66affSColin Finck NULL, 344c2c66affSColin Finck WS_OVERLAPPED | WS_DISABLED | WS_CLIPSIBLINGS | WS_BORDER | SS_LEFT, 345c2c66affSColin Finck posRect.left, 346c2c66affSColin Finck posRect.top, 347c2c66affSColin Finck posRect.right - posRect.left, 348c2c66affSColin Finck posRect.bottom - posRect.top, 349c2c66affSColin Finck NULL, 350c2c66affSColin Finck NULL, 351c2c66affSColin Finck NULL, 352c2c66affSColin Finck NULL); 353c2c66affSColin Finck 354c2c66affSColin Finck m_RunFileDlgOwner = hwnd; 355c2c66affSColin Finck 356c2c66affSColin Finck RunFileDlg(hwnd, NULL, NULL, NULL, NULL, RFF_CALCDIRECTORY); 357c2c66affSColin Finck 358c2c66affSColin Finck m_RunFileDlgOwner = NULL; 359c2c66affSColin Finck ::DestroyWindow(hwnd); 360c2c66affSColin Finck 361c2c66affSColin Finck return 0; 362c2c66affSColin Finck } 363c2c66affSColin Finck 364c2c66affSColin Finck static DWORD WINAPI s_RunFileDlgThread(IN OUT PVOID pParam) 365c2c66affSColin Finck { 366c2c66affSColin Finck CTrayWindow * This = (CTrayWindow*) pParam; 367c2c66affSColin Finck return This->RunFileDlgThread(); 368c2c66affSColin Finck } 369c2c66affSColin Finck 370c2c66affSColin Finck void DisplayRunFileDlg() 371c2c66affSColin Finck { 372c2c66affSColin Finck HWND hRunDlg; 373c2c66affSColin Finck if (m_RunFileDlgOwner) 374c2c66affSColin Finck { 375c2c66affSColin Finck hRunDlg = ::GetLastActivePopup(m_RunFileDlgOwner); 376c2c66affSColin Finck if (hRunDlg != NULL && 377c2c66affSColin Finck hRunDlg != m_RunFileDlgOwner) 378c2c66affSColin Finck { 379c2c66affSColin Finck SetForegroundWindow(hRunDlg); 380c2c66affSColin Finck return; 381c2c66affSColin Finck } 382c2c66affSColin Finck } 383c2c66affSColin Finck 384c2c66affSColin Finck CloseHandle(CreateThread(NULL, 0, s_RunFileDlgThread, this, 0, NULL)); 385c2c66affSColin Finck } 386c2c66affSColin Finck 387c2c66affSColin Finck DWORD WINAPI TrayPropertiesThread() 388c2c66affSColin Finck { 389c2c66affSColin Finck HWND hwnd; 390c2c66affSColin Finck RECT posRect; 391c2c66affSColin Finck 392c2c66affSColin Finck m_StartButton.GetWindowRect(&posRect); 393c2c66affSColin Finck hwnd = CreateWindowEx(0, 394c2c66affSColin Finck WC_STATIC, 395c2c66affSColin Finck NULL, 396c2c66affSColin Finck WS_OVERLAPPED | WS_DISABLED | WS_CLIPSIBLINGS | WS_BORDER | SS_LEFT, 397c2c66affSColin Finck posRect.left, 398c2c66affSColin Finck posRect.top, 399c2c66affSColin Finck posRect.right - posRect.left, 400c2c66affSColin Finck posRect.bottom - posRect.top, 401c2c66affSColin Finck NULL, 402c2c66affSColin Finck NULL, 403c2c66affSColin Finck NULL, 404c2c66affSColin Finck NULL); 405c2c66affSColin Finck 406c2c66affSColin Finck m_TrayPropertiesOwner = hwnd; 407c2c66affSColin Finck 4082ed535daSGiannis Adamopoulos DisplayTrayProperties(hwnd, m_hWnd); 409c2c66affSColin Finck 410c2c66affSColin Finck m_TrayPropertiesOwner = NULL; 411c2c66affSColin Finck ::DestroyWindow(hwnd); 412c2c66affSColin Finck 413c2c66affSColin Finck return 0; 414c2c66affSColin Finck } 415c2c66affSColin Finck 416c2c66affSColin Finck static DWORD WINAPI s_TrayPropertiesThread(IN OUT PVOID pParam) 417c2c66affSColin Finck { 418c2c66affSColin Finck CTrayWindow *This = (CTrayWindow*) pParam; 419c2c66affSColin Finck 420c2c66affSColin Finck return This->TrayPropertiesThread(); 421c2c66affSColin Finck } 422c2c66affSColin Finck 423c2c66affSColin Finck HWND STDMETHODCALLTYPE DisplayProperties() 424c2c66affSColin Finck { 425c2c66affSColin Finck HWND hTrayProp; 426c2c66affSColin Finck 427c2c66affSColin Finck if (m_TrayPropertiesOwner) 428c2c66affSColin Finck { 429c2c66affSColin Finck hTrayProp = ::GetLastActivePopup(m_TrayPropertiesOwner); 430c2c66affSColin Finck if (hTrayProp != NULL && 431c2c66affSColin Finck hTrayProp != m_TrayPropertiesOwner) 432c2c66affSColin Finck { 433c2c66affSColin Finck SetForegroundWindow(hTrayProp); 434c2c66affSColin Finck return NULL; 435c2c66affSColin Finck } 436c2c66affSColin Finck } 437c2c66affSColin Finck 438c2c66affSColin Finck CloseHandle(CreateThread(NULL, 0, s_TrayPropertiesThread, this, 0, NULL)); 439c2c66affSColin Finck return NULL; 440c2c66affSColin Finck } 441c2c66affSColin Finck 442c2c66affSColin Finck VOID OpenCommonStartMenuDirectory(IN HWND hWndOwner, IN LPCTSTR lpOperation) 443c2c66affSColin Finck { 444c2c66affSColin Finck WCHAR szDir[MAX_PATH]; 445c2c66affSColin Finck 446c2c66affSColin Finck if (SHGetSpecialFolderPath(hWndOwner, 447c2c66affSColin Finck szDir, 448c2c66affSColin Finck CSIDL_COMMON_STARTMENU, 449c2c66affSColin Finck FALSE)) 450c2c66affSColin Finck { 451c2c66affSColin Finck ShellExecute(hWndOwner, 452c2c66affSColin Finck lpOperation, 453c2c66affSColin Finck szDir, 454c2c66affSColin Finck NULL, 455c2c66affSColin Finck NULL, 456c2c66affSColin Finck SW_SHOWNORMAL); 457c2c66affSColin Finck } 458c2c66affSColin Finck } 459c2c66affSColin Finck 460c2c66affSColin Finck VOID OpenTaskManager(IN HWND hWndOwner) 461c2c66affSColin Finck { 462c2c66affSColin Finck ShellExecute(hWndOwner, 463c2c66affSColin Finck TEXT("open"), 464c2c66affSColin Finck TEXT("taskmgr.exe"), 465c2c66affSColin Finck NULL, 466c2c66affSColin Finck NULL, 467c2c66affSColin Finck SW_SHOWNORMAL); 468c2c66affSColin Finck } 469c2c66affSColin Finck 470c2c66affSColin Finck BOOL STDMETHODCALLTYPE ExecContextMenuCmd(IN UINT uiCmd) 471c2c66affSColin Finck { 472c2c66affSColin Finck switch (uiCmd) 473c2c66affSColin Finck { 474c2c66affSColin Finck case ID_SHELL_CMD_PROPERTIES: 475c2c66affSColin Finck DisplayProperties(); 476c2c66affSColin Finck break; 477c2c66affSColin Finck 478c2c66affSColin Finck case ID_SHELL_CMD_OPEN_ALL_USERS: 479c2c66affSColin Finck OpenCommonStartMenuDirectory(m_hWnd, 480c2c66affSColin Finck TEXT("open")); 481c2c66affSColin Finck break; 482c2c66affSColin Finck 483c2c66affSColin Finck case ID_SHELL_CMD_EXPLORE_ALL_USERS: 484c2c66affSColin Finck OpenCommonStartMenuDirectory(m_hWnd, 485c2c66affSColin Finck TEXT("explore")); 486c2c66affSColin Finck break; 487c2c66affSColin Finck 488c2c66affSColin Finck case ID_LOCKTASKBAR: 489c2c66affSColin Finck if (SHRestricted(REST_CLASSICSHELL) == 0) 490c2c66affSColin Finck { 4912ed535daSGiannis Adamopoulos Lock(!g_TaskbarSettings.bLock); 492c2c66affSColin Finck } 493c2c66affSColin Finck break; 494c2c66affSColin Finck 495c2c66affSColin Finck case ID_SHELL_CMD_OPEN_TASKMGR: 496c2c66affSColin Finck OpenTaskManager(m_hWnd); 497c2c66affSColin Finck break; 498c2c66affSColin Finck 499c2c66affSColin Finck case ID_SHELL_CMD_UNDO_ACTION: 500c2c66affSColin Finck break; 501c2c66affSColin Finck 502c2c66affSColin Finck case ID_SHELL_CMD_SHOW_DESKTOP: 503c2c66affSColin Finck break; 504c2c66affSColin Finck 505c2c66affSColin Finck case ID_SHELL_CMD_TILE_WND_H: 506c2c66affSColin Finck TileWindows(NULL, MDITILE_HORIZONTAL, NULL, 0, NULL); 507c2c66affSColin Finck break; 508c2c66affSColin Finck 509c2c66affSColin Finck case ID_SHELL_CMD_TILE_WND_V: 510c2c66affSColin Finck TileWindows(NULL, MDITILE_VERTICAL, NULL, 0, NULL); 511c2c66affSColin Finck break; 512c2c66affSColin Finck 513c2c66affSColin Finck case ID_SHELL_CMD_CASCADE_WND: 514c2c66affSColin Finck CascadeWindows(NULL, MDITILE_SKIPDISABLED, NULL, 0, NULL); 515c2c66affSColin Finck break; 516c2c66affSColin Finck 517c2c66affSColin Finck case ID_SHELL_CMD_CUST_NOTIF: 518c2c66affSColin Finck ShowCustomizeNotifyIcons(hExplorerInstance, m_hWnd); 519c2c66affSColin Finck break; 520c2c66affSColin Finck 521c2c66affSColin Finck case ID_SHELL_CMD_ADJUST_DAT: 522c2c66affSColin Finck //FIXME: Use SHRunControlPanel 523c2c66affSColin Finck ShellExecuteW(m_hWnd, NULL, L"timedate.cpl", NULL, NULL, SW_NORMAL); 524c2c66affSColin Finck break; 525c2c66affSColin Finck 526c2c66affSColin Finck default: 527c2c66affSColin Finck TRACE("ITrayWindow::ExecContextMenuCmd(%u): Unhandled Command ID!\n", uiCmd); 528c2c66affSColin Finck return FALSE; 529c2c66affSColin Finck } 530c2c66affSColin Finck 531c2c66affSColin Finck return TRUE; 532c2c66affSColin Finck } 533c2c66affSColin Finck 534c2c66affSColin Finck LRESULT HandleHotKey(DWORD id) 535c2c66affSColin Finck { 536c2c66affSColin Finck switch (id) 537c2c66affSColin Finck { 538c2c66affSColin Finck case IDHK_RUN: 539c2c66affSColin Finck DisplayRunFileDlg(); 540c2c66affSColin Finck break; 541c2c66affSColin Finck case IDHK_HELP: 542c2c66affSColin Finck ExecResourceCmd(IDS_HELP_COMMAND); 543c2c66affSColin Finck break; 544c2c66affSColin Finck case IDHK_EXPLORE: 545c2c66affSColin Finck //FIXME: We don't support this yet: 546c2c66affSColin Finck //ShellExecuteW(0, L"explore", NULL, NULL, NULL, 1); 5474b6d929bSGiannis Adamopoulos ShellExecuteW(0, NULL, L"explorer.exe", L"/e ,", NULL, 1); 548c2c66affSColin Finck break; 549c2c66affSColin Finck case IDHK_FIND: 550c2c66affSColin Finck SHFindFiles(NULL, NULL); 551c2c66affSColin Finck break; 552c2c66affSColin Finck case IDHK_FIND_COMPUTER: 553c2c66affSColin Finck SHFindComputer(NULL, NULL); 554c2c66affSColin Finck break; 555c2c66affSColin Finck case IDHK_SYS_PROPERTIES: 556c2c66affSColin Finck //FIXME: Use SHRunControlPanel 557c2c66affSColin Finck ShellExecuteW(m_hWnd, NULL, L"sysdm.cpl", NULL, NULL, SW_NORMAL); 558c2c66affSColin Finck break; 559c2c66affSColin Finck case IDHK_NEXT_TASK: 560c2c66affSColin Finck break; 561c2c66affSColin Finck case IDHK_PREV_TASK: 562c2c66affSColin Finck break; 563c2c66affSColin Finck case IDHK_MINIMIZE_ALL: 564c2c66affSColin Finck break; 565c2c66affSColin Finck case IDHK_RESTORE_ALL: 566c2c66affSColin Finck break; 567c2c66affSColin Finck case IDHK_DESKTOP: 568c2c66affSColin Finck break; 569c2c66affSColin Finck case IDHK_PAGER: 570c2c66affSColin Finck break; 571c2c66affSColin Finck } 572c2c66affSColin Finck 573c2c66affSColin Finck return 0; 574c2c66affSColin Finck } 575c2c66affSColin Finck 576c2c66affSColin Finck LRESULT HandleCommand(UINT uCommand) 577c2c66affSColin Finck { 578c2c66affSColin Finck switch (uCommand) 579c2c66affSColin Finck { 580c2c66affSColin Finck case IDM_TASKBARANDSTARTMENU: 581c2c66affSColin Finck DisplayProperties(); 582c2c66affSColin Finck break; 583c2c66affSColin Finck 584c2c66affSColin Finck case IDM_SEARCH: 585c2c66affSColin Finck SHFindFiles(NULL, NULL); 586c2c66affSColin Finck break; 587c2c66affSColin Finck 588c2c66affSColin Finck case IDM_HELPANDSUPPORT: 589c2c66affSColin Finck ExecResourceCmd(IDS_HELP_COMMAND); 590c2c66affSColin Finck break; 591c2c66affSColin Finck 592c2c66affSColin Finck case IDM_RUN: 593c2c66affSColin Finck DisplayRunFileDlg(); 594c2c66affSColin Finck break; 595c2c66affSColin Finck 596c2c66affSColin Finck /* FIXME: Handle these commands as well */ 597c2c66affSColin Finck case IDM_SYNCHRONIZE: 598c2c66affSColin Finck case IDM_DISCONNECT: 599c2c66affSColin Finck case IDM_UNDOCKCOMPUTER: 600c2c66affSColin Finck break; 601c2c66affSColin Finck 602c2c66affSColin Finck case IDM_LOGOFF: 603c2c66affSColin Finck LogoffWindowsDialog(m_hWnd); // FIXME: Maybe handle it in a similar way as DoExitWindows? 604c2c66affSColin Finck break; 605c2c66affSColin Finck 606c2c66affSColin Finck case IDM_SHUTDOWN: 607c2c66affSColin Finck DoExitWindows(); 608c2c66affSColin Finck break; 609c2c66affSColin Finck } 610c2c66affSColin Finck 611c2c66affSColin Finck return FALSE; 612c2c66affSColin Finck } 613c2c66affSColin Finck 614c2c66affSColin Finck 615c2c66affSColin Finck UINT TrackMenu( 616c2c66affSColin Finck IN HMENU hMenu, 617c2c66affSColin Finck IN POINT *ppt OPTIONAL, 618c2c66affSColin Finck IN HWND hwndExclude OPTIONAL, 619c2c66affSColin Finck IN BOOL TrackUp, 620c2c66affSColin Finck IN BOOL IsContextMenu) 621c2c66affSColin Finck { 622c2c66affSColin Finck TPMPARAMS tmp, *ptmp = NULL; 623c2c66affSColin Finck POINT pt; 624c2c66affSColin Finck UINT cmdId; 625c2c66affSColin Finck UINT fuFlags; 626c2c66affSColin Finck 627c2c66affSColin Finck if (hwndExclude != NULL) 628c2c66affSColin Finck { 629c2c66affSColin Finck /* Get the client rectangle and map it to screen coordinates */ 630c2c66affSColin Finck if (::GetClientRect(hwndExclude, 631c2c66affSColin Finck &tmp.rcExclude) && 632c2c66affSColin Finck ::MapWindowPoints(hwndExclude, 633c2c66affSColin Finck NULL, 634c2c66affSColin Finck (LPPOINT) &tmp.rcExclude, 635c2c66affSColin Finck 2) != 0) 636c2c66affSColin Finck { 637c2c66affSColin Finck ptmp = &tmp; 638c2c66affSColin Finck } 639c2c66affSColin Finck } 640c2c66affSColin Finck 641c2c66affSColin Finck if (ppt == NULL) 642c2c66affSColin Finck { 643c2c66affSColin Finck if (ptmp == NULL && 644c2c66affSColin Finck GetClientRect(&tmp.rcExclude) && 645c2c66affSColin Finck MapWindowPoints( 646c2c66affSColin Finck NULL, 647c2c66affSColin Finck (LPPOINT) &tmp.rcExclude, 648c2c66affSColin Finck 2) != 0) 649c2c66affSColin Finck { 650c2c66affSColin Finck ptmp = &tmp; 651c2c66affSColin Finck } 652c2c66affSColin Finck 653c2c66affSColin Finck if (ptmp != NULL) 654c2c66affSColin Finck { 655c2c66affSColin Finck /* NOTE: TrackPopupMenuEx will eventually align the track position 656c2c66affSColin Finck for us, no need to take care of it here as long as the 657c2c66affSColin Finck coordinates are somewhere within the exclusion rectangle */ 658c2c66affSColin Finck pt.x = ptmp->rcExclude.left; 659c2c66affSColin Finck pt.y = ptmp->rcExclude.top; 660c2c66affSColin Finck } 661c2c66affSColin Finck else 662c2c66affSColin Finck pt.x = pt.y = 0; 663c2c66affSColin Finck } 664c2c66affSColin Finck else 665c2c66affSColin Finck pt = *ppt; 666c2c66affSColin Finck 667c2c66affSColin Finck tmp.cbSize = sizeof(tmp); 668c2c66affSColin Finck 669c2c66affSColin Finck fuFlags = TPM_RETURNCMD | TPM_VERTICAL; 670c2c66affSColin Finck fuFlags |= (TrackUp ? TPM_BOTTOMALIGN : TPM_TOPALIGN); 671c2c66affSColin Finck if (IsContextMenu) 672c2c66affSColin Finck fuFlags |= TPM_RIGHTBUTTON; 673c2c66affSColin Finck else 674c2c66affSColin Finck fuFlags |= (TrackUp ? TPM_VERNEGANIMATION : TPM_VERPOSANIMATION); 675c2c66affSColin Finck 676c2c66affSColin Finck cmdId = TrackPopupMenuEx(hMenu, 677c2c66affSColin Finck fuFlags, 678c2c66affSColin Finck pt.x, 679c2c66affSColin Finck pt.y, 680c2c66affSColin Finck m_hWnd, 681c2c66affSColin Finck ptmp); 682c2c66affSColin Finck 683c2c66affSColin Finck return cmdId; 684c2c66affSColin Finck } 685c2c66affSColin Finck 686c2c66affSColin Finck HRESULT TrackCtxMenu( 687c2c66affSColin Finck IN IContextMenu * contextMenu, 688c2c66affSColin Finck IN POINT *ppt OPTIONAL, 689c2c66affSColin Finck IN HWND hwndExclude OPTIONAL, 690c2c66affSColin Finck IN BOOL TrackUp, 691c2c66affSColin Finck IN PVOID Context OPTIONAL) 692c2c66affSColin Finck { 693c2c66affSColin Finck INT x = ppt->x; 694c2c66affSColin Finck INT y = ppt->y; 695c2c66affSColin Finck HRESULT hr; 696c2c66affSColin Finck UINT uCommand; 697c2c66affSColin Finck HMENU popup = CreatePopupMenu(); 698c2c66affSColin Finck 699c2c66affSColin Finck if (popup == NULL) 700c2c66affSColin Finck return E_FAIL; 701c2c66affSColin Finck 702c2c66affSColin Finck TRACE("Before Query\n"); 703c2c66affSColin Finck hr = contextMenu->QueryContextMenu(popup, 0, 0, UINT_MAX, CMF_NORMAL); 704c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr)) 705c2c66affSColin Finck { 706c2c66affSColin Finck TRACE("Query failed\n"); 707c2c66affSColin Finck DestroyMenu(popup); 708c2c66affSColin Finck return hr; 709c2c66affSColin Finck } 710c2c66affSColin Finck 711c2c66affSColin Finck TRACE("Before Tracking\n"); 712c2c66affSColin Finck uCommand = ::TrackPopupMenuEx(popup, TPM_RETURNCMD, x, y, m_hWnd, NULL); 713c2c66affSColin Finck 714c2c66affSColin Finck if (uCommand != 0) 715c2c66affSColin Finck { 716c2c66affSColin Finck TRACE("Before InvokeCommand\n"); 717c2c66affSColin Finck CMINVOKECOMMANDINFO cmi = { 0 }; 718c2c66affSColin Finck cmi.cbSize = sizeof(cmi); 719c2c66affSColin Finck cmi.lpVerb = MAKEINTRESOURCEA(uCommand); 720c2c66affSColin Finck cmi.hwnd = m_hWnd; 721c2c66affSColin Finck hr = contextMenu->InvokeCommand(&cmi); 722c2c66affSColin Finck } 723c2c66affSColin Finck else 724c2c66affSColin Finck { 725c2c66affSColin Finck TRACE("TrackPopupMenu failed. Code=%d, LastError=%d\n", uCommand, GetLastError()); 726c2c66affSColin Finck hr = S_FALSE; 727c2c66affSColin Finck } 728c2c66affSColin Finck 729c2c66affSColin Finck DestroyMenu(popup); 730c2c66affSColin Finck return hr; 731c2c66affSColin Finck } 732c2c66affSColin Finck 733c2c66affSColin Finck 734c2c66affSColin Finck 735c2c66affSColin Finck 736c2c66affSColin Finck 737c2c66affSColin Finck /********************************************************** 738c2c66affSColin Finck * ##### moving and sizing handling ##### 739c2c66affSColin Finck */ 740c2c66affSColin Finck 741c2c66affSColin Finck void UpdateFonts() 742c2c66affSColin Finck { 743c2c66affSColin Finck /* There is nothing to do if themes are enabled */ 744c2c66affSColin Finck if (m_Theme) 745c2c66affSColin Finck return; 746c2c66affSColin Finck 747c2c66affSColin Finck m_StartButton.UpdateFont(); 748c2c66affSColin Finck 749c2c66affSColin Finck NONCLIENTMETRICS ncm = {sizeof(ncm)}; 750c2c66affSColin Finck if (!SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, FALSE)) 751c2c66affSColin Finck { 752c2c66affSColin Finck ERR("SPI_GETNONCLIENTMETRICS failed\n"); 753c2c66affSColin Finck return; 754c2c66affSColin Finck } 755c2c66affSColin Finck 756c2c66affSColin Finck if (m_Font != NULL) 757c2c66affSColin Finck DeleteObject(m_Font); 758c2c66affSColin Finck 759c2c66affSColin Finck ncm.lfCaptionFont.lfWeight = FW_NORMAL; 760c2c66affSColin Finck m_Font = CreateFontIndirect(&ncm.lfCaptionFont); 761c2c66affSColin Finck if (!m_Font) 762c2c66affSColin Finck { 763c2c66affSColin Finck ERR("CreateFontIndirect failed\n"); 764c2c66affSColin Finck return; 765c2c66affSColin Finck } 766c2c66affSColin Finck 767c2c66affSColin Finck SendMessage(m_Rebar, WM_SETFONT, (WPARAM) m_Font, TRUE); 768c2c66affSColin Finck SendMessage(m_TaskSwitch, WM_SETFONT, (WPARAM) m_Font, TRUE); 769c2c66affSColin Finck SendMessage(m_TrayNotify, WM_SETFONT, (WPARAM) m_Font, TRUE); 770c2c66affSColin Finck } 771c2c66affSColin Finck 772c2c66affSColin Finck HMONITOR GetScreenRectFromRect( 773c2c66affSColin Finck IN OUT RECT *pRect, 774c2c66affSColin Finck IN DWORD dwFlags) 775c2c66affSColin Finck { 776c2c66affSColin Finck MONITORINFO mi; 777c2c66affSColin Finck HMONITOR hMon; 778c2c66affSColin Finck 779c2c66affSColin Finck mi.cbSize = sizeof(mi); 780c2c66affSColin Finck hMon = MonitorFromRect(pRect, dwFlags); 781c2c66affSColin Finck if (hMon != NULL && 782c2c66affSColin Finck GetMonitorInfo(hMon, &mi)) 783c2c66affSColin Finck { 784c2c66affSColin Finck *pRect = mi.rcMonitor; 785c2c66affSColin Finck } 786c2c66affSColin Finck else 787c2c66affSColin Finck { 788c2c66affSColin Finck pRect->left = 0; 789c2c66affSColin Finck pRect->top = 0; 790c2c66affSColin Finck pRect->right = GetSystemMetrics(SM_CXSCREEN); 791c2c66affSColin Finck pRect->bottom = GetSystemMetrics(SM_CYSCREEN); 792c2c66affSColin Finck 793c2c66affSColin Finck hMon = NULL; 794c2c66affSColin Finck } 795c2c66affSColin Finck 796c2c66affSColin Finck return hMon; 797c2c66affSColin Finck } 798c2c66affSColin Finck 799c2c66affSColin Finck HMONITOR GetMonitorFromRect( 800c2c66affSColin Finck IN const RECT *pRect) 801c2c66affSColin Finck { 802c2c66affSColin Finck HMONITOR hMon; 803c2c66affSColin Finck 804c2c66affSColin Finck /* In case the monitor sizes or saved sizes differ a bit (probably 805c2c66affSColin Finck not a lot, only so the tray window overlaps into another monitor 806c2c66affSColin Finck now), minimize the risk that we determine a wrong monitor by 807c2c66affSColin Finck using the center point of the tray window if we can't determine 808c2c66affSColin Finck it using the rectangle. */ 809c2c66affSColin Finck hMon = MonitorFromRect(pRect, MONITOR_DEFAULTTONULL); 810c2c66affSColin Finck if (hMon == NULL) 811c2c66affSColin Finck { 812c2c66affSColin Finck POINT pt; 813c2c66affSColin Finck 814c2c66affSColin Finck pt.x = pRect->left + ((pRect->right - pRect->left) / 2); 815c2c66affSColin Finck pt.y = pRect->top + ((pRect->bottom - pRect->top) / 2); 816c2c66affSColin Finck 817c2c66affSColin Finck /* be less error-prone, find the nearest monitor */ 818c2c66affSColin Finck hMon = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST); 819c2c66affSColin Finck } 820c2c66affSColin Finck 821c2c66affSColin Finck return hMon; 822c2c66affSColin Finck } 823c2c66affSColin Finck 824c2c66affSColin Finck HMONITOR GetScreenRect( 825c2c66affSColin Finck IN HMONITOR hMonitor, 826c2c66affSColin Finck IN OUT RECT *pRect) 827c2c66affSColin Finck { 828c2c66affSColin Finck HMONITOR hMon = NULL; 829c2c66affSColin Finck 830c2c66affSColin Finck if (hMonitor != NULL) 831c2c66affSColin Finck { 832c2c66affSColin Finck MONITORINFO mi; 833c2c66affSColin Finck 834c2c66affSColin Finck mi.cbSize = sizeof(mi); 835c2c66affSColin Finck if (!GetMonitorInfo(hMonitor, &mi)) 836c2c66affSColin Finck { 837c2c66affSColin Finck /* Hm, the monitor is gone? Try to find a monitor where it 838c2c66affSColin Finck could be located now */ 839c2c66affSColin Finck hMon = GetMonitorFromRect(pRect); 840c2c66affSColin Finck if (hMon == NULL || 841c2c66affSColin Finck !GetMonitorInfo(hMon, &mi)) 842c2c66affSColin Finck { 843c2c66affSColin Finck hMon = NULL; 844c2c66affSColin Finck goto GetPrimaryRect; 845c2c66affSColin Finck } 846c2c66affSColin Finck } 847c2c66affSColin Finck 848c2c66affSColin Finck *pRect = mi.rcMonitor; 849c2c66affSColin Finck } 850c2c66affSColin Finck else 851c2c66affSColin Finck { 852c2c66affSColin Finck GetPrimaryRect: 853c2c66affSColin Finck pRect->left = 0; 854c2c66affSColin Finck pRect->top = 0; 855c2c66affSColin Finck pRect->right = GetSystemMetrics(SM_CXSCREEN); 856c2c66affSColin Finck pRect->bottom = GetSystemMetrics(SM_CYSCREEN); 857c2c66affSColin Finck } 858c2c66affSColin Finck 859c2c66affSColin Finck return hMon; 860c2c66affSColin Finck } 861c2c66affSColin Finck 862c2c66affSColin Finck VOID AdjustSizerRect(RECT *rc, DWORD pos) 863c2c66affSColin Finck { 864c2c66affSColin Finck int iSizerPart[4] = {TBP_SIZINGBARLEFT, TBP_SIZINGBARTOP, TBP_SIZINGBARRIGHT, TBP_SIZINGBARBOTTOM}; 865c2c66affSColin Finck SIZE size; 866c2c66affSColin Finck 867c2c66affSColin Finck if (pos > ABE_BOTTOM) 868c2c66affSColin Finck pos = ABE_BOTTOM; 869c2c66affSColin Finck 870c2c66affSColin Finck HRESULT hr = GetThemePartSize(m_Theme, NULL, iSizerPart[pos], 0, NULL, TS_TRUE, &size); 871c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr)) 872c2c66affSColin Finck return; 873c2c66affSColin Finck 874c2c66affSColin Finck switch (pos) 875c2c66affSColin Finck { 876c2c66affSColin Finck case ABE_TOP: 877c2c66affSColin Finck rc->bottom -= size.cy; 878c2c66affSColin Finck break; 879c2c66affSColin Finck case ABE_BOTTOM: 880c2c66affSColin Finck rc->top += size.cy; 881c2c66affSColin Finck break; 882c2c66affSColin Finck case ABE_LEFT: 883c2c66affSColin Finck rc->right -= size.cx; 884c2c66affSColin Finck break; 885c2c66affSColin Finck case ABE_RIGHT: 886c2c66affSColin Finck rc->left += size.cx; 887c2c66affSColin Finck break; 888c2c66affSColin Finck } 889c2c66affSColin Finck } 890c2c66affSColin Finck 891c2c66affSColin Finck VOID MakeTrayRectWithSize(IN DWORD Position, 892c2c66affSColin Finck IN const SIZE *pTraySize, 893c2c66affSColin Finck IN OUT RECT *pRect) 894c2c66affSColin Finck { 895c2c66affSColin Finck switch (Position) 896c2c66affSColin Finck { 897c2c66affSColin Finck case ABE_LEFT: 898c2c66affSColin Finck pRect->right = pRect->left + pTraySize->cx; 899c2c66affSColin Finck break; 900c2c66affSColin Finck 901c2c66affSColin Finck case ABE_TOP: 902c2c66affSColin Finck pRect->bottom = pRect->top + pTraySize->cy; 903c2c66affSColin Finck break; 904c2c66affSColin Finck 905c2c66affSColin Finck case ABE_RIGHT: 906c2c66affSColin Finck pRect->left = pRect->right - pTraySize->cx; 907c2c66affSColin Finck break; 908c2c66affSColin Finck 909c2c66affSColin Finck case ABE_BOTTOM: 910c2c66affSColin Finck default: 911c2c66affSColin Finck pRect->top = pRect->bottom - pTraySize->cy; 912c2c66affSColin Finck break; 913c2c66affSColin Finck } 914c2c66affSColin Finck } 915c2c66affSColin Finck 916c2c66affSColin Finck VOID GetTrayRectFromScreenRect(IN DWORD Position, 917c2c66affSColin Finck IN const RECT *pScreen, 918c2c66affSColin Finck IN const SIZE *pTraySize OPTIONAL, 919c2c66affSColin Finck OUT RECT *pRect) 920c2c66affSColin Finck { 921c2c66affSColin Finck if (pTraySize == NULL) 922c2c66affSColin Finck pTraySize = &m_TraySize; 923c2c66affSColin Finck 924c2c66affSColin Finck *pRect = *pScreen; 925c2c66affSColin Finck 926c2c66affSColin Finck if(!m_Theme) 927c2c66affSColin Finck { 928c2c66affSColin Finck /* Move the border outside of the screen */ 929c2c66affSColin Finck InflateRect(pRect, 930c2c66affSColin Finck GetSystemMetrics(SM_CXEDGE), 931c2c66affSColin Finck GetSystemMetrics(SM_CYEDGE)); 932c2c66affSColin Finck } 933c2c66affSColin Finck 934c2c66affSColin Finck MakeTrayRectWithSize(Position, pTraySize, pRect); 935c2c66affSColin Finck } 936c2c66affSColin Finck 937c2c66affSColin Finck BOOL IsPosHorizontal() 938c2c66affSColin Finck { 939c2c66affSColin Finck return m_Position == ABE_TOP || m_Position == ABE_BOTTOM; 940c2c66affSColin Finck } 941c2c66affSColin Finck 942c2c66affSColin Finck HMONITOR CalculateValidSize( 943c2c66affSColin Finck IN DWORD Position, 944c2c66affSColin Finck IN OUT RECT *pRect) 945c2c66affSColin Finck { 946c2c66affSColin Finck RECT rcScreen; 947c2c66affSColin Finck //BOOL Horizontal; 948c2c66affSColin Finck HMONITOR hMon; 949c2c66affSColin Finck SIZE szMax, szWnd; 950c2c66affSColin Finck 951c2c66affSColin Finck //Horizontal = IsPosHorizontal(); 952c2c66affSColin Finck 953c2c66affSColin Finck szWnd.cx = pRect->right - pRect->left; 954c2c66affSColin Finck szWnd.cy = pRect->bottom - pRect->top; 955c2c66affSColin Finck 956c2c66affSColin Finck rcScreen = *pRect; 957c2c66affSColin Finck hMon = GetScreenRectFromRect( 958c2c66affSColin Finck &rcScreen, 959c2c66affSColin Finck MONITOR_DEFAULTTONEAREST); 960c2c66affSColin Finck 961c2c66affSColin Finck /* Calculate the maximum size of the tray window and limit the window 962c2c66affSColin Finck size to half of the screen's size. */ 963c2c66affSColin Finck szMax.cx = (rcScreen.right - rcScreen.left) / 2; 964c2c66affSColin Finck szMax.cy = (rcScreen.bottom - rcScreen.top) / 2; 965c2c66affSColin Finck if (szWnd.cx > szMax.cx) 966c2c66affSColin Finck szWnd.cx = szMax.cx; 967c2c66affSColin Finck if (szWnd.cy > szMax.cy) 968c2c66affSColin Finck szWnd.cy = szMax.cy; 969c2c66affSColin Finck 970c2c66affSColin Finck /* FIXME - calculate */ 971c2c66affSColin Finck 972c2c66affSColin Finck GetTrayRectFromScreenRect(Position, 973c2c66affSColin Finck &rcScreen, 974c2c66affSColin Finck &szWnd, 975c2c66affSColin Finck pRect); 976c2c66affSColin Finck 977c2c66affSColin Finck return hMon; 978c2c66affSColin Finck } 979c2c66affSColin Finck 980c2c66affSColin Finck #if 0 981c2c66affSColin Finck VOID 982c2c66affSColin Finck GetMinimumWindowSize( 983c2c66affSColin Finck OUT RECT *pRect) 984c2c66affSColin Finck { 985c2c66affSColin Finck RECT rcMin = {0}; 986c2c66affSColin Finck 987c2c66affSColin Finck AdjustWindowRectEx(&rcMin, 988c2c66affSColin Finck GetWindowLong(m_hWnd, 989c2c66affSColin Finck GWL_STYLE), 990c2c66affSColin Finck FALSE, 991c2c66affSColin Finck GetWindowLong(m_hWnd, 992c2c66affSColin Finck GWL_EXSTYLE)); 993c2c66affSColin Finck 994c2c66affSColin Finck *pRect = rcMin; 995c2c66affSColin Finck } 996c2c66affSColin Finck #endif 997c2c66affSColin Finck 998c2c66affSColin Finck 999c2c66affSColin Finck DWORD GetDraggingRectFromPt( 1000c2c66affSColin Finck IN POINT pt, 1001c2c66affSColin Finck OUT RECT *pRect, 1002c2c66affSColin Finck OUT HMONITOR *phMonitor) 1003c2c66affSColin Finck { 1004c2c66affSColin Finck HMONITOR hMon, hMonNew; 1005c2c66affSColin Finck DWORD PosH, PosV, Pos; 1006c2c66affSColin Finck SIZE DeltaPt, ScreenOffset; 1007c2c66affSColin Finck RECT rcScreen; 1008c2c66affSColin Finck 1009c2c66affSColin Finck rcScreen.left = 0; 1010c2c66affSColin Finck rcScreen.top = 0; 1011c2c66affSColin Finck 1012c2c66affSColin Finck /* Determine the screen rectangle */ 1013c2c66affSColin Finck hMon = MonitorFromPoint(pt, MONITOR_DEFAULTTONULL); 1014c2c66affSColin Finck if (hMon != NULL) 1015c2c66affSColin Finck { 1016c2c66affSColin Finck MONITORINFO mi; 1017c2c66affSColin Finck 1018c2c66affSColin Finck mi.cbSize = sizeof(mi); 1019c2c66affSColin Finck if (!GetMonitorInfo(hMon, &mi)) 1020c2c66affSColin Finck { 1021c2c66affSColin Finck hMon = NULL; 1022c2c66affSColin Finck goto GetPrimaryScreenRect; 1023c2c66affSColin Finck } 1024c2c66affSColin Finck 1025c2c66affSColin Finck /* make left top corner of the screen zero based to 1026c2c66affSColin Finck make calculations easier */ 1027c2c66affSColin Finck pt.x -= mi.rcMonitor.left; 1028c2c66affSColin Finck pt.y -= mi.rcMonitor.top; 1029c2c66affSColin Finck 1030c2c66affSColin Finck ScreenOffset.cx = mi.rcMonitor.left; 1031c2c66affSColin Finck ScreenOffset.cy = mi.rcMonitor.top; 1032c2c66affSColin Finck rcScreen.right = mi.rcMonitor.right - mi.rcMonitor.left; 1033c2c66affSColin Finck rcScreen.bottom = mi.rcMonitor.bottom - mi.rcMonitor.top; 1034c2c66affSColin Finck } 1035c2c66affSColin Finck else 1036c2c66affSColin Finck { 1037c2c66affSColin Finck GetPrimaryScreenRect: 1038c2c66affSColin Finck ScreenOffset.cx = 0; 1039c2c66affSColin Finck ScreenOffset.cy = 0; 1040c2c66affSColin Finck rcScreen.right = GetSystemMetrics(SM_CXSCREEN); 1041c2c66affSColin Finck rcScreen.bottom = GetSystemMetrics(SM_CYSCREEN); 1042c2c66affSColin Finck } 1043c2c66affSColin Finck 1044c2c66affSColin Finck /* Calculate the nearest screen border */ 1045c2c66affSColin Finck if (pt.x < rcScreen.right / 2) 1046c2c66affSColin Finck { 1047c2c66affSColin Finck DeltaPt.cx = pt.x; 1048c2c66affSColin Finck PosH = ABE_LEFT; 1049c2c66affSColin Finck } 1050c2c66affSColin Finck else 1051c2c66affSColin Finck { 1052c2c66affSColin Finck DeltaPt.cx = rcScreen.right - pt.x; 1053c2c66affSColin Finck PosH = ABE_RIGHT; 1054c2c66affSColin Finck } 1055c2c66affSColin Finck 1056c2c66affSColin Finck if (pt.y < rcScreen.bottom / 2) 1057c2c66affSColin Finck { 1058c2c66affSColin Finck DeltaPt.cy = pt.y; 1059c2c66affSColin Finck PosV = ABE_TOP; 1060c2c66affSColin Finck } 1061c2c66affSColin Finck else 1062c2c66affSColin Finck { 1063c2c66affSColin Finck DeltaPt.cy = rcScreen.bottom - pt.y; 1064c2c66affSColin Finck PosV = ABE_BOTTOM; 1065c2c66affSColin Finck } 1066c2c66affSColin Finck 1067c2c66affSColin Finck Pos = (DeltaPt.cx * rcScreen.bottom < DeltaPt.cy * rcScreen.right) ? PosH : PosV; 1068c2c66affSColin Finck 1069c2c66affSColin Finck /* Fix the screen origin to be relative to the primary monitor again */ 1070c2c66affSColin Finck OffsetRect(&rcScreen, 1071c2c66affSColin Finck ScreenOffset.cx, 1072c2c66affSColin Finck ScreenOffset.cy); 1073c2c66affSColin Finck 1074c2c66affSColin Finck RECT rcPos = m_TrayRects[Pos]; 1075c2c66affSColin Finck 1076c2c66affSColin Finck hMonNew = GetMonitorFromRect(&rcPos); 1077c2c66affSColin Finck if (hMon != hMonNew) 1078c2c66affSColin Finck { 1079c2c66affSColin Finck SIZE szTray; 1080c2c66affSColin Finck 1081c2c66affSColin Finck /* Recalculate the rectangle, we're dragging to another monitor. 1082c2c66affSColin Finck We don't need to recalculate the rect on single monitor systems. */ 1083c2c66affSColin Finck szTray.cx = rcPos.right - rcPos.left; 1084c2c66affSColin Finck szTray.cy = rcPos.bottom - rcPos.top; 1085c2c66affSColin Finck 1086c2c66affSColin Finck GetTrayRectFromScreenRect(Pos, &rcScreen, &szTray, pRect); 1087c2c66affSColin Finck hMon = hMonNew; 1088c2c66affSColin Finck } 1089c2c66affSColin Finck else 1090c2c66affSColin Finck { 1091c2c66affSColin Finck /* The user is dragging the tray window on the same monitor. We don't need 1092c2c66affSColin Finck to recalculate the rectangle */ 1093c2c66affSColin Finck *pRect = rcPos; 1094c2c66affSColin Finck } 1095c2c66affSColin Finck 1096c2c66affSColin Finck *phMonitor = hMon; 1097c2c66affSColin Finck 1098c2c66affSColin Finck return Pos; 1099c2c66affSColin Finck } 1100c2c66affSColin Finck 1101c2c66affSColin Finck DWORD GetDraggingRectFromRect( 1102c2c66affSColin Finck IN OUT RECT *pRect, 1103c2c66affSColin Finck OUT HMONITOR *phMonitor) 1104c2c66affSColin Finck { 1105c2c66affSColin Finck POINT pt; 1106c2c66affSColin Finck 1107c2c66affSColin Finck /* Calculate the center of the rectangle. We call 1108c2c66affSColin Finck GetDraggingRectFromPt to calculate a valid 1109c2c66affSColin Finck dragging rectangle */ 1110c2c66affSColin Finck pt.x = pRect->left + ((pRect->right - pRect->left) / 2); 1111c2c66affSColin Finck pt.y = pRect->top + ((pRect->bottom - pRect->top) / 2); 1112c2c66affSColin Finck 1113c2c66affSColin Finck return GetDraggingRectFromPt( 1114c2c66affSColin Finck pt, 1115c2c66affSColin Finck pRect, 1116c2c66affSColin Finck phMonitor); 1117c2c66affSColin Finck } 1118c2c66affSColin Finck 1119c2c66affSColin Finck VOID ChangingWinPos(IN OUT LPWINDOWPOS pwp) 1120c2c66affSColin Finck { 1121c2c66affSColin Finck RECT rcTray; 1122c2c66affSColin Finck 1123c2c66affSColin Finck if (IsDragging) 1124c2c66affSColin Finck { 1125c2c66affSColin Finck rcTray.left = pwp->x; 1126c2c66affSColin Finck rcTray.top = pwp->y; 1127c2c66affSColin Finck rcTray.right = rcTray.left + pwp->cx; 1128c2c66affSColin Finck rcTray.bottom = rcTray.top + pwp->cy; 1129c2c66affSColin Finck 1130c2c66affSColin Finck if (!EqualRect(&rcTray, 1131c2c66affSColin Finck &m_TrayRects[m_DraggingPosition])) 1132c2c66affSColin Finck { 1133c2c66affSColin Finck /* Recalculate the rectangle, the user dragged the tray 1134c2c66affSColin Finck window to another monitor or the window was somehow else 1135c2c66affSColin Finck moved or resized */ 1136c2c66affSColin Finck m_DraggingPosition = GetDraggingRectFromRect( 1137c2c66affSColin Finck &rcTray, 1138c2c66affSColin Finck &m_DraggingMonitor); 1139c2c66affSColin Finck //m_TrayRects[DraggingPosition] = rcTray; 1140c2c66affSColin Finck } 1141c2c66affSColin Finck 1142c2c66affSColin Finck //Monitor = CalculateValidSize(DraggingPosition, 1143c2c66affSColin Finck // &rcTray); 1144c2c66affSColin Finck 1145c2c66affSColin Finck m_Monitor = m_DraggingMonitor; 1146c2c66affSColin Finck m_Position = m_DraggingPosition; 1147c2c66affSColin Finck IsDragging = FALSE; 1148c2c66affSColin Finck 1149c2c66affSColin Finck m_TrayRects[m_Position] = rcTray; 1150c2c66affSColin Finck goto ChangePos; 1151c2c66affSColin Finck } 1152c2c66affSColin Finck else if (GetWindowRect(&rcTray)) 1153c2c66affSColin Finck { 1154c2c66affSColin Finck if (InSizeMove) 1155c2c66affSColin Finck { 1156c2c66affSColin Finck if (!(pwp->flags & SWP_NOMOVE)) 1157c2c66affSColin Finck { 1158c2c66affSColin Finck rcTray.left = pwp->x; 1159c2c66affSColin Finck rcTray.top = pwp->y; 1160c2c66affSColin Finck } 1161c2c66affSColin Finck 1162c2c66affSColin Finck if (!(pwp->flags & SWP_NOSIZE)) 1163c2c66affSColin Finck { 1164c2c66affSColin Finck rcTray.right = rcTray.left + pwp->cx; 1165c2c66affSColin Finck rcTray.bottom = rcTray.top + pwp->cy; 1166c2c66affSColin Finck } 1167c2c66affSColin Finck 1168c2c66affSColin Finck m_Position = GetDraggingRectFromRect(&rcTray, &m_Monitor); 1169c2c66affSColin Finck 1170c2c66affSColin Finck if (!(pwp->flags & (SWP_NOMOVE | SWP_NOSIZE))) 1171c2c66affSColin Finck { 1172c2c66affSColin Finck SIZE szWnd; 1173c2c66affSColin Finck 1174c2c66affSColin Finck szWnd.cx = pwp->cx; 1175c2c66affSColin Finck szWnd.cy = pwp->cy; 1176c2c66affSColin Finck 1177c2c66affSColin Finck MakeTrayRectWithSize(m_Position, &szWnd, &rcTray); 1178c2c66affSColin Finck } 1179c2c66affSColin Finck 1180c2c66affSColin Finck m_TrayRects[m_Position] = rcTray; 1181c2c66affSColin Finck } 1182c2c66affSColin Finck else 1183c2c66affSColin Finck { 1184c2c66affSColin Finck /* If the user isn't resizing the tray window we need to make sure the 1185c2c66affSColin Finck new size or position is valid. this is to prevent changes to the window 1186c2c66affSColin Finck without user interaction. */ 1187c2c66affSColin Finck rcTray = m_TrayRects[m_Position]; 1188c2c66affSColin Finck 11892ed535daSGiannis Adamopoulos if (g_TaskbarSettings.sr.AutoHide) 1190c2c66affSColin Finck { 1191c2c66affSColin Finck rcTray.left += m_AutoHideOffset.cx; 1192c2c66affSColin Finck rcTray.right += m_AutoHideOffset.cx; 1193c2c66affSColin Finck rcTray.top += m_AutoHideOffset.cy; 1194c2c66affSColin Finck rcTray.bottom += m_AutoHideOffset.cy; 1195c2c66affSColin Finck } 1196c2c66affSColin Finck 11974238f223SGiannis Adamopoulos } 11984238f223SGiannis Adamopoulos 11994238f223SGiannis Adamopoulos ChangePos: 12004238f223SGiannis Adamopoulos m_TraySize.cx = rcTray.right - rcTray.left; 12014238f223SGiannis Adamopoulos m_TraySize.cy = rcTray.bottom - rcTray.top; 12024238f223SGiannis Adamopoulos 1203c2c66affSColin Finck pwp->flags &= ~(SWP_NOMOVE | SWP_NOSIZE); 1204c2c66affSColin Finck pwp->x = rcTray.left; 1205c2c66affSColin Finck pwp->y = rcTray.top; 1206c2c66affSColin Finck pwp->cx = m_TraySize.cx; 1207c2c66affSColin Finck pwp->cy = m_TraySize.cy; 1208c2c66affSColin Finck } 1209c2c66affSColin Finck } 1210c2c66affSColin Finck 1211c2c66affSColin Finck VOID ApplyClipping(IN BOOL Clip) 1212c2c66affSColin Finck { 1213c2c66affSColin Finck RECT rcClip, rcWindow; 1214c2c66affSColin Finck HRGN hClipRgn; 1215c2c66affSColin Finck 1216c2c66affSColin Finck if (GetWindowRect(&rcWindow)) 1217c2c66affSColin Finck { 1218c2c66affSColin Finck /* Disable clipping on systems with only one monitor */ 1219c2c66affSColin Finck if (GetSystemMetrics(SM_CMONITORS) <= 1) 1220c2c66affSColin Finck Clip = FALSE; 1221c2c66affSColin Finck 1222c2c66affSColin Finck if (Clip) 1223c2c66affSColin Finck { 1224c2c66affSColin Finck rcClip = rcWindow; 1225c2c66affSColin Finck 1226c2c66affSColin Finck GetScreenRect(m_Monitor, &rcClip); 1227c2c66affSColin Finck 1228c2c66affSColin Finck if (!IntersectRect(&rcClip, &rcClip, &rcWindow)) 1229c2c66affSColin Finck { 1230c2c66affSColin Finck rcClip = rcWindow; 1231c2c66affSColin Finck } 1232c2c66affSColin Finck 1233c2c66affSColin Finck OffsetRect(&rcClip, 1234c2c66affSColin Finck -rcWindow.left, 1235c2c66affSColin Finck -rcWindow.top); 1236c2c66affSColin Finck 1237c2c66affSColin Finck hClipRgn = CreateRectRgnIndirect(&rcClip); 1238c2c66affSColin Finck } 1239c2c66affSColin Finck else 1240c2c66affSColin Finck hClipRgn = NULL; 1241c2c66affSColin Finck 1242c2c66affSColin Finck /* Set the clipping region or make sure the window isn't clipped 1243c2c66affSColin Finck by disabling it explicitly. */ 1244c2c66affSColin Finck SetWindowRgn(hClipRgn, TRUE); 1245c2c66affSColin Finck } 1246c2c66affSColin Finck } 1247c2c66affSColin Finck 1248c2c66affSColin Finck VOID ResizeWorkArea() 1249c2c66affSColin Finck { 1250c2c66affSColin Finck #if !WIN7_DEBUG_MODE 1251c2c66affSColin Finck RECT rcTray, rcWorkArea; 1252c2c66affSColin Finck 1253c2c66affSColin Finck /* If monitor has changed then fix the previous monitors work area */ 1254c2c66affSColin Finck if (m_PreviousMonitor != m_Monitor) 1255c2c66affSColin Finck { 1256c2c66affSColin Finck GetScreenRect(m_PreviousMonitor, &rcWorkArea); 1257c2c66affSColin Finck SystemParametersInfoW(SPI_SETWORKAREA, 1258c2c66affSColin Finck 1, 1259c2c66affSColin Finck &rcWorkArea, 1260c2c66affSColin Finck SPIF_SENDCHANGE); 1261c2c66affSColin Finck } 1262c2c66affSColin Finck 1263c2c66affSColin Finck rcTray = m_TrayRects[m_Position]; 1264c2c66affSColin Finck 1265c2c66affSColin Finck GetScreenRect(m_Monitor, &rcWorkArea); 1266c2c66affSColin Finck m_PreviousMonitor = m_Monitor; 1267c2c66affSColin Finck 1268c2c66affSColin Finck /* If AutoHide is false then change the workarea to exclude 1269c2c66affSColin Finck the area that the taskbar covers. */ 12702ed535daSGiannis Adamopoulos if (!g_TaskbarSettings.sr.AutoHide) 1271c2c66affSColin Finck { 1272c2c66affSColin Finck switch (m_Position) 1273c2c66affSColin Finck { 1274c2c66affSColin Finck case ABE_TOP: 1275c2c66affSColin Finck rcWorkArea.top = rcTray.bottom; 1276c2c66affSColin Finck break; 1277c2c66affSColin Finck case ABE_LEFT: 1278c2c66affSColin Finck rcWorkArea.left = rcTray.right; 1279c2c66affSColin Finck break; 1280c2c66affSColin Finck case ABE_RIGHT: 1281c2c66affSColin Finck rcWorkArea.right = rcTray.left; 1282c2c66affSColin Finck break; 1283c2c66affSColin Finck case ABE_BOTTOM: 1284c2c66affSColin Finck rcWorkArea.bottom = rcTray.top; 1285c2c66affSColin Finck break; 1286c2c66affSColin Finck } 1287c2c66affSColin Finck } 1288c2c66affSColin Finck 1289c2c66affSColin Finck /* 1290c2c66affSColin Finck * Resize the current monitor work area. Win32k will also send 1291c2c66affSColin Finck * a WM_SIZE message to automatically resize the desktop. 1292c2c66affSColin Finck */ 1293c2c66affSColin Finck SystemParametersInfoW(SPI_SETWORKAREA, 1294c2c66affSColin Finck 1, 1295c2c66affSColin Finck &rcWorkArea, 1296c2c66affSColin Finck SPIF_SENDCHANGE); 1297c2c66affSColin Finck #endif 1298c2c66affSColin Finck } 1299c2c66affSColin Finck 1300c2c66affSColin Finck VOID CheckTrayWndPosition() 1301c2c66affSColin Finck { 13024238f223SGiannis Adamopoulos /* Force the rebar bands to resize */ 1303c2c66affSColin Finck IUnknown_Exec(m_TrayBandSite, 1304c2c66affSColin Finck IID_IDeskBand, 1305c2c66affSColin Finck DBID_BANDINFOCHANGED, 1306c2c66affSColin Finck 0, 1307c2c66affSColin Finck NULL, 1308c2c66affSColin Finck NULL); 1309c2c66affSColin Finck 13104238f223SGiannis Adamopoulos /* Calculate the size of the taskbar based on the rebar */ 13114238f223SGiannis Adamopoulos FitToRebar(&m_TrayRects[m_Position]); 1312c2c66affSColin Finck 1313c2c66affSColin Finck /* Move the tray window */ 13144238f223SGiannis Adamopoulos /* The handler of WM_WINDOWPOSCHANGING will override whatever size 13154238f223SGiannis Adamopoulos *and position we use here with m_TrayRects */ 13164238f223SGiannis Adamopoulos SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOACTIVATE); 1317c2c66affSColin Finck ResizeWorkArea(); 1318c2c66affSColin Finck ApplyClipping(TRUE); 1319c2c66affSColin Finck } 1320c2c66affSColin Finck 1321c2c66affSColin Finck VOID RegLoadSettings() 1322c2c66affSColin Finck { 1323c2c66affSColin Finck DWORD Pos; 1324c2c66affSColin Finck RECT rcScreen; 1325c2c66affSColin Finck SIZE WndSize, EdgeSize, DlgFrameSize; 1326c2c66affSColin Finck SIZE StartBtnSize = m_StartButton.GetSize(); 1327c2c66affSColin Finck 1328c2c66affSColin Finck EdgeSize.cx = GetSystemMetrics(SM_CXEDGE); 1329c2c66affSColin Finck EdgeSize.cy = GetSystemMetrics(SM_CYEDGE); 1330c2c66affSColin Finck DlgFrameSize.cx = GetSystemMetrics(SM_CXDLGFRAME); 1331c2c66affSColin Finck DlgFrameSize.cy = GetSystemMetrics(SM_CYDLGFRAME); 1332c2c66affSColin Finck 13332ed535daSGiannis Adamopoulos m_Position = g_TaskbarSettings.sr.Position; 13342ed535daSGiannis Adamopoulos rcScreen = g_TaskbarSettings.sr.Rect; 13352ed535daSGiannis Adamopoulos GetScreenRectFromRect(&rcScreen, MONITOR_DEFAULTTONEAREST); 13362ed535daSGiannis Adamopoulos 13372ed535daSGiannis Adamopoulos if (!g_TaskbarSettings.sr.Size.cx || !g_TaskbarSettings.sr.Size.cy) 1338c2c66affSColin Finck { 1339c2c66affSColin Finck /* Use the minimum size of the taskbar, we'll use the start 1340c2c66affSColin Finck button as a minimum for now. Make sure we calculate the 1341c2c66affSColin Finck entire window size, not just the client size. However, we 1342c2c66affSColin Finck use a thinner border than a standard thick border, so that 1343c2c66affSColin Finck the start button and bands are not stuck to the screen border. */ 1344c2c66affSColin Finck if(!m_Theme) 1345c2c66affSColin Finck { 13462ed535daSGiannis Adamopoulos g_TaskbarSettings.sr.Size.cx = StartBtnSize.cx + (2 * (EdgeSize.cx + DlgFrameSize.cx)); 13472ed535daSGiannis Adamopoulos g_TaskbarSettings.sr.Size.cy = StartBtnSize.cy + (2 * (EdgeSize.cy + DlgFrameSize.cy)); 1348c2c66affSColin Finck } 1349c2c66affSColin Finck else 1350c2c66affSColin Finck { 13512ed535daSGiannis Adamopoulos g_TaskbarSettings.sr.Size.cx = StartBtnSize.cx - EdgeSize.cx; 13522ed535daSGiannis Adamopoulos g_TaskbarSettings.sr.Size.cy = StartBtnSize.cy - EdgeSize.cy; 13532ed535daSGiannis Adamopoulos if(!g_TaskbarSettings.bLock) 13542ed535daSGiannis Adamopoulos g_TaskbarSettings.sr.Size.cy += GetSystemMetrics(SM_CYSIZEFRAME); 1355c2c66affSColin Finck } 1356c2c66affSColin Finck } 1357c2c66affSColin Finck /* Determine a minimum tray window rectangle. The "client" height is 1358c2c66affSColin Finck zero here since we cannot determine an optimal minimum width when 1359c2c66affSColin Finck loaded as a vertical tray window. We just need to make sure the values 1360c2c66affSColin Finck loaded from the registry are at least. The windows explorer behaves 1361c2c66affSColin Finck the same way, it allows the user to save a zero width vertical tray 1362c2c66affSColin Finck window, but not a zero height horizontal tray window. */ 1363c2c66affSColin Finck if(!m_Theme) 1364c2c66affSColin Finck { 1365c2c66affSColin Finck WndSize.cx = 2 * (EdgeSize.cx + DlgFrameSize.cx); 1366c2c66affSColin Finck WndSize.cy = StartBtnSize.cy + (2 * (EdgeSize.cy + DlgFrameSize.cy)); 1367c2c66affSColin Finck } 1368c2c66affSColin Finck else 1369c2c66affSColin Finck { 1370c2c66affSColin Finck WndSize.cx = StartBtnSize.cx; 1371c2c66affSColin Finck WndSize.cy = StartBtnSize.cy - EdgeSize.cx; 1372c2c66affSColin Finck } 1373c2c66affSColin Finck 13742ed535daSGiannis Adamopoulos if (WndSize.cx < g_TaskbarSettings.sr.Size.cx) 13752ed535daSGiannis Adamopoulos WndSize.cx = g_TaskbarSettings.sr.Size.cx; 13762ed535daSGiannis Adamopoulos if (WndSize.cy < g_TaskbarSettings.sr.Size.cy) 13772ed535daSGiannis Adamopoulos WndSize.cy = g_TaskbarSettings.sr.Size.cy; 1378c2c66affSColin Finck 1379c2c66affSColin Finck /* Save the calculated size */ 1380c2c66affSColin Finck m_TraySize = WndSize; 1381c2c66affSColin Finck 1382c2c66affSColin Finck /* Calculate all docking rectangles. We need to do this here so they're 1383c2c66affSColin Finck initialized and dragging the tray window to another position gives 1384c2c66affSColin Finck usable results */ 1385c2c66affSColin Finck for (Pos = ABE_LEFT; Pos <= ABE_BOTTOM; Pos++) 1386c2c66affSColin Finck { 1387c2c66affSColin Finck GetTrayRectFromScreenRect(Pos, 1388c2c66affSColin Finck &rcScreen, 1389c2c66affSColin Finck &m_TraySize, 1390c2c66affSColin Finck &m_TrayRects[Pos]); 1391c2c66affSColin 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); 1392c2c66affSColin Finck } 1393c2c66affSColin Finck 1394c2c66affSColin Finck /* Determine which monitor we are on. It shouldn't matter which docked 1395c2c66affSColin Finck position rectangle we use */ 1396c2c66affSColin Finck m_Monitor = GetMonitorFromRect(&m_TrayRects[ABE_LEFT]); 1397c2c66affSColin Finck } 1398c2c66affSColin Finck 1399c2c66affSColin Finck VOID AlignControls(IN PRECT prcClient OPTIONAL) 1400c2c66affSColin Finck { 1401c2c66affSColin Finck RECT rcClient; 1402c2c66affSColin Finck SIZE TraySize, StartSize; 1403c2c66affSColin Finck POINT ptTrayNotify = { 0, 0 }; 1404c2c66affSColin Finck BOOL Horizontal; 1405c2c66affSColin Finck HDWP dwp; 1406c2c66affSColin Finck 1407c2c66affSColin Finck m_StartButton.UpdateSize(); 1408c2c66affSColin Finck if (prcClient != NULL) 1409c2c66affSColin Finck { 1410c2c66affSColin Finck rcClient = *prcClient; 1411c2c66affSColin Finck } 1412c2c66affSColin Finck else 1413c2c66affSColin Finck { 1414c2c66affSColin Finck if (!GetClientRect(&rcClient)) 1415c2c66affSColin Finck { 1416c2c66affSColin Finck ERR("Could not get client rect lastErr=%d\n", GetLastError()); 1417c2c66affSColin Finck return; 1418c2c66affSColin Finck } 1419c2c66affSColin Finck } 1420c2c66affSColin Finck 1421c2c66affSColin Finck Horizontal = IsPosHorizontal(); 1422c2c66affSColin Finck 1423c2c66affSColin Finck /* We're about to resize/move the start button, the rebar control and 1424c2c66affSColin Finck the tray notification control */ 1425c2c66affSColin Finck dwp = BeginDeferWindowPos(3); 1426c2c66affSColin Finck if (dwp == NULL) 1427c2c66affSColin Finck { 1428c2c66affSColin Finck ERR("BeginDeferWindowPos failed. lastErr=%d\n", GetLastError()); 1429c2c66affSColin Finck return; 1430c2c66affSColin Finck } 1431c2c66affSColin Finck 1432c2c66affSColin Finck /* Limit the Start button width to the client width, if necessary */ 1433c2c66affSColin Finck StartSize = m_StartButton.GetSize(); 1434c2c66affSColin Finck if (StartSize.cx > rcClient.right) 1435c2c66affSColin Finck StartSize.cx = rcClient.right; 1436c2c66affSColin Finck 1437c2c66affSColin Finck if (!m_Theme) 1438c2c66affSColin Finck { 1439c2c66affSColin Finck HWND hwndTaskToolbar = ::GetWindow(m_TaskSwitch, GW_CHILD); 1440c2c66affSColin Finck if (hwndTaskToolbar) 1441c2c66affSColin Finck { 1442c2c66affSColin Finck DWORD size = SendMessageW(hwndTaskToolbar, TB_GETBUTTONSIZE, 0, 0); 1443c2c66affSColin Finck StartSize.cy = HIWORD(size); 1444c2c66affSColin Finck } 1445c2c66affSColin Finck } 1446c2c66affSColin Finck 1447c2c66affSColin Finck if (m_StartButton.m_hWnd != NULL) 1448c2c66affSColin Finck { 1449c2c66affSColin Finck /* Resize and reposition the button */ 1450c2c66affSColin Finck dwp = m_StartButton.DeferWindowPos(dwp, 1451c2c66affSColin Finck NULL, 1452c2c66affSColin Finck 0, 1453c2c66affSColin Finck 0, 1454c2c66affSColin Finck StartSize.cx, 1455c2c66affSColin Finck StartSize.cy, 1456c2c66affSColin Finck SWP_NOZORDER | SWP_NOACTIVATE); 1457c2c66affSColin Finck if (dwp == NULL) 1458c2c66affSColin Finck { 1459c2c66affSColin Finck ERR("DeferWindowPos for start button failed. lastErr=%d\n", GetLastError()); 1460c2c66affSColin Finck return; 1461c2c66affSColin Finck } 1462c2c66affSColin Finck } 1463c2c66affSColin Finck 1464c2c66affSColin Finck /* Determine the size that the tray notification window needs */ 1465c2c66affSColin Finck if (Horizontal) 1466c2c66affSColin Finck { 1467c2c66affSColin Finck TraySize.cx = 0; 1468c2c66affSColin Finck TraySize.cy = rcClient.bottom; 1469c2c66affSColin Finck } 1470c2c66affSColin Finck else 1471c2c66affSColin Finck { 1472c2c66affSColin Finck TraySize.cx = rcClient.right; 1473c2c66affSColin Finck TraySize.cy = 0; 1474c2c66affSColin Finck } 1475c2c66affSColin Finck 1476c2c66affSColin Finck if (m_TrayNotify != NULL && 1477c2c66affSColin Finck SendMessage(m_TrayNotify, 1478c2c66affSColin Finck TNWM_GETMINIMUMSIZE, 1479c2c66affSColin Finck (WPARAM)Horizontal, 1480c2c66affSColin Finck (LPARAM)&TraySize)) 1481c2c66affSColin Finck { 1482c2c66affSColin Finck /* Move the tray notification window to the desired location */ 1483c2c66affSColin Finck if (Horizontal) 1484c2c66affSColin Finck ptTrayNotify.x = rcClient.right - TraySize.cx; 1485c2c66affSColin Finck else 1486c2c66affSColin Finck ptTrayNotify.y = rcClient.bottom - TraySize.cy; 1487c2c66affSColin Finck 1488c2c66affSColin Finck dwp = ::DeferWindowPos(dwp, 1489c2c66affSColin Finck m_TrayNotify, 1490c2c66affSColin Finck NULL, 1491c2c66affSColin Finck ptTrayNotify.x, 1492c2c66affSColin Finck ptTrayNotify.y, 1493c2c66affSColin Finck TraySize.cx, 1494c2c66affSColin Finck TraySize.cy, 1495c2c66affSColin Finck SWP_NOZORDER | SWP_NOACTIVATE); 1496c2c66affSColin Finck if (dwp == NULL) 1497c2c66affSColin Finck { 1498c2c66affSColin Finck ERR("DeferWindowPos for notification area failed. lastErr=%d\n", GetLastError()); 1499c2c66affSColin Finck return; 1500c2c66affSColin Finck } 1501c2c66affSColin Finck } 1502c2c66affSColin Finck 1503c2c66affSColin Finck /* Resize/Move the rebar control */ 1504c2c66affSColin Finck if (m_Rebar != NULL) 1505c2c66affSColin Finck { 1506c2c66affSColin Finck POINT ptRebar = { 0, 0 }; 1507c2c66affSColin Finck SIZE szRebar; 1508c2c66affSColin Finck 1509c2c66affSColin Finck SetWindowStyle(m_Rebar, CCS_VERT, Horizontal ? 0 : CCS_VERT); 1510c2c66affSColin Finck 1511c2c66affSColin Finck if (Horizontal) 1512c2c66affSColin Finck { 1513c2c66affSColin Finck ptRebar.x = StartSize.cx + GetSystemMetrics(SM_CXSIZEFRAME); 1514c2c66affSColin Finck szRebar.cx = ptTrayNotify.x - ptRebar.x; 1515c2c66affSColin Finck szRebar.cy = rcClient.bottom; 1516c2c66affSColin Finck } 1517c2c66affSColin Finck else 1518c2c66affSColin Finck { 1519c2c66affSColin Finck ptRebar.y = StartSize.cy + GetSystemMetrics(SM_CYSIZEFRAME); 1520c2c66affSColin Finck szRebar.cx = rcClient.right; 1521c2c66affSColin Finck szRebar.cy = ptTrayNotify.y - ptRebar.y; 1522c2c66affSColin Finck } 1523c2c66affSColin Finck 1524c2c66affSColin Finck dwp = ::DeferWindowPos(dwp, 1525c2c66affSColin Finck m_Rebar, 1526c2c66affSColin Finck NULL, 1527c2c66affSColin Finck ptRebar.x, 1528c2c66affSColin Finck ptRebar.y, 1529c2c66affSColin Finck szRebar.cx, 1530c2c66affSColin Finck szRebar.cy, 1531c2c66affSColin Finck SWP_NOZORDER | SWP_NOACTIVATE); 1532c2c66affSColin Finck } 1533c2c66affSColin Finck 1534c2c66affSColin Finck if (dwp != NULL) 1535c2c66affSColin Finck EndDeferWindowPos(dwp); 1536c2c66affSColin Finck 1537c2c66affSColin Finck if (m_TaskSwitch != NULL) 1538c2c66affSColin Finck { 1539c2c66affSColin Finck /* Update the task switch window configuration */ 1540c2c66affSColin Finck SendMessage(m_TaskSwitch, TSWM_UPDATETASKBARPOS, 0, 0); 1541c2c66affSColin Finck } 1542c2c66affSColin Finck } 1543c2c66affSColin Finck 1544c2c66affSColin Finck void FitToRebar(PRECT pRect) 1545c2c66affSColin Finck { 1546c2c66affSColin Finck /* Get the rect of the rebar */ 1547c2c66affSColin Finck RECT rebarRect, taskbarRect, clientRect; 1548c2c66affSColin Finck ::GetWindowRect(m_Rebar, &rebarRect); 1549c2c66affSColin Finck ::GetWindowRect(m_hWnd, &taskbarRect); 1550c2c66affSColin Finck ::GetClientRect(m_hWnd, &clientRect); 1551c2c66affSColin Finck OffsetRect(&rebarRect, -taskbarRect.left, -taskbarRect.top); 1552c2c66affSColin Finck 1553c2c66affSColin Finck /* Calculate the difference of size of the taskbar and the rebar */ 1554c2c66affSColin Finck SIZE margins; 1555c2c66affSColin Finck margins.cx = taskbarRect.right - taskbarRect.left - clientRect.right + clientRect.left; 1556c2c66affSColin Finck margins.cy = taskbarRect.bottom - taskbarRect.top - clientRect.bottom + clientRect.top; 1557c2c66affSColin Finck 1558c2c66affSColin Finck /* Calculate the new size of the rebar and make it resize, then change the new taskbar size */ 1559c2c66affSColin Finck switch (m_Position) 1560c2c66affSColin Finck { 1561c2c66affSColin Finck case ABE_TOP: 1562c2c66affSColin Finck rebarRect.bottom = rebarRect.top + pRect->bottom - pRect->top - margins.cy; 1563c2c66affSColin Finck ::SendMessageW(m_Rebar, RB_SIZETORECT, RBSTR_CHANGERECT, (LPARAM)&rebarRect); 1564c2c66affSColin Finck pRect->bottom = pRect->top + rebarRect.bottom - rebarRect.top + margins.cy; 1565c2c66affSColin Finck break; 1566c2c66affSColin Finck case ABE_BOTTOM: 1567c2c66affSColin Finck rebarRect.top = rebarRect.bottom - (pRect->bottom - pRect->top - margins.cy); 1568c2c66affSColin Finck ::SendMessageW(m_Rebar, RB_SIZETORECT, RBSTR_CHANGERECT, (LPARAM)&rebarRect); 1569c2c66affSColin Finck pRect->top = pRect->bottom - (rebarRect.bottom - rebarRect.top + margins.cy); 1570c2c66affSColin Finck break; 1571c2c66affSColin Finck case ABE_LEFT: 1572c2c66affSColin Finck rebarRect.right = rebarRect.left + (pRect->right - pRect->left - margins.cx); 1573c2c66affSColin Finck ::SendMessageW(m_Rebar, RB_SIZETORECT, RBSTR_CHANGERECT, (LPARAM)&rebarRect); 1574c2c66affSColin Finck pRect->right = pRect->left + (rebarRect.right - rebarRect.left + margins.cx); 1575c2c66affSColin Finck break; 1576c2c66affSColin Finck case ABE_RIGHT: 1577c2c66affSColin Finck rebarRect.left = rebarRect.right - (pRect->right - pRect->left - margins.cx); 1578c2c66affSColin Finck ::SendMessageW(m_Rebar, RB_SIZETORECT, RBSTR_CHANGERECT, (LPARAM)&rebarRect); 1579c2c66affSColin Finck pRect->left = pRect->right - (rebarRect.right - rebarRect.left + margins.cx); 1580c2c66affSColin Finck break; 1581c2c66affSColin Finck } 1582c2c66affSColin Finck 1583c2c66affSColin Finck CalculateValidSize(m_Position, pRect); 1584c2c66affSColin Finck } 1585c2c66affSColin Finck 1586c2c66affSColin Finck void PopupStartMenu() 1587c2c66affSColin Finck { 1588c2c66affSColin Finck if (m_StartMenuPopup != NULL) 1589c2c66affSColin Finck { 1590c2c66affSColin Finck POINTL pt; 1591c2c66affSColin Finck RECTL rcExclude; 1592c2c66affSColin Finck DWORD dwFlags = 0; 1593c2c66affSColin Finck 1594c2c66affSColin Finck if (m_StartButton.GetWindowRect((RECT*) &rcExclude)) 1595c2c66affSColin Finck { 1596c2c66affSColin Finck switch (m_Position) 1597c2c66affSColin Finck { 1598c2c66affSColin Finck case ABE_BOTTOM: 1599c2c66affSColin Finck pt.x = rcExclude.left; 1600c2c66affSColin Finck pt.y = rcExclude.top; 1601c2c66affSColin Finck dwFlags |= MPPF_TOP; 1602c2c66affSColin Finck break; 1603c2c66affSColin Finck case ABE_TOP: 1604c2c66affSColin Finck pt.x = rcExclude.left; 1605c2c66affSColin Finck pt.y = rcExclude.bottom; 1606c2c66affSColin Finck dwFlags |= MPPF_BOTTOM; 1607c2c66affSColin Finck break; 1608c2c66affSColin Finck case ABE_LEFT: 1609c2c66affSColin Finck pt.x = rcExclude.right; 1610c2c66affSColin Finck pt.y = rcExclude.top; 1611c2c66affSColin Finck dwFlags |= MPPF_RIGHT; 1612c2c66affSColin Finck break; 1613c2c66affSColin Finck case ABE_RIGHT: 1614c2c66affSColin Finck pt.x = rcExclude.left; 1615c2c66affSColin Finck pt.y = rcExclude.top; 1616c2c66affSColin Finck dwFlags |= MPPF_LEFT; 1617c2c66affSColin Finck break; 1618c2c66affSColin Finck } 1619c2c66affSColin Finck 1620c2c66affSColin Finck m_StartMenuPopup->Popup(&pt, &rcExclude, dwFlags); 1621c2c66affSColin Finck 1622c2c66affSColin Finck m_StartButton.SendMessageW(BM_SETSTATE, TRUE, 0); 1623c2c66affSColin Finck } 1624c2c66affSColin Finck } 1625c2c66affSColin Finck } 1626c2c66affSColin Finck 1627c2c66affSColin Finck void ProcessMouseTracking() 1628c2c66affSColin Finck { 1629c2c66affSColin Finck RECT rcCurrent; 1630c2c66affSColin Finck POINT pt; 1631c2c66affSColin Finck BOOL over; 1632c2c66affSColin Finck UINT state = m_AutoHideState; 1633c2c66affSColin Finck 1634c2c66affSColin Finck GetCursorPos(&pt); 1635c2c66affSColin Finck GetWindowRect(&rcCurrent); 1636c2c66affSColin Finck over = PtInRect(&rcCurrent, pt); 1637c2c66affSColin Finck 1638c2c66affSColin Finck if (m_StartButton.SendMessage( BM_GETSTATE, 0, 0) != BST_UNCHECKED) 1639c2c66affSColin Finck { 1640c2c66affSColin Finck over = TRUE; 1641c2c66affSColin Finck } 1642c2c66affSColin Finck 1643c2c66affSColin Finck if (over) 1644c2c66affSColin Finck { 1645c2c66affSColin Finck if (state == AUTOHIDE_HIDING) 1646c2c66affSColin Finck { 1647c2c66affSColin Finck TRACE("AutoHide cancelling hide.\n"); 1648c2c66affSColin Finck m_AutoHideState = AUTOHIDE_SHOWING; 1649c2c66affSColin Finck SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_INTERVAL_ANIMATING, NULL); 1650c2c66affSColin Finck } 1651c2c66affSColin Finck else if (state == AUTOHIDE_HIDDEN) 1652c2c66affSColin Finck { 1653c2c66affSColin Finck TRACE("AutoHide starting show.\n"); 1654c2c66affSColin Finck m_AutoHideState = AUTOHIDE_SHOWING; 1655c2c66affSColin Finck SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_DELAY_SHOW, NULL); 1656c2c66affSColin Finck } 1657c2c66affSColin Finck } 1658c2c66affSColin Finck else 1659c2c66affSColin Finck { 1660c2c66affSColin Finck if (state == AUTOHIDE_SHOWING) 1661c2c66affSColin Finck { 1662c2c66affSColin Finck TRACE("AutoHide cancelling show.\n"); 1663c2c66affSColin Finck m_AutoHideState = AUTOHIDE_HIDING; 1664c2c66affSColin Finck SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_INTERVAL_ANIMATING, NULL); 1665c2c66affSColin Finck } 1666c2c66affSColin Finck else if (state == AUTOHIDE_SHOWN) 1667c2c66affSColin Finck { 1668c2c66affSColin Finck TRACE("AutoHide starting hide.\n"); 1669c2c66affSColin Finck m_AutoHideState = AUTOHIDE_HIDING; 1670c2c66affSColin Finck SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_DELAY_HIDE, NULL); 1671c2c66affSColin Finck } 1672c2c66affSColin Finck 1673c2c66affSColin Finck KillTimer(TIMER_ID_MOUSETRACK); 1674c2c66affSColin Finck } 1675c2c66affSColin Finck } 1676c2c66affSColin Finck 1677c2c66affSColin Finck void ProcessAutoHide() 1678c2c66affSColin Finck { 1679c2c66affSColin Finck INT w = m_TraySize.cx - GetSystemMetrics(SM_CXBORDER) * 2 - 1; 1680c2c66affSColin Finck INT h = m_TraySize.cy - GetSystemMetrics(SM_CYBORDER) * 2 - 1; 1681c2c66affSColin Finck 1682c2c66affSColin Finck switch (m_AutoHideState) 1683c2c66affSColin Finck { 1684c2c66affSColin Finck case AUTOHIDE_HIDING: 1685c2c66affSColin Finck switch (m_Position) 1686c2c66affSColin Finck { 1687c2c66affSColin Finck case ABE_LEFT: 1688c2c66affSColin Finck m_AutoHideOffset.cy = 0; 1689c2c66affSColin Finck m_AutoHideOffset.cx -= AUTOHIDE_SPEED_HIDE; 1690c2c66affSColin Finck if (m_AutoHideOffset.cx < -w) 1691c2c66affSColin Finck m_AutoHideOffset.cx = -w; 1692c2c66affSColin Finck break; 1693c2c66affSColin Finck case ABE_TOP: 1694c2c66affSColin Finck m_AutoHideOffset.cx = 0; 1695c2c66affSColin Finck m_AutoHideOffset.cy -= AUTOHIDE_SPEED_HIDE; 1696c2c66affSColin Finck if (m_AutoHideOffset.cy < -h) 1697c2c66affSColin Finck m_AutoHideOffset.cy = -h; 1698c2c66affSColin Finck break; 1699c2c66affSColin Finck case ABE_RIGHT: 1700c2c66affSColin Finck m_AutoHideOffset.cy = 0; 1701c2c66affSColin Finck m_AutoHideOffset.cx += AUTOHIDE_SPEED_HIDE; 1702c2c66affSColin Finck if (m_AutoHideOffset.cx > w) 1703c2c66affSColin Finck m_AutoHideOffset.cx = w; 1704c2c66affSColin Finck break; 1705c2c66affSColin Finck case ABE_BOTTOM: 1706c2c66affSColin Finck m_AutoHideOffset.cx = 0; 1707c2c66affSColin Finck m_AutoHideOffset.cy += AUTOHIDE_SPEED_HIDE; 1708c2c66affSColin Finck if (m_AutoHideOffset.cy > h) 1709c2c66affSColin Finck m_AutoHideOffset.cy = h; 1710c2c66affSColin Finck break; 1711c2c66affSColin Finck } 1712c2c66affSColin Finck 1713c2c66affSColin Finck if (m_AutoHideOffset.cx != w && m_AutoHideOffset.cy != h) 1714c2c66affSColin Finck { 1715c2c66affSColin Finck SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_INTERVAL_ANIMATING, NULL); 1716c2c66affSColin Finck break; 1717c2c66affSColin Finck } 1718c2c66affSColin Finck 1719c2c66affSColin Finck /* fallthrough */ 1720c2c66affSColin Finck case AUTOHIDE_HIDDEN: 1721c2c66affSColin Finck 1722c2c66affSColin Finck switch (m_Position) 1723c2c66affSColin Finck { 1724c2c66affSColin Finck case ABE_LEFT: 1725c2c66affSColin Finck m_AutoHideOffset.cx = -w; 1726c2c66affSColin Finck m_AutoHideOffset.cy = 0; 1727c2c66affSColin Finck break; 1728c2c66affSColin Finck case ABE_TOP: 1729c2c66affSColin Finck m_AutoHideOffset.cx = 0; 1730c2c66affSColin Finck m_AutoHideOffset.cy = -h; 1731c2c66affSColin Finck break; 1732c2c66affSColin Finck case ABE_RIGHT: 1733c2c66affSColin Finck m_AutoHideOffset.cx = w; 1734c2c66affSColin Finck m_AutoHideOffset.cy = 0; 1735c2c66affSColin Finck break; 1736c2c66affSColin Finck case ABE_BOTTOM: 1737c2c66affSColin Finck m_AutoHideOffset.cx = 0; 1738c2c66affSColin Finck m_AutoHideOffset.cy = h; 1739c2c66affSColin Finck break; 1740c2c66affSColin Finck } 1741c2c66affSColin Finck 1742c2c66affSColin Finck KillTimer(TIMER_ID_AUTOHIDE); 1743c2c66affSColin Finck m_AutoHideState = AUTOHIDE_HIDDEN; 1744c2c66affSColin Finck break; 1745c2c66affSColin Finck 1746c2c66affSColin Finck case AUTOHIDE_SHOWING: 1747c2c66affSColin Finck if (m_AutoHideOffset.cx >= AUTOHIDE_SPEED_SHOW) 1748c2c66affSColin Finck { 1749c2c66affSColin Finck m_AutoHideOffset.cx -= AUTOHIDE_SPEED_SHOW; 1750c2c66affSColin Finck } 1751c2c66affSColin Finck else if (m_AutoHideOffset.cx <= -AUTOHIDE_SPEED_SHOW) 1752c2c66affSColin Finck { 1753c2c66affSColin Finck m_AutoHideOffset.cx += AUTOHIDE_SPEED_SHOW; 1754c2c66affSColin Finck } 1755c2c66affSColin Finck else 1756c2c66affSColin Finck { 1757c2c66affSColin Finck m_AutoHideOffset.cx = 0; 1758c2c66affSColin Finck } 1759c2c66affSColin Finck 1760c2c66affSColin Finck if (m_AutoHideOffset.cy >= AUTOHIDE_SPEED_SHOW) 1761c2c66affSColin Finck { 1762c2c66affSColin Finck m_AutoHideOffset.cy -= AUTOHIDE_SPEED_SHOW; 1763c2c66affSColin Finck } 1764c2c66affSColin Finck else if (m_AutoHideOffset.cy <= -AUTOHIDE_SPEED_SHOW) 1765c2c66affSColin Finck { 1766c2c66affSColin Finck m_AutoHideOffset.cy += AUTOHIDE_SPEED_SHOW; 1767c2c66affSColin Finck } 1768c2c66affSColin Finck else 1769c2c66affSColin Finck { 1770c2c66affSColin Finck m_AutoHideOffset.cy = 0; 1771c2c66affSColin Finck } 1772c2c66affSColin Finck 1773c2c66affSColin Finck if (m_AutoHideOffset.cx != 0 || m_AutoHideOffset.cy != 0) 1774c2c66affSColin Finck { 1775c2c66affSColin Finck SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_INTERVAL_ANIMATING, NULL); 1776c2c66affSColin Finck break; 1777c2c66affSColin Finck } 1778c2c66affSColin Finck 1779c2c66affSColin Finck /* fallthrough */ 1780c2c66affSColin Finck case AUTOHIDE_SHOWN: 1781c2c66affSColin Finck 1782c2c66affSColin Finck KillTimer(TIMER_ID_AUTOHIDE); 1783c2c66affSColin Finck m_AutoHideState = AUTOHIDE_SHOWN; 1784c2c66affSColin Finck break; 1785c2c66affSColin Finck } 1786c2c66affSColin Finck 17874238f223SGiannis Adamopoulos SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOZORDER); 1788c2c66affSColin Finck } 1789c2c66affSColin Finck 1790c2c66affSColin Finck 1791c2c66affSColin Finck 1792c2c66affSColin Finck 1793c2c66affSColin Finck 1794c2c66affSColin Finck /********************************************************** 1795c2c66affSColin Finck * ##### taskbar drawing ##### 1796c2c66affSColin Finck */ 1797c2c66affSColin Finck 1798c2c66affSColin Finck LRESULT EraseBackgroundWithTheme(HDC hdc) 1799c2c66affSColin Finck { 1800c2c66affSColin Finck RECT rect; 1801c2c66affSColin Finck int iSBkgndPart[4] = {TBP_BACKGROUNDLEFT, TBP_BACKGROUNDTOP, TBP_BACKGROUNDRIGHT, TBP_BACKGROUNDBOTTOM}; 1802c2c66affSColin Finck 1803c2c66affSColin Finck ASSERT(m_Position <= ABE_BOTTOM); 1804c2c66affSColin Finck 1805c2c66affSColin Finck if (m_Theme) 1806c2c66affSColin Finck { 1807c2c66affSColin Finck GetClientRect(&rect); 1808c2c66affSColin Finck DrawThemeBackground(m_Theme, hdc, iSBkgndPart[m_Position], 0, &rect, 0); 1809c2c66affSColin Finck } 1810c2c66affSColin Finck 1811c2c66affSColin Finck return 0; 1812c2c66affSColin Finck } 1813c2c66affSColin Finck 1814c2c66affSColin Finck int DrawSizerWithTheme(IN HRGN hRgn) 1815c2c66affSColin Finck { 1816c2c66affSColin Finck HDC hdc; 1817c2c66affSColin Finck RECT rect; 1818c2c66affSColin Finck int iSizerPart[4] = {TBP_SIZINGBARLEFT, TBP_SIZINGBARTOP, TBP_SIZINGBARRIGHT, TBP_SIZINGBARBOTTOM}; 1819c2c66affSColin Finck SIZE size; 1820c2c66affSColin Finck 1821c2c66affSColin Finck ASSERT(m_Position <= ABE_BOTTOM); 1822c2c66affSColin Finck 1823c2c66affSColin Finck HRESULT hr = GetThemePartSize(m_Theme, NULL, iSizerPart[m_Position], 0, NULL, TS_TRUE, &size); 1824c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr)) 1825c2c66affSColin Finck return 0; 1826c2c66affSColin Finck 1827c2c66affSColin Finck GetWindowRect(&rect); 1828c2c66affSColin Finck OffsetRect(&rect, -rect.left, -rect.top); 1829c2c66affSColin Finck 1830c2c66affSColin Finck hdc = GetWindowDC(); 1831c2c66affSColin Finck 1832c2c66affSColin Finck switch (m_Position) 1833c2c66affSColin Finck { 1834c2c66affSColin Finck case ABE_LEFT: 1835c2c66affSColin Finck rect.left = rect.right - size.cx; 1836c2c66affSColin Finck break; 1837c2c66affSColin Finck case ABE_TOP: 1838c2c66affSColin Finck rect.top = rect.bottom - size.cy; 1839c2c66affSColin Finck break; 1840c2c66affSColin Finck case ABE_RIGHT: 1841c2c66affSColin Finck rect.right = rect.left + size.cx; 1842c2c66affSColin Finck break; 1843c2c66affSColin Finck case ABE_BOTTOM: 1844c2c66affSColin Finck default: 1845c2c66affSColin Finck rect.bottom = rect.top + size.cy; 1846c2c66affSColin Finck break; 1847c2c66affSColin Finck } 1848c2c66affSColin Finck 1849c2c66affSColin Finck DrawThemeBackground(m_Theme, hdc, iSizerPart[m_Position], 0, &rect, 0); 1850c2c66affSColin Finck 1851c2c66affSColin Finck ReleaseDC(hdc); 1852c2c66affSColin Finck return 0; 1853c2c66affSColin Finck } 1854c2c66affSColin Finck 1855c2c66affSColin Finck 1856c2c66affSColin Finck 1857c2c66affSColin Finck 1858c2c66affSColin Finck 1859c2c66affSColin Finck /* 1860c2c66affSColin Finck * ITrayWindow 1861c2c66affSColin Finck */ 1862c2c66affSColin Finck HRESULT STDMETHODCALLTYPE Open() 1863c2c66affSColin Finck { 1864c2c66affSColin Finck RECT rcWnd; 1865c2c66affSColin Finck 1866c2c66affSColin Finck /* Check if there's already a window created and try to show it. 1867c2c66affSColin Finck If it was somehow destroyed just create a new tray window. */ 1868c2c66affSColin Finck if (m_hWnd != NULL && IsWindow()) 1869c2c66affSColin Finck { 1870c2c66affSColin Finck return S_OK; 1871c2c66affSColin Finck } 1872c2c66affSColin Finck 1873c2c66affSColin Finck DWORD dwExStyle = WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE; 18742ed535daSGiannis Adamopoulos if (g_TaskbarSettings.sr.AlwaysOnTop) 1875c2c66affSColin Finck dwExStyle |= WS_EX_TOPMOST; 1876c2c66affSColin Finck 1877c2c66affSColin Finck DWORD dwStyle = WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; 1878c2c66affSColin Finck if(!m_Theme) 1879c2c66affSColin Finck { 1880c2c66affSColin Finck dwStyle |= WS_THICKFRAME | WS_BORDER; 1881c2c66affSColin Finck } 1882c2c66affSColin Finck 1883c2c66affSColin Finck ZeroMemory(&rcWnd, sizeof(rcWnd)); 1884c2c66affSColin Finck if (m_Position != (DWORD) -1) 1885c2c66affSColin Finck rcWnd = m_TrayRects[m_Position]; 1886c2c66affSColin Finck 1887c2c66affSColin Finck if (!Create(NULL, rcWnd, NULL, dwStyle, dwExStyle)) 1888c2c66affSColin Finck return E_FAIL; 1889c2c66affSColin Finck 1890c2c66affSColin Finck /* Align all controls on the tray window */ 1891c2c66affSColin Finck AlignControls(NULL); 1892c2c66affSColin Finck 1893c2c66affSColin Finck /* Move the tray window to the right position and resize it if necessary */ 1894c2c66affSColin Finck CheckTrayWndPosition(); 1895c2c66affSColin Finck 1896c2c66affSColin Finck return S_OK; 1897c2c66affSColin Finck } 1898c2c66affSColin Finck 1899c2c66affSColin Finck HRESULT STDMETHODCALLTYPE Close() 1900c2c66affSColin Finck { 1901c2c66affSColin Finck if (m_hWnd != NULL) 1902c2c66affSColin Finck { 1903c2c66affSColin Finck SendMessage(m_hWnd, 1904c2c66affSColin Finck WM_APP_TRAYDESTROY, 1905c2c66affSColin Finck 0, 1906c2c66affSColin Finck 0); 1907c2c66affSColin Finck } 1908c2c66affSColin Finck 1909c2c66affSColin Finck return S_OK; 1910c2c66affSColin Finck } 1911c2c66affSColin Finck 1912c2c66affSColin Finck HWND STDMETHODCALLTYPE GetHWND() 1913c2c66affSColin Finck { 1914c2c66affSColin Finck return m_hWnd; 1915c2c66affSColin Finck } 1916c2c66affSColin Finck 1917c2c66affSColin Finck BOOL STDMETHODCALLTYPE IsSpecialHWND(IN HWND hWnd) 1918c2c66affSColin Finck { 1919c2c66affSColin Finck return (m_hWnd == hWnd || 1920c2c66affSColin Finck (m_DesktopWnd != NULL && m_hWnd == m_DesktopWnd)); 1921c2c66affSColin Finck } 1922c2c66affSColin Finck 1923c2c66affSColin Finck BOOL STDMETHODCALLTYPE IsHorizontal() 1924c2c66affSColin Finck { 1925c2c66affSColin Finck return IsPosHorizontal(); 1926c2c66affSColin Finck } 1927c2c66affSColin Finck 1928c2c66affSColin Finck BOOL STDMETHODCALLTYPE Lock(IN BOOL bLock) 1929c2c66affSColin Finck { 19302ed535daSGiannis Adamopoulos BOOL bPrevLock = g_TaskbarSettings.bLock; 1931c2c66affSColin Finck 19322ed535daSGiannis Adamopoulos if (g_TaskbarSettings.bLock != bLock) 1933c2c66affSColin Finck { 19342ed535daSGiannis Adamopoulos g_TaskbarSettings.bLock = bLock; 1935c2c66affSColin Finck 1936c2c66affSColin Finck if (m_TrayBandSite != NULL) 1937c2c66affSColin Finck { 1938c2c66affSColin Finck if (!SUCCEEDED(m_TrayBandSite->Lock(bLock))) 1939c2c66affSColin Finck { 1940c2c66affSColin Finck /* Reset?? */ 19412ed535daSGiannis Adamopoulos g_TaskbarSettings.bLock = bPrevLock; 1942c2c66affSColin Finck return bPrevLock; 1943c2c66affSColin Finck } 1944c2c66affSColin Finck } 1945c2c66affSColin Finck 1946c2c66affSColin Finck if (m_Theme) 1947c2c66affSColin Finck { 1948c2c66affSColin Finck /* Update cached tray sizes */ 1949c2c66affSColin Finck for(DWORD Pos = ABE_LEFT; Pos <= ABE_BOTTOM; Pos++) 1950c2c66affSColin Finck { 1951c2c66affSColin Finck RECT rcGripper = {0}; 1952c2c66affSColin Finck AdjustSizerRect(&rcGripper, Pos); 1953c2c66affSColin Finck 19542ed535daSGiannis Adamopoulos if(g_TaskbarSettings.bLock) 1955c2c66affSColin Finck { 1956c2c66affSColin Finck m_TrayRects[Pos].top += rcGripper.top; 1957c2c66affSColin Finck m_TrayRects[Pos].left += rcGripper.left; 1958c2c66affSColin Finck m_TrayRects[Pos].bottom += rcGripper.bottom; 1959c2c66affSColin Finck m_TrayRects[Pos].right += rcGripper.right; 1960c2c66affSColin Finck } 1961c2c66affSColin Finck else 1962c2c66affSColin Finck { 1963c2c66affSColin Finck m_TrayRects[Pos].top -= rcGripper.top; 1964c2c66affSColin Finck m_TrayRects[Pos].left -= rcGripper.left; 1965c2c66affSColin Finck m_TrayRects[Pos].bottom -= rcGripper.bottom; 1966c2c66affSColin Finck m_TrayRects[Pos].right -= rcGripper.right; 1967c2c66affSColin Finck } 1968c2c66affSColin Finck } 1969c2c66affSColin Finck } 1970c2c66affSColin Finck SetWindowPos(NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER); 1971c2c66affSColin Finck ResizeWorkArea(); 1972c2c66affSColin Finck ApplyClipping(TRUE); 1973c2c66affSColin Finck } 1974c2c66affSColin Finck 1975c2c66affSColin Finck return bPrevLock; 1976c2c66affSColin Finck } 1977c2c66affSColin Finck 1978c2c66affSColin Finck 1979c2c66affSColin Finck /* 1980c2c66affSColin Finck * IContextMenu 1981c2c66affSColin Finck */ 1982c2c66affSColin Finck HRESULT STDMETHODCALLTYPE QueryContextMenu(HMENU hPopup, 1983c2c66affSColin Finck UINT indexMenu, 1984c2c66affSColin Finck UINT idCmdFirst, 1985c2c66affSColin Finck UINT idCmdLast, 1986c2c66affSColin Finck UINT uFlags) 1987c2c66affSColin Finck { 1988c2c66affSColin Finck if (!m_ContextMenu) 1989c2c66affSColin Finck { 1990c2c66affSColin Finck HRESULT hr = TrayWindowCtxMenuCreator(this, m_hWnd, &m_ContextMenu); 1991c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr)) 1992c2c66affSColin Finck return hr; 1993c2c66affSColin Finck } 1994c2c66affSColin Finck 1995c2c66affSColin Finck return m_ContextMenu->QueryContextMenu(hPopup, indexMenu, idCmdFirst, idCmdLast, uFlags); 1996c2c66affSColin Finck } 1997c2c66affSColin Finck 1998c2c66affSColin Finck HRESULT STDMETHODCALLTYPE InvokeCommand(LPCMINVOKECOMMANDINFO lpici) 1999c2c66affSColin Finck { 2000c2c66affSColin Finck if (!m_ContextMenu) 2001c2c66affSColin Finck return E_INVALIDARG; 2002c2c66affSColin Finck 2003c2c66affSColin Finck return m_ContextMenu->InvokeCommand(lpici); 2004c2c66affSColin Finck } 2005c2c66affSColin Finck 2006c2c66affSColin Finck HRESULT STDMETHODCALLTYPE GetCommandString(UINT_PTR idCmd, 2007c2c66affSColin Finck UINT uType, 2008c2c66affSColin Finck UINT *pwReserved, 2009c2c66affSColin Finck LPSTR pszName, 2010c2c66affSColin Finck UINT cchMax) 2011c2c66affSColin Finck { 2012c2c66affSColin Finck if (!m_ContextMenu) 2013c2c66affSColin Finck return E_INVALIDARG; 2014c2c66affSColin Finck 2015c2c66affSColin Finck return m_ContextMenu->GetCommandString(idCmd, uType, pwReserved, pszName, cchMax); 2016c2c66affSColin Finck } 2017c2c66affSColin Finck 2018c2c66affSColin Finck 2019c2c66affSColin Finck /********************************************************** 2020c2c66affSColin Finck * ##### message handling ##### 2021c2c66affSColin Finck */ 2022c2c66affSColin Finck 2023c2c66affSColin Finck LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 2024c2c66affSColin Finck { 2025c2c66affSColin Finck HRESULT hRet; 2026c2c66affSColin Finck 2027c2c66affSColin Finck ((ITrayWindow*)this)->AddRef(); 2028c2c66affSColin Finck 2029c2c66affSColin Finck SetWindowTheme(m_hWnd, L"TaskBar", NULL); 2030c2c66affSColin Finck 2031c2c66affSColin Finck /* Create the Start button */ 2032c2c66affSColin Finck m_StartButton.Create(m_hWnd); 2033c2c66affSColin Finck 2034c2c66affSColin Finck /* Load the saved tray window settings */ 2035c2c66affSColin Finck RegLoadSettings(); 2036c2c66affSColin Finck 2037c2c66affSColin Finck /* Create and initialize the start menu */ 2038c2c66affSColin Finck HBITMAP hbmBanner = LoadBitmapW(hExplorerInstance, MAKEINTRESOURCEW(IDB_STARTMENU)); 2039c2c66affSColin Finck m_StartMenuPopup = CreateStartMenu(this, &m_StartMenuBand, hbmBanner, 0); 2040c2c66affSColin Finck 2041c2c66affSColin Finck /* Create the task band */ 2042c2c66affSColin Finck hRet = CTaskBand_CreateInstance(this, m_StartButton.m_hWnd, IID_PPV_ARG(IDeskBand, &m_TaskBand)); 2043c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hRet)) 2044c2c66affSColin Finck return FALSE; 2045c2c66affSColin Finck 2046c2c66affSColin Finck /* Create the rebar band site. This actually creates the rebar and the tasks toolbar. */ 2047c2c66affSColin Finck hRet = CTrayBandSite_CreateInstance(this, m_TaskBand, &m_TrayBandSite); 2048c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hRet)) 2049c2c66affSColin Finck return FALSE; 2050c2c66affSColin Finck 2051c2c66affSColin Finck /* Get the hwnd of the rebar */ 2052c2c66affSColin Finck hRet = IUnknown_GetWindow(m_TrayBandSite, &m_Rebar); 2053c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hRet)) 2054c2c66affSColin Finck return FALSE; 2055c2c66affSColin Finck 2056c2c66affSColin Finck /* Get the hwnd of the tasks toolbar */ 2057c2c66affSColin Finck hRet = IUnknown_GetWindow(m_TaskBand, &m_TaskSwitch); 2058c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hRet)) 2059c2c66affSColin Finck return FALSE; 2060c2c66affSColin Finck 2061c2c66affSColin Finck SetWindowTheme(m_Rebar, L"TaskBar", NULL); 2062c2c66affSColin Finck 2063c2c66affSColin Finck /* Create the tray notification window */ 2064*7f35908aSGiannis Adamopoulos m_TrayNotify = CreateTrayNotifyWnd(m_hWnd, &m_TrayNotifyInstance); 2065c2c66affSColin Finck 2066c2c66affSColin Finck UpdateFonts(); 2067c2c66affSColin Finck 2068c2c66affSColin Finck InitShellServices(&m_ShellServices); 2069c2c66affSColin Finck 20702ed535daSGiannis Adamopoulos if (g_TaskbarSettings.sr.AutoHide) 2071c2c66affSColin Finck { 2072c2c66affSColin Finck m_AutoHideState = AUTOHIDE_HIDING; 2073c2c66affSColin Finck SetTimer(TIMER_ID_AUTOHIDE, AUTOHIDE_DELAY_HIDE, NULL); 2074c2c66affSColin Finck } 2075c2c66affSColin Finck 2076c2c66affSColin Finck RegisterHotKey(m_hWnd, IDHK_RUN, MOD_WIN, 'R'); 2077c2c66affSColin Finck RegisterHotKey(m_hWnd, IDHK_MINIMIZE_ALL, MOD_WIN, 'M'); 2078c2c66affSColin Finck RegisterHotKey(m_hWnd, IDHK_RESTORE_ALL, MOD_WIN|MOD_SHIFT, 'M'); 2079c2c66affSColin Finck RegisterHotKey(m_hWnd, IDHK_HELP, MOD_WIN, VK_F1); 2080c2c66affSColin Finck RegisterHotKey(m_hWnd, IDHK_EXPLORE, MOD_WIN, 'E'); 2081c2c66affSColin Finck RegisterHotKey(m_hWnd, IDHK_FIND, MOD_WIN, 'F'); 2082c2c66affSColin Finck RegisterHotKey(m_hWnd, IDHK_FIND_COMPUTER, MOD_WIN|MOD_CONTROL, 'F'); 2083c2c66affSColin Finck RegisterHotKey(m_hWnd, IDHK_NEXT_TASK, MOD_WIN, VK_TAB); 2084c2c66affSColin Finck RegisterHotKey(m_hWnd, IDHK_PREV_TASK, MOD_WIN|MOD_SHIFT, VK_TAB); 2085c2c66affSColin Finck RegisterHotKey(m_hWnd, IDHK_SYS_PROPERTIES, MOD_WIN, VK_PAUSE); 2086c2c66affSColin Finck RegisterHotKey(m_hWnd, IDHK_DESKTOP, MOD_WIN, 'D'); 2087c2c66affSColin Finck RegisterHotKey(m_hWnd, IDHK_PAGER, MOD_WIN, 'B'); 2088c2c66affSColin Finck 2089c2c66affSColin Finck return TRUE; 2090c2c66affSColin Finck } 2091c2c66affSColin Finck 2092c2c66affSColin Finck LRESULT OnThemeChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 2093c2c66affSColin Finck { 2094c2c66affSColin Finck if (m_Theme) 2095c2c66affSColin Finck CloseThemeData(m_Theme); 2096c2c66affSColin Finck 2097c2c66affSColin Finck m_Theme = OpenThemeData(m_hWnd, L"TaskBar"); 2098c2c66affSColin Finck 2099c2c66affSColin Finck if (m_Theme) 2100c2c66affSColin Finck { 2101c2c66affSColin Finck SetWindowStyle(m_hWnd, WS_THICKFRAME | WS_BORDER, 0); 2102c2c66affSColin Finck } 2103c2c66affSColin Finck else 2104c2c66affSColin Finck { 2105c2c66affSColin Finck SetWindowStyle(m_hWnd, WS_THICKFRAME | WS_BORDER, WS_THICKFRAME | WS_BORDER); 2106c2c66affSColin Finck } 2107c2c66affSColin Finck SetWindowPos(NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER); 2108c2c66affSColin Finck 2109c2c66affSColin Finck return TRUE; 2110c2c66affSColin Finck } 2111c2c66affSColin Finck 2112c2c66affSColin Finck LRESULT OnSettingChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 2113c2c66affSColin Finck { 2114c2c66affSColin Finck if (wParam == SPI_SETNONCLIENTMETRICS) 2115c2c66affSColin Finck { 2116c2c66affSColin Finck SendMessage(m_TrayNotify, uMsg, wParam, lParam); 2117c2c66affSColin Finck SendMessage(m_TaskSwitch, uMsg, wParam, lParam); 2118c2c66affSColin Finck UpdateFonts(); 2119c2c66affSColin Finck AlignControls(NULL); 2120c2c66affSColin Finck CheckTrayWndPosition(); 2121c2c66affSColin Finck } 2122c2c66affSColin Finck 2123c2c66affSColin Finck return 0; 2124c2c66affSColin Finck } 2125c2c66affSColin Finck 2126c2c66affSColin Finck LRESULT OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 2127c2c66affSColin Finck { 2128c2c66affSColin Finck HDC hdc = (HDC) wParam; 2129c2c66affSColin Finck 2130c2c66affSColin Finck if (!m_Theme) 2131c2c66affSColin Finck { 2132c2c66affSColin Finck bHandled = FALSE; 2133c2c66affSColin Finck return 0; 2134c2c66affSColin Finck } 2135c2c66affSColin Finck 2136c2c66affSColin Finck return EraseBackgroundWithTheme(hdc); 2137c2c66affSColin Finck } 2138c2c66affSColin Finck 2139c2c66affSColin Finck LRESULT OnDisplayChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 2140c2c66affSColin Finck { 2141c2c66affSColin Finck /* Load the saved tray window settings */ 2142c2c66affSColin Finck RegLoadSettings(); 2143c2c66affSColin Finck 2144c2c66affSColin Finck /* Move the tray window to the right position and resize it if necessary */ 2145c2c66affSColin Finck CheckTrayWndPosition(); 2146c2c66affSColin Finck 2147c2c66affSColin Finck return TRUE; 2148c2c66affSColin Finck } 2149c2c66affSColin Finck 2150c2c66affSColin Finck LRESULT OnCopyData(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 2151c2c66affSColin Finck { 2152c2c66affSColin Finck if (m_TrayNotify) 2153*7f35908aSGiannis Adamopoulos ::SendMessageW(m_TrayNotify, uMsg, wParam, lParam); 2154c2c66affSColin Finck return TRUE; 2155c2c66affSColin Finck } 2156c2c66affSColin Finck 2157c2c66affSColin Finck LRESULT OnNcPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 2158c2c66affSColin Finck { 2159c2c66affSColin Finck if (!m_Theme) 2160c2c66affSColin Finck { 2161c2c66affSColin Finck bHandled = FALSE; 2162c2c66affSColin Finck return 0; 2163c2c66affSColin Finck } 2164c2c66affSColin Finck 2165c2c66affSColin Finck return DrawSizerWithTheme((HRGN) wParam); 2166c2c66affSColin Finck } 2167c2c66affSColin Finck 2168c2c66affSColin Finck LRESULT OnCtlColorBtn(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 2169c2c66affSColin Finck { 2170c2c66affSColin Finck SetBkMode((HDC) wParam, TRANSPARENT); 2171c2c66affSColin Finck return (LRESULT) GetStockObject(HOLLOW_BRUSH); 2172c2c66affSColin Finck } 2173c2c66affSColin Finck 2174c2c66affSColin Finck LRESULT OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 2175c2c66affSColin Finck { 2176c2c66affSColin Finck RECT rcClient; 2177c2c66affSColin Finck POINT pt; 2178c2c66affSColin Finck 21792ed535daSGiannis Adamopoulos if (g_TaskbarSettings.bLock) 2180c2c66affSColin Finck { 2181c2c66affSColin Finck /* The user may not be able to resize the tray window. 2182c2c66affSColin Finck Pretend like the window is not sizeable when the user 2183c2c66affSColin Finck clicks on the border. */ 2184c2c66affSColin Finck return HTBORDER; 2185c2c66affSColin Finck } 2186c2c66affSColin Finck 2187c2c66affSColin Finck SetLastError(ERROR_SUCCESS); 2188c2c66affSColin Finck if (GetClientRect(&rcClient) && 2189c2c66affSColin Finck (MapWindowPoints(NULL, (LPPOINT) &rcClient, 2) != 0 || GetLastError() == ERROR_SUCCESS)) 2190c2c66affSColin Finck { 2191c2c66affSColin Finck pt.x = (SHORT) LOWORD(lParam); 2192c2c66affSColin Finck pt.y = (SHORT) HIWORD(lParam); 2193c2c66affSColin Finck 2194c2c66affSColin Finck if (PtInRect(&rcClient, 2195c2c66affSColin Finck pt)) 2196c2c66affSColin Finck { 2197c2c66affSColin Finck /* The user is trying to drag the tray window */ 2198c2c66affSColin Finck return HTCAPTION; 2199c2c66affSColin Finck } 2200c2c66affSColin Finck 2201c2c66affSColin Finck /* Depending on the position of the tray window, allow only 2202c2c66affSColin Finck changing the border next to the monitor working area */ 2203c2c66affSColin Finck switch (m_Position) 2204c2c66affSColin Finck { 2205c2c66affSColin Finck case ABE_TOP: 2206c2c66affSColin Finck if (pt.y > rcClient.bottom) 2207c2c66affSColin Finck return HTBOTTOM; 2208c2c66affSColin Finck break; 2209c2c66affSColin Finck case ABE_LEFT: 2210c2c66affSColin Finck if (pt.x > rcClient.right) 2211c2c66affSColin Finck return HTRIGHT; 2212c2c66affSColin Finck break; 2213c2c66affSColin Finck case ABE_RIGHT: 2214c2c66affSColin Finck if (pt.x < rcClient.left) 2215c2c66affSColin Finck return HTLEFT; 2216c2c66affSColin Finck break; 2217c2c66affSColin Finck case ABE_BOTTOM: 2218c2c66affSColin Finck default: 2219c2c66affSColin Finck if (pt.y < rcClient.top) 2220c2c66affSColin Finck return HTTOP; 2221c2c66affSColin Finck break; 2222c2c66affSColin Finck } 2223c2c66affSColin Finck } 2224c2c66affSColin Finck return HTBORDER; 2225c2c66affSColin Finck return TRUE; 2226c2c66affSColin Finck } 2227c2c66affSColin Finck 2228c2c66affSColin Finck LRESULT OnMoving(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 2229c2c66affSColin Finck { 2230c2c66affSColin Finck POINT ptCursor; 2231c2c66affSColin Finck PRECT pRect = (PRECT) lParam; 2232c2c66affSColin Finck 2233c2c66affSColin Finck /* We need to ensure that an application can not accidently 2234c2c66affSColin Finck move the tray window (using SetWindowPos). However, we still 2235c2c66affSColin Finck need to be able to move the window in case the user wants to 2236c2c66affSColin Finck drag the tray window to another position or in case the user 2237c2c66affSColin Finck wants to resize the tray window. */ 22382ed535daSGiannis Adamopoulos if (!g_TaskbarSettings.bLock && GetCursorPos(&ptCursor)) 2239c2c66affSColin Finck { 2240c2c66affSColin Finck IsDragging = TRUE; 2241c2c66affSColin Finck m_DraggingPosition = GetDraggingRectFromPt(ptCursor, pRect, &m_DraggingMonitor); 2242c2c66affSColin Finck } 2243c2c66affSColin Finck else 2244c2c66affSColin Finck { 2245c2c66affSColin Finck *pRect = m_TrayRects[m_Position]; 2246c2c66affSColin Finck } 2247c2c66affSColin Finck return TRUE; 2248c2c66affSColin Finck } 2249c2c66affSColin Finck 2250c2c66affSColin Finck LRESULT OnSizing(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 2251c2c66affSColin Finck { 2252c2c66affSColin Finck PRECT pRect = (PRECT) lParam; 2253c2c66affSColin Finck 22542ed535daSGiannis Adamopoulos if (!g_TaskbarSettings.bLock) 2255c2c66affSColin Finck { 2256c2c66affSColin Finck FitToRebar(pRect); 2257c2c66affSColin Finck } 2258c2c66affSColin Finck else 2259c2c66affSColin Finck { 2260c2c66affSColin Finck *pRect = m_TrayRects[m_Position]; 2261c2c66affSColin Finck } 2262c2c66affSColin Finck return TRUE; 2263c2c66affSColin Finck } 2264c2c66affSColin Finck 22654238f223SGiannis Adamopoulos LRESULT OnWindowPosChanging(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 2266c2c66affSColin Finck { 2267c2c66affSColin Finck ChangingWinPos((LPWINDOWPOS) lParam); 2268c2c66affSColin Finck return TRUE; 2269c2c66affSColin Finck } 2270c2c66affSColin Finck 2271c2c66affSColin Finck LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 2272c2c66affSColin Finck { 2273c2c66affSColin Finck RECT rcClient; 2274c2c66affSColin Finck if (wParam == SIZE_RESTORED && lParam == 0) 2275c2c66affSColin Finck { 2276c2c66affSColin Finck ResizeWorkArea(); 2277c2c66affSColin Finck /* Clip the tray window on multi monitor systems so the edges can't 2278c2c66affSColin Finck overlap into another monitor */ 2279c2c66affSColin Finck ApplyClipping(TRUE); 2280c2c66affSColin Finck 2281c2c66affSColin Finck if (!GetClientRect(&rcClient)) 2282c2c66affSColin Finck { 2283c2c66affSColin Finck return FALSE; 2284c2c66affSColin Finck } 2285c2c66affSColin Finck } 2286c2c66affSColin Finck else 2287c2c66affSColin Finck { 2288c2c66affSColin Finck rcClient.left = rcClient.top = 0; 2289c2c66affSColin Finck rcClient.right = LOWORD(lParam); 2290c2c66affSColin Finck rcClient.bottom = HIWORD(lParam); 2291c2c66affSColin Finck } 2292c2c66affSColin Finck 2293c2c66affSColin Finck AlignControls(&rcClient); 2294c2c66affSColin Finck return TRUE; 2295c2c66affSColin Finck } 2296c2c66affSColin Finck 2297c2c66affSColin Finck LRESULT OnEnterSizeMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 2298c2c66affSColin Finck { 2299c2c66affSColin Finck InSizeMove = TRUE; 2300c2c66affSColin Finck IsDragging = FALSE; 23012ed535daSGiannis Adamopoulos if (!g_TaskbarSettings.bLock) 2302c2c66affSColin Finck { 2303c2c66affSColin Finck /* Remove the clipping on multi monitor systems while dragging around */ 2304c2c66affSColin Finck ApplyClipping(FALSE); 2305c2c66affSColin Finck } 2306c2c66affSColin Finck return TRUE; 2307c2c66affSColin Finck } 2308c2c66affSColin Finck 2309c2c66affSColin Finck LRESULT OnExitSizeMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 2310c2c66affSColin Finck { 2311c2c66affSColin Finck InSizeMove = FALSE; 23122ed535daSGiannis Adamopoulos if (!g_TaskbarSettings.bLock) 2313c2c66affSColin Finck { 2314c2c66affSColin Finck FitToRebar(&m_TrayRects[m_Position]); 2315c2c66affSColin Finck 2316c2c66affSColin Finck /* Apply clipping */ 2317c2c66affSColin Finck PostMessage(WM_SIZE, SIZE_RESTORED, 0); 2318c2c66affSColin Finck } 2319c2c66affSColin Finck return TRUE; 2320c2c66affSColin Finck } 2321c2c66affSColin Finck 2322c2c66affSColin Finck LRESULT OnSysChar(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 2323c2c66affSColin Finck { 2324c2c66affSColin Finck switch (wParam) 2325c2c66affSColin Finck { 2326c2c66affSColin Finck case TEXT(' '): 2327c2c66affSColin Finck { 2328c2c66affSColin Finck /* The user pressed Alt+Space, this usually brings up the system menu of a window. 2329c2c66affSColin Finck The tray window needs to handle this specially, since it normally doesn't have 2330c2c66affSColin Finck a system menu. */ 2331c2c66affSColin Finck 2332c2c66affSColin Finck static const UINT uidDisableItem [] = { 2333c2c66affSColin Finck SC_RESTORE, 2334c2c66affSColin Finck SC_MOVE, 2335c2c66affSColin Finck SC_SIZE, 2336c2c66affSColin Finck SC_MAXIMIZE, 2337c2c66affSColin Finck SC_MINIMIZE, 2338c2c66affSColin Finck }; 2339c2c66affSColin Finck HMENU hSysMenu; 2340c2c66affSColin Finck UINT i, uId; 2341c2c66affSColin Finck 2342c2c66affSColin Finck /* temporarily enable the system menu */ 2343c2c66affSColin Finck SetWindowStyle(m_hWnd, WS_SYSMENU, WS_SYSMENU); 2344c2c66affSColin Finck 2345c2c66affSColin Finck hSysMenu = GetSystemMenu(FALSE); 2346c2c66affSColin Finck if (hSysMenu != NULL) 2347c2c66affSColin Finck { 2348c2c66affSColin Finck /* Disable all items that are not relevant */ 2349c2c66affSColin Finck for (i = 0; i < _countof(uidDisableItem); i++) 2350c2c66affSColin Finck { 2351c2c66affSColin Finck EnableMenuItem(hSysMenu, 2352c2c66affSColin Finck uidDisableItem[i], 2353c2c66affSColin Finck MF_BYCOMMAND | MF_GRAYED); 2354c2c66affSColin Finck } 2355c2c66affSColin Finck 2356c2c66affSColin Finck EnableMenuItem(hSysMenu, 2357c2c66affSColin Finck SC_CLOSE, 2358c2c66affSColin Finck MF_BYCOMMAND | 2359c2c66affSColin Finck (SHRestricted(REST_NOCLOSE) ? MF_GRAYED : MF_ENABLED)); 2360c2c66affSColin Finck 2361c2c66affSColin Finck /* Display the system menu */ 2362c2c66affSColin Finck uId = TrackMenu( 2363c2c66affSColin Finck hSysMenu, 2364c2c66affSColin Finck NULL, 2365c2c66affSColin Finck m_StartButton.m_hWnd, 2366c2c66affSColin Finck m_Position != ABE_TOP, 2367c2c66affSColin Finck FALSE); 2368c2c66affSColin Finck if (uId != 0) 2369c2c66affSColin Finck { 2370c2c66affSColin Finck SendMessage(m_hWnd, WM_SYSCOMMAND, (WPARAM) uId, 0); 2371c2c66affSColin Finck } 2372c2c66affSColin Finck } 2373c2c66affSColin Finck 2374c2c66affSColin Finck /* revert the system menu window style */ 2375c2c66affSColin Finck SetWindowStyle(m_hWnd, WS_SYSMENU, 0); 2376c2c66affSColin Finck break; 2377c2c66affSColin Finck } 2378c2c66affSColin Finck 2379c2c66affSColin Finck default: 2380c2c66affSColin Finck bHandled = FALSE; 2381c2c66affSColin Finck } 2382c2c66affSColin Finck return TRUE; 2383c2c66affSColin Finck } 2384c2c66affSColin Finck 2385c2c66affSColin Finck LRESULT OnNcLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 2386c2c66affSColin Finck { 2387c2c66affSColin Finck /* This handler implements the trick that makes the start button to 2388c2c66affSColin Finck get pressed when the user clicked left or below the button */ 2389c2c66affSColin Finck 2390c2c66affSColin Finck POINT pt = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)}; 2391c2c66affSColin Finck WINDOWINFO wi = {sizeof(WINDOWINFO)}; 2392c2c66affSColin Finck RECT rcStartBtn; 2393c2c66affSColin Finck 2394c2c66affSColin Finck bHandled = FALSE; 2395c2c66affSColin Finck 2396c2c66affSColin Finck m_StartButton.GetWindowRect(&rcStartBtn); 2397c2c66affSColin Finck GetWindowInfo(m_hWnd, &wi); 2398c2c66affSColin Finck 2399c2c66affSColin Finck switch (m_Position) 2400c2c66affSColin Finck { 2401c2c66affSColin Finck case ABE_TOP: 2402c2c66affSColin Finck case ABE_LEFT: 2403c2c66affSColin Finck { 2404c2c66affSColin Finck if (pt.x > rcStartBtn.right || pt.y > rcStartBtn.bottom) 2405c2c66affSColin Finck return 0; 2406c2c66affSColin Finck break; 2407c2c66affSColin Finck } 2408c2c66affSColin Finck case ABE_RIGHT: 2409c2c66affSColin Finck { 2410c2c66affSColin Finck if (pt.x < rcStartBtn.left || pt.y > rcStartBtn.bottom) 2411c2c66affSColin Finck return 0; 2412c2c66affSColin Finck 2413c2c66affSColin Finck if (rcStartBtn.right + (int)wi.cxWindowBorders * 2 + 1 < wi.rcWindow.right && 2414c2c66affSColin Finck pt.x > rcStartBtn.right) 2415c2c66affSColin Finck { 2416c2c66affSColin Finck return 0; 2417c2c66affSColin Finck } 2418c2c66affSColin Finck break; 2419c2c66affSColin Finck } 2420c2c66affSColin Finck case ABE_BOTTOM: 2421c2c66affSColin Finck { 2422c2c66affSColin Finck if (pt.x > rcStartBtn.right || pt.y < rcStartBtn.top) 2423c2c66affSColin Finck { 2424c2c66affSColin Finck return 0; 2425c2c66affSColin Finck } 2426c2c66affSColin Finck 2427c2c66affSColin Finck if (rcStartBtn.bottom + (int)wi.cyWindowBorders * 2 + 1 < wi.rcWindow.bottom && 2428c2c66affSColin Finck pt.y > rcStartBtn.bottom) 2429c2c66affSColin Finck { 2430c2c66affSColin Finck return 0; 2431c2c66affSColin Finck } 2432c2c66affSColin Finck 2433c2c66affSColin Finck break; 2434c2c66affSColin Finck } 2435c2c66affSColin Finck } 2436c2c66affSColin Finck 2437c2c66affSColin Finck bHandled = TRUE; 2438c2c66affSColin Finck PopupStartMenu(); 2439c2c66affSColin Finck return 0; 2440c2c66affSColin Finck } 2441c2c66affSColin Finck 2442c2c66affSColin Finck LRESULT OnNcRButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 2443c2c66affSColin Finck { 2444c2c66affSColin Finck /* We want the user to be able to get a context menu even on the nonclient 2445c2c66affSColin Finck area (including the sizing border)! */ 2446c2c66affSColin Finck uMsg = WM_CONTEXTMENU; 2447c2c66affSColin Finck wParam = (WPARAM) m_hWnd; 2448c2c66affSColin Finck 2449c2c66affSColin Finck return OnContextMenu(uMsg, wParam, lParam, bHandled); 2450c2c66affSColin Finck } 2451c2c66affSColin Finck 2452c2c66affSColin Finck LRESULT OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 2453c2c66affSColin Finck { 2454c2c66affSColin Finck LRESULT Ret = FALSE; 2455c2c66affSColin Finck POINT pt, *ppt = NULL; 2456c2c66affSColin Finck HWND hWndExclude = NULL; 2457c2c66affSColin Finck 2458c2c66affSColin Finck /* Check if the administrator has forbidden access to context menus */ 2459c2c66affSColin Finck if (SHRestricted(REST_NOTRAYCONTEXTMENU)) 2460c2c66affSColin Finck return FALSE; 2461c2c66affSColin Finck 2462c2c66affSColin Finck pt.x = (SHORT) LOWORD(lParam); 2463c2c66affSColin Finck pt.y = (SHORT) HIWORD(lParam); 2464c2c66affSColin Finck 2465c2c66affSColin Finck if (pt.x != -1 || pt.y != -1) 2466c2c66affSColin Finck ppt = &pt; 2467c2c66affSColin Finck else 2468c2c66affSColin Finck hWndExclude = m_StartButton.m_hWnd; 2469c2c66affSColin Finck 2470c2c66affSColin Finck if ((HWND) wParam == m_StartButton.m_hWnd) 2471c2c66affSColin Finck { 2472c2c66affSColin Finck /* Make sure we can't track the context menu if the start 2473c2c66affSColin Finck menu is currently being shown */ 2474c2c66affSColin Finck if (!(m_StartButton.SendMessage(BM_GETSTATE, 0, 0) & BST_PUSHED)) 2475c2c66affSColin Finck { 2476c2c66affSColin Finck CComPtr<IContextMenu> ctxMenu; 2477c2c66affSColin Finck StartMenuBtnCtxMenuCreator(this, m_hWnd, &ctxMenu); 2478c2c66affSColin Finck TrackCtxMenu(ctxMenu, ppt, hWndExclude, m_Position == ABE_BOTTOM, this); 2479c2c66affSColin Finck } 2480c2c66affSColin Finck } 2481c2c66affSColin Finck else 2482c2c66affSColin Finck { 2483c2c66affSColin Finck /* See if the context menu should be handled by the task band site */ 2484c2c66affSColin Finck if (ppt != NULL && m_TrayBandSite != NULL) 2485c2c66affSColin Finck { 2486c2c66affSColin Finck HWND hWndAtPt; 2487c2c66affSColin Finck POINT ptClient = *ppt; 2488c2c66affSColin Finck 2489c2c66affSColin Finck /* Convert the coordinates to client-coordinates */ 2490c2c66affSColin Finck ::MapWindowPoints(NULL, m_hWnd, &ptClient, 1); 2491c2c66affSColin Finck 2492c2c66affSColin Finck hWndAtPt = ChildWindowFromPoint(ptClient); 2493c2c66affSColin Finck if (hWndAtPt != NULL && 2494c2c66affSColin Finck (hWndAtPt == m_Rebar || ::IsChild(m_Rebar, hWndAtPt))) 2495c2c66affSColin Finck { 2496c2c66affSColin Finck /* Check if the user clicked on the task switch window */ 2497c2c66affSColin Finck ptClient = *ppt; 2498c2c66affSColin Finck ::MapWindowPoints(NULL, m_Rebar, &ptClient, 1); 2499c2c66affSColin Finck 2500c2c66affSColin Finck hWndAtPt = ::ChildWindowFromPointEx(m_Rebar, ptClient, CWP_SKIPINVISIBLE | CWP_SKIPDISABLED); 2501c2c66affSColin Finck if (hWndAtPt == m_TaskSwitch) 2502c2c66affSColin Finck goto HandleTrayContextMenu; 2503c2c66affSColin Finck 2504c2c66affSColin Finck /* Forward the message to the task band site */ 2505c2c66affSColin Finck m_TrayBandSite->ProcessMessage(m_hWnd, uMsg, wParam, lParam, &Ret); 2506c2c66affSColin Finck } 2507c2c66affSColin Finck else 2508c2c66affSColin Finck goto HandleTrayContextMenu; 2509c2c66affSColin Finck } 2510c2c66affSColin Finck else 2511c2c66affSColin Finck { 2512c2c66affSColin Finck HandleTrayContextMenu: 2513c2c66affSColin Finck /* Tray the default tray window context menu */ 2514c2c66affSColin Finck TrackCtxMenu(this, ppt, NULL, FALSE, this); 2515c2c66affSColin Finck } 2516c2c66affSColin Finck } 2517c2c66affSColin Finck return Ret; 2518c2c66affSColin Finck } 2519c2c66affSColin Finck 2520c2c66affSColin Finck LRESULT OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 2521c2c66affSColin Finck { 2522c2c66affSColin Finck LRESULT Ret = FALSE; 2523c2c66affSColin Finck /* FIXME: We can't check with IsChild whether the hwnd is somewhere inside 2524c2c66affSColin Finck the rebar control! But we shouldn't forward messages that the band 2525c2c66affSColin Finck site doesn't handle, such as other controls (start button, tray window */ 2526c2c66affSColin Finck 2527c2c66affSColin Finck HRESULT hr = E_FAIL; 2528c2c66affSColin Finck 2529c2c66affSColin Finck if (m_TrayBandSite) 2530c2c66affSColin Finck { 2531c2c66affSColin Finck hr = m_TrayBandSite->ProcessMessage(m_hWnd, uMsg, wParam, lParam, &Ret); 2532c2c66affSColin Finck if (SUCCEEDED(hr)) 2533c2c66affSColin Finck return Ret; 2534c2c66affSColin Finck } 2535c2c66affSColin Finck 2536c2c66affSColin Finck if (m_TrayBandSite == NULL || FAILED(hr)) 2537c2c66affSColin Finck { 2538c2c66affSColin Finck const NMHDR *nmh = (const NMHDR *) lParam; 2539c2c66affSColin Finck 2540c2c66affSColin Finck if (nmh->hwndFrom == m_TrayNotify) 2541c2c66affSColin Finck { 2542c2c66affSColin Finck switch (nmh->code) 2543c2c66affSColin Finck { 2544c2c66affSColin Finck case NTNWM_REALIGN: 2545c2c66affSColin Finck /* Cause all controls to be aligned */ 2546c2c66affSColin Finck PostMessage(WM_SIZE, SIZE_RESTORED, 0); 2547c2c66affSColin Finck break; 2548c2c66affSColin Finck } 2549c2c66affSColin Finck } 2550c2c66affSColin Finck } 2551c2c66affSColin Finck return Ret; 2552c2c66affSColin Finck } 2553c2c66affSColin Finck 2554c2c66affSColin Finck LRESULT OnNcLButtonDblClick(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 2555c2c66affSColin Finck { 2556*7f35908aSGiannis Adamopoulos /* Let the clock handle the double click */ 2557*7f35908aSGiannis Adamopoulos ::SendMessageW(m_TrayNotify, uMsg, wParam, lParam); 2558*7f35908aSGiannis Adamopoulos 2559c2c66affSColin Finck /* We "handle" this message so users can't cause a weird maximize/restore 2560c2c66affSColin Finck window animation when double-clicking the tray window! */ 2561c2c66affSColin Finck return TRUE; 2562c2c66affSColin Finck } 2563c2c66affSColin Finck 2564c2c66affSColin Finck LRESULT OnAppTrayDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 2565c2c66affSColin Finck { 2566c2c66affSColin Finck DestroyWindow(); 2567c2c66affSColin Finck return TRUE; 2568c2c66affSColin Finck } 2569c2c66affSColin Finck 2570c2c66affSColin Finck LRESULT OnOpenStartMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 2571c2c66affSColin Finck { 2572c2c66affSColin Finck HWND hwndStartMenu; 2573c2c66affSColin Finck HRESULT hr = IUnknown_GetWindow(m_StartMenuPopup, &hwndStartMenu); 2574c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr)) 2575c2c66affSColin Finck return FALSE; 2576c2c66affSColin Finck 2577c2c66affSColin Finck if (::IsWindowVisible(hwndStartMenu)) 2578c2c66affSColin Finck { 2579c2c66affSColin Finck m_StartMenuPopup->OnSelect(MPOS_CANCELLEVEL); 2580c2c66affSColin Finck } 2581c2c66affSColin Finck else 2582c2c66affSColin Finck { 2583c2c66affSColin Finck PopupStartMenu(); 2584c2c66affSColin Finck } 2585c2c66affSColin Finck 2586c2c66affSColin Finck return TRUE; 2587c2c66affSColin Finck } 2588c2c66affSColin Finck 2589c2c66affSColin Finck LRESULT OnDoExitWindows(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 2590c2c66affSColin Finck { 2591c2c66affSColin Finck /* 2592c2c66affSColin Finck * TWM_DOEXITWINDOWS is send by the CDesktopBrowser to us 2593c2c66affSColin Finck * to show the shutdown dialog. Also a WM_CLOSE message sent 2594c2c66affSColin Finck * by apps should show the dialog. 2595c2c66affSColin Finck */ 2596c2c66affSColin Finck return DoExitWindows(); 2597c2c66affSColin Finck } 2598c2c66affSColin Finck 2599c2c66affSColin Finck LRESULT OnSysCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 2600c2c66affSColin Finck { 2601c2c66affSColin Finck if (wParam == SC_CLOSE) 2602c2c66affSColin Finck { 2603c2c66affSColin Finck return DoExitWindows(); 2604c2c66affSColin Finck } 2605c2c66affSColin Finck 2606c2c66affSColin Finck bHandled = FALSE; 2607c2c66affSColin Finck return TRUE; 2608c2c66affSColin Finck } 2609c2c66affSColin Finck 2610c2c66affSColin Finck LRESULT OnHotkey(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 2611c2c66affSColin Finck { 2612c2c66affSColin Finck return HandleHotKey(wParam); 2613c2c66affSColin Finck } 2614c2c66affSColin Finck 2615c2c66affSColin Finck LRESULT OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 2616c2c66affSColin Finck { 2617c2c66affSColin Finck LRESULT Ret = FALSE; 2618c2c66affSColin Finck 2619c2c66affSColin Finck if ((HWND) lParam == m_StartButton.m_hWnd) 2620c2c66affSColin Finck { 2621c2c66affSColin Finck return FALSE; 2622c2c66affSColin Finck } 2623c2c66affSColin Finck 2624c2c66affSColin Finck if (m_TrayBandSite == NULL || FAILED_UNEXPECTEDLY(m_TrayBandSite->ProcessMessage(m_hWnd, uMsg, wParam, lParam, &Ret))) 2625c2c66affSColin Finck { 2626c2c66affSColin Finck return HandleCommand(LOWORD(wParam)); 2627c2c66affSColin Finck } 2628c2c66affSColin Finck return Ret; 2629c2c66affSColin Finck } 2630c2c66affSColin Finck 2631c2c66affSColin Finck LRESULT OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 2632c2c66affSColin Finck { 26332ed535daSGiannis Adamopoulos if (g_TaskbarSettings.sr.AutoHide) 2634c2c66affSColin Finck { 2635c2c66affSColin Finck SetTimer(TIMER_ID_MOUSETRACK, MOUSETRACK_INTERVAL, NULL); 2636c2c66affSColin Finck } 2637c2c66affSColin Finck 2638c2c66affSColin Finck return TRUE; 2639c2c66affSColin Finck } 2640c2c66affSColin Finck 2641c2c66affSColin Finck LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 2642c2c66affSColin Finck { 2643c2c66affSColin Finck if (wParam == TIMER_ID_MOUSETRACK) 2644c2c66affSColin Finck { 2645c2c66affSColin Finck ProcessMouseTracking(); 2646c2c66affSColin Finck } 2647c2c66affSColin Finck else if (wParam == TIMER_ID_AUTOHIDE) 2648c2c66affSColin Finck { 2649c2c66affSColin Finck ProcessAutoHide(); 2650c2c66affSColin Finck } 2651c2c66affSColin Finck 2652c2c66affSColin Finck bHandled = FALSE; 2653c2c66affSColin Finck return TRUE; 2654c2c66affSColin Finck } 2655c2c66affSColin Finck 2656c2c66affSColin Finck LRESULT OnNcCalcSize(INT code, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 2657c2c66affSColin Finck { 2658c2c66affSColin Finck RECT *rc = NULL; 2659c2c66affSColin Finck /* Ignore WM_NCCALCSIZE if we are not themed or locked */ 26602ed535daSGiannis Adamopoulos if(!m_Theme || g_TaskbarSettings.bLock) 2661c2c66affSColin Finck { 2662c2c66affSColin Finck bHandled = FALSE; 2663c2c66affSColin Finck return 0; 2664c2c66affSColin Finck } 2665c2c66affSColin Finck if(!wParam) 2666c2c66affSColin Finck { 2667c2c66affSColin Finck rc = (RECT*)wParam; 2668c2c66affSColin Finck } 2669c2c66affSColin Finck else 2670c2c66affSColin Finck { 2671c2c66affSColin Finck NCCALCSIZE_PARAMS *prms = (NCCALCSIZE_PARAMS*)lParam; 2672c2c66affSColin Finck if(prms->lppos->flags & SWP_NOSENDCHANGING) 2673c2c66affSColin Finck { 2674c2c66affSColin Finck bHandled = FALSE; 2675c2c66affSColin Finck return 0; 2676c2c66affSColin Finck } 2677c2c66affSColin Finck rc = &prms->rgrc[0]; 2678c2c66affSColin Finck } 2679c2c66affSColin Finck 2680c2c66affSColin Finck AdjustSizerRect(rc, m_Position); 2681c2c66affSColin Finck 2682c2c66affSColin Finck return 0; 2683c2c66affSColin Finck } 2684c2c66affSColin Finck 2685c2c66affSColin Finck LRESULT OnRebarAutoSize(INT code, LPNMHDR nmhdr, BOOL& bHandled) 2686c2c66affSColin Finck { 2687c2c66affSColin Finck #if 0 2688c2c66affSColin Finck LPNMRBAUTOSIZE as = (LPNMRBAUTOSIZE) nmhdr; 2689c2c66affSColin Finck 2690c2c66affSColin Finck if (!as->fChanged) 2691c2c66affSColin Finck return 0; 2692c2c66affSColin Finck 2693c2c66affSColin Finck RECT rc; 2694c2c66affSColin Finck ::GetWindowRect(m_hWnd, &rc); 2695c2c66affSColin Finck 2696c2c66affSColin Finck SIZE szWindow = { 2697c2c66affSColin Finck rc.right - rc.left, 2698c2c66affSColin Finck rc.bottom - rc.top }; 2699c2c66affSColin Finck SIZE szTarget = { 2700c2c66affSColin Finck as->rcTarget.right - as->rcTarget.left, 2701c2c66affSColin Finck as->rcTarget.bottom - as->rcTarget.top }; 2702c2c66affSColin Finck SIZE szActual = { 2703c2c66affSColin Finck as->rcActual.right - as->rcActual.left, 2704c2c66affSColin Finck as->rcActual.bottom - as->rcActual.top }; 2705c2c66affSColin Finck 2706c2c66affSColin Finck SIZE borders = { 2707c2c66affSColin Finck szWindow.cx - szTarget.cx, 2708c2c66affSColin Finck szWindow.cy - szTarget.cx, 2709c2c66affSColin Finck }; 2710c2c66affSColin Finck 2711c2c66affSColin Finck switch (m_Position) 2712c2c66affSColin Finck { 2713c2c66affSColin Finck case ABE_LEFT: 2714c2c66affSColin Finck szWindow.cx = szActual.cx + borders.cx; 2715c2c66affSColin Finck break; 2716c2c66affSColin Finck case ABE_TOP: 2717c2c66affSColin Finck szWindow.cy = szActual.cy + borders.cy; 2718c2c66affSColin Finck break; 2719c2c66affSColin Finck case ABE_RIGHT: 2720c2c66affSColin Finck szWindow.cx = szActual.cx + borders.cx; 2721c2c66affSColin Finck rc.left = rc.right - szWindow.cy; 2722c2c66affSColin Finck break; 2723c2c66affSColin Finck case ABE_BOTTOM: 2724c2c66affSColin Finck szWindow.cy = szActual.cy + borders.cy; 2725c2c66affSColin Finck rc.top = rc.bottom - szWindow.cy; 2726c2c66affSColin Finck break; 2727c2c66affSColin Finck } 2728c2c66affSColin Finck 2729c2c66affSColin Finck SetWindowPos(NULL, rc.left, rc.top, szWindow.cx, szWindow.cy, SWP_NOACTIVATE | SWP_NOZORDER); 2730c2c66affSColin Finck #else 2731c2c66affSColin Finck bHandled = FALSE; 2732c2c66affSColin Finck #endif 2733c2c66affSColin Finck return 0; 2734c2c66affSColin Finck } 2735c2c66affSColin Finck 27362ed535daSGiannis Adamopoulos LRESULT OnTaskbarSettingsChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 27372ed535daSGiannis Adamopoulos { 27382ed535daSGiannis Adamopoulos TaskbarSettings* newSettings = (TaskbarSettings*)lParam; 27392ed535daSGiannis Adamopoulos 27402ed535daSGiannis Adamopoulos /* Propagate the new settings to the children */ 27412ed535daSGiannis Adamopoulos ::SendMessageW(m_TaskSwitch, uMsg, wParam, lParam); 27422ed535daSGiannis Adamopoulos ::SendMessageW(m_TrayNotify, uMsg, wParam, lParam); 27432ed535daSGiannis Adamopoulos 27442ed535daSGiannis Adamopoulos /* Toggle autohide */ 27452ed535daSGiannis Adamopoulos if (newSettings->sr.AutoHide != g_TaskbarSettings.sr.AutoHide) 27462ed535daSGiannis Adamopoulos { 27472ed535daSGiannis Adamopoulos g_TaskbarSettings.sr.AutoHide = newSettings->sr.AutoHide; 27482ed535daSGiannis Adamopoulos memset(&m_AutoHideOffset, 0, sizeof(m_AutoHideOffset)); 27492ed535daSGiannis Adamopoulos m_AutoHideState = AUTOHIDE_SHOWN; 27502ed535daSGiannis Adamopoulos if (!newSettings->sr.AutoHide) 27512ed535daSGiannis Adamopoulos SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOZORDER); 27522ed535daSGiannis Adamopoulos else 27532ed535daSGiannis Adamopoulos SetTimer(TIMER_ID_MOUSETRACK, MOUSETRACK_INTERVAL, NULL); 27542ed535daSGiannis Adamopoulos } 27552ed535daSGiannis Adamopoulos 27562ed535daSGiannis Adamopoulos /* Toggle lock state */ 27572ed535daSGiannis Adamopoulos Lock(newSettings->bLock); 27582ed535daSGiannis Adamopoulos 27592ed535daSGiannis Adamopoulos /* Toggle OnTop state */ 27602ed535daSGiannis Adamopoulos if (newSettings->sr.AlwaysOnTop != g_TaskbarSettings.sr.AlwaysOnTop) 27612ed535daSGiannis Adamopoulos { 27622ed535daSGiannis Adamopoulos g_TaskbarSettings.sr.AlwaysOnTop = newSettings->sr.AlwaysOnTop; 27632ed535daSGiannis Adamopoulos HWND hWndInsertAfter = newSettings->sr.AlwaysOnTop ? HWND_TOPMOST : HWND_BOTTOM; 27642ed535daSGiannis Adamopoulos SetWindowPos(hWndInsertAfter, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); 27652ed535daSGiannis Adamopoulos } 27662ed535daSGiannis Adamopoulos 27672ed535daSGiannis Adamopoulos g_TaskbarSettings.Save(); 27682ed535daSGiannis Adamopoulos return 0; 27692ed535daSGiannis Adamopoulos } 27702ed535daSGiannis Adamopoulos 2771c2c66affSColin Finck DECLARE_WND_CLASS_EX(szTrayWndClass, CS_DBLCLKS, COLOR_3DFACE) 2772c2c66affSColin Finck 2773c2c66affSColin Finck BEGIN_MSG_MAP(CTrayWindow) 2774c2c66affSColin Finck if (m_StartMenuBand != NULL) 2775c2c66affSColin Finck { 2776c2c66affSColin Finck MSG Msg; 2777c2c66affSColin Finck LRESULT lRet; 2778c2c66affSColin Finck 2779c2c66affSColin Finck Msg.hwnd = m_hWnd; 2780c2c66affSColin Finck Msg.message = uMsg; 2781c2c66affSColin Finck Msg.wParam = wParam; 2782c2c66affSColin Finck Msg.lParam = lParam; 2783c2c66affSColin Finck 2784c2c66affSColin Finck if (m_StartMenuBand->TranslateMenuMessage(&Msg, &lRet) == S_OK) 2785c2c66affSColin Finck { 2786c2c66affSColin Finck return lRet; 2787c2c66affSColin Finck } 2788c2c66affSColin Finck 2789c2c66affSColin Finck wParam = Msg.wParam; 2790c2c66affSColin Finck lParam = Msg.lParam; 2791c2c66affSColin Finck } 2792c2c66affSColin Finck MESSAGE_HANDLER(WM_THEMECHANGED, OnThemeChanged) 2793c2c66affSColin Finck MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChanged) 2794c2c66affSColin Finck NOTIFY_CODE_HANDLER(RBN_AUTOSIZE, OnRebarAutoSize) // Doesn't quite work ;P 2795c2c66affSColin Finck MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) 2796c2c66affSColin Finck MESSAGE_HANDLER(WM_SIZE, OnSize) 2797c2c66affSColin Finck MESSAGE_HANDLER(WM_CREATE, OnCreate) 2798c2c66affSColin Finck /*MESSAGE_HANDLER(WM_DESTROY, OnDestroy)*/ 2799c2c66affSColin Finck MESSAGE_HANDLER(WM_NCHITTEST, OnNcHitTest) 2800c2c66affSColin Finck MESSAGE_HANDLER(WM_COMMAND, OnCommand) 2801c2c66affSColin Finck MESSAGE_HANDLER(WM_SYSCOMMAND, OnSysCommand) 2802c2c66affSColin Finck MESSAGE_HANDLER(WM_NOTIFY, OnNotify) 2803c2c66affSColin Finck MESSAGE_HANDLER(WM_CONTEXTMENU, OnContextMenu) 2804c2c66affSColin Finck MESSAGE_HANDLER(WM_TIMER, OnTimer) 2805c2c66affSColin Finck MESSAGE_HANDLER(WM_DISPLAYCHANGE, OnDisplayChange) 2806c2c66affSColin Finck MESSAGE_HANDLER(WM_COPYDATA, OnCopyData) 2807c2c66affSColin Finck MESSAGE_HANDLER(WM_NCPAINT, OnNcPaint) 2808c2c66affSColin Finck MESSAGE_HANDLER(WM_CTLCOLORBTN, OnCtlColorBtn) 2809c2c66affSColin Finck MESSAGE_HANDLER(WM_MOVING, OnMoving) 2810c2c66affSColin Finck MESSAGE_HANDLER(WM_SIZING, OnSizing) 28114238f223SGiannis Adamopoulos MESSAGE_HANDLER(WM_WINDOWPOSCHANGING, OnWindowPosChanging) 2812c2c66affSColin Finck MESSAGE_HANDLER(WM_ENTERSIZEMOVE, OnEnterSizeMove) 2813c2c66affSColin Finck MESSAGE_HANDLER(WM_EXITSIZEMOVE, OnExitSizeMove) 2814c2c66affSColin Finck MESSAGE_HANDLER(WM_NCLBUTTONDOWN, OnNcLButtonDown) 2815c2c66affSColin Finck MESSAGE_HANDLER(WM_SYSCHAR, OnSysChar) 2816c2c66affSColin Finck MESSAGE_HANDLER(WM_NCRBUTTONUP, OnNcRButtonUp) 2817c2c66affSColin Finck MESSAGE_HANDLER(WM_NCLBUTTONDBLCLK, OnNcLButtonDblClick) 2818c2c66affSColin Finck MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove) 2819c2c66affSColin Finck MESSAGE_HANDLER(WM_NCMOUSEMOVE, OnMouseMove) 2820c2c66affSColin Finck MESSAGE_HANDLER(WM_APP_TRAYDESTROY, OnAppTrayDestroy) 2821c2c66affSColin Finck MESSAGE_HANDLER(TWM_OPENSTARTMENU, OnOpenStartMenu) 2822c2c66affSColin Finck MESSAGE_HANDLER(TWM_DOEXITWINDOWS, OnDoExitWindows) 2823c2c66affSColin Finck MESSAGE_HANDLER(WM_CLOSE, OnDoExitWindows) 2824c2c66affSColin Finck MESSAGE_HANDLER(WM_HOTKEY, OnHotkey) 2825c2c66affSColin Finck MESSAGE_HANDLER(WM_NCCALCSIZE, OnNcCalcSize) 28262ed535daSGiannis Adamopoulos MESSAGE_HANDLER(TWM_SETTINGSCHANGED, OnTaskbarSettingsChanged) 2827c2c66affSColin Finck ALT_MSG_MAP(1) 2828c2c66affSColin Finck END_MSG_MAP() 2829c2c66affSColin Finck 2830c2c66affSColin Finck /*****************************************************************************/ 2831c2c66affSColin Finck 2832c2c66affSColin Finck VOID TrayProcessMessages() 2833c2c66affSColin Finck { 2834c2c66affSColin Finck MSG Msg; 2835c2c66affSColin Finck 2836c2c66affSColin Finck /* FIXME: We should keep a reference here... */ 2837c2c66affSColin Finck 2838c2c66affSColin Finck while (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE)) 2839c2c66affSColin Finck { 2840c2c66affSColin Finck if (Msg.message == WM_QUIT) 2841c2c66affSColin Finck break; 2842c2c66affSColin Finck 2843c2c66affSColin Finck if (m_StartMenuBand == NULL || 2844c2c66affSColin Finck m_StartMenuBand->IsMenuMessage(&Msg) != S_OK) 2845c2c66affSColin Finck { 2846c2c66affSColin Finck TranslateMessage(&Msg); 2847c2c66affSColin Finck DispatchMessage(&Msg); 2848c2c66affSColin Finck } 2849c2c66affSColin Finck } 2850c2c66affSColin Finck } 2851c2c66affSColin Finck 2852c2c66affSColin Finck VOID TrayMessageLoop() 2853c2c66affSColin Finck { 2854c2c66affSColin Finck MSG Msg; 2855c2c66affSColin Finck BOOL Ret; 2856c2c66affSColin Finck 2857c2c66affSColin Finck /* FIXME: We should keep a reference here... */ 2858c2c66affSColin Finck 2859c2c66affSColin Finck while (true) 2860c2c66affSColin Finck { 2861c2c66affSColin Finck Ret = GetMessage(&Msg, NULL, 0, 0); 2862c2c66affSColin Finck 2863c2c66affSColin Finck if (!Ret || Ret == -1) 2864c2c66affSColin Finck break; 2865c2c66affSColin Finck 2866c2c66affSColin Finck if (m_StartMenuBand == NULL || 2867c2c66affSColin Finck m_StartMenuBand->IsMenuMessage(&Msg) != S_OK) 2868c2c66affSColin Finck { 2869c2c66affSColin Finck TranslateMessage(&Msg); 2870c2c66affSColin Finck DispatchMessage(&Msg); 2871c2c66affSColin Finck } 2872c2c66affSColin Finck } 2873c2c66affSColin Finck } 2874c2c66affSColin Finck 2875c2c66affSColin Finck /* 2876c2c66affSColin Finck * IShellDesktopTray 2877c2c66affSColin Finck * 2878c2c66affSColin Finck * NOTE: this is a very windows-specific COM interface used by SHCreateDesktop()! 2879c2c66affSColin Finck * These are the calls I observed, it may be wrong/incomplete/buggy!!! 2880c2c66affSColin Finck * The reason we implement it is because we have to use SHCreateDesktop() so 2881c2c66affSColin Finck * that the shell provides the desktop window and all the features that come 2882c2c66affSColin Finck * with it (especially positioning of desktop icons) 2883c2c66affSColin Finck */ 2884c2c66affSColin Finck 2885c2c66affSColin Finck virtual ULONG STDMETHODCALLTYPE GetState() 2886c2c66affSColin Finck { 2887c2c66affSColin Finck /* FIXME: Return ABS_ flags? */ 2888c2c66affSColin Finck TRACE("IShellDesktopTray::GetState() unimplemented!\n"); 2889c2c66affSColin Finck return 0; 2890c2c66affSColin Finck } 2891c2c66affSColin Finck 2892c2c66affSColin Finck virtual HRESULT STDMETHODCALLTYPE GetTrayWindow(OUT HWND *phWndTray) 2893c2c66affSColin Finck { 2894c2c66affSColin Finck TRACE("IShellDesktopTray::GetTrayWindow(0x%p)\n", phWndTray); 2895c2c66affSColin Finck *phWndTray = m_hWnd; 2896c2c66affSColin Finck return S_OK; 2897c2c66affSColin Finck } 2898c2c66affSColin Finck 2899c2c66affSColin Finck virtual HRESULT STDMETHODCALLTYPE RegisterDesktopWindow(IN HWND hWndDesktop) 2900c2c66affSColin Finck { 2901c2c66affSColin Finck TRACE("IShellDesktopTray::RegisterDesktopWindow(0x%p)\n", hWndDesktop); 2902c2c66affSColin Finck 2903c2c66affSColin Finck m_DesktopWnd = hWndDesktop; 2904c2c66affSColin Finck return S_OK; 2905c2c66affSColin Finck } 2906c2c66affSColin Finck 2907c2c66affSColin Finck virtual HRESULT STDMETHODCALLTYPE Unknown(IN DWORD dwUnknown1, IN DWORD dwUnknown2) 2908c2c66affSColin Finck { 2909c2c66affSColin Finck TRACE("IShellDesktopTray::Unknown(%u,%u) unimplemented!\n", dwUnknown1, dwUnknown2); 2910c2c66affSColin Finck return S_OK; 2911c2c66affSColin Finck } 2912c2c66affSColin Finck 2913c2c66affSColin Finck virtual HRESULT RaiseStartButton() 2914c2c66affSColin Finck { 2915c2c66affSColin Finck m_StartButton.SendMessageW(BM_SETSTATE, FALSE, 0); 2916c2c66affSColin Finck return S_OK; 2917c2c66affSColin Finck } 2918c2c66affSColin Finck 2919c2c66affSColin Finck HRESULT WINAPI GetWindow(HWND* phwnd) 2920c2c66affSColin Finck { 2921c2c66affSColin Finck if (!phwnd) 2922c2c66affSColin Finck return E_INVALIDARG; 2923c2c66affSColin Finck *phwnd = m_hWnd; 2924c2c66affSColin Finck return S_OK; 2925c2c66affSColin Finck } 2926c2c66affSColin Finck 2927c2c66affSColin Finck HRESULT WINAPI ContextSensitiveHelp(BOOL fEnterMode) 2928c2c66affSColin Finck { 2929c2c66affSColin Finck return E_NOTIMPL; 2930c2c66affSColin Finck } 2931c2c66affSColin Finck 2932c2c66affSColin Finck void _Init() 2933c2c66affSColin Finck { 2934c2c66affSColin Finck m_Position = (DWORD) -1; 2935c2c66affSColin Finck } 2936c2c66affSColin Finck 2937c2c66affSColin Finck DECLARE_NOT_AGGREGATABLE(CTrayWindow) 2938c2c66affSColin Finck 2939c2c66affSColin Finck DECLARE_PROTECT_FINAL_CONSTRUCT() 2940c2c66affSColin Finck BEGIN_COM_MAP(CTrayWindow) 2941c2c66affSColin Finck /*COM_INTERFACE_ENTRY_IID(IID_ITrayWindow, ITrayWindow)*/ 2942c2c66affSColin Finck COM_INTERFACE_ENTRY_IID(IID_IShellDesktopTray, IShellDesktopTray) 2943c2c66affSColin Finck COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow) 2944c2c66affSColin Finck COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu) 2945c2c66affSColin Finck END_COM_MAP() 2946c2c66affSColin Finck }; 2947c2c66affSColin Finck 2948c2c66affSColin Finck class CTrayWindowCtxMenu : 2949c2c66affSColin Finck public CComCoClass<CTrayWindowCtxMenu>, 2950c2c66affSColin Finck public CComObjectRootEx<CComMultiThreadModelNoCS>, 2951c2c66affSColin Finck public IContextMenu 2952c2c66affSColin Finck { 2953c2c66affSColin Finck HWND hWndOwner; 2954c2c66affSColin Finck CComPtr<CTrayWindow> TrayWnd; 2955c2c66affSColin Finck CComPtr<IContextMenu> pcm; 2956c2c66affSColin Finck UINT m_idCmdCmFirst; 2957c2c66affSColin Finck 2958c2c66affSColin Finck public: 2959c2c66affSColin Finck HRESULT Initialize(ITrayWindow * pTrayWnd, IN HWND hWndOwner) 2960c2c66affSColin Finck { 2961c2c66affSColin Finck this->TrayWnd = (CTrayWindow *) pTrayWnd; 2962c2c66affSColin Finck this->hWndOwner = hWndOwner; 2963c2c66affSColin Finck this->m_idCmdCmFirst = 0; 2964c2c66affSColin Finck return S_OK; 2965c2c66affSColin Finck } 2966c2c66affSColin Finck 2967c2c66affSColin Finck virtual HRESULT STDMETHODCALLTYPE 2968c2c66affSColin Finck QueryContextMenu(HMENU hPopup, 2969c2c66affSColin Finck UINT indexMenu, 2970c2c66affSColin Finck UINT idCmdFirst, 2971c2c66affSColin Finck UINT idCmdLast, 2972c2c66affSColin Finck UINT uFlags) 2973c2c66affSColin Finck { 2974c2c66affSColin Finck HMENU menubase = LoadPopupMenu(hExplorerInstance, MAKEINTRESOURCEW(IDM_TRAYWND)); 2975c2c66affSColin Finck if (!menubase) 2976c2c66affSColin Finck return HRESULT_FROM_WIN32(GetLastError()); 2977c2c66affSColin Finck 2978c2c66affSColin Finck if (SHRestricted(REST_CLASSICSHELL) != 0) 2979c2c66affSColin Finck { 2980c2c66affSColin Finck DeleteMenu(hPopup, 2981c2c66affSColin Finck ID_LOCKTASKBAR, 2982c2c66affSColin Finck MF_BYCOMMAND); 2983c2c66affSColin Finck } 2984c2c66affSColin Finck 2985c2c66affSColin Finck CheckMenuItem(hPopup, 2986c2c66affSColin Finck ID_LOCKTASKBAR, 29872ed535daSGiannis Adamopoulos MF_BYCOMMAND | (g_TaskbarSettings.bLock ? MF_CHECKED : MF_UNCHECKED)); 2988c2c66affSColin Finck 2989c2c66affSColin Finck UINT idCmdNext; 2990c2c66affSColin Finck idCmdNext = Shell_MergeMenus(hPopup, menubase, indexMenu, idCmdFirst, idCmdLast, MM_SUBMENUSHAVEIDS | MM_ADDSEPARATOR); 2991c2c66affSColin Finck m_idCmdCmFirst = idCmdNext - idCmdFirst; 2992c2c66affSColin Finck 2993c2c66affSColin Finck ::DestroyMenu(menubase); 2994c2c66affSColin Finck 2995c2c66affSColin Finck if (TrayWnd->m_TrayBandSite != NULL) 2996c2c66affSColin Finck { 2997c2c66affSColin Finck if (FAILED(TrayWnd->m_TrayBandSite->AddContextMenus( 2998c2c66affSColin Finck hPopup, 2999c2c66affSColin Finck indexMenu, 3000c2c66affSColin Finck idCmdNext, 3001c2c66affSColin Finck idCmdLast, 3002c2c66affSColin Finck CMF_NORMAL, 3003c2c66affSColin Finck &pcm))) 3004c2c66affSColin Finck { 3005c2c66affSColin Finck WARN("AddContextMenus failed.\n"); 3006c2c66affSColin Finck pcm = NULL; 3007c2c66affSColin Finck } 3008c2c66affSColin Finck } 3009c2c66affSColin Finck 3010c2c66affSColin Finck return S_OK; 3011c2c66affSColin Finck } 3012c2c66affSColin Finck 3013c2c66affSColin Finck virtual HRESULT STDMETHODCALLTYPE 3014c2c66affSColin Finck InvokeCommand(LPCMINVOKECOMMANDINFO lpici) 3015c2c66affSColin Finck { 3016c2c66affSColin Finck UINT uiCmdId = (UINT) lpici->lpVerb; 3017c2c66affSColin Finck if (uiCmdId != 0) 3018c2c66affSColin Finck { 3019c2c66affSColin Finck if (uiCmdId >= m_idCmdCmFirst) 3020c2c66affSColin Finck { 3021c2c66affSColin Finck CMINVOKECOMMANDINFO cmici = { 0 }; 3022c2c66affSColin Finck 3023c2c66affSColin Finck if (pcm != NULL) 3024c2c66affSColin Finck { 3025c2c66affSColin Finck /* Setup and invoke the shell command */ 3026c2c66affSColin Finck cmici.cbSize = sizeof(cmici); 3027c2c66affSColin Finck cmici.hwnd = hWndOwner; 3028c2c66affSColin Finck cmici.lpVerb = (LPCSTR) MAKEINTRESOURCEW(uiCmdId - m_idCmdCmFirst); 3029c2c66affSColin Finck cmici.nShow = SW_NORMAL; 3030c2c66affSColin Finck 3031c2c66affSColin Finck pcm->InvokeCommand(&cmici); 3032c2c66affSColin Finck } 3033c2c66affSColin Finck } 3034c2c66affSColin Finck else 3035c2c66affSColin Finck { 3036c2c66affSColin Finck TrayWnd->ExecContextMenuCmd(uiCmdId); 3037c2c66affSColin Finck } 3038c2c66affSColin Finck } 3039c2c66affSColin Finck 3040c2c66affSColin Finck return S_OK; 3041c2c66affSColin Finck } 3042c2c66affSColin Finck 3043c2c66affSColin Finck virtual HRESULT STDMETHODCALLTYPE 3044c2c66affSColin Finck GetCommandString(UINT_PTR idCmd, 3045c2c66affSColin Finck UINT uType, 3046c2c66affSColin Finck UINT *pwReserved, 3047c2c66affSColin Finck LPSTR pszName, 3048c2c66affSColin Finck UINT cchMax) 3049c2c66affSColin Finck { 3050c2c66affSColin Finck return E_NOTIMPL; 3051c2c66affSColin Finck } 3052c2c66affSColin Finck 3053c2c66affSColin Finck CTrayWindowCtxMenu() 3054c2c66affSColin Finck { 3055c2c66affSColin Finck } 3056c2c66affSColin Finck 3057c2c66affSColin Finck virtual ~CTrayWindowCtxMenu() 3058c2c66affSColin Finck { 3059c2c66affSColin Finck } 3060c2c66affSColin Finck 3061c2c66affSColin Finck BEGIN_COM_MAP(CTrayWindowCtxMenu) 3062c2c66affSColin Finck COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu) 3063c2c66affSColin Finck END_COM_MAP() 3064c2c66affSColin Finck }; 3065c2c66affSColin Finck 3066c2c66affSColin Finck HRESULT TrayWindowCtxMenuCreator(ITrayWindow * TrayWnd, IN HWND hWndOwner, IContextMenu ** ppCtxMenu) 3067c2c66affSColin Finck { 3068c2c66affSColin Finck CTrayWindowCtxMenu * mnu = new CComObject<CTrayWindowCtxMenu>(); 3069c2c66affSColin Finck mnu->Initialize(TrayWnd, hWndOwner); 3070c2c66affSColin Finck *ppCtxMenu = mnu; 3071c2c66affSColin Finck return S_OK; 3072c2c66affSColin Finck } 3073c2c66affSColin Finck 3074c2c66affSColin Finck HRESULT CreateTrayWindow(ITrayWindow ** ppTray) 3075c2c66affSColin Finck { 3076c2c66affSColin Finck CComPtr<CTrayWindow> Tray = new CComObject<CTrayWindow>(); 3077c2c66affSColin Finck if (Tray == NULL) 3078c2c66affSColin Finck return E_OUTOFMEMORY; 3079c2c66affSColin Finck 3080c2c66affSColin Finck Tray->_Init(); 3081c2c66affSColin Finck Tray->Open(); 3082c2c66affSColin Finck 3083c2c66affSColin Finck *ppTray = (ITrayWindow *) Tray; 3084c2c66affSColin Finck 3085c2c66affSColin Finck return S_OK; 3086c2c66affSColin Finck } 3087c2c66affSColin Finck 3088c2c66affSColin Finck HRESULT 3089c2c66affSColin Finck Tray_OnStartMenuDismissed(ITrayWindow* Tray) 3090c2c66affSColin Finck { 3091c2c66affSColin Finck CTrayWindow * TrayWindow = static_cast<CTrayWindow *>(Tray); 3092c2c66affSColin Finck return TrayWindow->RaiseStartButton(); 3093c2c66affSColin Finck } 3094c2c66affSColin Finck 3095c2c66affSColin Finck VOID TrayProcessMessages(ITrayWindow *Tray) 3096c2c66affSColin Finck { 3097c2c66affSColin Finck CTrayWindow * TrayWindow = static_cast<CTrayWindow *>(Tray); 3098c2c66affSColin Finck TrayWindow->TrayProcessMessages(); 3099c2c66affSColin Finck } 3100c2c66affSColin Finck 3101c2c66affSColin Finck VOID TrayMessageLoop(ITrayWindow *Tray) 3102c2c66affSColin Finck { 3103c2c66affSColin Finck CTrayWindow * TrayWindow = static_cast<CTrayWindow *>(Tray); 3104c2c66affSColin Finck TrayWindow->TrayMessageLoop(); 3105c2c66affSColin Finck } 3106