Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendesktop.cpp
Go to the documentation of this file.
00001 /* 00002 * Shell Desktop 00003 * 00004 * Copyright 2008 Thomas Bluemel 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00019 */ 00020 00021 #include <precomp.h> 00022 00023 WINE_DEFAULT_DEBUG_CHANNEL(desktop); 00024 00025 BOOL WINAPI SetShellWindowEx(HWND, HWND); 00026 00027 #define SHDESK_TAG 0x4b534544 00028 00029 static const WCHAR szProgmanClassName[] = {'P','r','o','g','m','a','n'}; 00030 static const WCHAR szProgmanWindowName[] = { 00031 'P','r','o','g','r','a','m',' ','M','a','n','a','g','e','r' 00032 }; 00033 00034 class CDesktopBrowser : 00035 public CComObjectRootEx<CComMultiThreadModelNoCS>, 00036 public IShellBrowser, 00037 public ICommDlgBrowser, 00038 public IServiceProvider 00039 { 00040 public: 00041 DWORD Tag; 00042 private: 00043 HWND hWnd; 00044 HWND hWndShellView; 00045 HWND hWndDesktopListView; 00046 CComPtr<IShellDesktopTray> ShellDesk; 00047 CComPtr<IShellView> DesktopView; 00048 IShellBrowser *DefaultShellBrowser; 00049 LPITEMIDLIST pidlDesktopDirectory; 00050 LPITEMIDLIST pidlDesktop; 00051 public: 00052 CDesktopBrowser(); 00053 ~CDesktopBrowser(); 00054 HRESULT Initialize(HWND hWndx, IShellDesktopTray *ShellDeskx); 00055 HWND FindDesktopListView (); 00056 BOOL CreateDeskWnd(); 00057 HWND DesktopGetWindowControl(IN UINT id); 00058 static LRESULT CALLBACK ProgmanWindowProc(IN HWND hwnd, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam); 00059 static BOOL MessageLoop(); 00060 00061 // *** IOleWindow methods *** 00062 virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND *lphwnd); 00063 virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode); 00064 00065 // *** IShellBrowser methods *** 00066 virtual HRESULT STDMETHODCALLTYPE InsertMenusSB(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths); 00067 virtual HRESULT STDMETHODCALLTYPE SetMenuSB(HMENU hmenuShared, HOLEMENU holemenuRes, HWND hwndActiveObject); 00068 virtual HRESULT STDMETHODCALLTYPE RemoveMenusSB(HMENU hmenuShared); 00069 virtual HRESULT STDMETHODCALLTYPE SetStatusTextSB(LPCOLESTR pszStatusText); 00070 virtual HRESULT STDMETHODCALLTYPE EnableModelessSB(BOOL fEnable); 00071 virtual HRESULT STDMETHODCALLTYPE TranslateAcceleratorSB(MSG *pmsg, WORD wID); 00072 virtual HRESULT STDMETHODCALLTYPE BrowseObject(LPCITEMIDLIST pidl, UINT wFlags); 00073 virtual HRESULT STDMETHODCALLTYPE GetViewStateStream(DWORD grfMode, IStream **ppStrm); 00074 virtual HRESULT STDMETHODCALLTYPE GetControlWindow(UINT id, HWND *lphwnd); 00075 virtual HRESULT STDMETHODCALLTYPE SendControlMsg(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pret); 00076 virtual HRESULT STDMETHODCALLTYPE QueryActiveShellView(struct IShellView **ppshv); 00077 virtual HRESULT STDMETHODCALLTYPE OnViewWindowActive(struct IShellView *ppshv); 00078 virtual HRESULT STDMETHODCALLTYPE SetToolbarItems(LPTBBUTTON lpButtons, UINT nButtons, UINT uFlags); 00079 00080 // *** ICommDlgBrowser methods *** 00081 virtual HRESULT STDMETHODCALLTYPE OnDefaultCommand (struct IShellView *ppshv); 00082 virtual HRESULT STDMETHODCALLTYPE OnStateChange (struct IShellView *ppshv, ULONG uChange); 00083 virtual HRESULT STDMETHODCALLTYPE IncludeObject (struct IShellView *ppshv, LPCITEMIDLIST pidl); 00084 00085 // *** IServiceProvider methods *** 00086 virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void **ppvObject); 00087 00088 BEGIN_COM_MAP(CDesktopBrowser) 00089 COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow) 00090 COM_INTERFACE_ENTRY_IID(IID_IShellBrowser, IShellBrowser) 00091 COM_INTERFACE_ENTRY_IID(IID_ICommDlgBrowser, ICommDlgBrowser) 00092 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider) 00093 END_COM_MAP() 00094 }; 00095 00096 CDesktopBrowser::CDesktopBrowser() 00097 { 00098 Tag = SHDESK_TAG; 00099 hWnd = NULL; 00100 hWndShellView = NULL; 00101 hWndDesktopListView = NULL; 00102 DefaultShellBrowser = NULL; 00103 pidlDesktopDirectory = NULL; 00104 pidlDesktop = NULL; 00105 } 00106 00107 CDesktopBrowser::~CDesktopBrowser() 00108 { 00109 if (DesktopView.p != NULL) 00110 { 00111 if (hWndShellView != NULL) 00112 DesktopView->DestroyViewWindow(); 00113 00114 hWndShellView = NULL; 00115 hWndDesktopListView = NULL; 00116 } 00117 00118 if (pidlDesktopDirectory != NULL) 00119 { 00120 ILFree(pidlDesktopDirectory); 00121 pidlDesktopDirectory = NULL; 00122 } 00123 00124 if (pidlDesktop != NULL) 00125 { 00126 ILFree(pidlDesktop); 00127 pidlDesktop = NULL; 00128 } 00129 } 00130 00131 HRESULT CDesktopBrowser::Initialize(HWND hWndx, IShellDesktopTray *ShellDeskx) 00132 { 00133 CComPtr<IShellFolder> psfDesktopFolder; 00134 CSFV csfv; 00135 HRESULT hRet; 00136 00137 hWnd = hWndx; 00138 ShellDesk = ShellDeskx; 00139 ShellDesk->AddRef(); 00140 00141 pidlDesktopDirectory = SHCloneSpecialIDList(hWnd, CSIDL_DESKTOPDIRECTORY, FALSE); 00142 hRet = SHGetSpecialFolderLocation(hWnd, CSIDL_DESKTOP, &pidlDesktop); 00143 if (FAILED(hRet)) 00144 return hRet; 00145 00146 hRet = SHGetDesktopFolder(&psfDesktopFolder); 00147 if (FAILED(hRet)) 00148 return hRet; 00149 00150 ZeroMemory(&csfv, sizeof(csfv)); 00151 csfv.cbSize = sizeof(csfv); 00152 csfv.pshf = psfDesktopFolder; 00153 csfv.psvOuter = NULL; 00154 00155 hRet = SHCreateShellFolderViewEx(&csfv, &DesktopView); 00156 00157 return hRet; 00158 } 00159 00160 static CDesktopBrowser *SHDESK_Create(HWND hWnd, LPCREATESTRUCT lpCreateStruct) 00161 { 00162 IShellDesktopTray *ShellDesk; 00163 CComObject<CDesktopBrowser> *pThis; 00164 HRESULT hRet; 00165 00166 ShellDesk = (IShellDesktopTray *)lpCreateStruct->lpCreateParams; 00167 if (ShellDesk == NULL) 00168 { 00169 WARN("No IShellDesk interface provided!"); 00170 return NULL; 00171 } 00172 00173 pThis = new CComObject<CDesktopBrowser>; 00174 if (pThis == NULL) 00175 return NULL; 00176 pThis->AddRef(); 00177 00178 hRet = pThis->Initialize(hWnd, ShellDesk); 00179 if (FAILED(hRet)) 00180 { 00181 pThis->Release(); 00182 return NULL; 00183 } 00184 00185 return pThis; 00186 } 00187 00188 HWND CDesktopBrowser::FindDesktopListView () 00189 { 00190 return FindWindowExW(hWndShellView, NULL, WC_LISTVIEW, NULL); 00191 } 00192 00193 BOOL CDesktopBrowser::CreateDeskWnd() 00194 { 00195 FOLDERSETTINGS fs; 00196 RECT rcClient; 00197 HRESULT hRet; 00198 00199 if (!GetClientRect(hWnd, &rcClient)) 00200 { 00201 return FALSE; 00202 } 00203 00204 fs.ViewMode = FVM_ICON; 00205 fs.fFlags = FWF_DESKTOP | FWF_NOCLIENTEDGE | FWF_NOSCROLL | FWF_TRANSPARENT; 00206 hRet = DesktopView->CreateViewWindow(NULL, &fs, (IShellBrowser *)this, &rcClient, &hWndShellView); 00207 if (!SUCCEEDED(hRet)) 00208 return FALSE; 00209 00210 SetShellWindowEx(hWnd, FindDesktopListView()); 00211 00212 return TRUE; 00213 } 00214 00215 HRESULT STDMETHODCALLTYPE CDesktopBrowser::GetWindow(HWND *phwnd) 00216 { 00217 if (hWnd != NULL) 00218 { 00219 *phwnd = hWnd; 00220 return S_OK; 00221 } 00222 00223 *phwnd = NULL; 00224 return E_UNEXPECTED; 00225 } 00226 00227 HRESULT STDMETHODCALLTYPE CDesktopBrowser::ContextSensitiveHelp(BOOL fEnterMode) 00228 { 00229 return E_NOTIMPL; 00230 } 00231 00232 HRESULT STDMETHODCALLTYPE CDesktopBrowser::InsertMenusSB(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths) 00233 { 00234 return E_NOTIMPL; 00235 } 00236 00237 HRESULT STDMETHODCALLTYPE CDesktopBrowser::SetMenuSB(HMENU hmenuShared, HOLEMENU holemenuRes, HWND hwndActiveObject) 00238 { 00239 return E_NOTIMPL; 00240 } 00241 00242 HRESULT STDMETHODCALLTYPE CDesktopBrowser::RemoveMenusSB(HMENU hmenuShared) 00243 { 00244 return E_NOTIMPL; 00245 } 00246 00247 HRESULT STDMETHODCALLTYPE CDesktopBrowser::SetStatusTextSB(LPCOLESTR lpszStatusText) 00248 { 00249 return E_NOTIMPL; 00250 } 00251 00252 HRESULT STDMETHODCALLTYPE CDesktopBrowser::EnableModelessSB(BOOL fEnable) 00253 { 00254 return E_NOTIMPL; 00255 } 00256 00257 HRESULT STDMETHODCALLTYPE CDesktopBrowser::TranslateAcceleratorSB(LPMSG lpmsg, WORD wID) 00258 { 00259 return S_FALSE; 00260 } 00261 00262 HRESULT STDMETHODCALLTYPE CDesktopBrowser::BrowseObject(LPCITEMIDLIST pidl, UINT wFlags) 00263 { 00264 return E_NOTIMPL; 00265 } 00266 00267 HRESULT STDMETHODCALLTYPE CDesktopBrowser::GetViewStateStream(DWORD grfMode, IStream **ppStrm) 00268 { 00269 return E_NOTIMPL; 00270 } 00271 00272 HWND CDesktopBrowser::DesktopGetWindowControl(IN UINT id) 00273 { 00274 switch (id) 00275 { 00276 case FCW_TOOLBAR: 00277 case FCW_STATUS: 00278 case FCW_TREE: 00279 case FCW_PROGRESS: 00280 return NULL; 00281 00282 default: 00283 return NULL; 00284 } 00285 00286 } 00287 00288 HRESULT STDMETHODCALLTYPE CDesktopBrowser::GetControlWindow(UINT id, HWND *lphwnd) 00289 { 00290 HWND hWnd; 00291 00292 hWnd = DesktopGetWindowControl(id); 00293 if (hWnd != NULL) 00294 { 00295 *lphwnd = hWnd; 00296 return S_OK; 00297 } 00298 00299 *lphwnd = NULL; 00300 return E_NOTIMPL; 00301 } 00302 00303 HRESULT STDMETHODCALLTYPE CDesktopBrowser::SendControlMsg(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pret) 00304 { 00305 HWND hWnd; 00306 00307 if (pret == NULL) 00308 return E_POINTER; 00309 00310 hWnd = DesktopGetWindowControl(id); 00311 if (hWnd != NULL) 00312 { 00313 *pret = SendMessageW(hWnd, 00314 uMsg, 00315 wParam, 00316 lParam); 00317 return S_OK; 00318 } 00319 00320 return E_NOTIMPL; 00321 } 00322 00323 HRESULT STDMETHODCALLTYPE CDesktopBrowser::QueryActiveShellView(IShellView **ppshv) 00324 { 00325 *ppshv = DesktopView; 00326 if (DesktopView != NULL) 00327 DesktopView->AddRef(); 00328 00329 return S_OK; 00330 } 00331 00332 HRESULT STDMETHODCALLTYPE CDesktopBrowser::OnViewWindowActive(IShellView *ppshv) 00333 { 00334 return E_NOTIMPL; 00335 } 00336 00337 HRESULT STDMETHODCALLTYPE CDesktopBrowser::SetToolbarItems(LPTBBUTTON lpButtons, UINT nButtons, UINT uFlags) 00338 { 00339 return E_NOTIMPL; 00340 } 00341 00342 HRESULT STDMETHODCALLTYPE CDesktopBrowser::OnDefaultCommand(IShellView *ppshv) 00343 { 00344 return E_NOTIMPL; 00345 } 00346 00347 HRESULT STDMETHODCALLTYPE CDesktopBrowser::OnStateChange(IShellView *ppshv, ULONG uChange) 00348 { 00349 return S_OK; 00350 } 00351 00352 HRESULT STDMETHODCALLTYPE CDesktopBrowser::IncludeObject(IShellView *ppshv, LPCITEMIDLIST pidl) 00353 { 00354 return S_OK; 00355 } 00356 00357 HRESULT STDMETHODCALLTYPE CDesktopBrowser::QueryService(REFGUID guidService, REFIID riid, PVOID *ppv) 00358 { 00359 /* FIXME - handle guidService */ 00360 return QueryInterface(riid, ppv); 00361 } 00362 00363 BOOL CDesktopBrowser::MessageLoop() 00364 { 00365 MSG Msg; 00366 BOOL bRet; 00367 00368 while ((bRet = GetMessageW(&Msg, NULL, 0, 0)) != 0) 00369 { 00370 if (bRet != -1) 00371 { 00372 TranslateMessage(&Msg); 00373 DispatchMessageW(&Msg); 00374 } 00375 } 00376 00377 return TRUE; 00378 } 00379 00380 LRESULT CALLBACK CDesktopBrowser::ProgmanWindowProc(IN HWND hwnd, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam) 00381 { 00382 CDesktopBrowser *pThis = NULL; 00383 LRESULT Ret = FALSE; 00384 00385 if (uMsg != WM_NCCREATE) 00386 { 00387 pThis = (CDesktopBrowser*)GetWindowLongPtrW(hwnd, 00388 0); 00389 if (pThis == NULL) 00390 goto DefMsgHandler; 00391 } 00392 00393 if (pThis != NULL || uMsg == WM_NCCREATE) 00394 { 00395 switch (uMsg) 00396 { 00397 case WM_ERASEBKGND: 00398 return (LRESULT)PaintDesktop((HDC)wParam); 00399 00400 case WM_GETISHELLBROWSER: 00401 Ret = (LRESULT)((IShellBrowser *)pThis); 00402 break; 00403 00404 case WM_SIZE: 00405 if (wParam == SIZE_MINIMIZED) 00406 { 00407 /* Hey, we're the desktop!!! */ 00408 ShowWindow(hwnd, 00409 SW_RESTORE); 00410 } 00411 else 00412 { 00413 RECT rcDesktop; 00414 00415 rcDesktop.left = GetSystemMetrics(SM_XVIRTUALSCREEN); 00416 rcDesktop.top = GetSystemMetrics(SM_YVIRTUALSCREEN); 00417 rcDesktop.right = GetSystemMetrics(SM_CXVIRTUALSCREEN); 00418 rcDesktop.bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN); 00419 00420 /* FIXME: Update work area */ 00421 } 00422 break; 00423 00424 case WM_SYSCOLORCHANGE: 00425 case WM_SETTINGCHANGE: 00426 { 00427 if (uMsg == WM_SYSCOLORCHANGE || wParam == SPI_SETDESKWALLPAPER || wParam == 0) 00428 { 00429 if (pThis->hWndShellView != NULL) 00430 { 00431 /* Forward the message */ 00432 SendMessageW(pThis->hWndShellView, 00433 uMsg, 00434 wParam, 00435 lParam); 00436 } 00437 } 00438 break; 00439 } 00440 00441 case WM_CREATE: 00442 { 00443 pThis->ShellDesk->RegisterDesktopWindow(pThis->hWnd); 00444 00445 if (!pThis->CreateDeskWnd()) 00446 WARN("Could not create the desktop view control!\n"); 00447 break; 00448 } 00449 00450 case WM_NCCREATE: 00451 { 00452 LPCREATESTRUCT CreateStruct = (LPCREATESTRUCT)lParam; 00453 pThis = SHDESK_Create(hwnd, CreateStruct); 00454 if (pThis == NULL) 00455 { 00456 WARN("Failed to create desktop structure\n"); 00457 break; 00458 } 00459 00460 SetWindowLongPtrW(hwnd, 00461 0, 00462 (LONG_PTR)pThis); 00463 Ret = TRUE; 00464 break; 00465 } 00466 00467 case WM_NCDESTROY: 00468 { 00469 pThis->Release(); 00470 break; 00471 } 00472 00473 default: 00474 DefMsgHandler: 00475 Ret = DefWindowProcW(hwnd, uMsg, wParam, lParam); 00476 break; 00477 } 00478 } 00479 00480 return Ret; 00481 } 00482 00483 static BOOL 00484 RegisterProgmanWindowClass(VOID) 00485 { 00486 WNDCLASSW wcProgman; 00487 00488 wcProgman.style = CS_DBLCLKS; 00489 wcProgman.lpfnWndProc = CDesktopBrowser::ProgmanWindowProc; 00490 wcProgman.cbClsExtra = 0; 00491 wcProgman.cbWndExtra = sizeof(CDesktopBrowser *); 00492 wcProgman.hInstance = shell32_hInstance; 00493 wcProgman.hIcon = NULL; 00494 wcProgman.hCursor = LoadCursorW(NULL, IDC_ARROW); 00495 wcProgman.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1); 00496 wcProgman.lpszMenuName = NULL; 00497 wcProgman.lpszClassName = szProgmanClassName; 00498 00499 return RegisterClassW(&wcProgman) != 0; 00500 } 00501 00502 00503 /************************************************************************* 00504 * SHCreateDesktop [SHELL32.200] 00505 * 00506 */ 00507 HANDLE WINAPI SHCreateDesktop(IShellDesktopTray *ShellDesk) 00508 { 00509 HWND hWndDesk; 00510 RECT rcDesk; 00511 00512 if (ShellDesk == NULL) 00513 { 00514 SetLastError(ERROR_INVALID_PARAMETER); 00515 return NULL; 00516 } 00517 00518 if (RegisterProgmanWindowClass() == 0) 00519 { 00520 WARN("Failed to register the Progman window class!\n"); 00521 return NULL; 00522 } 00523 00524 rcDesk.left = GetSystemMetrics(SM_XVIRTUALSCREEN); 00525 rcDesk.top = GetSystemMetrics(SM_YVIRTUALSCREEN); 00526 rcDesk.right = rcDesk.left + GetSystemMetrics(SM_CXVIRTUALSCREEN); 00527 rcDesk.bottom = rcDesk.top + GetSystemMetrics(SM_CYVIRTUALSCREEN); 00528 00529 if (IsRectEmpty(&rcDesk)) 00530 { 00531 rcDesk.left = rcDesk.top = 0; 00532 rcDesk.right = GetSystemMetrics(SM_CXSCREEN); 00533 rcDesk.bottom = GetSystemMetrics(SM_CYSCREEN); 00534 } 00535 00536 hWndDesk = CreateWindowExW(0, szProgmanClassName, szProgmanWindowName, 00537 WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 00538 rcDesk.left, rcDesk.top, rcDesk.right, rcDesk.bottom, 00539 NULL, NULL, shell32_hInstance, (LPVOID)ShellDesk); 00540 if (hWndDesk != NULL) 00541 return (HANDLE)GetWindowLongPtrW(hWndDesk, 0); 00542 00543 return NULL; 00544 } 00545 00546 /************************************************************************* 00547 * SHCreateDesktop [SHELL32.201] 00548 * 00549 */ 00550 BOOL WINAPI SHDesktopMessageLoop(HANDLE hDesktop) 00551 { 00552 CDesktopBrowser *Desk = (CDesktopBrowser *)hDesktop; 00553 00554 if (Desk == NULL || Desk->Tag != SHDESK_TAG) 00555 { 00556 SetLastError(ERROR_INVALID_PARAMETER); 00557 return FALSE; 00558 } 00559 00560 return Desk->MessageLoop(); 00561 } Generated on Sat May 26 2012 04:17:27 for ReactOS by
1.7.6.1
|