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