📄 desktop.c
字号:
/*
* ReactOS Explorer
*
* Copyright 2006 - 2007 Thomas Weidenmueller <w3seek@reactos.org>
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <precomp.h>
#if USE_API_SHCREATEDESKTOP
typedef struct _DESKCREATEINFO
{
HANDLE hEvent;
ITrayWindow *Tray;
HANDLE hDesktop;
} DESKCREATEINFO, *PDESKCREATEINFO;
static DWORD CALLBACK
DesktopThreadProc(IN OUT LPVOID lpParameter)
{
volatile DESKCREATEINFO *DeskCreateInfo = (volatile DESKCREATEINFO *)lpParameter;
IShellDesktopTray *pSdt;
HANDLE hDesktop;
HRESULT hRet;
hRet = ITrayWindow_QueryInterface(DeskCreateInfo->Tray,
&IID_IShellDesktopTray,
(PVOID*)&pSdt);
if (!SUCCEEDED(hRet))
return 1;
hDesktop = SHCreateDesktop(pSdt);
IShellDesktopTray_Release(pSdt);
if (hDesktop == NULL)
return 1;
(void)InterlockedExchangePointer(&DeskCreateInfo->hDesktop,
hDesktop);
if (!SetEvent(DeskCreateInfo->hEvent))
{
/* Failed to notify that we initialized successfully, kill ourselves
to make the main thread wake up! */
return 1;
}
SHDesktopMessageLoop(hDesktop);
/* FIXME: Properly rundown the main thread! */
ExitProcess(0);
return 0;
}
HANDLE
DesktopCreateWindow(IN OUT ITrayWindow *Tray)
{
HANDLE hThread;
HANDLE hEvent;
DWORD DesktopThreadId;
HANDLE hDesktop = NULL;
HANDLE Handles[2];
DWORD WaitResult;
hEvent = CreateEvent(NULL,
FALSE,
FALSE,
NULL);
if (hEvent != NULL)
{
volatile DESKCREATEINFO DeskCreateInfo;
DeskCreateInfo.hEvent = hEvent;
DeskCreateInfo.Tray = Tray;
DeskCreateInfo.hDesktop = NULL;
hThread = CreateThread(NULL,
0,
DesktopThreadProc,
(PVOID)&DeskCreateInfo,
0,
&DesktopThreadId);
if (hThread != NULL)
{
Handles[0] = hThread;
Handles[1] = hEvent;
for (;;)
{
WaitResult = MsgWaitForMultipleObjects(sizeof(Handles) / sizeof(Handles[0]),
Handles,
FALSE,
INFINITE,
QS_ALLEVENTS);
if (WaitResult == WAIT_OBJECT_0 + (sizeof(Handles) / sizeof(Handles[0])))
TrayProcessMessages(Tray);
else if (WaitResult != WAIT_FAILED && WaitResult != WAIT_OBJECT_0)
{
hDesktop = DeskCreateInfo.hDesktop;
break;
}
}
CloseHandle(hThread);
}
CloseHandle(hEvent);
}
return hDesktop;
}
VOID
DesktopDestroyShellWindow(IN HANDLE hDesktop)
{
return;
}
#else /* USE_API_SHCREATEDESKTOP == 0 */
/*
******************************************************************************
* NOTE: This could may be reused in a shell implementation of *
* SHCreateDesktop(). *
******************************************************************************
*/
#define WM_SHELL_ADDDRIVENOTIFY (WM_USER + 0x100)
static const IShellBrowserVtbl IDesktopShellBrowserImpl_Vtbl;
static const ICommDlgBrowserVtbl IDesktopShellBrowserImpl_ICommDlgBrowser_Vtbl;
static const IServiceProviderVtbl IDesktopShellBrowserImpl_IServiceProvider_Vtbl;
static const IShellFolderViewCBVtbl IDesktopShellBrowserImpl_IShellFolderViewCB_Vtbl;
/*
* IShellBrowser
*/
typedef struct
{
const IShellBrowserVtbl *lpVtbl;
const ICommDlgBrowserVtbl *lpVtblCommDlgBrowser;
const IServiceProviderVtbl *lpVtblServiceProvider;
const IShellFolderViewCBVtbl *lpVtblShellFolderViewCB;
LONG Ref;
IShellView2 *DesktopView2;
IShellView *DesktopView;
IShellBrowser *DefaultShellBrowser;
HWND hWnd;
HWND hWndShellView;
HWND hWndDesktopListView;
ITrayWindow *Tray;
LPITEMIDLIST pidlDesktopDirectory;
LPITEMIDLIST pidlDesktop;
IDropTarget *DropTarget;
ULONG ChangeNotificationId;
} IDesktopShellBrowserImpl;
static IUnknown *
IUnknown_from_impl(IDesktopShellBrowserImpl *This)
{
return (IUnknown *)&This->lpVtbl;
}
static IShellBrowser *
IShellBrowser_from_impl(IDesktopShellBrowserImpl *This)
{
return (IShellBrowser *)&This->lpVtbl;
}
static IOleWindow *
IOleWindow_from_impl(IDesktopShellBrowserImpl *This)
{
return (IOleWindow *)&This->lpVtbl;
}
static ICommDlgBrowser *
ICommDlgBrowser_from_impl(IDesktopShellBrowserImpl *This)
{
return (ICommDlgBrowser *)&This->lpVtblCommDlgBrowser;
}
static IServiceProvider *
IServiceProvider_from_impl(IDesktopShellBrowserImpl *This)
{
return (IServiceProvider *)&This->lpVtblServiceProvider;
}
static IShellFolderViewCB *
IShellFolderViewCB_from_impl(IDesktopShellBrowserImpl *This)
{
return (IShellFolderViewCB *)&This->lpVtblShellFolderViewCB;
}
static IDesktopShellBrowserImpl *
impl_from_IShellBrowser(IShellBrowser *iface)
{
return (IDesktopShellBrowserImpl *)((ULONG_PTR)iface - FIELD_OFFSET(IDesktopShellBrowserImpl,
lpVtbl));
}
static IDesktopShellBrowserImpl *
impl_from_ICommDlgBrowser(ICommDlgBrowser *iface)
{
return (IDesktopShellBrowserImpl *)((ULONG_PTR)iface - FIELD_OFFSET(IDesktopShellBrowserImpl,
lpVtblCommDlgBrowser));
}
static IDesktopShellBrowserImpl *
impl_from_IServiceProvider(IServiceProvider *iface)
{
return (IDesktopShellBrowserImpl *)((ULONG_PTR)iface - FIELD_OFFSET(IDesktopShellBrowserImpl,
lpVtblServiceProvider));
}
static IDesktopShellBrowserImpl *
impl_from_IShellFolderViewCB(IShellFolderViewCB *iface)
{
return (IDesktopShellBrowserImpl *)((ULONG_PTR)iface - FIELD_OFFSET(IDesktopShellBrowserImpl,
lpVtblShellFolderViewCB));
}
static VOID
IDesktopShellBrowserImpl_Free(IDesktopShellBrowserImpl *This)
{
if (This->DropTarget != NULL)
{
IDropTarget_Release(This->DropTarget);
This->DropTarget = NULL;
}
if (This->Tray != NULL)
{
ITrayWindow_Release(This->Tray);
This->Tray = NULL;
}
if (This->pidlDesktopDirectory != NULL)
{
ILFree(This->pidlDesktopDirectory);
This->pidlDesktopDirectory = NULL;
}
if (This->pidlDesktop != NULL)
{
ILFree(This->pidlDesktop);
This->pidlDesktop = NULL;
}
HeapFree(hProcessHeap,
0,
This);
}
static VOID
IDesktopShellBrowserImpl_Destroy(IDesktopShellBrowserImpl *This)
{
if (This->ChangeNotificationId != 0)
{
SHChangeNotifyDeregister(This->ChangeNotificationId);
This->ChangeNotificationId = 0;
}
if (This->Tray != NULL)
{
ITrayWindow_Close(This->Tray);
This->Tray = NULL;
}
if (This->DropTarget != NULL && This->hWndDesktopListView != NULL)
{
RevokeDragDrop(This->hWndDesktopListView);
This->hWndDesktopListView = NULL;
}
if (This->DesktopView2 != NULL)
{
IShellView2_Release(This->DesktopView2);
}
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;
}
}
static HRESULT
IDesktopShellBrowserImpl_GetNotify(IN OUT IDesktopShellBrowserImpl *This,
OUT LPITEMIDLIST *ppidl,
OUT LONG *plEvents)
{
*ppidl = This->pidlDesktopDirectory;
*plEvents = SHCNE_DISKEVENTS;
return S_OK;
}
static ULONG STDMETHODCALLTYPE
IDesktopShellBrowserImpl_Release(IN OUT IShellBrowser *iface)
{
IDesktopShellBrowserImpl *This = impl_from_IShellBrowser(iface);
ULONG Ret;
Ret = InterlockedDecrement(&This->Ref);
if (Ret == 0)
IDesktopShellBrowserImpl_Free(This);
return Ret;
}
static ULONG STDMETHODCALLTYPE
IDesktopShellBrowserImpl_AddRef(IN OUT IShellBrowser *iface)
{
IDesktopShellBrowserImpl *This = impl_from_IShellBrowser(iface);
return InterlockedIncrement(&This->Ref);
}
static HRESULT STDMETHODCALLTYPE
IDesktopShellBrowserImpl_QueryInterface(IN OUT IShellBrowser *iface,
IN REFIID riid,
OUT LPVOID *ppvObj)
{
IDesktopShellBrowserImpl *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 if (IsEqualIID(riid,
&IID_IShellFolderViewCB))
{
*ppvObj = IShellFolderViewCB_from_impl(This);
}
else
{
*ppvObj = NULL;
return E_NOINTERFACE;
}
IDesktopShellBrowserImpl_AddRef(iface);
return S_OK;
}
static IDesktopShellBrowserImpl *
IDesktopShellBrowserImpl_Construct(IN HWND hwndParent,
IN LPCREATESTRUCT lpCreateStruct OPTIONAL)
{
IDesktopShellBrowserImpl *This;
IShellBrowser *ShellBrowser;
IShellFolder *psfDesktopFolder;
#if 1
SFV_CREATE csfv;
#endif
FOLDERSETTINGS fs;
HRESULT hr;
RECT rcClient;
SHChangeNotifyEntry cne;
This = HeapAlloc(hProcessHeap,
0,
sizeof(*This));
if (This == NULL)
return NULL;
ZeroMemory(This,
sizeof(*This));
This->lpVtbl = &IDesktopShellBrowserImpl_Vtbl;
This->lpVtblCommDlgBrowser = &IDesktopShellBrowserImpl_ICommDlgBrowser_Vtbl;
This->lpVtblServiceProvider = &IDesktopShellBrowserImpl_IServiceProvider_Vtbl;
This->lpVtblShellFolderViewCB = &IDesktopShellBrowserImpl_IShellFolderViewCB_Vtbl;
This->Ref = 1;
This->hWnd = hwndParent;
ShellBrowser = IShellBrowser_from_impl(This);
This->pidlDesktopDirectory = SHCloneSpecialIDList(This->hWnd,
CSIDL_DESKTOPDIRECTORY,
FALSE);
hr = SHGetSpecialFolderLocation(This->hWnd,
CSIDL_DESKTOP,
&This->pidlDesktop);
if (!SUCCEEDED(hr))
goto Fail;
#if 1
hr = SHGetDesktopFolder(&psfDesktopFolder);
#else
hr = CoCreateInstance(&CLSID_ShellDesktop,
NULL,
CLSCTX_INPROC,
&IID_IShellFolder,
(PVOID*)&psfDesktopFolder);
#endif
if (!SUCCEEDED(hr))
goto Fail;
#if 0
hr = IShellFolder_CreateViewObject(psfDesktopFolder,
This->hWnd,
&IID_IShellView,
(PVOID*)&This->DesktopView);
#else
csfv.cbSize = sizeof(csfv);
csfv.pshf = psfDesktopFolder;
csfv.psvOuter = NULL;
hr = IDesktopShellBrowserImpl_QueryInterface(ShellBrowser,
&IID_IShellFolderViewCB,
(PVOID*)&csfv.psfvcb);
if (!SUCCEEDED(hr))
csfv.psfvcb = NULL;
hr = SHCreateShellFolderView(&csfv,
&This->DesktopView);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -