mirror of
https://github.com/reactos/reactos.git
synced 2024-08-19 18:02:55 +00:00
780 lines
19 KiB
C
780 lines
19 KiB
C
/*
|
|
* Shell Desktop
|
|
*
|
|
* Copyright 2008 Thomas Bluemel
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
*/
|
|
|
|
#include <precomp.h>
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(desktop);
|
|
|
|
BOOL WINAPI SetShellWindowEx(HWND, HWND);
|
|
|
|
#define SHDESK_TAG 0x4b534544
|
|
|
|
static const WCHAR szProgmanClassName[] = {'P','r','o','g','m','a','n'};
|
|
static const WCHAR szProgmanWindowName[] = {
|
|
'P','r','o','g','r','a','m',' ','M','a','n','a','g','e','r'
|
|
};
|
|
|
|
static const IShellBrowserVtbl SHDESK_Vtbl;
|
|
static const ICommDlgBrowserVtbl SHDESK_ICommDlgBrowser_Vtbl;
|
|
static const IServiceProviderVtbl SHDESK_IServiceProvider_Vtbl;
|
|
|
|
typedef struct _SHDESK
|
|
{
|
|
DWORD Tag;
|
|
const IShellBrowserVtbl *lpVtbl;
|
|
const ICommDlgBrowserVtbl *lpVtblCommDlgBrowser;
|
|
const IServiceProviderVtbl *lpVtblServiceProvider;
|
|
LONG Ref;
|
|
HWND hWnd;
|
|
HWND hWndShellView;
|
|
HWND hWndDesktopListView;
|
|
IShellDesktopTray *ShellDesk;
|
|
IShellView *DesktopView;
|
|
IShellBrowser *DefaultShellBrowser;
|
|
LPITEMIDLIST pidlDesktopDirectory;
|
|
LPITEMIDLIST pidlDesktop;
|
|
} SHDESK, *PSHDESK;
|
|
|
|
static IUnknown *
|
|
IUnknown_from_impl(SHDESK *This)
|
|
{
|
|
return (IUnknown *)&This->lpVtbl;
|
|
}
|
|
|
|
static IShellBrowser *
|
|
IShellBrowser_from_impl(SHDESK *This)
|
|
{
|
|
return (IShellBrowser *)&This->lpVtbl;
|
|
}
|
|
|
|
static IOleWindow *
|
|
IOleWindow_from_impl(SHDESK *This)
|
|
{
|
|
return (IOleWindow *)&This->lpVtbl;
|
|
}
|
|
|
|
static ICommDlgBrowser *
|
|
ICommDlgBrowser_from_impl(SHDESK *This)
|
|
{
|
|
return (ICommDlgBrowser *)&This->lpVtblCommDlgBrowser;
|
|
}
|
|
|
|
static IServiceProvider *
|
|
IServiceProvider_from_impl(SHDESK *This)
|
|
{
|
|
return (IServiceProvider *)&This->lpVtblServiceProvider;
|
|
}
|
|
|
|
static SHDESK *
|
|
impl_from_IShellBrowser(IShellBrowser *iface)
|
|
{
|
|
return (SHDESK *)((ULONG_PTR)iface - FIELD_OFFSET(SHDESK, lpVtbl));
|
|
}
|
|
|
|
static SHDESK *
|
|
impl_from_ICommDlgBrowser(ICommDlgBrowser *iface)
|
|
{
|
|
return (SHDESK *)((ULONG_PTR)iface - FIELD_OFFSET(SHDESK, lpVtblCommDlgBrowser));
|
|
}
|
|
|
|
static SHDESK *
|
|
impl_from_IServiceProvider(IServiceProvider *iface)
|
|
{
|
|
return (SHDESK *)((ULONG_PTR)iface - FIELD_OFFSET(SHDESK, lpVtblServiceProvider));
|
|
}
|
|
|
|
static void
|
|
SHDESK_Free(SHDESK *This)
|
|
{
|
|
if (This->ShellDesk != NULL)
|
|
IShellDesktopTray_Release(This->ShellDesk);
|
|
|
|
if (This->DesktopView != NULL)
|
|
{
|
|
if (This->hWndShellView != NULL)
|
|
IShellView_DestroyViewWindow(This->DesktopView);
|
|
|
|
IShellView_Release(This->DesktopView);
|
|
This->DesktopView = NULL;
|
|
This->hWndShellView = NULL;
|
|
This->hWndDesktopListView = NULL;
|
|
}
|
|
|
|
if (This->pidlDesktopDirectory != NULL)
|
|
{
|
|
ILFree(This->pidlDesktopDirectory);
|
|
This->pidlDesktopDirectory = NULL;
|
|
}
|
|
|
|
if (This->pidlDesktop != NULL)
|
|
{
|
|
ILFree(This->pidlDesktop);
|
|
This->pidlDesktop = NULL;
|
|
}
|
|
|
|
ZeroMemory(This, sizeof(SHDESK));
|
|
LocalFree((HLOCAL)This);
|
|
}
|
|
|
|
static ULONG STDMETHODCALLTYPE
|
|
SHDESK_Release(IShellBrowser *iface)
|
|
{
|
|
SHDESK *This = impl_from_IShellBrowser(iface);
|
|
ULONG Ret;
|
|
|
|
Ret = InterlockedDecrement(&This->Ref);
|
|
if (Ret == 0)
|
|
SHDESK_Free(This);
|
|
|
|
return Ret;
|
|
}
|
|
|
|
static ULONG STDMETHODCALLTYPE
|
|
SHDESK_AddRef(IShellBrowser *iface)
|
|
{
|
|
SHDESK *This = impl_from_IShellBrowser(iface);
|
|
|
|
return InterlockedIncrement(&This->Ref);
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE
|
|
SHDESK_QueryInterface(IShellBrowser *iface, REFIID riid, LPVOID *ppvObj)
|
|
{
|
|
SHDESK *This;
|
|
|
|
if (ppvObj == NULL)
|
|
return E_POINTER;
|
|
|
|
This = impl_from_IShellBrowser(iface);
|
|
|
|
if (IsEqualIID(riid, &IID_IUnknown))
|
|
{
|
|
*ppvObj = IUnknown_from_impl(This);
|
|
}
|
|
else if (This->DefaultShellBrowser != NULL)
|
|
{
|
|
return IShellBrowser_QueryInterface(This->DefaultShellBrowser, riid, ppvObj);
|
|
}
|
|
else if (IsEqualIID(riid, &IID_IOleWindow))
|
|
{
|
|
*ppvObj = IOleWindow_from_impl(This);
|
|
}
|
|
else if (IsEqualIID(riid, &IID_IShellBrowser))
|
|
{
|
|
*ppvObj = IShellBrowser_from_impl(This);
|
|
}
|
|
else if (IsEqualIID(riid, &IID_ICommDlgBrowser))
|
|
{
|
|
*ppvObj = ICommDlgBrowser_from_impl(This);
|
|
}
|
|
else if (IsEqualIID(riid, &IID_IServiceProvider))
|
|
{
|
|
*ppvObj = IServiceProvider_from_impl(This);
|
|
}
|
|
else
|
|
{
|
|
*ppvObj = NULL;
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
SHDESK_AddRef(iface);
|
|
return S_OK;
|
|
}
|
|
|
|
static PSHDESK
|
|
SHDESK_Create(HWND hWnd, LPCREATESTRUCT lpCreateStruct)
|
|
{
|
|
IShellFolder *psfDesktopFolder;
|
|
IShellDesktopTray *ShellDesk;
|
|
CSFV csfv;
|
|
SHDESK *This;
|
|
HRESULT hRet;
|
|
|
|
ShellDesk = (IShellDesktopTray *)lpCreateStruct->lpCreateParams;
|
|
if (ShellDesk == NULL)
|
|
{
|
|
WARN("No IShellDesk interface provided!");
|
|
return NULL;
|
|
}
|
|
|
|
This = (PSHDESK)LocalAlloc(LMEM_FIXED, sizeof(SHDESK));
|
|
if (This == NULL)
|
|
return NULL;
|
|
|
|
ZeroMemory(This, sizeof(SHDESK));
|
|
This->Tag = SHDESK_TAG;
|
|
This->lpVtbl = &SHDESK_Vtbl;
|
|
This->lpVtblCommDlgBrowser = &SHDESK_ICommDlgBrowser_Vtbl;
|
|
This->lpVtblServiceProvider = &SHDESK_IServiceProvider_Vtbl;
|
|
This->Ref = 1;
|
|
This->hWnd = hWnd;
|
|
This->ShellDesk = ShellDesk;
|
|
IShellDesktopTray_AddRef(ShellDesk);
|
|
|
|
This->pidlDesktopDirectory = SHCloneSpecialIDList(This->hWnd, CSIDL_DESKTOPDIRECTORY, FALSE);
|
|
hRet = SHGetSpecialFolderLocation(This->hWnd, CSIDL_DESKTOP, &This->pidlDesktop);
|
|
if (!SUCCEEDED(hRet))
|
|
goto Fail;
|
|
|
|
hRet = SHGetDesktopFolder(&psfDesktopFolder);
|
|
if (!SUCCEEDED(hRet))
|
|
goto Fail;
|
|
|
|
ZeroMemory(&csfv, sizeof(csfv));
|
|
csfv.cbSize = sizeof(csfv);
|
|
csfv.pshf = psfDesktopFolder;
|
|
csfv.psvOuter = NULL;
|
|
|
|
hRet = SHCreateShellFolderViewEx(&csfv, &This->DesktopView);
|
|
IShellFolder_Release(psfDesktopFolder);
|
|
|
|
if (!SUCCEEDED(hRet))
|
|
{
|
|
Fail:
|
|
SHDESK_Release(IShellBrowser_from_impl(This));
|
|
return NULL;
|
|
}
|
|
|
|
return This;
|
|
}
|
|
|
|
static HWND
|
|
SHDESK_FindDesktopListView (SHDESK *This)
|
|
{
|
|
return FindWindowExW(This->hWndShellView,
|
|
NULL,
|
|
WC_LISTVIEW,
|
|
NULL);
|
|
}
|
|
|
|
static BOOL
|
|
SHDESK_CreateDeskWnd(SHDESK *This)
|
|
{
|
|
IShellBrowser *ShellBrowser;
|
|
FOLDERSETTINGS fs;
|
|
RECT rcClient;
|
|
HRESULT hRet;
|
|
|
|
if (!GetClientRect(This->hWnd,
|
|
&rcClient))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
ShellBrowser = IShellBrowser_from_impl(This);
|
|
|
|
fs.ViewMode = FVM_ICON;
|
|
fs.fFlags = FWF_DESKTOP | FWF_NOCLIENTEDGE | FWF_NOSCROLL | FWF_TRANSPARENT;
|
|
hRet = IShellView_CreateViewWindow(This->DesktopView, NULL, &fs, ShellBrowser, &rcClient, &This->hWndShellView);
|
|
if (!SUCCEEDED(hRet))
|
|
return FALSE;
|
|
|
|
SetShellWindowEx (This->hWnd,
|
|
SHDESK_FindDesktopListView (This));
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE
|
|
SHDESK_GetWindow(IShellBrowser *iface, HWND *phwnd)
|
|
{
|
|
SHDESK *This = impl_from_IShellBrowser(iface);
|
|
|
|
if (This->hWnd != NULL)
|
|
{
|
|
*phwnd = This->hWnd;
|
|
return S_OK;
|
|
}
|
|
|
|
*phwnd = NULL;
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE
|
|
SHDESK_ContextSensitiveHelp(IShellBrowser *iface, BOOL fEnterMode)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE
|
|
SHDESK_InsertMenusSB(IShellBrowser *iface, HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE
|
|
SHDESK_SetMenuSB(IShellBrowser *iface, HMENU hmenuShared, HOLEMENU holemenuRes, HWND hwndActiveObject)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE
|
|
SHDESK_RemoveMenusSB(IShellBrowser *iface, HMENU hmenuShared)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE
|
|
SHDESK_SetStatusTextSB(IShellBrowser *iface, LPCOLESTR lpszStatusText)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE
|
|
SHDESK_EnableModelessSB(IShellBrowser *iface, BOOL fEnable)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE
|
|
SHDESK_TranslateAcceleratorSB(IShellBrowser *iface, LPMSG lpmsg, WORD wID)
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE
|
|
SHDESK_BrowseObject(IShellBrowser *iface, LPCITEMIDLIST pidl, UINT wFlags)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE
|
|
SHDESK_GetViewStateStream(IShellBrowser *iface, DWORD grfMode, IStream **ppStrm)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HWND
|
|
DesktopGetWindowControl(IN SHDESK *This,
|
|
IN UINT id)
|
|
{
|
|
switch (id)
|
|
{
|
|
case FCW_TOOLBAR:
|
|
case FCW_STATUS:
|
|
case FCW_TREE:
|
|
case FCW_PROGRESS:
|
|
return NULL;
|
|
|
|
default:
|
|
return NULL;
|
|
}
|
|
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE
|
|
SHDESK_GetControlWindow(IShellBrowser *iface, UINT id, HWND *lphwnd)
|
|
{
|
|
SHDESK *This = impl_from_IShellBrowser(iface);
|
|
HWND hWnd;
|
|
|
|
hWnd = DesktopGetWindowControl(This,
|
|
id);
|
|
if (hWnd != NULL)
|
|
{
|
|
*lphwnd = hWnd;
|
|
return S_OK;
|
|
}
|
|
|
|
*lphwnd = NULL;
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE
|
|
SHDESK_SendControlMsg(IShellBrowser *iface, UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pret)
|
|
{
|
|
SHDESK *This = impl_from_IShellBrowser(iface);
|
|
HWND hWnd;
|
|
|
|
if (pret == NULL)
|
|
return E_POINTER;
|
|
|
|
hWnd = DesktopGetWindowControl(This,
|
|
id);
|
|
if (hWnd != NULL)
|
|
{
|
|
*pret = SendMessageW(hWnd,
|
|
uMsg,
|
|
wParam,
|
|
lParam);
|
|
return S_OK;
|
|
}
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE
|
|
SHDESK_QueryActiveShellView(IShellBrowser *iface, IShellView **ppshv)
|
|
{
|
|
IShellView *ActiveView;
|
|
SHDESK *This = impl_from_IShellBrowser(iface);
|
|
|
|
ActiveView = This->DesktopView;
|
|
SHDESK_AddRef(iface);
|
|
*ppshv = ActiveView;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE
|
|
SHDESK_OnViewWindowActive(IShellBrowser *iface, IShellView *ppshv)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE
|
|
SHDESK_SetToolbarItems(IShellBrowser *iface, LPTBBUTTON lpButtons, UINT nButtons, UINT uFlags)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE
|
|
SHDESK_ICommDlgBrowser_QueryInterface(ICommDlgBrowser *iface, REFIID riid, LPVOID *ppvObj)
|
|
{
|
|
SHDESK *This = impl_from_ICommDlgBrowser(iface);
|
|
IShellBrowser *ShellBrowser = IShellBrowser_from_impl(This);
|
|
|
|
return SHDESK_QueryInterface(ShellBrowser, riid, ppvObj);
|
|
}
|
|
|
|
static ULONG STDMETHODCALLTYPE
|
|
SHDESK_ICommDlgBrowser_Release(ICommDlgBrowser *iface)
|
|
{
|
|
SHDESK *This = impl_from_ICommDlgBrowser(iface);
|
|
IShellBrowser *ShellBrowser = IShellBrowser_from_impl(This);
|
|
|
|
return SHDESK_Release(ShellBrowser);
|
|
}
|
|
|
|
static ULONG STDMETHODCALLTYPE
|
|
SHDESK_ICommDlgBrowser_AddRef(ICommDlgBrowser *iface)
|
|
{
|
|
SHDESK *This = impl_from_ICommDlgBrowser(iface);
|
|
IShellBrowser *ShellBrowser = IShellBrowser_from_impl(This);
|
|
|
|
return SHDESK_AddRef(ShellBrowser);
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE
|
|
SHDESK_ICommDlgBrowser_OnDefaultCommand(ICommDlgBrowser *iface, IShellView *ppshv)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE
|
|
SHDESK_ICommDlgBrowser_OnStateChange(ICommDlgBrowser *iface, IShellView *ppshv, ULONG uChange)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE
|
|
SHDESK_ICommDlgBrowser_IncludeObject(ICommDlgBrowser *iface, IShellView *ppshv, LPCITEMIDLIST pidl)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
static const ICommDlgBrowserVtbl SHDESK_ICommDlgBrowser_Vtbl =
|
|
{
|
|
/* IUnknown */
|
|
SHDESK_ICommDlgBrowser_QueryInterface,
|
|
SHDESK_ICommDlgBrowser_AddRef,
|
|
SHDESK_ICommDlgBrowser_Release,
|
|
/* ICommDlgBrowser */
|
|
SHDESK_ICommDlgBrowser_OnDefaultCommand,
|
|
SHDESK_ICommDlgBrowser_OnStateChange,
|
|
SHDESK_ICommDlgBrowser_IncludeObject
|
|
};
|
|
|
|
static HRESULT STDMETHODCALLTYPE
|
|
SHDESK_IServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, LPVOID *ppvObj)
|
|
{
|
|
SHDESK *This = impl_from_IServiceProvider(iface);
|
|
IShellBrowser *ShellBrowser = IShellBrowser_from_impl(This);
|
|
|
|
return SHDESK_QueryInterface(ShellBrowser, riid, ppvObj);
|
|
}
|
|
|
|
static ULONG STDMETHODCALLTYPE
|
|
SHDESK_IServiceProvider_Release(IServiceProvider *iface)
|
|
{
|
|
SHDESK *This = impl_from_IServiceProvider(iface);
|
|
IShellBrowser *ShellBrowser = IShellBrowser_from_impl(This);
|
|
|
|
return SHDESK_Release(ShellBrowser);
|
|
}
|
|
|
|
static ULONG STDMETHODCALLTYPE
|
|
SHDESK_IServiceProvider_AddRef(IServiceProvider *iface)
|
|
{
|
|
SHDESK *This = impl_from_IServiceProvider(iface);
|
|
IShellBrowser *ShellBrowser = IShellBrowser_from_impl(This);
|
|
|
|
return SHDESK_AddRef(ShellBrowser);
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE
|
|
SHDESK_IServiceProvider_QueryService(IServiceProvider *iface, REFGUID guidService, REFIID riid, PVOID *ppv)
|
|
{
|
|
/* FIXME - handle guidService */
|
|
return SHDESK_IServiceProvider_QueryInterface(iface, riid, ppv);
|
|
}
|
|
|
|
static const IServiceProviderVtbl SHDESK_IServiceProvider_Vtbl =
|
|
{
|
|
/* IUnknown */
|
|
SHDESK_IServiceProvider_QueryInterface,
|
|
SHDESK_IServiceProvider_AddRef,
|
|
SHDESK_IServiceProvider_Release,
|
|
/* IServiceProvider */
|
|
SHDESK_IServiceProvider_QueryService
|
|
};
|
|
|
|
static BOOL
|
|
SHDESK_MessageLoop(SHDESK *This)
|
|
{
|
|
MSG Msg;
|
|
BOOL bRet;
|
|
|
|
while ((bRet = GetMessageW(&Msg, NULL, 0, 0)) != 0)
|
|
{
|
|
if (bRet != -1)
|
|
{
|
|
TranslateMessage(&Msg);
|
|
DispatchMessageW(&Msg);
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static LRESULT CALLBACK
|
|
ProgmanWindowProc(IN HWND hwnd,
|
|
IN UINT uMsg,
|
|
IN WPARAM wParam,
|
|
IN LPARAM lParam)
|
|
{
|
|
SHDESK *This = NULL;
|
|
LRESULT Ret = FALSE;
|
|
|
|
if (uMsg != WM_NCCREATE)
|
|
{
|
|
This = (SHDESK*)GetWindowLongPtrW(hwnd,
|
|
0);
|
|
if (This == NULL)
|
|
goto DefMsgHandler;
|
|
}
|
|
|
|
if (This != NULL || uMsg == WM_NCCREATE)
|
|
{
|
|
switch (uMsg)
|
|
{
|
|
case WM_ERASEBKGND:
|
|
return (LRESULT)PaintDesktop((HDC)wParam);
|
|
|
|
case WM_GETISHELLBROWSER:
|
|
Ret = (LRESULT)IShellBrowser_from_impl(This);
|
|
break;
|
|
|
|
case WM_SIZE:
|
|
if (wParam == SIZE_MINIMIZED)
|
|
{
|
|
/* Hey, we're the desktop!!! */
|
|
ShowWindow(hwnd,
|
|
SW_RESTORE);
|
|
}
|
|
else
|
|
{
|
|
RECT rcDesktop;
|
|
|
|
rcDesktop.left = GetSystemMetrics(SM_XVIRTUALSCREEN);
|
|
rcDesktop.top = GetSystemMetrics(SM_YVIRTUALSCREEN);
|
|
rcDesktop.right = GetSystemMetrics(SM_CXVIRTUALSCREEN);
|
|
rcDesktop.bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN);
|
|
|
|
/* FIXME: Update work area */
|
|
}
|
|
break;
|
|
|
|
case WM_SYSCOLORCHANGE:
|
|
{
|
|
InvalidateRect(This->hWnd,
|
|
NULL,
|
|
TRUE);
|
|
|
|
if (This->hWndShellView != NULL)
|
|
{
|
|
/* Forward the message */
|
|
SendMessageW(This->hWndShellView,
|
|
WM_SYSCOLORCHANGE,
|
|
wParam,
|
|
lParam);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case WM_CREATE:
|
|
{
|
|
IShellDesktopTray_RegisterDesktopWindow(This->ShellDesk,
|
|
This->hWnd);
|
|
|
|
if (!SHDESK_CreateDeskWnd(This))
|
|
WARN("Could not create the desktop view control!\n");
|
|
break;
|
|
}
|
|
|
|
case WM_NCCREATE:
|
|
{
|
|
LPCREATESTRUCT CreateStruct = (LPCREATESTRUCT)lParam;
|
|
This = SHDESK_Create(hwnd, CreateStruct);
|
|
if (This == NULL)
|
|
{
|
|
WARN("Failed to create desktop structure\n");
|
|
break;
|
|
}
|
|
|
|
SetWindowLongPtrW(hwnd,
|
|
0,
|
|
(LONG_PTR)This);
|
|
Ret = TRUE;
|
|
break;
|
|
}
|
|
|
|
case WM_NCDESTROY:
|
|
{
|
|
SHDESK_Free(This);
|
|
break;
|
|
}
|
|
|
|
default:
|
|
DefMsgHandler:
|
|
Ret = DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return Ret;
|
|
}
|
|
|
|
static BOOL
|
|
RegisterProgmanWindowClass(VOID)
|
|
{
|
|
WNDCLASSW wcProgman;
|
|
|
|
wcProgman.style = CS_DBLCLKS;
|
|
wcProgman.lpfnWndProc = ProgmanWindowProc;
|
|
wcProgman.cbClsExtra = 0;
|
|
wcProgman.cbWndExtra = sizeof(PSHDESK);
|
|
wcProgman.hInstance = shell32_hInstance;
|
|
wcProgman.hIcon = NULL;
|
|
wcProgman.hCursor = LoadCursorW(NULL,
|
|
IDC_ARROW);
|
|
wcProgman.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
|
|
wcProgman.lpszMenuName = NULL;
|
|
wcProgman.lpszClassName = szProgmanClassName;
|
|
|
|
return RegisterClassW(&wcProgman) != 0;
|
|
}
|
|
|
|
|
|
/*************************************************************************
|
|
* SHCreateDesktop [SHELL32.200]
|
|
*
|
|
*/
|
|
HANDLE WINAPI SHCreateDesktop(IShellDesktopTray *ShellDesk)
|
|
{
|
|
HWND hWndDesk;
|
|
RECT rcDesk;
|
|
|
|
if (ShellDesk == NULL)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return NULL;
|
|
}
|
|
|
|
if (RegisterProgmanWindowClass() == 0)
|
|
{
|
|
WARN("Failed to register the Progman window class!\n");
|
|
return NULL;
|
|
}
|
|
|
|
rcDesk.left = GetSystemMetrics(SM_XVIRTUALSCREEN);
|
|
rcDesk.top = GetSystemMetrics(SM_YVIRTUALSCREEN);
|
|
rcDesk.right = rcDesk.left + GetSystemMetrics(SM_CXVIRTUALSCREEN);
|
|
rcDesk.bottom = rcDesk.top + GetSystemMetrics(SM_CYVIRTUALSCREEN);
|
|
|
|
if (IsRectEmpty(&rcDesk))
|
|
{
|
|
rcDesk.left = rcDesk.top = 0;
|
|
rcDesk.right = GetSystemMetrics(SM_CXSCREEN);
|
|
rcDesk.bottom = GetSystemMetrics(SM_CYSCREEN);
|
|
}
|
|
|
|
hWndDesk = CreateWindowExW(0, szProgmanClassName, szProgmanWindowName,
|
|
WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
|
|
rcDesk.left, rcDesk.top, rcDesk.right, rcDesk.bottom,
|
|
NULL, NULL, shell32_hInstance, (LPVOID)ShellDesk);
|
|
if (hWndDesk != NULL)
|
|
return (HANDLE)GetWindowLongPtrW(hWndDesk, 0);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/*************************************************************************
|
|
* SHCreateDesktop [SHELL32.201]
|
|
*
|
|
*/
|
|
BOOL WINAPI SHDesktopMessageLoop(HANDLE hDesktop)
|
|
{
|
|
PSHDESK Desk = (PSHDESK)hDesktop;
|
|
|
|
if (Desk == NULL || Desk->Tag != SHDESK_TAG)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
return SHDESK_MessageLoop(Desk);
|
|
}
|
|
|
|
static const IShellBrowserVtbl SHDESK_Vtbl =
|
|
{
|
|
/* IUnknown */
|
|
SHDESK_QueryInterface,
|
|
SHDESK_AddRef,
|
|
SHDESK_Release,
|
|
/* IOleWindow */
|
|
SHDESK_GetWindow,
|
|
SHDESK_ContextSensitiveHelp,
|
|
/* IShellBrowser */
|
|
SHDESK_InsertMenusSB,
|
|
SHDESK_SetMenuSB,
|
|
SHDESK_RemoveMenusSB,
|
|
SHDESK_SetStatusTextSB,
|
|
SHDESK_EnableModelessSB,
|
|
SHDESK_TranslateAcceleratorSB,
|
|
SHDESK_BrowseObject,
|
|
SHDESK_GetViewStateStream,
|
|
SHDESK_GetControlWindow,
|
|
SHDESK_SendControlMsg,
|
|
SHDESK_QueryActiveShellView,
|
|
SHDESK_OnViewWindowActive,
|
|
SHDESK_SetToolbarItems
|
|
};
|