📄 desktop.c
字号:
IN REFIID riid,
OUT PVOID *ppv)
{
/* FIXME - handle guidService */
return IDesktopShellBrowserImpl_IServiceProvider_QueryInterface(iface,
riid,
ppv);
}
static const IServiceProviderVtbl IDesktopShellBrowserImpl_IServiceProvider_Vtbl =
{
/* IUnknown */
IDesktopShellBrowserImpl_IServiceProvider_QueryInterface,
IDesktopShellBrowserImpl_IServiceProvider_AddRef,
IDesktopShellBrowserImpl_IServiceProvider_Release,
/* IServiceProvider */
IDesktopShellBrowserImpl_IServiceProvider_QueryService
};
/*
* IShellFolderViewCB
*/
static HRESULT STDMETHODCALLTYPE
IDesktopShellBrowserImpl_IShellFolderViewCB_QueryInterface(IN OUT IShellFolderViewCB *iface,
IN REFIID riid,
OUT LPVOID *ppvObj)
{
IDesktopShellBrowserImpl *This = impl_from_IShellFolderViewCB(iface);
IShellBrowser *ShellBrowser = IShellBrowser_from_impl(This);
return IDesktopShellBrowserImpl_QueryInterface(ShellBrowser,
riid,
ppvObj);
}
static ULONG STDMETHODCALLTYPE
IDesktopShellBrowserImpl_IShellFolderViewCB_Release(IN OUT IShellFolderViewCB *iface)
{
IDesktopShellBrowserImpl *This = impl_from_IShellFolderViewCB(iface);
IShellBrowser *ShellBrowser = IShellBrowser_from_impl(This);
return IDesktopShellBrowserImpl_Release(ShellBrowser);
}
static ULONG STDMETHODCALLTYPE
IDesktopShellBrowserImpl_IShellFolderViewCB_AddRef(IN OUT IShellFolderViewCB *iface)
{
IDesktopShellBrowserImpl *This = impl_from_IShellFolderViewCB(iface);
IShellBrowser *ShellBrowser = IShellBrowser_from_impl(This);
return IDesktopShellBrowserImpl_AddRef(ShellBrowser);
}
static HRESULT STDMETHODCALLTYPE
IDesktopShellBrowserImpl_IShellFolderViewCB_MessageSFVCB(IN OUT IShellFolderViewCB *iface,
IN UINT uMsg,
IN WPARAM wParam,
IN LPARAM lParam)
{
IDesktopShellBrowserImpl *This = impl_from_IShellFolderViewCB(iface);
HRESULT hr = S_OK;
switch (uMsg)
{
case SFVM_GETNOTIFY:
hr = IDesktopShellBrowserImpl_GetNotify(This,
(LPITEMIDLIST *)wParam,
(LONG *)lParam);
break;
case SFVM_FSNOTIFY:
hr = S_OK;
break;
default:
hr = E_NOTIMPL;
break;
}
return hr;
}
static const IShellFolderViewCBVtbl IDesktopShellBrowserImpl_IShellFolderViewCB_Vtbl =
{
/* IUnknown */
IDesktopShellBrowserImpl_IShellFolderViewCB_QueryInterface,
IDesktopShellBrowserImpl_IShellFolderViewCB_AddRef,
IDesktopShellBrowserImpl_IShellFolderViewCB_Release,
/* IShellFolderViewCB */
IDesktopShellBrowserImpl_IShellFolderViewCB_MessageSFVCB
};
/*****************************************************************************/
static const TCHAR szProgmanClassName[] = TEXT("Progman");
static const TCHAR szProgmanWindowName[] = TEXT("Program Manager");
static VOID
PositionIcons(IN OUT IDesktopShellBrowserImpl *This,
IN const RECT *prcDesktopRect)
{
/* FIXME - Move all icons and align them on the destop. Before moving, we should
check if we're moving an icon above an existing one. If so, we should
let the list view control arrange the icons */
return;
}
static VOID
UpdateWorkArea(IN OUT IDesktopShellBrowserImpl *This,
IN const RECT *prcDesktopRect)
{
RECT rcDesktopRect;
LONG Style;
Style = GetWindowLong(This->hWndDesktopListView,
GWL_STYLE);
if (!(Style & LVS_AUTOARRANGE ) &&
GetWindowRect(This->hWnd,
&rcDesktopRect))
{
/* Only resize the desktop if it was resized to something other
than the virtual screen size/position! */
if (!EqualRect(prcDesktopRect,
&rcDesktopRect))
{
SetWindowPos(This->hWnd,
NULL,
prcDesktopRect->left,
prcDesktopRect->top,
prcDesktopRect->right - prcDesktopRect->left,
prcDesktopRect->bottom - prcDesktopRect->top,
SWP_NOZORDER | SWP_NOACTIVATE);
/* Let's try to rearrange the icons on the desktop. This is
especially neccessary when switching screen resolutions... */
PositionIcons(This,
prcDesktopRect);
}
}
}
static LRESULT CALLBACK
ProgmanWindowProc(IN HWND hwnd,
IN UINT uMsg,
IN WPARAM wParam,
IN LPARAM lParam)
{
IDesktopShellBrowserImpl *This = NULL;
LRESULT Ret = FALSE;
if (uMsg != WM_NCCREATE)
{
This = (IDesktopShellBrowserImpl*)GetWindowLongPtr(hwnd,
0);
}
if (This != NULL || uMsg == WM_NCCREATE)
{
switch (uMsg)
{
case WM_ERASEBKGND:
PaintDesktop((HDC)wParam);
break;
case WM_GETISHELLBROWSER:
Ret = (LRESULT)IShellBrowser_from_impl(This);
break;
case WM_SHELL_ADDDRIVENOTIFY:
{
HANDLE hLock;
LPITEMIDLIST *ppidl;
LONG lEventId;
hLock = SHChangeNotification_Lock((HANDLE)wParam,
(DWORD)lParam,
&ppidl,
&lEventId);
if (hLock != NULL)
{
/* FIXME */
SHChangeNotification_Unlock(hLock);
}
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);
UpdateWorkArea(This,
&rcDesktop);
}
break;
case WM_SYSCOLORCHANGE:
{
InvalidateRect(This->hWnd,
NULL,
TRUE);
if (This->hWndShellView != NULL)
{
/* Forward the message */
SendMessage(This->hWndShellView,
WM_SYSCOLORCHANGE,
wParam,
lParam);
}
break;
}
case WM_NCCREATE:
{
LPCREATESTRUCT CreateStruct = (LPCREATESTRUCT)lParam;
This = IDesktopShellBrowserImpl_Construct(hwnd,
CreateStruct);
if (This == NULL)
break;
SetWindowLongPtr(hwnd,
0,
(LONG_PTR)This);
if (This->hWndShellView != NULL)
SetShellWindowEx(This->hWnd,
This->hWndDesktopListView);
else
SetShellWindow(This->hWnd);
Ret = TRUE;
break;
}
case WM_DESTROY:
{
IDesktopShellBrowserImpl_Destroy(This);
break;
}
case WM_NCDESTROY:
{
IDesktopShellBrowserImpl_Release(IShellBrowser_from_impl(This));
PostQuitMessage(0);
break;
}
default:
Ret = DefWindowProc(hwnd, uMsg, wParam, lParam);
break;
}
}
return Ret;
}
static BOOL
RegisterProgmanWindowClass(VOID)
{
WNDCLASS wcProgman;
wcProgman.style = CS_DBLCLKS;
wcProgman.lpfnWndProc = ProgmanWindowProc;
wcProgman.cbClsExtra = 0;
wcProgman.cbWndExtra = sizeof(IDesktopShellBrowserImpl *);
wcProgman.hInstance = hExplorerInstance;
wcProgman.hIcon = NULL;
wcProgman.hCursor = LoadCursor(NULL,
IDC_ARROW);
wcProgman.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
wcProgman.lpszMenuName = NULL;
wcProgman.lpszClassName = szProgmanClassName;
return RegisterClass(&wcProgman) != 0;
}
static VOID
UnregisterProgmanWindowClass(VOID)
{
UnregisterClass(szProgmanClassName,
hExplorerInstance);
}
typedef struct _DESKCREATEINFO
{
HANDLE hEvent;
HWND hWndDesktop;
IDesktopShellBrowserImpl *pDesktop;
} DESKCREATEINFO, *PDESKCREATEINFO;
static DWORD CALLBACK
DesktopThreadProc(IN OUT LPVOID lpParameter)
{
volatile DESKCREATEINFO *DeskCreateInfo = (volatile DESKCREATEINFO *)lpParameter;
HWND hwndDesktop;
IDesktopShellBrowserImpl *pDesktop;
IShellDesktopTray *pSdt;
MSG Msg;
BOOL Ret;
OleInitialize(NULL);
hwndDesktop = CreateWindowEx(WS_EX_TOOLWINDOW,
szProgmanClassName,
szProgmanWindowName,
WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
0,
0,
GetSystemMetrics(SM_CXVIRTUALSCREEN),
GetSystemMetrics(SM_CYVIRTUALSCREEN),
NULL,
NULL,
hExplorerInstance,
NULL);
DeskCreateInfo->hWndDesktop = hWndDesktop;
if (hwndDesktop == NULL)
return 1;
pDesktop = (IDesktopShellBrowserImpl*)GetWindowLongPtr(hwndDesktop,
0);
(void)InterlockedExchangePointer(&DeskCreateInfo->pDesktop,
pDesktop);
if (!SetEvent(DeskCreateInfo->hEvent))
{
/* Failed to notify that we initialized successfully, kill ourselves
to make the main thread wake up! */
return 1;
}
while (1)
{
Ret = (GetMessage(&Msg,
NULL,
0,
0) != 0);
if (Ret != -1)
{
if (!Ret)
break;
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
OleUninitialize();
/* FIXME: Properly rundown the main thread! */
ExitProcess(0);
return 0;
}
HANDLE
DesktopCreateWindow(IN OUT ITrayWindow *Tray)
{
HANDLE hThread;
HANDLE hEvent;
DWORD DesktopThreadId;
IDesktopShellBrowserImpl *pDesktop = NULL;
HANDLE Handles[2];
DWORD WaitResult;
HWND hWndDesktop = NULL;
IShellDesktopTray *pSdt;
HRESULT hRet;
if (!RegisterProgmanWindowClass())
return NULL;
if (!RegisterTrayWindowClass())
{
UnregisterProgmanWindowClass();
return NULL;
}
if (!RegisterTaskSwitchWndClass())
{
UnregisterProgmanWindowClass();
UnregisterTrayWindowClass();
return NULL;
}
hEvent = CreateEvent(NULL,
FALSE,
FALSE,
NULL);
if (hEvent != NULL)
{
volatile DESKCREATEINFO DeskCreateInfo;
DeskCreateInfo.hEvent = hEvent;
DeskCreateInfo.pDesktop = NULL;
hThread = CreateThread(NULL,
0,
DesktopThreadProc,
(PVOID)&DeskCreateInfo,
0,
&DesktopThreadId);
if (hThread != NULL)
{
Handles[0] = hThread;
Handles[1] = hEvent;
WaitResult = WaitForMultipleObjects(sizeof(Handles) / sizeof(Handles[0]),
Handles,
FALSE,
INFINITE);
if (WaitResult != WAIT_FAILED && WaitResult != WAIT_OBJECT_0)
{
pDesktop = DeskCreateInfo.pDesktop;
hWndDesktop = DeskCreateInfo.hWndDesktop;
}
CloseHandle(hThread);
}
CloseHandle(hEvent);
}
if (pDesktop != NULL)
{
hRet = ITrayWindow_QueryInterface(Tray,
&IID_IShellDesktopTray,
(PVOID*)&pSdt);
if (SUCCEEDED(hRet))
{
IShellDesktopTray_RegisterDesktopWindow(pSdt,
hWndDesktop);
IShellDesktopTray_Release(pSdt);
}
}
else
{
UnregisterProgmanWindowClass();
UnregisterTrayWindowClass();
UnregisterTaskSwitchWndClass();
}
return (HANDLE)pDesktop;
}
VOID
DesktopDestroyShellWindow(IN HANDLE hDesktop)
{
//IDesktopShellBrowserImpl *pDesktop = (IDesktopShellBrowserImpl *)hDesktop;
/* FIXME - Destroy window (don't use DestroyWindow() as
the window belongs to another thread!) */
UnregisterProgmanWindowClass();
UnregisterTrayWindowClass();
}
#endif /* USE_API_SHCREATEDESKTOP */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -