xref: /reactos/base/shell/explorer/explorer.cpp (revision a6726659)
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     HANDLE hShellDesktop = NULL;
158     if (Tray != NULL)
159         hShellDesktop = DesktopCreateWindow(Tray);
160 
161     /* WinXP: Notify msgina to hide the welcome screen */
162     if (!SetShellReadyEvent(L"msgina: ShellReadyEvent"))
163         SetShellReadyEvent(L"Global\\msgina: ShellReadyEvent");
164 
165     if (DoStartStartupItems(Tray))
166     {
167         ProcessStartupItems();
168         DoFinishStartupItems();
169     }
170 #endif
171 
172     if (Tray != NULL)
173     {
174         TrayMessageLoop(Tray);
175 #if !WIN7_DEBUG_MODE
176         HideMinimizedWindows(FALSE);
177 #endif
178     }
179 
180 #if !WIN7_DEBUG_MODE
181     if (hShellDesktop != NULL)
182         DesktopDestroyShellWindow(hShellDesktop);
183 #endif
184 
185     OleUninitialize();
186 
187     RegCloseKey(hkExplorer);
188     hkExplorer = NULL;
189 
190     InitializeAtlModule(hInstance, FALSE);
191 
192     return 0;
193 }
194 
195 INT WINAPI
196 _tWinMain(IN HINSTANCE hInstance,
197           IN HINSTANCE hPrevInstance,
198           IN LPTSTR lpCmdLine,
199           IN INT nCmdShow)
200 {
201     /*
202     * Set our shutdown parameters: we want to shutdown the very last,
203     * but before any TaskMgr instance (which has a shutdown level of 1).
204     */
205     SetProcessShutdownParameters(2, 0);
206 
207     InitRSHELL();
208 
209     TRACE("Explorer starting... Command line: %S\n", lpCmdLine);
210 
211 #if !WIN7_COMPAT_MODE
212     if (GetShellWindow() == NULL)
213         bExplorerIsShell = TRUE;
214 
215     if (!bExplorerIsShell)
216     {
217         return StartWithCommandLine(hInstance);
218     }
219 #else
220     bExplorerIsShell = TRUE;
221 #endif
222 
223     return StartWithDesktop(hInstance);
224 }
225