[EXPLORER-NEW]

* Refactor the desktop thread/creation code.

svn path=/branches/shell-experiments/; revision=65199
This commit is contained in:
David Quintana 2014-11-02 21:52:54 +00:00
parent 162ff471bb
commit d2f5f7f14f

View file

@ -20,38 +20,32 @@
#include "precomp.h" #include "precomp.h"
typedef struct _DESKCREATEINFO
{
HANDLE hEvent;
ITrayWindow *Tray;
HANDLE hDesktop;
} DESKCREATEINFO, *PDESKCREATEINFO;
HANDLE WINAPI _SHCreateDesktop(IShellDesktopTray *ShellDesk); HANDLE WINAPI _SHCreateDesktop(IShellDesktopTray *ShellDesk);
BOOL WINAPI _SHDesktopMessageLoop(HANDLE hDesktop); BOOL WINAPI _SHDesktopMessageLoop(HANDLE hDesktop);
static DWORD CALLBACK class CDesktopThread
DesktopThreadProc(IN OUT LPVOID lpParameter) {
HANDLE hEvent;
HANDLE hDesktop;
CComPtr<ITrayWindow> Tray;
DWORD DesktopThreadProc()
{ {
volatile DESKCREATEINFO *DeskCreateInfo = (volatile DESKCREATEINFO *)lpParameter;
CComPtr<IShellDesktopTray> pSdt; CComPtr<IShellDesktopTray> pSdt;
HANDLE hDesktop; HANDLE hDesktop;
HRESULT hRet; HRESULT hRet;
OleInitialize(NULL); OleInitialize(NULL);
hRet = DeskCreateInfo->Tray->QueryInterface(IID_PPV_ARG(IShellDesktopTray, &pSdt)); hRet = Tray->QueryInterface(IID_PPV_ARG(IShellDesktopTray, &pSdt));
if (!SUCCEEDED(hRet)) if (!SUCCEEDED(hRet))
return 1; return 1;
hDesktop = _SHCreateDesktop(pSdt); hDesktop = _SHCreateDesktop(pSdt);
if (hDesktop == NULL) if (hDesktop == NULL)
return 1; return 1;
(void)InterlockedExchangePointer(&DeskCreateInfo->hDesktop, hDesktop); if (!SetEvent(hEvent))
if (!SetEvent(DeskCreateInfo->hEvent))
{ {
/* Failed to notify that we initialized successfully, kill ourselves /* Failed to notify that we initialized successfully, kill ourselves
to make the main thread wake up! */ to make the main thread wake up! */
@ -66,66 +60,85 @@ DesktopThreadProc(IN OUT LPVOID lpParameter)
return 0; return 0;
} }
HANDLE static DWORD CALLBACK s_DesktopThreadProc(IN OUT LPVOID lpParameter)
DesktopCreateWindow(IN OUT ITrayWindow *Tray) {
return reinterpret_cast<CDesktopThread*>(lpParameter)->DesktopThreadProc();
}
public:
CDesktopThread() :
hEvent(NULL),
hDesktop(NULL),
Tray(NULL)
{
}
HANDLE Initialize(IN OUT ITrayWindow *pTray)
{ {
HANDLE hThread; HANDLE hThread;
HANDLE hEvent;
DWORD DesktopThreadId;
HANDLE hDesktop = NULL;
HANDLE Handles[2]; HANDLE Handles[2];
DWORD WaitResult;
hEvent = CreateEvent(NULL, Tray = pTray;
FALSE,
FALSE, hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
NULL); if (!hEvent)
if (hEvent != NULL) return NULL;
hThread = CreateThread(NULL, 0, s_DesktopThreadProc, (PVOID)this, 0, NULL);
if (!hThread)
{ {
volatile DESKCREATEINFO DeskCreateInfo; CloseHandle(hEvent);
return NULL;
}
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[0] = hThread;
Handles[1] = hEvent; Handles[1] = hEvent;
for (;;) for (;;)
{ {
WaitResult = MsgWaitForMultipleObjects(sizeof(Handles) / sizeof(Handles[0]), DWORD WaitResult = MsgWaitForMultipleObjects(_countof(Handles), Handles, FALSE, INFINITE, QS_ALLEVENTS);
Handles, if (WaitResult == WAIT_OBJECT_0 + _countof(Handles))
FALSE, {
INFINITE,
QS_ALLEVENTS);
if (WaitResult == WAIT_OBJECT_0 + (sizeof(Handles) / sizeof(Handles[0])))
TrayProcessMessages(Tray); TrayProcessMessages(Tray);
}
else if (WaitResult != WAIT_FAILED && WaitResult != WAIT_OBJECT_0) else if (WaitResult != WAIT_FAILED && WaitResult != WAIT_OBJECT_0)
{ {
hDesktop = DeskCreateInfo.hDesktop;
break; break;
} }
} }
CloseHandle(hThread); CloseHandle(hThread);
}
CloseHandle(hEvent); CloseHandle(hEvent);
}
return hDesktop; return hDesktop;
} }
void Destroy()
{
return;
}
} * g_pDesktopWindowInstance;
HANDLE
DesktopCreateWindow(IN OUT ITrayWindow *Tray)
{
if (!g_pDesktopWindowInstance)
{
g_pDesktopWindowInstance = new CDesktopThread();
}
if (!g_pDesktopWindowInstance)
return NULL;
return g_pDesktopWindowInstance->Initialize(Tray);
}
VOID VOID
DesktopDestroyShellWindow(IN HANDLE hDesktop) DesktopDestroyShellWindow(IN HANDLE hDesktop)
{ {
return; if (g_pDesktopWindowInstance)
{
g_pDesktopWindowInstance->Destroy();
}
} }