[EXPLORER-NEW]
[reactos.git] / base / shell / explorer-new / startmnusite.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
23 /*****************************************************************************
24 ** IStartMenuSite ***********************************************************
25 *****************************************************************************/
26
27 class CStartMenuSite :
28 public CComCoClass<CStartMenuSite>,
29 public CComObjectRootEx<CComMultiThreadModelNoCS>,
30 public IStartMenuSite,
31 public IServiceProvider,
32 public ITrayPriv,
33 public IOleCommandTarget,
34 public IMenuPopup
35 {
36 CComPtr<ITrayWindow> Tray;
37 CComPtr<IMenuPopup> StartMenuPopup;
38
39 public:
40 CStartMenuSite()
41 {
42 }
43
44 virtual ~CStartMenuSite() {}
45
46 /*******************************************************************/
47
48 virtual HRESULT STDMETHODCALLTYPE QueryService(
49 IN REFGUID guidService,
50 IN REFIID riid,
51 OUT PVOID *ppvObject)
52 {
53 if (IsEqualGUID(guidService, SID_SMenuPopup))
54 {
55 return QueryInterface(riid, ppvObject);
56 }
57
58 return E_NOINTERFACE;
59 }
60
61 /*******************************************************************/
62
63 virtual HRESULT STDMETHODCALLTYPE GetWindow(
64 OUT HWND *phwnd)
65 {
66 TRACE("ITrayPriv::GetWindow\n");
67
68 *phwnd = Tray->GetHWND();
69 if (*phwnd != NULL)
70 return S_OK;
71
72 return E_FAIL;
73 }
74
75 virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(
76 IN BOOL fEnterMode)
77 {
78 TRACE("ITrayPriv::ContextSensitiveHelp\n");
79 return E_NOTIMPL;
80 }
81
82 virtual HRESULT STDMETHODCALLTYPE Execute(
83 IN IShellFolder *pShellFolder,
84 IN LPCITEMIDLIST pidl)
85 {
86 HMODULE hShlwapi;
87 HRESULT ret = S_FALSE;
88
89 TRACE("ITrayPriv::Execute\n");
90
91 hShlwapi = GetModuleHandle(TEXT("SHLWAPI.DLL"));
92 if (hShlwapi != NULL)
93 {
94 SHINVDEFCMD SHInvokeDefCmd;
95
96 /* SHInvokeDefaultCommand */
97 SHInvokeDefCmd = (SHINVDEFCMD) GetProcAddress(hShlwapi,
98 (LPCSTR) ((LONG) 279));
99 if (SHInvokeDefCmd != NULL)
100 {
101 ret = SHInvokeDefCmd(Tray->GetHWND(),
102 pShellFolder,
103 pidl);
104 }
105 }
106
107 return ret;
108 }
109
110 virtual HRESULT STDMETHODCALLTYPE Unknown(
111 IN PVOID Unknown1,
112 IN PVOID Unknown2,
113 IN PVOID Unknown3,
114 IN PVOID Unknown4)
115 {
116 TRACE("ITrayPriv::Unknown(0x%p,0x%p,0x%p,0x%p)\n", Unknown1, Unknown2, Unknown3, Unknown4);
117 return E_NOTIMPL;
118 }
119
120 virtual BOOL
121 ShowUndockMenuItem(VOID)
122 {
123 TRACE("ShowUndockMenuItem() not implemented!\n");
124 /* FIXME: How do we detect this?! */
125 return FALSE;
126 }
127
128 virtual BOOL
129 ShowSynchronizeMenuItem(VOID)
130 {
131 TRACE("ShowSynchronizeMenuItem() not implemented!\n");
132 /* FIXME: How do we detect this?! */
133 return FALSE;
134 }
135
136 virtual HRESULT STDMETHODCALLTYPE AppendMenu(
137 OUT HMENU* phMenu)
138 {
139 HMENU hMenu, hSettingsMenu;
140 DWORD dwLogoff;
141 BOOL bWantLogoff;
142 UINT uLastItemsCount = 5; /* 5 menu items below the last separator */
143 WCHAR szUser[128];
144
145 TRACE("ITrayPriv::AppendMenu\n");
146
147 hMenu = LoadPopupMenu(hExplorerInstance,
148 MAKEINTRESOURCE(IDM_STARTMENU));
149 *phMenu = hMenu;
150 if (hMenu == NULL)
151 return E_FAIL;
152
153 /* Remove menu items that don't apply */
154
155 dwLogoff = SHRestricted(REST_STARTMENULOGOFF);
156 bWantLogoff = (dwLogoff == 2 ||
157 SHRestricted(REST_FORCESTARTMENULOGOFF) ||
158 GetExplorerRegValueSet(HKEY_CURRENT_USER,
159 TEXT("Advanced"),
160 TEXT("StartMenuLogoff")));
161
162 /* Favorites */
163 if (!GetExplorerRegValueSet(HKEY_CURRENT_USER,
164 TEXT("Advanced"),
165 TEXT("StartMenuFavorites")))
166 {
167 DeleteMenu(hMenu,
168 IDM_FAVORITES,
169 MF_BYCOMMAND);
170 }
171
172 /* Documents */
173 if (SHRestricted(REST_NORECENTDOCSMENU))
174 {
175 DeleteMenu(hMenu,
176 IDM_DOCUMENTS,
177 MF_BYCOMMAND);
178 }
179
180 /* Settings */
181 hSettingsMenu = FindSubMenu(hMenu,
182 IDM_SETTINGS,
183 FALSE);
184 if (hSettingsMenu != NULL)
185 {
186 if (SHRestricted(REST_NOSETFOLDERS))
187 {
188 /* Control Panel */
189 if (SHRestricted(REST_NOCONTROLPANEL))
190 {
191 DeleteMenu(hSettingsMenu,
192 IDM_CONTROLPANEL,
193 MF_BYCOMMAND);
194
195 /* Delete the separator below it */
196 DeleteMenu(hSettingsMenu,
197 0,
198 MF_BYPOSITION);
199 }
200
201 /* Network Connections */
202 if (SHRestricted(REST_NONETWORKCONNECTIONS))
203 {
204 DeleteMenu(hSettingsMenu,
205 IDM_NETWORKCONNECTIONS,
206 MF_BYCOMMAND);
207 }
208
209 /* Printers and Faxes */
210 DeleteMenu(hSettingsMenu,
211 IDM_PRINTERSANDFAXES,
212 MF_BYCOMMAND);
213 }
214
215 /* Security */
216 if (GetSystemMetrics(SM_REMOTECONTROL) == 0 ||
217 SHRestricted(REST_NOSECURITY))
218 {
219 DeleteMenu(hSettingsMenu,
220 IDM_SECURITY,
221 MF_BYCOMMAND);
222 }
223
224 if (GetMenuItemCount(hSettingsMenu) == 0)
225 {
226 DeleteMenu(hMenu,
227 IDM_SETTINGS,
228 MF_BYCOMMAND);
229 }
230 }
231
232 /* Search */
233 /* FIXME: Enable after implementing */
234 /* if (SHRestricted(REST_NOFIND)) */
235 {
236 DeleteMenu(hMenu,
237 IDM_SEARCH,
238 MF_BYCOMMAND);
239 }
240
241 /* FIXME: Help */
242
243 /* Run */
244 if (SHRestricted(REST_NORUN))
245 {
246 DeleteMenu(hMenu,
247 IDM_RUN,
248 MF_BYCOMMAND);
249 }
250
251 /* Synchronize */
252 if (!ShowSynchronizeMenuItem())
253 {
254 DeleteMenu(hMenu,
255 IDM_SYNCHRONIZE,
256 MF_BYCOMMAND);
257 uLastItemsCount--;
258 }
259
260 /* Log off */
261 if (dwLogoff != 1 && bWantLogoff)
262 {
263 /* FIXME: We need a more sophisticated way to determine whether to show
264 or hide it, it might be hidden in too many cases!!! */
265
266 /* Update Log Off menu item */
267 if (!GetCurrentLoggedOnUserName(szUser,
268 sizeof(szUser) / sizeof(szUser[0])))
269 {
270 szUser[0] = _T('\0');
271 }
272
273 if (!FormatMenuString(hMenu,
274 IDM_LOGOFF,
275 MF_BYCOMMAND,
276 szUser))
277 {
278 /* We couldn't update the menu item, delete it... */
279 DeleteMenu(hMenu,
280 IDM_LOGOFF,
281 MF_BYCOMMAND);
282 }
283 }
284 else
285 {
286 DeleteMenu(hMenu,
287 IDM_LOGOFF,
288 MF_BYCOMMAND);
289 uLastItemsCount--;
290 }
291
292
293 /* Disconnect */
294 if (GetSystemMetrics(SM_REMOTECONTROL) == 0)
295 {
296 DeleteMenu(hMenu,
297 IDM_DISCONNECT,
298 MF_BYCOMMAND);
299 uLastItemsCount--;
300 }
301
302 /* Undock computer */
303 if (!ShowUndockMenuItem())
304 {
305 DeleteMenu(hMenu,
306 IDM_UNDOCKCOMPUTER,
307 MF_BYCOMMAND);
308 uLastItemsCount--;
309 }
310
311 /* Shut down */
312 if (SHRestricted(REST_NOCLOSE))
313 {
314 DeleteMenu(hMenu,
315 IDM_SHUTDOWN,
316 MF_BYCOMMAND);
317 uLastItemsCount--;
318 }
319
320 if (uLastItemsCount == 0)
321 {
322 /* Remove the separator at the end of the menu */
323 DeleteMenu(hMenu,
324 IDM_LASTSTARTMENU_SEPARATOR,
325 MF_BYCOMMAND);
326 }
327
328 return S_OK;
329 }
330
331 /*******************************************************************/
332
333 virtual HRESULT STDMETHODCALLTYPE QueryStatus(
334 IN const GUID *pguidCmdGroup OPTIONAL,
335 IN ULONG cCmds,
336 IN OUT OLECMD *prgCmds,
337 IN OUT OLECMDTEXT *pCmdText OPTIONAL)
338 {
339 return E_NOTIMPL;
340 }
341
342 virtual HRESULT STDMETHODCALLTYPE Exec(
343 IN const GUID *pguidCmdGroup OPTIONAL,
344 IN DWORD nCmdID,
345 IN DWORD nCmdExecOpt,
346 IN VARIANTARG *pvaIn OPTIONAL,
347 IN VARIANTARG *pvaOut OPTIONAL)
348 {
349 return E_NOTIMPL;
350 }
351
352 /*******************************************************************/
353
354 virtual HRESULT STDMETHODCALLTYPE SetClient(IUnknown *punkClient)
355 {
356 return E_NOTIMPL;
357 }
358
359 virtual HRESULT STDMETHODCALLTYPE GetClient(IUnknown ** ppunkClient)
360 {
361 return E_NOTIMPL;
362 }
363
364 virtual HRESULT STDMETHODCALLTYPE OnPosRectChangeDB(RECT *prc)
365 {
366 return E_NOTIMPL;
367 }
368
369 virtual HRESULT STDMETHODCALLTYPE Popup(POINTL *ppt, RECTL *prcExclude, MP_POPUPFLAGS dwFlags)
370 {
371 return E_NOTIMPL;
372 }
373
374 virtual HRESULT STDMETHODCALLTYPE OnSelect(DWORD dwSelectType)
375 {
376 return E_NOTIMPL;
377 }
378
379 virtual HRESULT STDMETHODCALLTYPE SetSubMenu(IMenuPopup *pmp, BOOL fSet)
380 {
381 if (!fSet)
382 {
383 return Tray_OnStartMenuDismissed();
384 }
385
386 return S_OK;
387 }
388
389 /*******************************************************************/
390
391 HRESULT Initialize(IN ITrayWindow *tray)
392 {
393 Tray = tray;
394 return S_OK;
395 }
396
397 DECLARE_NOT_AGGREGATABLE(CStartMenuSite)
398
399 DECLARE_PROTECT_FINAL_CONSTRUCT()
400 BEGIN_COM_MAP(CStartMenuSite)
401 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider)
402 COM_INTERFACE_ENTRY_IID(IID_ITrayPriv, ITrayPriv)
403 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget)
404 COM_INTERFACE_ENTRY_IID(IID_IMenuPopup, IMenuPopup)
405 COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
406 END_COM_MAP()
407 };
408
409 HRESULT CreateStartMenuSite(IN OUT ITrayWindow *Tray, const IID & riid, PVOID * ppv)
410 {
411 return ShellObjectCreatorInit<CStartMenuSite>(Tray, riid, ppv);
412 }