Reintegrate header-work branch. Important changes include continued work on headers...
[reactos.git] / reactos / base / shell / explorer-new / explorer.c
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 HINSTANCE hExplorerInstance;
24 HMODULE hUser32;
25 HANDLE hProcessHeap;
26 HKEY hkExplorer = NULL;
27 DRAWCAPTEMP DrawCapTemp = NULL;
28
29 /* undoc GUID */
30 DEFINE_GUID(CLSID_RebarBandSite, 0xECD4FC4D, 0x521C, 0x11D0, 0xB7, 0x92, 0x00, 0xA0, 0xC9, 0x03, 0x12, 0xE1);
31
32 LONG
33 SetWindowStyle(IN HWND hWnd,
34 IN LONG dwStyleMask,
35 IN LONG dwStyle)
36 {
37 LONG PrevStyle, Style;
38
39 ASSERT((~dwStyleMask & dwStyle) == 0);
40
41 PrevStyle = GetWindowLongPtr(hWnd,
42 GWL_STYLE);
43 if (PrevStyle != 0 &&
44 (PrevStyle & dwStyleMask) != dwStyle)
45 {
46 Style = PrevStyle & ~dwStyleMask;
47 Style |= dwStyle;
48
49 PrevStyle = SetWindowLongPtr(hWnd,
50 GWL_STYLE,
51 Style);
52 }
53
54 return PrevStyle;
55 }
56
57 LONG
58 SetWindowExStyle(IN HWND hWnd,
59 IN LONG dwStyleMask,
60 IN LONG dwStyle)
61 {
62 LONG PrevStyle, Style;
63
64 ASSERT((~dwStyleMask & dwStyle) == 0);
65
66 PrevStyle = GetWindowLongPtr(hWnd,
67 GWL_EXSTYLE);
68 if (PrevStyle != 0 &&
69 (PrevStyle & dwStyleMask) != dwStyle)
70 {
71 Style = PrevStyle & ~dwStyleMask;
72 Style |= dwStyle;
73
74 PrevStyle = SetWindowLongPtr(hWnd,
75 GWL_EXSTYLE,
76 Style);
77 }
78
79 return PrevStyle;
80 }
81
82 HMENU
83 LoadPopupMenu(IN HINSTANCE hInstance,
84 IN LPCTSTR lpMenuName)
85 {
86 HMENU hMenu, hSubMenu = NULL;
87
88 hMenu = LoadMenu(hInstance,
89 lpMenuName);
90
91 if (hMenu != NULL)
92 {
93 hSubMenu = GetSubMenu(hMenu,
94 0);
95 if (hSubMenu != NULL &&
96 !RemoveMenu(hMenu,
97 0,
98 MF_BYPOSITION))
99 {
100 hSubMenu = NULL;
101 }
102
103 DestroyMenu(hMenu);
104 }
105
106 return hSubMenu;
107 }
108
109 HMENU
110 FindSubMenu(IN HMENU hMenu,
111 IN UINT uItem,
112 IN BOOL fByPosition)
113 {
114 MENUITEMINFO mii;
115
116 mii.cbSize = sizeof(mii);
117 mii.fMask = MIIM_SUBMENU;
118
119 if (GetMenuItemInfo(hMenu,
120 uItem,
121 fByPosition,
122 &mii))
123 {
124 return mii.hSubMenu;
125 }
126
127 return NULL;
128 }
129
130 BOOL
131 GetCurrentLoggedOnUserName(OUT LPTSTR szBuffer,
132 IN DWORD dwBufferSize)
133 {
134 DWORD dwType;
135 DWORD dwSize;
136
137 /* Query the user name from the registry */
138 dwSize = (dwBufferSize * sizeof(TCHAR)) - 1;
139 if (RegQueryValueEx(hkExplorer,
140 TEXT("Logon User Name"),
141 0,
142 &dwType,
143 (LPBYTE)szBuffer,
144 &dwSize) == ERROR_SUCCESS &&
145 (dwSize / sizeof(TCHAR)) > 1 &&
146 szBuffer[0] != _T('\0'))
147 {
148 szBuffer[dwSize / sizeof(TCHAR)] = _T('\0');
149 return TRUE;
150 }
151
152 /* Fall back to GetUserName() */
153 dwSize = dwBufferSize;
154 if (!GetUserName(szBuffer,
155 &dwSize))
156 {
157 szBuffer[0] = _T('\0');
158 return FALSE;
159 }
160
161 return TRUE;
162 }
163
164 BOOL
165 FormatMenuString(IN HMENU hMenu,
166 IN UINT uPosition,
167 IN UINT uFlags,
168 ...)
169 {
170 va_list vl;
171 MENUITEMINFO mii;
172 TCHAR szBuf[128];
173 TCHAR szBufFmt[128];
174
175 /* Find the menu item and read the formatting string */
176 mii.cbSize = sizeof(mii);
177 mii.fMask = MIIM_STRING;
178 mii.dwTypeData = (LPTSTR)szBufFmt;
179 mii.cch = sizeof(szBufFmt) / sizeof(szBufFmt[0]);
180 if (GetMenuItemInfo(hMenu,
181 uPosition,
182 uFlags,
183 &mii))
184 {
185 /* Format the string */
186 va_start(vl, uFlags);
187 _vsntprintf(szBuf,
188 (sizeof(szBuf) / sizeof(szBuf[0])) - 1,
189 szBufFmt,
190 vl);
191 va_end(vl);
192 szBuf[(sizeof(szBuf) / sizeof(szBuf[0])) - 1] = _T('\0');
193
194 /* Update the menu item */
195 mii.dwTypeData = (LPTSTR)szBuf;
196 if (SetMenuItemInfo(hMenu,
197 uPosition,
198 uFlags,
199 &mii))
200 {
201 return TRUE;
202 }
203 }
204
205 return FALSE;
206 }
207
208 BOOL
209 GetExplorerRegValueSet(IN HKEY hKey,
210 IN LPCTSTR lpSubKey,
211 IN LPCTSTR lpValue)
212 {
213 TCHAR szBuffer[MAX_PATH];
214 HKEY hkSubKey;
215 DWORD dwType, dwSize;
216 BOOL Ret = FALSE;
217
218 _tcscpy(szBuffer,
219 TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"));
220 _tcscat(szBuffer,
221 _T("\\"));
222 _tcscat(szBuffer,
223 lpSubKey);
224
225 dwSize = sizeof(szBuffer);
226 if (RegOpenKeyEx(hKey,
227 szBuffer,
228 0,
229 KEY_QUERY_VALUE,
230 &hkSubKey) == ERROR_SUCCESS)
231 {
232 ZeroMemory(szBuffer,
233 sizeof(szBuffer));
234
235 if (RegQueryValueEx(hkSubKey,
236 lpValue,
237 0,
238 &dwType,
239 (LPBYTE)szBuffer,
240 &dwSize) == ERROR_SUCCESS)
241 {
242 if (dwType == REG_DWORD && dwSize == sizeof(DWORD))
243 Ret = *((PDWORD)szBuffer) != 0;
244 else if (dwSize > 0)
245 Ret = *((PUCHAR)szBuffer) != 0;
246 }
247
248 RegCloseKey(hkSubKey);
249 }
250 return Ret;
251 }
252
253
254 static BOOL
255 SetShellReadyEvent(IN LPCTSTR lpEventName)
256 {
257 HANDLE hEvent;
258
259 hEvent = OpenEvent(EVENT_MODIFY_STATE,
260 FALSE,
261 lpEventName);
262 if (hEvent != NULL)
263 {
264 SetEvent(hEvent);
265
266 CloseHandle(hEvent);
267 return TRUE;
268 }
269
270 return FALSE;
271 }
272
273 INT WINAPI
274 _tWinMain(IN HINSTANCE hInstance,
275 IN HINSTANCE hPrevInstance,
276 IN LPTSTR lpCmdLine,
277 IN INT nCmdShow)
278 {
279 ITrayWindow *Tray = NULL;
280 HANDLE hShellDesktop = NULL;
281 BOOL CreateShellDesktop = FALSE;
282
283 if (RegOpenKey(HKEY_CURRENT_USER,
284 TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"),
285 &hkExplorer) != ERROR_SUCCESS)
286 {
287 TCHAR Message[256];
288 LoadString(hInstance, IDS_STARTUP_ERROR, Message, 256);
289 MessageBox(NULL, Message, NULL, MB_ICONERROR);
290 return 1;
291 }
292
293 hExplorerInstance = hInstance;
294 hProcessHeap = GetProcessHeap();
295
296 hUser32 = GetModuleHandle(TEXT("USER32.DLL"));
297 if (hUser32 != NULL)
298 {
299 DrawCapTemp = (DRAWCAPTEMP)GetProcAddress(hUser32,
300 PROC_NAME_DRAWCAPTIONTEMP);
301 }
302
303 InitCommonControls();
304 OleInitialize(NULL);
305
306 if (GetShellWindow() == NULL)
307 CreateShellDesktop = TRUE;
308
309 /* FIXME - initialize SSO Thread */
310
311 if (CreateShellDesktop)
312 {
313 if (RegisterTrayWindowClass() && RegisterTaskSwitchWndClass())
314 {
315 Tray = CreateTrayWindow();
316
317 if (Tray != NULL)
318 hShellDesktop = DesktopCreateWindow(Tray);
319 }
320
321 /* WinXP: Notify msgina to hide the welcome screen */
322 if (!SetShellReadyEvent(TEXT("msgina: ShellReadyEvent")))
323 SetShellReadyEvent(TEXT("Global\\msgina: ShellReadyEvent"));
324 }
325 else
326 {
327 /* A shell is already loaded. Parse the command line arguments
328 and unless we need to do something specific simply display
329 the desktop in a separate explorer window */
330 /* FIXME */
331 }
332
333 if (Tray != NULL)
334 TrayMessageLoop(Tray);
335
336 if (hShellDesktop != NULL)
337 DesktopDestroyShellWindow(hShellDesktop);
338
339 /* FIXME - shutdown SSO Thread */
340
341 OleUninitialize();
342
343 RegCloseKey(hkExplorer);
344 hkExplorer = NULL;
345
346 return 0;
347 }