xref: /reactos/base/shell/explorer/explorer.cpp (revision e4930be4)
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 #include <browseui_undoc.h>
23 
24 HINSTANCE hExplorerInstance;
25 HANDLE hProcessHeap;
26 HKEY hkExplorer = NULL;
27 BOOL bExplorerIsShell = FALSE;
28 
29 class CExplorerModule : public CComModule
30 {
31 public:
32 };
33 
34 BEGIN_OBJECT_MAP(ObjectMap)
35 END_OBJECT_MAP()
36 
37 CExplorerModule gModule;
38 CAtlWinModule   gWinModule;
39 
40 static VOID InitializeAtlModule(HINSTANCE hInstance, BOOL bInitialize)
41 {
42     if (bInitialize)
43     {
44         gModule.Init(ObjectMap, hInstance, NULL);
45     }
46     else
47     {
48         gModule.Term();
49     }
50 }
51 
52 #if !WIN7_DEBUG_MODE
53 static BOOL
54 SetShellReadyEvent(IN LPCWSTR lpEventName)
55 {
56     HANDLE hEvent;
57 
58     hEvent = OpenEventW(EVENT_MODIFY_STATE, FALSE, lpEventName);
59     if (hEvent != NULL)
60     {
61         SetEvent(hEvent);
62 
63         CloseHandle(hEvent);
64         return TRUE;
65     }
66 
67     return FALSE;
68 }
69 
70 static VOID
71 HideMinimizedWindows(IN BOOL bHide)
72 {
73     MINIMIZEDMETRICS mm;
74 
75     mm.cbSize = sizeof(mm);
76     if (!SystemParametersInfoW(SPI_GETMINIMIZEDMETRICS, sizeof(mm), &mm, 0))
77     {
78         ERR("SystemParametersInfoW failed with %lu\n", GetLastError());
79         return;
80     }
81     if (bHide)
82         mm.iArrange |= ARW_HIDE;
83     else
84         mm.iArrange &= ~ARW_HIDE;
85     if (!SystemParametersInfoW(SPI_SETMINIMIZEDMETRICS, sizeof(mm), &mm, 0))
86         ERR("SystemParametersInfoW failed with %lu\n", GetLastError());
87 }
88 #endif
89 
90 #if !WIN7_COMPAT_MODE
91 static INT
92 StartWithCommandLine(IN HINSTANCE hInstance)
93 {
94     BOOL b = FALSE;
95     EXPLORER_CMDLINE_PARSE_RESULTS parseResults = { 0 };
96 
97     if (SHExplorerParseCmdLine(&parseResults))
98         b = SHCreateFromDesktop(&parseResults);
99 
100     if (parseResults.strPath)
101         SHFree(parseResults.strPath);
102 
103     if (parseResults.pidlPath)
104         ILFree(parseResults.pidlPath);
105 
106     if (parseResults.pidlRoot)
107         ILFree(parseResults.pidlRoot);
108 
109     return b;
110 }
111 #endif
112 
113 static INT
114 StartWithDesktop(IN HINSTANCE hInstance)
115 {
116     InitializeAtlModule(hInstance, TRUE);
117 
118     if (RegOpenKeyW(HKEY_CURRENT_USER,
119         L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer",
120         &hkExplorer) != ERROR_SUCCESS)
121     {
122         WCHAR Message[256];
123         LoadStringW(hInstance, IDS_STARTUP_ERROR, Message, _countof(Message));
124         MessageBox(NULL, Message, NULL, MB_ICONERROR);
125         return 1;
126     }
127 
128     hExplorerInstance = hInstance;
129     hProcessHeap = GetProcessHeap();
130 
131     g_TaskbarSettings.Load();
132 
133     InitCommonControls();
134     OleInitialize(NULL);
135 
136 #if !WIN7_COMPAT_MODE
137     /* Initialize shell dde support */
138     _ShellDDEInit(TRUE);
139 #endif
140 
141     /* Initialize shell icons */
142     FileIconInit(TRUE);
143 
144     /* Initialize CLSID_ShellWindows class */
145     _WinList_Init();
146 
147     CComPtr<ITrayWindow> Tray;
148     CreateTrayWindow(&Tray);
149 
150 #if !WIN7_DEBUG_MODE
151     /* This not only hides the minimized window captions in the bottom
152     left screen corner, but is also needed in order to receive
153     HSHELL_* notification messages (which are required for taskbar
154     buttons to work right) */
155     HideMinimizedWindows(TRUE);
156 
157     ProcessRunOnceItems(); // Must be executed before the desktop is created
158 
159     HANDLE hShellDesktop = NULL;
160     if (Tray != NULL)
161         hShellDesktop = DesktopCreateWindow(Tray);
162 
163     /* WinXP: Notify msgina to hide the welcome screen */
164     if (!SetShellReadyEvent(L"msgina: ShellReadyEvent"))
165         SetShellReadyEvent(L"Global\\msgina: ShellReadyEvent");
166 
167     if (DoStartStartupItems(Tray))
168     {
169         ProcessStartupItems();
170         DoFinishStartupItems();
171     }
172     ReleaseStartupMutex(); // For ProcessRunOnceItems
173 #endif
174 
175     if (Tray != NULL)
176     {
177         TrayMessageLoop(Tray);
178 #if !WIN7_DEBUG_MODE
179         HideMinimizedWindows(FALSE);
180 #endif
181     }
182 
183 #if !WIN7_DEBUG_MODE
184     if (hShellDesktop != NULL)
185         DesktopDestroyShellWindow(hShellDesktop);
186 #endif
187 
188     OleUninitialize();
189 
190     RegCloseKey(hkExplorer);
191     hkExplorer = NULL;
192 
193     InitializeAtlModule(hInstance, FALSE);
194 
195     return 0;
196 }
197 
198 INT WINAPI
199 _tWinMain(IN HINSTANCE hInstance,
200           IN HINSTANCE hPrevInstance,
201           IN LPTSTR lpCmdLine,
202           IN INT nCmdShow)
203 {
204     /*
205     * Set our shutdown parameters: we want to shutdown the very last,
206     * but before any TaskMgr instance (which has a shutdown level of 1).
207     */
208     SetProcessShutdownParameters(2, 0);
209 
210     InitRSHELL();
211 
212     TRACE("Explorer starting... Command line: %S\n", lpCmdLine);
213 
214 #if !WIN7_COMPAT_MODE
215     if (GetShellWindow() == NULL)
216         bExplorerIsShell = TRUE;
217 
218     if (!bExplorerIsShell)
219     {
220         return StartWithCommandLine(hInstance);
221     }
222 #else
223     bExplorerIsShell = TRUE;
224 #endif
225 
226     return StartWithDesktop(hInstance);
227 }
228