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