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