ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

desktop.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.