Reactos
at master 645 lines 20 kB view raw
1/* 2 * Shell Desktop 3 * 4 * Copyright 2008 Thomas Bluemel 5 * Copyright 2020 Katayama Hirofumi MZ 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20 */ 21 22#include "shelldesktop.h" 23 24// Support for multiple monitors is disabled till LVM_SETWORKAREAS gets implemented 25#ifdef MULTIMONITOR_SUPPORT 26#include <atlcoll.h> 27#endif 28 29#include <dbt.h> 30 31WINE_DEFAULT_DEBUG_CHANNEL(desktop); 32 33static const WCHAR szProgmanClassName[] = L"Progman"; 34static const WCHAR szProgmanWindowName[] = L"Program Manager"; 35 36static BOOL IsDesktopBrowserForwardShellViewCmd(WORD Cmd) 37{ 38 // Note: The normal CShellBrowser forwards the entire FCIDM_SHVIEWFIRST..LAST range, we do not. 39 // Note: Windows allows FCIDM_SHVIEW_SHOWINGROUPS but we don't support it nor does it make sense. 40 return (FCIDM_SHVIEW_CREATELINK <= Cmd && Cmd <= FCIDM_SHVIEW_DESELECTALL) || 41 (FCIDM_SHVIEW_ARRANGE_AUTO <= Cmd && Cmd <= FCIDM_SHVIEW_ARRANGE_AUTOGRID) || 42 (Cmd == FCIDM_SHVIEW_REFRESH); 43} 44 45class CDesktopBrowser : 46 public CWindowImpl<CDesktopBrowser, CWindow, CFrameWinTraits>, 47 public CComObjectRootEx<CComMultiThreadModelNoCS>, 48 public IShellBrowser, 49 public IShellBrowserService, 50 public IServiceProvider 51{ 52private: 53 HACCEL m_hAccel; 54 HWND m_hWndShellView; 55 CComPtr<IShellDesktopTray> m_Tray; 56 CComPtr<IShellView> m_ShellView; 57 58 CComPtr<IOleWindow> m_ChangeNotifyServer; 59 HWND m_hwndChangeNotifyServer; 60 DWORD m_dwDrives; 61 62 LRESULT _NotifyTray(UINT uMsg, WPARAM wParam, LPARAM lParam); 63 HRESULT _Resize(); 64 65public: 66 CDesktopBrowser(); 67 ~CDesktopBrowser(); 68 HRESULT Initialize(IShellDesktopTray *ShellDeskx); 69 70 // *** IOleWindow methods *** 71 STDMETHOD(GetWindow)(HWND *lphwnd) override; 72 STDMETHOD(ContextSensitiveHelp)(BOOL fEnterMode) override; 73 74 // *** IShellBrowser methods *** 75 STDMETHOD(InsertMenusSB)(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths) override; 76 STDMETHOD(SetMenuSB)(HMENU hmenuShared, HOLEMENU holemenuRes, HWND hwndActiveObject) override; 77 STDMETHOD(RemoveMenusSB)(HMENU hmenuShared) override; 78 STDMETHOD(SetStatusTextSB)(LPCOLESTR pszStatusText) override; 79 STDMETHOD(EnableModelessSB)(BOOL fEnable) override; 80 STDMETHOD(TranslateAcceleratorSB)(MSG *pmsg, WORD wID) override; 81 STDMETHOD(BrowseObject)(LPCITEMIDLIST pidl, UINT wFlags) override; 82 STDMETHOD(GetViewStateStream)(DWORD grfMode, IStream **ppStrm) override; 83 STDMETHOD(GetControlWindow)(UINT id, HWND *lphwnd) override; 84 STDMETHOD(SendControlMsg)(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pret) override; 85 STDMETHOD(QueryActiveShellView)(struct IShellView **ppshv) override; 86 STDMETHOD(OnViewWindowActive)(struct IShellView *ppshv) override; 87 STDMETHOD(SetToolbarItems)(LPTBBUTTON lpButtons, UINT nButtons, UINT uFlags) override; 88 89 // *** IShellBrowserService methods *** 90 STDMETHOD(GetPropertyBag)(long flags, REFIID riid, void **ppv) override; 91 92 // *** IBrowserService2 methods (fake for now) *** 93 inline void SetTopBrowser() const {} 94 95 // *** IServiceProvider methods *** 96 STDMETHOD(QueryService)(REFGUID guidService, REFIID riid, void **ppvObject) override; 97 98 // message handlers 99 LRESULT OnEraseBkgnd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 100 LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 101 LRESULT OnSettingChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 102 LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 103 LRESULT OnOpenNewWindow(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 104 LRESULT OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 105 LRESULT OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 106 LRESULT OnGetChangeNotifyServer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 107 LRESULT OnDeviceChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 108 LRESULT OnShowOptionsDlg(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 109 LRESULT OnSaveState(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 110 111DECLARE_WND_CLASS_EX(szProgmanClassName, CS_DBLCLKS, COLOR_DESKTOP) 112 113BEGIN_MSG_MAP(CBaseBar) 114 MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd) 115 MESSAGE_HANDLER(WM_SIZE, OnSize) 116 MESSAGE_HANDLER(WM_SYSCOLORCHANGE, OnSettingChange) 117 MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange) 118 MESSAGE_HANDLER(WM_CLOSE, OnClose) 119 MESSAGE_HANDLER(WM_EXPLORER_OPEN_NEW_WINDOW, OnOpenNewWindow) 120 MESSAGE_HANDLER(WM_COMMAND, OnCommand) 121 MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus) 122 MESSAGE_HANDLER(WM_DESKTOP_GET_CNOTIFY_SERVER, OnGetChangeNotifyServer) 123 MESSAGE_HANDLER(WM_DEVICECHANGE, OnDeviceChange) 124 MESSAGE_HANDLER(WM_PROGMAN_OPENSHELLSETTINGS, OnShowOptionsDlg) 125 MESSAGE_HANDLER(WM_PROGMAN_SAVESTATE, OnSaveState) 126END_MSG_MAP() 127 128BEGIN_COM_MAP(CDesktopBrowser) 129 COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow) 130 COM_INTERFACE_ENTRY_IID(IID_IShellBrowser, IShellBrowser) 131 COM_INTERFACE_ENTRY_IID(IID_IShellBrowserService, IShellBrowserService) 132 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider) 133END_COM_MAP() 134}; 135 136CDesktopBrowser::CDesktopBrowser(): 137 m_hAccel(NULL), 138 m_hWndShellView(NULL), 139 m_hwndChangeNotifyServer(NULL), 140 m_dwDrives(::GetLogicalDrives()) 141{ 142 SetTopBrowser(); 143} 144 145CDesktopBrowser::~CDesktopBrowser() 146{ 147 if (m_ShellView.p != NULL && m_hWndShellView != NULL) 148 { 149 m_ShellView->DestroyViewWindow(); 150 } 151 152 if (m_hwndChangeNotifyServer) 153 { 154 ::DestroyWindow(m_hwndChangeNotifyServer); 155 } 156} 157 158#ifdef MULTIMONITOR_SUPPORT 159BOOL CALLBACK MonitorEnumProc( 160 _In_ HMONITOR hMonitor, 161 _In_ HDC hdcMonitor, 162 _In_ LPRECT lprcMonitor, 163 _In_ LPARAM dwData 164) 165{ 166 CAtlList<RECT> *list = (CAtlList<RECT>*)dwData; 167 MONITORINFO MonitorInfo; 168 MonitorInfo.cbSize = sizeof(MonitorInfo); 169 if (::GetMonitorInfoW(hMonitor, &MonitorInfo)) 170 { 171 list->AddTail(MonitorInfo.rcWork); 172 } 173 174 return TRUE; 175} 176#endif 177 178HRESULT CDesktopBrowser::_Resize() 179{ 180 RECT rcNewSize; 181 182#ifdef MULTIMONITOR_SUPPORT 183 184 UINT cMonitors = GetSystemMetrics(SM_CMONITORS); 185 if (cMonitors == 1) 186 { 187 SystemParametersInfoW(SPI_GETWORKAREA, 0, &rcNewSize, 0); 188 } 189 else 190 { 191 SetRect(&rcNewSize, 192 GetSystemMetrics(SM_XVIRTUALSCREEN), 193 GetSystemMetrics(SM_YVIRTUALSCREEN), 194 GetSystemMetrics(SM_XVIRTUALSCREEN) + GetSystemMetrics(SM_CXVIRTUALSCREEN), 195 GetSystemMetrics(SM_YVIRTUALSCREEN) + GetSystemMetrics(SM_CYVIRTUALSCREEN)); 196 } 197 198 ::MoveWindow(m_hWnd, rcNewSize.left, rcNewSize.top, rcNewSize.right - rcNewSize.left, rcNewSize.bottom - rcNewSize.top, TRUE); 199 ::MoveWindow(m_hWndShellView, 0, 0, rcNewSize.right - rcNewSize.left, rcNewSize.bottom - rcNewSize.top, TRUE); 200 201 if (cMonitors != 1) 202 { 203 CAtlList<RECT> list; 204 EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, (LPARAM)&list); 205 RECT* prcWorkAreas = new RECT[list.GetCount()]; 206 int i = 0; 207 for (POSITION it = list.GetHeadPosition(); it; list.GetNext(it)) 208 prcWorkAreas[i++] = list.GetAt(it); 209 210 HWND hwndListView = FindWindowExW(m_hWndShellView, NULL, WC_LISTVIEW, NULL); 211 212 ::SendMessageW(hwndListView, LVM_SETWORKAREAS , i, (LPARAM)prcWorkAreas); 213 } 214 215#else 216 SystemParametersInfoW(SPI_GETWORKAREA, 0, &rcNewSize, 0); 217 ::MoveWindow(m_hWnd, rcNewSize.left, rcNewSize.top, rcNewSize.right - rcNewSize.left, rcNewSize.bottom - rcNewSize.top, TRUE); 218 ::MoveWindow(m_hWndShellView, 0, 0, rcNewSize.right - rcNewSize.left, rcNewSize.bottom - rcNewSize.top, TRUE); 219 220#endif 221 return S_OK; 222} 223 224HRESULT CDesktopBrowser::Initialize(IShellDesktopTray *ShellDesk) 225{ 226 CComPtr<IShellFolder> psfDesktop; 227 HRESULT hRet; 228 hRet = SHGetDesktopFolder(&psfDesktop); 229 if (FAILED_UNEXPECTEDLY(hRet)) 230 return hRet; 231 232 m_Tray = ShellDesk; 233 234 Create(NULL, NULL, szProgmanWindowName, WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, WS_EX_TOOLWINDOW); 235 if (!m_hWnd) 236 return E_FAIL; 237 238 hRet = psfDesktop->CreateViewObject(m_hWnd, IID_PPV_ARG(IShellView, &m_ShellView)); 239 if (FAILED_UNEXPECTEDLY(hRet)) 240 return hRet; 241 242 m_Tray->RegisterDesktopWindow(m_hWnd); 243 if (FAILED_UNEXPECTEDLY(hRet)) 244 return hRet; 245 246 BOOL fHideIcons = SHELL_GetSetting(SSF_HIDEICONS, fHideIcons); 247 FOLDERSETTINGS fs; 248 RECT rcShellView = {0,0,0,0}; 249 fs.ViewMode = FVM_ICON; 250 fs.fFlags = FWF_DESKTOP | FWF_NOCLIENTEDGE | FWF_NOSCROLL | FWF_TRANSPARENT | 251 FWF_AUTOARRANGE | (fHideIcons ? FWF_NOICONS : 0); 252 hRet = m_ShellView->CreateViewWindow(NULL, &fs, (IShellBrowser *)this, &rcShellView, &m_hWndShellView); 253 if (FAILED_UNEXPECTEDLY(hRet)) 254 return hRet; 255 256 _Resize(); 257 258 HWND hwndListView = FindWindowExW(m_hWndShellView, NULL, WC_LISTVIEW, NULL); 259 260 m_hAccel = LoadAcceleratorsW(shell32_hInstance, MAKEINTRESOURCEW(IDA_DESKBROWSER)); 261 262#if 1 263 /* A Windows8+ specific hack */ 264 ::ShowWindow(m_hWndShellView, SW_SHOW); 265 ::ShowWindow(hwndListView, SW_SHOW); 266#endif 267 ShowWindow(SW_SHOW); 268 UpdateWindow(); 269 270 return hRet; 271} 272 273HRESULT STDMETHODCALLTYPE CDesktopBrowser::GetWindow(HWND *lphwnd) 274{ 275 if (lphwnd == NULL) 276 return E_POINTER; 277 *lphwnd = m_hWnd; 278 return S_OK; 279} 280 281HRESULT STDMETHODCALLTYPE CDesktopBrowser::ContextSensitiveHelp(BOOL fEnterMode) 282{ 283 return E_NOTIMPL; 284} 285 286HRESULT STDMETHODCALLTYPE CDesktopBrowser::InsertMenusSB(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths) 287{ 288 return E_NOTIMPL; 289} 290 291HRESULT STDMETHODCALLTYPE CDesktopBrowser::SetMenuSB(HMENU hmenuShared, HOLEMENU holemenuRes, HWND hwndActiveObject) 292{ 293 return E_NOTIMPL; 294} 295 296HRESULT STDMETHODCALLTYPE CDesktopBrowser::RemoveMenusSB(HMENU hmenuShared) 297{ 298 return E_NOTIMPL; 299} 300 301HRESULT STDMETHODCALLTYPE CDesktopBrowser::SetStatusTextSB(LPCOLESTR lpszStatusText) 302{ 303 return E_NOTIMPL; 304} 305 306HRESULT STDMETHODCALLTYPE CDesktopBrowser::EnableModelessSB(BOOL fEnable) 307{ 308 return E_NOTIMPL; 309} 310 311HRESULT STDMETHODCALLTYPE CDesktopBrowser::TranslateAcceleratorSB(LPMSG lpmsg, WORD wID) 312{ 313 if (!::TranslateAcceleratorW(m_hWnd, m_hAccel, lpmsg)) 314 return S_FALSE; 315 return S_OK; 316} 317 318HRESULT STDMETHODCALLTYPE CDesktopBrowser::BrowseObject(LPCITEMIDLIST pidl, UINT wFlags) 319{ 320 /* 321 * We should use IShellWindows interface here in order to attempt to 322 * find an open shell window that shows the requested pidl and activate it 323 */ 324 325 DWORD dwFlags = ((wFlags & SBSP_EXPLOREMODE) != 0) ? SH_EXPLORER_CMDLINE_FLAG_E : 0; 326 return SHOpenNewFrame(ILClone(pidl), NULL, 0, dwFlags); 327} 328 329HRESULT STDMETHODCALLTYPE CDesktopBrowser::GetViewStateStream(DWORD grfMode, IStream **ppStrm) 330{ 331 return E_NOTIMPL; 332} 333 334HRESULT STDMETHODCALLTYPE CDesktopBrowser::GetControlWindow(UINT id, HWND *lphwnd) 335{ 336 if (lphwnd == NULL) 337 return E_POINTER; 338 return E_NOTIMPL; 339} 340 341HRESULT STDMETHODCALLTYPE CDesktopBrowser::SendControlMsg(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pret) 342{ 343 if (pret == NULL) 344 return E_POINTER; 345 return E_NOTIMPL; 346} 347 348HRESULT STDMETHODCALLTYPE CDesktopBrowser::QueryActiveShellView(IShellView **ppshv) 349{ 350 if (ppshv == NULL) 351 return E_POINTER; 352 *ppshv = m_ShellView; 353 if (*ppshv != NULL) 354 (*ppshv)->AddRef(); 355 356 return S_OK; 357} 358 359HRESULT STDMETHODCALLTYPE CDesktopBrowser::OnViewWindowActive(IShellView *ppshv) 360{ 361 return E_NOTIMPL; 362} 363 364HRESULT STDMETHODCALLTYPE CDesktopBrowser::SetToolbarItems(LPTBBUTTON lpButtons, UINT nButtons, UINT uFlags) 365{ 366 return E_NOTIMPL; 367} 368 369HRESULT STDMETHODCALLTYPE CDesktopBrowser::GetPropertyBag(long flags, REFIID riid, void **ppv) 370{ 371 ITEMIDLIST deskpidl = {}; 372 return SHGetViewStatePropertyBag(&deskpidl, L"Desktop", flags | SHGVSPB_ROAM, riid, ppv); 373} 374 375HRESULT STDMETHODCALLTYPE CDesktopBrowser::QueryService(REFGUID guidService, REFIID riid, PVOID *ppv) 376{ 377 /* FIXME - handle guidService (SID_STopLevelBrowser for IShellBrowserService etc) */ 378 return QueryInterface(riid, ppv); 379} 380 381LRESULT CDesktopBrowser::_NotifyTray(UINT uMsg, WPARAM wParam, LPARAM lParam) 382{ 383 HWND hWndTray; 384 HRESULT hRet; 385 386 hRet = m_Tray->GetTrayWindow(&hWndTray); 387 if (SUCCEEDED(hRet)) 388 ::PostMessageW(hWndTray, uMsg, wParam, lParam); 389 390 return 0; 391} 392 393LRESULT CDesktopBrowser::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) 394{ 395 switch (LOWORD(wParam)) 396 { 397 case FCIDM_DESKBROWSER_CLOSE: 398 return _NotifyTray(TWM_DOEXITWINDOWS, 0, 0); 399 case FCIDM_DESKBROWSER_FOCUS: 400 if (GetKeyState(VK_SHIFT)) 401 return _NotifyTray(TWM_CYCLEFOCUS, 1, 0xFFFFFFFF); 402 else 403 return _NotifyTray(TWM_CYCLEFOCUS, 1, 1); 404 case FCIDM_DESKBROWSER_SEARCH: 405 SHFindFiles(NULL, NULL); 406 break; 407 case FCIDM_DESKBROWSER_REFRESH: 408 if (m_ShellView) 409 m_ShellView->Refresh(); 410 break; 411 default: 412 if (IsDesktopBrowserForwardShellViewCmd(LOWORD(wParam)) && m_hWndShellView) 413 return SendMessageW(m_hWndShellView, uMsg, wParam, lParam); 414 break; 415 } 416 return 0; 417} 418 419 420LRESULT CDesktopBrowser::OnEraseBkgnd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) 421{ 422 return (LRESULT)PaintDesktop((HDC)wParam); 423} 424 425LRESULT CDesktopBrowser::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) 426{ 427 if (wParam == SIZE_MINIMIZED) 428 { 429 /* Hey, we're the desktop!!! */ 430 ::ShowWindow(m_hWnd, SW_RESTORE); 431 } 432 433 ::InvalidateRect(m_hWndShellView, NULL, TRUE); 434 435 return 0; 436} 437 438LRESULT CDesktopBrowser::OnSettingChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) 439{ 440 if (uMsg == WM_SETTINGCHANGE /* == WM_WININICHANGE */ && 441 lstrcmpiW((LPCWSTR)lParam, L"Environment") == 0) 442 { 443 LPVOID lpEnvironment; 444 RegenerateUserEnvironment(&lpEnvironment, TRUE); 445 } 446 SHSettingsChanged((LPCVOID)wParam, (PCWSTR)lParam); // Invalidate cached restrictions 447 448 if (m_hWndShellView) 449 { 450 /* Forward the message */ 451 ::SendMessageW(m_hWndShellView, uMsg, wParam, lParam); 452 } 453 454 if (uMsg == WM_SETTINGCHANGE && wParam == SPI_SETWORKAREA && m_hWndShellView != NULL) 455 { 456 _Resize(); 457 } 458 459 return 0; 460} 461 462LRESULT CDesktopBrowser::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) 463{ 464 return _NotifyTray(TWM_DOEXITWINDOWS, 0, 0); 465} 466 467LRESULT CDesktopBrowser::OnOpenNewWindow(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) 468{ 469 TRACE("Proxy Desktop message 1035 received.\n"); 470 SHOnCWMCommandLine((HANDLE)lParam); 471 return 0; 472} 473 474LRESULT CDesktopBrowser::OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) 475{ 476 ::SetFocus(m_hWndShellView); 477 return 0; 478} 479 480// Message WM_DESKTOP_GET_CNOTIFY_SERVER: Get or create the change notification server. 481// wParam: BOOL bCreate; The flag whether it creates or not. 482// lParam: Ignored. 483// return: The window handle of the server window. 484LRESULT CDesktopBrowser::OnGetChangeNotifyServer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) 485{ 486 BOOL bCreate = (BOOL)wParam; 487 if (bCreate && !::IsWindow(m_hwndChangeNotifyServer)) 488 { 489 HRESULT hres = CChangeNotifyServer_CreateInstance(IID_PPV_ARG(IOleWindow, &m_ChangeNotifyServer)); 490 if (FAILED_UNEXPECTEDLY(hres)) 491 return NULL; 492 493 hres = m_ChangeNotifyServer->GetWindow(&m_hwndChangeNotifyServer); 494 if (FAILED_UNEXPECTEDLY(hres)) 495 return NULL; 496 } 497 return (LRESULT)m_hwndChangeNotifyServer; 498} 499 500// Detect DBT_DEVICEARRIVAL and DBT_DEVICEREMOVECOMPLETE 501LRESULT CDesktopBrowser::OnDeviceChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) 502{ 503 if (wParam != DBT_DEVICEARRIVAL && wParam != DBT_DEVICEREMOVECOMPLETE) 504 return 0; 505 506 DWORD dwDrives = ::GetLogicalDrives(); 507 for (INT iDrive = 0; iDrive <= 'Z' - 'A'; ++iDrive) 508 { 509 WCHAR szPath[MAX_PATH]; 510 DWORD dwBit = (1 << iDrive); 511 if (!(m_dwDrives & dwBit) && (dwDrives & dwBit)) // The drive is added 512 { 513 PathBuildRootW(szPath, iDrive); 514 SHChangeNotify(SHCNE_DRIVEADD, SHCNF_PATHW, szPath, NULL); 515 } 516 else if ((m_dwDrives & dwBit) && !(dwDrives & dwBit)) // The drive is removed 517 { 518 PathBuildRootW(szPath, iDrive); 519 SHChangeNotify(SHCNE_DRIVEREMOVED, SHCNF_PATHW, szPath, NULL); 520 } 521 } 522 523 m_dwDrives = dwDrives; 524 return 0; 525} 526 527extern VOID WINAPI ShowFolderOptionsDialog(UINT Page, BOOL Async); 528 529LRESULT CDesktopBrowser::OnShowOptionsDlg(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) 530{ 531 switch (wParam) 532 { 533 case 0: 534#if (NTDDI_VERSION >= NTDDI_VISTA) 535 case 2: 536 case 7: 537#endif 538 ShowFolderOptionsDialog((UINT)(UINT_PTR)wParam, TRUE); 539 break; 540 case 1: 541 _NotifyTray(WM_COMMAND, TRAYCMD_TASKBAR_PROPERTIES, 0); 542 break; 543 } 544 return 0; 545} 546 547LRESULT CDesktopBrowser::OnSaveState(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) 548{ 549 if (m_ShellView && !SHRestricted(REST_NOSAVESET)) 550 m_ShellView->SaveViewState(); 551 return 0; 552} 553 554HRESULT CDesktopBrowser_CreateInstance(IShellDesktopTray *Tray, REFIID riid, void **ppv) 555{ 556 return ShellObjectCreatorInit<CDesktopBrowser, IShellDesktopTray*>(Tray, riid, ppv); 557} 558 559/************************************************************************* 560 * SHCreateDesktop [SHELL32.200] 561 * 562 */ 563HANDLE WINAPI SHCreateDesktop(IShellDesktopTray *Tray) 564{ 565 if (Tray == NULL) 566 { 567 SetLastError(ERROR_INVALID_PARAMETER); 568 return NULL; 569 } 570 571 CComPtr<IShellBrowser> Browser; 572 HRESULT hr = CDesktopBrowser_CreateInstance(Tray, IID_PPV_ARG(IShellBrowser, &Browser)); 573 if (FAILED_UNEXPECTEDLY(hr)) 574 return NULL; 575 576 return static_cast<HANDLE>(Browser.Detach()); 577} 578 579/************************************************************************* 580 * SHCreateDesktop [SHELL32.201] 581 * 582 */ 583BOOL WINAPI SHDesktopMessageLoop(HANDLE hDesktop) 584{ 585 if (hDesktop == NULL) 586 { 587 SetLastError(ERROR_INVALID_PARAMETER); 588 return FALSE; 589 } 590 591 MSG Msg; 592 BOOL bRet; 593 594 CComPtr<IShellBrowser> browser; 595 CComPtr<IShellView> shellView; 596 597 browser.Attach(static_cast<IShellBrowser*>(hDesktop)); 598 HRESULT hr = browser->QueryActiveShellView(&shellView); 599 if (FAILED_UNEXPECTEDLY(hr)) 600 return FALSE; 601 602 while ((bRet = ::GetMessageW(&Msg, NULL, 0, 0)) != 0) 603 { 604 if (bRet != -1) 605 { 606 if (shellView->TranslateAcceleratorW(&Msg) != S_OK) 607 { 608 ::TranslateMessage(&Msg); 609 ::DispatchMessageW(&Msg); 610 } 611 } 612 } 613 614 return TRUE; 615} 616 617/************************************************************************* 618 * SHIsTempDisplayMode [SHELL32.724] 619 * 620 * Is the current display settings temporary? 621 */ 622EXTERN_C BOOL WINAPI SHIsTempDisplayMode(VOID) 623{ 624 TRACE("\n"); 625 626 if (GetSystemMetrics(SM_REMOTESESSION) || GetSystemMetrics(SM_REMOTECONTROL)) 627 return FALSE; 628 629 DEVMODEW DevMode; 630 ZeroMemory(&DevMode, sizeof(DevMode)); 631 DevMode.dmSize = sizeof(DevMode); 632 633 if (!EnumDisplaySettingsW(NULL, ENUM_REGISTRY_SETTINGS, &DevMode)) 634 return FALSE; 635 636 if (!DevMode.dmPelsWidth || !DevMode.dmPelsHeight) 637 return FALSE; 638 639 HDC hDC = GetDC(NULL); 640 DWORD cxWidth = GetDeviceCaps(hDC, HORZRES); 641 DWORD cyHeight = GetDeviceCaps(hDC, VERTRES); 642 ReleaseDC(NULL, hDC); 643 644 return (cxWidth != DevMode.dmPelsWidth || cyHeight != DevMode.dmPelsHeight); 645}