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 if (SHRestricted(REST_NOFIND)) 212 { 213 DeleteMenu(hMenu, 214 IDM_SEARCH, 215 MF_BYCOMMAND); 216 } 217 218 /* FIXME: Help */ 219 220 /* Run */ 221 if (SHRestricted(REST_NORUN)) 222 { 223 DeleteMenu(hMenu, 224 IDM_RUN, 225 MF_BYCOMMAND); 226 } 227 228 /* Synchronize */ 229 if (!ShowSynchronizeMenuItem()) 230 { 231 DeleteMenu(hMenu, 232 IDM_SYNCHRONIZE, 233 MF_BYCOMMAND); 234 uLastItemsCount--; 235 } 236 237 /* Log off */ 238 if (dwLogoff != 1 && bWantLogoff) 239 { 240 /* FIXME: We need a more sophisticated way to determine whether to show 241 or hide it, it might be hidden in too many cases!!! */ 242 243 /* Update Log Off menu item */ 244 if (!GetCurrentLoggedOnUserName(szUser, _countof(szUser))) 245 { 246 szUser[0] = _T('\0'); 247 } 248 249 if (!FormatMenuString(hMenu, 250 IDM_LOGOFF, 251 MF_BYCOMMAND, 252 szUser)) 253 { 254 /* We couldn't update the menu item, delete it... */ 255 DeleteMenu(hMenu, 256 IDM_LOGOFF, 257 MF_BYCOMMAND); 258 } 259 } 260 else 261 { 262 DeleteMenu(hMenu, 263 IDM_LOGOFF, 264 MF_BYCOMMAND); 265 uLastItemsCount--; 266 } 267 268 269 /* Disconnect */ 270 if (GetSystemMetrics(SM_REMOTECONTROL) == 0) 271 { 272 DeleteMenu(hMenu, 273 IDM_DISCONNECT, 274 MF_BYCOMMAND); 275 uLastItemsCount--; 276 } 277 278 /* Undock computer */ 279 if (!ShowUndockMenuItem()) 280 { 281 DeleteMenu(hMenu, 282 IDM_UNDOCKCOMPUTER, 283 MF_BYCOMMAND); 284 uLastItemsCount--; 285 } 286 287 /* Shut down */ 288 if (SHRestricted(REST_NOCLOSE)) 289 { 290 DeleteMenu(hMenu, 291 IDM_SHUTDOWN, 292 MF_BYCOMMAND); 293 uLastItemsCount--; 294 } 295 296 if (uLastItemsCount == 0) 297 { 298 /* Remove the separator at the end of the menu */ 299 DeleteMenu(hMenu, 300 IDM_LASTSTARTMENU_SEPARATOR, 301 MF_BYCOMMAND); 302 } 303 304 return S_OK; 305 } 306 307 /*******************************************************************/ 308 309 virtual HRESULT STDMETHODCALLTYPE QueryStatus( 310 IN const GUID *pguidCmdGroup OPTIONAL, 311 IN ULONG cCmds, 312 IN OUT OLECMD *prgCmds, 313 IN OUT OLECMDTEXT *pCmdText OPTIONAL) 314 { 315 return E_NOTIMPL; 316 } 317 318 virtual HRESULT STDMETHODCALLTYPE Exec( 319 IN const GUID *pguidCmdGroup OPTIONAL, 320 IN DWORD nCmdID, 321 IN DWORD nCmdExecOpt, 322 IN VARIANTARG *pvaIn OPTIONAL, 323 IN VARIANTARG *pvaOut OPTIONAL) 324 { 325 return E_NOTIMPL; 326 } 327 328 /*******************************************************************/ 329 330 virtual HRESULT STDMETHODCALLTYPE SetClient(IUnknown *punkClient) 331 { 332 return E_NOTIMPL; 333 } 334 335 virtual HRESULT STDMETHODCALLTYPE GetClient(IUnknown ** ppunkClient) 336 { 337 return E_NOTIMPL; 338 } 339 340 virtual HRESULT STDMETHODCALLTYPE OnPosRectChangeDB(RECT *prc) 341 { 342 return E_NOTIMPL; 343 } 344 345 virtual HRESULT STDMETHODCALLTYPE Popup(POINTL *ppt, RECTL *prcExclude, MP_POPUPFLAGS dwFlags) 346 { 347 return E_NOTIMPL; 348 } 349 350 virtual HRESULT STDMETHODCALLTYPE OnSelect(DWORD dwSelectType) 351 { 352 return E_NOTIMPL; 353 } 354 355 virtual HRESULT STDMETHODCALLTYPE SetSubMenu(IMenuPopup *pmp, BOOL fSet) 356 { 357 if (!fSet) 358 { 359 return Tray_OnStartMenuDismissed(m_Tray); 360 } 361 362 return S_OK; 363 } 364 365 /*******************************************************************/ 366 367 HRESULT Initialize(IN ITrayWindow *tray) 368 { 369 m_Tray = tray; 370 return S_OK; 371 } 372 373 DECLARE_NOT_AGGREGATABLE(CStartMenuSite) 374 375 DECLARE_PROTECT_FINAL_CONSTRUCT() 376 BEGIN_COM_MAP(CStartMenuSite) 377 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider) 378 COM_INTERFACE_ENTRY_IID(IID_ITrayPriv, ITrayPriv) 379 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget) 380 COM_INTERFACE_ENTRY_IID(IID_IMenuPopup, IMenuPopup) 381 COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow) 382 END_COM_MAP() 383 }; 384 385 HRESULT CStartMenuSite_CreateInstance(IN OUT ITrayWindow *Tray, const IID & riid, PVOID * ppv) 386 { 387 return ShellObjectCreatorInit<CStartMenuSite>(Tray, riid, ppv); 388 } 389