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 /* Favorites */ 134 if (SHRestricted(REST_NOFAVORITESMENU) || 135 !GetAdvancedBool(L"StartMenuFavorites", FALSE)) 136 { 137 DeleteMenu(hMenu, IDM_FAVORITES, MF_BYCOMMAND); 138 } 139 140 /* Documents */ 141 if (SHRestricted(REST_NORECENTDOCSMENU) || 142 !GetAdvancedBool(L"Start_ShowRecentDocs", TRUE)) 143 { 144 DeleteMenu(hMenu, IDM_DOCUMENTS, MF_BYCOMMAND); 145 } 146 147 /* Settings */ 148 hSettingsMenu = FindSubMenu(hMenu, IDM_SETTINGS, FALSE); 149 150 /* Control Panel */ 151 if (SHRestricted(REST_NOSETFOLDERS) || 152 SHRestricted(REST_NOCONTROLPANEL) || 153 !GetAdvancedBool(L"Start_ShowControlPanel", TRUE)) 154 { 155 DeleteMenu(hSettingsMenu, IDM_CONTROLPANEL, MF_BYCOMMAND); 156 157 /* Delete the separator below it */ 158 DeleteMenu(hSettingsMenu, 0, MF_BYPOSITION); 159 } 160 161 /* Network Connections */ 162 if (SHRestricted(REST_NOSETFOLDERS) || 163 SHRestricted(REST_NONETWORKCONNECTIONS) || 164 !GetAdvancedBool(L"Start_ShowNetConn", TRUE)) 165 { 166 DeleteMenu(hSettingsMenu, IDM_NETWORKCONNECTIONS, MF_BYCOMMAND); 167 } 168 169 /* Printers and Faxes */ 170 if (SHRestricted(REST_NOSETFOLDERS) || 171 !GetAdvancedBool(L"Start_ShowPrinters", TRUE)) 172 { 173 DeleteMenu(hSettingsMenu, IDM_PRINTERSANDFAXES, MF_BYCOMMAND); 174 } 175 176 /* Security */ 177 if (SHRestricted(REST_NOSETFOLDERS) || 178 GetSystemMetrics(SM_REMOTECONTROL) == 0 || 179 SHRestricted(REST_NOSECURITY)) 180 { 181 DeleteMenu(hSettingsMenu, IDM_SECURITY, MF_BYCOMMAND); 182 } 183 184 /* Delete Settings menu if it was empty */ 185 if (GetMenuItemCount(hSettingsMenu) == 0) 186 { 187 DeleteMenu(hMenu, IDM_SETTINGS, MF_BYCOMMAND); 188 } 189 190 /* Search */ 191 if (SHRestricted(REST_NOFIND) || 192 !GetAdvancedBool(L"Start_ShowSearch", TRUE)) 193 { 194 DeleteMenu(hMenu, IDM_SEARCH, MF_BYCOMMAND); 195 } 196 197 /* Help */ 198 if (SHRestricted(REST_NOSMHELP) || 199 !GetAdvancedBool(L"Start_ShowHelp", TRUE)) 200 { 201 DeleteMenu(hMenu, IDM_HELPANDSUPPORT, MF_BYCOMMAND); 202 } 203 204 /* Run */ 205 if (SHRestricted(REST_NORUN) || 206 !GetAdvancedBool(L"StartMenuRun", TRUE)) 207 { 208 DeleteMenu(hMenu, IDM_RUN, MF_BYCOMMAND); 209 } 210 211 /* Synchronize */ 212 if (!ShowSynchronizeMenuItem()) 213 { 214 DeleteMenu(hMenu, IDM_SYNCHRONIZE, MF_BYCOMMAND); 215 uLastItemsCount--; 216 } 217 218 /* Log off */ 219 dwLogoff = SHRestricted(REST_STARTMENULOGOFF); 220 bWantLogoff = (dwLogoff == 2 || 221 SHRestricted(REST_FORCESTARTMENULOGOFF) || 222 GetAdvancedBool(L"StartMenuLogoff", FALSE)); 223 if (dwLogoff != 1 && bWantLogoff) 224 { 225 /* FIXME: We need a more sophisticated way to determine whether to show 226 or hide it, it might be hidden in too many cases!!! */ 227 228 /* Update Log Off menu item */ 229 if (!GetCurrentLoggedOnUserName(szUser, _countof(szUser))) 230 { 231 szUser[0] = _T('\0'); 232 } 233 234 if (!FormatMenuString(hMenu, 235 IDM_LOGOFF, 236 MF_BYCOMMAND, 237 szUser)) 238 { 239 /* We couldn't update the menu item, delete it... */ 240 DeleteMenu(hMenu, IDM_LOGOFF, MF_BYCOMMAND); 241 } 242 } 243 else 244 { 245 DeleteMenu(hMenu, IDM_LOGOFF, MF_BYCOMMAND); 246 uLastItemsCount--; 247 } 248 249 /* Disconnect */ 250 if (SHRestricted(REST_NODISCONNECT) || 251 GetSystemMetrics(SM_REMOTECONTROL) == 0) 252 { 253 DeleteMenu(hMenu, IDM_DISCONNECT, MF_BYCOMMAND); 254 uLastItemsCount--; 255 } 256 257 /* Undock computer */ 258 if (!ShowUndockMenuItem()) 259 { 260 DeleteMenu(hMenu, IDM_UNDOCKCOMPUTER, MF_BYCOMMAND); 261 uLastItemsCount--; 262 } 263 264 /* Shut down */ 265 if (SHRestricted(REST_NOCLOSE)) 266 { 267 DeleteMenu(hMenu, IDM_SHUTDOWN, MF_BYCOMMAND); 268 uLastItemsCount--; 269 } 270 271 if (uLastItemsCount == 0) 272 { 273 /* Remove the separator at the end of the menu */ 274 DeleteMenu(hMenu, IDM_LASTSTARTMENU_SEPARATOR, MF_BYCOMMAND); 275 } 276 277 return S_OK; 278 } 279 280 /*******************************************************************/ 281 282 virtual HRESULT STDMETHODCALLTYPE QueryStatus( 283 IN const GUID *pguidCmdGroup OPTIONAL, 284 IN ULONG cCmds, 285 IN OUT OLECMD *prgCmds, 286 IN OUT OLECMDTEXT *pCmdText OPTIONAL) 287 { 288 return E_NOTIMPL; 289 } 290 291 virtual HRESULT STDMETHODCALLTYPE Exec( 292 IN const GUID *pguidCmdGroup OPTIONAL, 293 IN DWORD nCmdID, 294 IN DWORD nCmdExecOpt, 295 IN VARIANTARG *pvaIn OPTIONAL, 296 IN VARIANTARG *pvaOut OPTIONAL) 297 { 298 return E_NOTIMPL; 299 } 300 301 /*******************************************************************/ 302 303 virtual HRESULT STDMETHODCALLTYPE SetClient(IUnknown *punkClient) 304 { 305 return E_NOTIMPL; 306 } 307 308 virtual HRESULT STDMETHODCALLTYPE GetClient(IUnknown ** ppunkClient) 309 { 310 return E_NOTIMPL; 311 } 312 313 virtual HRESULT STDMETHODCALLTYPE OnPosRectChangeDB(RECT *prc) 314 { 315 return E_NOTIMPL; 316 } 317 318 virtual HRESULT STDMETHODCALLTYPE Popup(POINTL *ppt, RECTL *prcExclude, MP_POPUPFLAGS dwFlags) 319 { 320 return E_NOTIMPL; 321 } 322 323 virtual HRESULT STDMETHODCALLTYPE OnSelect(DWORD dwSelectType) 324 { 325 return E_NOTIMPL; 326 } 327 328 virtual HRESULT STDMETHODCALLTYPE SetSubMenu(IMenuPopup *pmp, BOOL fSet) 329 { 330 if (!fSet) 331 { 332 return Tray_OnStartMenuDismissed(m_Tray); 333 } 334 335 return S_OK; 336 } 337 338 /*******************************************************************/ 339 340 HRESULT Initialize(IN ITrayWindow *tray) 341 { 342 m_Tray = tray; 343 return S_OK; 344 } 345 346 DECLARE_NOT_AGGREGATABLE(CStartMenuSite) 347 348 DECLARE_PROTECT_FINAL_CONSTRUCT() 349 BEGIN_COM_MAP(CStartMenuSite) 350 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider) 351 COM_INTERFACE_ENTRY_IID(IID_ITrayPriv, ITrayPriv) 352 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget) 353 COM_INTERFACE_ENTRY_IID(IID_IMenuPopup, IMenuPopup) 354 COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow) 355 END_COM_MAP() 356 }; 357 358 HRESULT CStartMenuSite_CreateInstance(IN OUT ITrayWindow *Tray, const IID & riid, PVOID * ppv) 359 { 360 return ShellObjectCreatorInit<CStartMenuSite>(Tray, riid, ppv); 361 } 362