a bit of refactoring
[reactos.git] / reactos / subsys / system / explorer / explorer.cpp
1 /*
2 * Copyright 2003 Martin Fuchs
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19
20 //
21 // Explorer clone
22 //
23 // explorer.cpp
24 //
25 // Martin Fuchs, 23.07.2003
26 //
27 // Credits: Thanks to Leon Finker for his explorer window example
28 //
29
30
31 #include "utility/utility.h"
32
33 #include "explorer.h"
34 #include "desktop/desktop.h"
35
36 #include "globals.h"
37 #include "externals.h"
38
39 #include "explorer_intres.h"
40
41 #include <locale.h> // for setlocale()
42
43 #ifndef __WINE__
44 #include <io.h> // for dup2()
45 #include <fcntl.h> // for _O_RDONLY
46 #endif
47
48
49 ExplorerGlobals g_Globals;
50
51
52 ExplorerGlobals::ExplorerGlobals()
53 {
54 _hInstance = 0;
55 _hframeClass = 0;
56 _cfStrFName = 0;
57 _hMainWnd = 0;
58 _prescan_nodes = false;
59 _desktop_mode = false;
60 _log = NULL;
61 #ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003)
62 _SHRestricted = 0;
63 #endif
64 }
65
66
67 void _log_(LPCTSTR txt)
68 {
69 FmtString msg(TEXT("%s\n"), txt);
70
71 if (g_Globals._log)
72 _fputts(msg, g_Globals._log);
73
74 OutputDebugString(msg);
75 }
76
77
78 ResString::ResString(UINT nid)
79 {
80 TCHAR buffer[BUFFER_LEN];
81
82 int len = LoadString(g_Globals._hInstance, nid, buffer, sizeof(buffer)/sizeof(TCHAR));
83
84 super::assign(buffer, len);
85 }
86
87
88 ResIcon::ResIcon(UINT nid)
89 {
90 _hIcon = LoadIcon(g_Globals._hInstance, MAKEINTRESOURCE(nid));
91 }
92
93 SmallIcon::SmallIcon(UINT nid)
94 {
95 _hIcon = (HICON)LoadImage(g_Globals._hInstance, MAKEINTRESOURCE(nid), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED);
96 }
97
98 ResIconEx::ResIconEx(UINT nid, int w, int h)
99 {
100 _hIcon = (HICON)LoadImage(g_Globals._hInstance, MAKEINTRESOURCE(nid), IMAGE_ICON, w, h, LR_SHARED);
101 }
102
103
104 void SetWindowIcon(HWND hwnd, UINT nid)
105 {
106 HICON hIcon = ResIcon(nid);
107 Window_SetIcon(hwnd, ICON_BIG, hIcon);
108
109 HICON hIconSmall = SmallIcon(nid);
110 Window_SetIcon(hwnd, ICON_SMALL, hIconSmall);
111 }
112
113
114 ResBitmap::ResBitmap(UINT nid)
115 {
116 _hBmp = LoadBitmap(g_Globals._hInstance, MAKEINTRESOURCE(nid));
117 }
118
119
120 void explorer_show_frame(HWND hwndDesktop, int cmdshow)
121 {
122 if (g_Globals._hMainWnd)
123 return;
124
125 g_Globals._prescan_nodes = false;
126
127 // create main window
128 HWND hMainFrame = MainFrame::Create();
129
130 if (hMainFrame) {
131 g_Globals._hMainWnd = hMainFrame;
132
133 ShowWindow(hMainFrame, cmdshow);
134 UpdateWindow(hMainFrame);
135
136 // Open the first child window after initializing the whole application
137 PostMessage(hMainFrame, PM_OPEN_WINDOW, OWM_EXPLORE|OWM_DETAILS, 0);
138 }
139 }
140
141
142 static void InitInstance(HINSTANCE hInstance)
143 {
144 CONTEXT("InitInstance");
145
146 setlocale(LC_COLLATE, ""); // set collating rules to local settings for compareName
147
148 // register frame window class
149 g_Globals._hframeClass = IconWindowClass(CLASSNAME_FRAME,IDI_EXPLORER);
150
151 // register child windows class
152 WindowClass(CLASSNAME_CHILDWND, CS_CLASSDC|CS_DBLCLKS|CS_VREDRAW).Register();
153
154 // register tree windows class
155 WindowClass(CLASSNAME_WINEFILETREE, CS_CLASSDC|CS_DBLCLKS|CS_VREDRAW).Register();
156
157 g_Globals._cfStrFName = RegisterClipboardFormat(CFSTR_FILENAME);
158 }
159
160
161 int explorer_main(HINSTANCE hInstance, HWND hwndDesktop, int cmdshow)
162 {
163 CONTEXT("explorer_main");
164
165 // initialize COM and OLE
166 OleInit usingCOM;
167
168 // initialize Common Controls library
169 CommonControlInit usingCmnCtrl;
170
171 try {
172 InitInstance(hInstance);
173 } catch(COMException& e) {
174 HandleException(e, hwndDesktop);
175 return -1;
176 }
177
178 if (hwndDesktop)
179 g_Globals._desktop_mode = true;
180
181 if (cmdshow != SW_HIDE) {
182 /* // don't maximize if being called from the ROS desktop
183 if (cmdshow == SW_SHOWNORMAL)
184 ///@todo read window placement from registry
185 cmdshow = SW_MAXIMIZE;
186 */
187
188 explorer_show_frame(hwndDesktop, cmdshow);
189 }
190
191 return Window::MessageLoop();
192 }
193
194
195 // MinGW does not provide a Unicode startup routine, so we have to implement an own.
196 #if defined(__MINGW32__) && defined(UNICODE)
197
198 #define _tWinMain wWinMain
199 int WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int);
200
201 int main(int argc, char* argv[])
202 {
203 CONTEXT("main");
204
205 STARTUPINFO startupinfo;
206 int nShowCmd = SW_SHOWNORMAL;
207
208 GetStartupInfo(&startupinfo);
209
210 if (startupinfo.dwFlags & STARTF_USESHOWWINDOW)
211 nShowCmd = startupinfo.wShowWindow;
212
213 return wWinMain(GetModuleHandle(NULL), 0, GetCommandLine(), nShowCmd);
214 }
215
216 #endif // __MINGW && UNICODE
217
218
219 int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd)
220 {
221 CONTEXT("WinMain()");
222
223 // create desktop window and task bar only, if there is no other shell and we are
224 // the first explorer instance
225 BOOL startup_desktop = !IsAnyDesktopRunning();
226
227 bool autostart = true;
228
229 #ifdef _DEBUG //MF: disabled for debugging
230 autostart = false;
231 #endif
232
233 // If there is given the command line option "-desktop", create desktop window anyways
234 if (_tcsstr(lpCmdLine,TEXT("-desktop")))
235 startup_desktop = TRUE;
236
237 if (_tcsstr(lpCmdLine,TEXT("-nodesktop")))
238 startup_desktop = FALSE;
239
240 if (_tcsstr(lpCmdLine,TEXT("-noexplorer"))) {
241 nShowCmd = SW_HIDE;
242 startup_desktop = TRUE;
243 }
244
245 if (_tcsstr(lpCmdLine,TEXT("-noautostart")))
246 autostart = false;
247
248 #ifndef __WINE__
249 if (_tcsstr(lpCmdLine,TEXT("-console"))) {
250 AllocConsole();
251
252 _dup2(_open_osfhandle((long)GetStdHandle(STD_INPUT_HANDLE), _O_RDONLY), 0);
253 _dup2(_open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE), 0), 1);
254 _dup2(_open_osfhandle((long)GetStdHandle(STD_ERROR_HANDLE), 0), 2);
255
256 g_Globals._log = fdopen(1, "w");
257 setvbuf(g_Globals._log, 0, _IONBF, 0);
258
259 LOG(TEXT("starting explore debug log\n"));
260 }
261 #endif
262
263 g_Globals._hInstance = hInstance;
264 #ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003)
265 g_Globals._SHRestricted = (DWORD(STDAPICALLTYPE*)(RESTRICTIONS)) GetProcAddress(GetModuleHandle(TEXT("SHELL32")), "SHRestricted");
266 #endif
267
268 HWND hwndDesktop = 0;
269
270 if (startup_desktop)
271 {
272 hwndDesktop = DesktopWindow::Create();
273
274 if (autostart)
275 {
276 char* argv[] = {"", "s"}; // call startup routine in SESSION_START mode
277 startup(2, argv);
278 }
279 }
280
281 int ret = explorer_main(hInstance, hwndDesktop, nShowCmd);
282
283 return ret;
284 }