[EXPLORER-NEW]
[reactos.git] / base / shell / explorer-new / desktop.cpp
index 99c71d4..766a069 100644 (file)
 
 #include "precomp.h"
 
-typedef struct _DESKCREATEINFO
-{
-    HANDLE hEvent;
-    ITrayWindow *Tray;
-    HANDLE hDesktop;
-} DESKCREATEINFO, *PDESKCREATEINFO;
-
 HANDLE WINAPI _SHCreateDesktop(IShellDesktopTray *ShellDesk);
 BOOL WINAPI _SHDesktopMessageLoop(HANDLE hDesktop);
 
-static DWORD CALLBACK
-DesktopThreadProc(IN OUT LPVOID lpParameter)
+class CDesktopThread
 {
-    volatile DESKCREATEINFO *DeskCreateInfo = (volatile DESKCREATEINFO *)lpParameter;
-    CComPtr<IShellDesktopTray> pSdt;
+    HANDLE hEvent;
     HANDLE hDesktop;
-    HRESULT hRet;
+    CComPtr<ITrayWindow> Tray;
 
-    OleInitialize(NULL);
+    DWORD DesktopThreadProc()
+    {
+        CComPtr<IShellDesktopTray> pSdt;
+        HANDLE hDesktop;
+        HRESULT hRet;
 
-    hRet = DeskCreateInfo->Tray->QueryInterface(IID_PPV_ARG(IShellDesktopTray, &pSdt));
-    if (!SUCCEEDED(hRet))
-        return 1;
+        OleInitialize(NULL);
 
-    hDesktop = _SHCreateDesktop(pSdt);
+        hRet = Tray->QueryInterface(IID_PPV_ARG(IShellDesktopTray, &pSdt));
+        if (!SUCCEEDED(hRet))
+            return 1;
 
-    if (hDesktop == NULL)
-        return 1;
+        hDesktop = _SHCreateDesktop(pSdt);
+        if (hDesktop == NULL)
+            return 1;
 
-    (void)InterlockedExchangePointer(&DeskCreateInfo->hDesktop, hDesktop);
+        if (!SetEvent(hEvent))
+        {
+            /* Failed to notify that we initialized successfully, kill ourselves
+            to make the main thread wake up! */
+            return 1;
+        }
+
+        _SHDesktopMessageLoop(hDesktop);
 
-    if (!SetEvent(DeskCreateInfo->hEvent))
+        /* FIXME: Properly rundown the main thread! */
+        ExitProcess(0);
+
+        return 0;
+    }
+
+    static DWORD CALLBACK s_DesktopThreadProc(IN OUT LPVOID lpParameter)
     {
-        /* Failed to notify that we initialized successfully, kill ourselves
-           to make the main thread wake up! */
-        return 1;
+        return reinterpret_cast<CDesktopThread*>(lpParameter)->DesktopThreadProc();
     }
 
-    _SHDesktopMessageLoop(hDesktop);
+public:
+    CDesktopThread() :
+        hEvent(NULL),
+        hDesktop(NULL),
+        Tray(NULL)
+    {
+    }
 
-    /* FIXME: Properly rundown the main thread! */
-    ExitProcess(0);
+    HANDLE Initialize(IN OUT ITrayWindow *pTray)
+    {
+        HANDLE hThread;
+        HANDLE Handles[2];
 
-    return 0;
-}
+        Tray = pTray;
 
-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)
+        hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+        if (!hEvent)
+            return NULL;
+
+        hThread = CreateThread(NULL, 0, s_DesktopThreadProc, (PVOID)this, 0, NULL);
+        if (!hThread)
         {
-            Handles[0] = hThread;
-            Handles[1] = hEvent;
+            CloseHandle(hEvent);
+            return NULL;
+        }
+
+        Handles[0] = hThread;
+        Handles[1] = hEvent;
 
-            for (;;)
+        for (;;)
+        {
+            DWORD WaitResult = MsgWaitForMultipleObjects(_countof(Handles), Handles, FALSE, INFINITE, QS_ALLEVENTS);
+            if (WaitResult == WAIT_OBJECT_0 + _countof(Handles))
             {
-                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;
-                }
+                TrayProcessMessages(Tray);
+            }
+            else if (WaitResult != WAIT_FAILED && WaitResult != WAIT_OBJECT_0)
+            {
+                break;
             }
-
-            CloseHandle(hThread);
         }
 
+        CloseHandle(hThread);
         CloseHandle(hEvent);
+
+        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 hDesktop;
+    return g_pDesktopWindowInstance->Initialize(Tray);
 }
 
 VOID
 DesktopDestroyShellWindow(IN HANDLE hDesktop)
 {
-    return;
+    if (g_pDesktopWindowInstance)
+    {
+        g_pDesktopWindowInstance->Destroy();
+    }
 }