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