1 /* 2 * ReactOS Explorer 3 * 4 * Copyright 2006 - 2007 Thomas Weidenmueller <w3seek@reactos.org> 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 #include "precomp.h" 22 23 class CDesktopThread 24 { 25 HANDLE m_hEvent; 26 CComPtr<ITrayWindow> m_Tray; 27 28 DWORD DesktopThreadProc() 29 { 30 CComPtr<IShellDesktopTray> pSdt; 31 HANDLE hDesktop; 32 HRESULT hRet; 33 34 OleInitialize(NULL); 35 36 hRet = m_Tray->QueryInterface(IID_PPV_ARG(IShellDesktopTray, &pSdt)); 37 if (!SUCCEEDED(hRet)) 38 return 1; 39 40 hDesktop = _SHCreateDesktop(pSdt); 41 if (hDesktop == NULL) 42 return 1; 43 44 if (!SetEvent(m_hEvent)) 45 { 46 /* Failed to notify that we initialized successfully, kill ourselves 47 to make the main thread wake up! */ 48 return 1; 49 } 50 51 _SHDesktopMessageLoop(hDesktop); 52 53 /* FIXME: Properly rundown the main thread! */ 54 ExitProcess(0); 55 56 return 0; 57 } 58 59 static DWORD CALLBACK s_DesktopThreadProc(IN OUT LPVOID lpParameter) 60 { 61 return reinterpret_cast<CDesktopThread*>(lpParameter)->DesktopThreadProc(); 62 } 63 64 public: 65 CDesktopThread() : 66 m_hEvent(NULL), 67 m_Tray(NULL) 68 { 69 } 70 71 HRESULT Initialize(IN OUT ITrayWindow *pTray) 72 { 73 HANDLE hThread; 74 HANDLE Handles[2]; 75 76 m_Tray = pTray; 77 78 m_hEvent = CreateEventW(NULL, FALSE, FALSE, NULL); 79 if (!m_hEvent) 80 return E_FAIL; 81 82 hThread = CreateThread(NULL, 0, s_DesktopThreadProc, (PVOID)this, 0, NULL); 83 if (!hThread) 84 { 85 CloseHandle(m_hEvent); 86 return E_FAIL; 87 } 88 89 Handles[0] = hThread; 90 Handles[1] = m_hEvent; 91 92 for (;;) 93 { 94 DWORD WaitResult = MsgWaitForMultipleObjects(_countof(Handles), Handles, FALSE, INFINITE, QS_ALLEVENTS); 95 if (WaitResult == WAIT_OBJECT_0 + _countof(Handles)) 96 { 97 TrayProcessMessages(m_Tray); 98 } 99 else if (WaitResult != WAIT_FAILED && WaitResult != WAIT_OBJECT_0) 100 { 101 break; 102 } 103 } 104 105 CloseHandle(hThread); 106 CloseHandle(m_hEvent); 107 108 return S_OK; 109 } 110 111 void Destroy() 112 { 113 return; 114 } 115 }; 116 117 HANDLE 118 DesktopCreateWindow(IN OUT ITrayWindow *Tray) 119 { 120 CDesktopThread* pDesktopThread = new CDesktopThread(); 121 122 HRESULT hres = pDesktopThread->Initialize(Tray); 123 if (FAILED_UNEXPECTEDLY(hres)) 124 { 125 delete pDesktopThread; 126 return NULL; 127 } 128 129 return pDesktopThread; 130 } 131 132 VOID 133 DesktopDestroyShellWindow(IN HANDLE hDesktop) 134 { 135 CDesktopThread* pDesktopThread = reinterpret_cast<CDesktopThread*>(hDesktop); 136 pDesktopThread->Destroy(); 137 } 138