mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
8bd071a51e
Correct the details of Start Menu customization. JIRA issue: CORE-16956 - Hide the setting item if the item is restricted. - Don't change restriction in Explorer. - Fix Start Menu settings for restriction and registry. - Fix and simplify code.
361 lines
10 KiB
C++
361 lines
10 KiB
C++
/*
|
|
* ReactOS Explorer
|
|
*
|
|
* Copyright 2006 - 2007 Thomas Weidenmueller <w3seek@reactos.org>
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#include "precomp.h"
|
|
|
|
class CStartMenuSite :
|
|
public CComCoClass<CStartMenuSite>,
|
|
public CComObjectRootEx<CComMultiThreadModelNoCS>,
|
|
public IServiceProvider,
|
|
public ITrayPriv,
|
|
public IOleCommandTarget,
|
|
public IMenuPopup
|
|
{
|
|
CComPtr<ITrayWindow> m_Tray;
|
|
|
|
public:
|
|
CStartMenuSite()
|
|
{
|
|
}
|
|
|
|
virtual ~CStartMenuSite() {}
|
|
|
|
/*******************************************************************/
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE QueryService(
|
|
IN REFGUID guidService,
|
|
IN REFIID riid,
|
|
OUT PVOID *ppvObject)
|
|
{
|
|
if (IsEqualGUID(guidService, SID_SMenuPopup))
|
|
{
|
|
return QueryInterface(riid, ppvObject);
|
|
}
|
|
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
/*******************************************************************/
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetWindow(
|
|
OUT HWND *phwnd)
|
|
{
|
|
TRACE("ITrayPriv::GetWindow\n");
|
|
|
|
*phwnd = m_Tray->GetHWND();
|
|
if (*phwnd != NULL)
|
|
return S_OK;
|
|
|
|
return E_FAIL;
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(
|
|
IN BOOL fEnterMode)
|
|
{
|
|
TRACE("ITrayPriv::ContextSensitiveHelp\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE Execute(
|
|
IN IShellFolder *pShellFolder,
|
|
IN LPCITEMIDLIST pidl)
|
|
{
|
|
HRESULT ret = S_FALSE;
|
|
|
|
TRACE("ITrayPriv::Execute\n");
|
|
|
|
ret = SHInvokeDefaultCommand(m_Tray->GetHWND(), pShellFolder, pidl);
|
|
|
|
return ret;
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE Unknown(
|
|
IN PVOID Unknown1,
|
|
IN PVOID Unknown2,
|
|
IN PVOID Unknown3,
|
|
IN PVOID Unknown4)
|
|
{
|
|
TRACE("ITrayPriv::Unknown(0x%p,0x%p,0x%p,0x%p)\n", Unknown1, Unknown2, Unknown3, Unknown4);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
virtual BOOL
|
|
ShowUndockMenuItem(VOID)
|
|
{
|
|
TRACE("ShowUndockMenuItem() not implemented!\n");
|
|
/* FIXME: How do we detect this?! */
|
|
return FALSE;
|
|
}
|
|
|
|
virtual BOOL
|
|
ShowSynchronizeMenuItem(VOID)
|
|
{
|
|
TRACE("ShowSynchronizeMenuItem() not implemented!\n");
|
|
/* FIXME: How do we detect this?! */
|
|
return FALSE;
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE AppendMenu(
|
|
OUT HMENU* phMenu)
|
|
{
|
|
HMENU hMenu, hSettingsMenu;
|
|
DWORD dwLogoff;
|
|
BOOL bWantLogoff;
|
|
UINT uLastItemsCount = 5; /* 5 menu items below the last separator */
|
|
WCHAR szUser[128];
|
|
|
|
TRACE("ITrayPriv::AppendMenu\n");
|
|
|
|
hMenu = LoadPopupMenu(hExplorerInstance, MAKEINTRESOURCEW(IDM_STARTMENU));
|
|
*phMenu = hMenu;
|
|
if (hMenu == NULL)
|
|
return E_FAIL;
|
|
|
|
/* Remove menu items that don't apply */
|
|
|
|
/* Favorites */
|
|
if (SHRestricted(REST_NOFAVORITESMENU) ||
|
|
!GetAdvancedBool(L"StartMenuFavorites", FALSE))
|
|
{
|
|
DeleteMenu(hMenu, IDM_FAVORITES, MF_BYCOMMAND);
|
|
}
|
|
|
|
/* Documents */
|
|
if (SHRestricted(REST_NORECENTDOCSMENU) ||
|
|
!GetAdvancedBool(L"Start_ShowRecentDocs", TRUE))
|
|
{
|
|
DeleteMenu(hMenu, IDM_DOCUMENTS, MF_BYCOMMAND);
|
|
}
|
|
|
|
/* Settings */
|
|
hSettingsMenu = FindSubMenu(hMenu, IDM_SETTINGS, FALSE);
|
|
|
|
/* Control Panel */
|
|
if (SHRestricted(REST_NOSETFOLDERS) ||
|
|
SHRestricted(REST_NOCONTROLPANEL) ||
|
|
!GetAdvancedBool(L"Start_ShowControlPanel", TRUE))
|
|
{
|
|
DeleteMenu(hSettingsMenu, IDM_CONTROLPANEL, MF_BYCOMMAND);
|
|
|
|
/* Delete the separator below it */
|
|
DeleteMenu(hSettingsMenu, 0, MF_BYPOSITION);
|
|
}
|
|
|
|
/* Network Connections */
|
|
if (SHRestricted(REST_NOSETFOLDERS) ||
|
|
SHRestricted(REST_NONETWORKCONNECTIONS) ||
|
|
!GetAdvancedBool(L"Start_ShowNetConn", TRUE))
|
|
{
|
|
DeleteMenu(hSettingsMenu, IDM_NETWORKCONNECTIONS, MF_BYCOMMAND);
|
|
}
|
|
|
|
/* Printers and Faxes */
|
|
if (SHRestricted(REST_NOSETFOLDERS) ||
|
|
!GetAdvancedBool(L"Start_ShowPrinters", TRUE))
|
|
{
|
|
DeleteMenu(hSettingsMenu, IDM_PRINTERSANDFAXES, MF_BYCOMMAND);
|
|
}
|
|
|
|
/* Security */
|
|
if (SHRestricted(REST_NOSETFOLDERS) ||
|
|
GetSystemMetrics(SM_REMOTECONTROL) == 0 ||
|
|
SHRestricted(REST_NOSECURITY))
|
|
{
|
|
DeleteMenu(hSettingsMenu, IDM_SECURITY, MF_BYCOMMAND);
|
|
}
|
|
|
|
/* Delete Settings menu if it was empty */
|
|
if (GetMenuItemCount(hSettingsMenu) == 0)
|
|
{
|
|
DeleteMenu(hMenu, IDM_SETTINGS, MF_BYCOMMAND);
|
|
}
|
|
|
|
/* Search */
|
|
if (SHRestricted(REST_NOFIND) ||
|
|
!GetAdvancedBool(L"Start_ShowSearch", TRUE))
|
|
{
|
|
DeleteMenu(hMenu, IDM_SEARCH, MF_BYCOMMAND);
|
|
}
|
|
|
|
/* Help */
|
|
if (SHRestricted(REST_NOSMHELP) ||
|
|
!GetAdvancedBool(L"Start_ShowHelp", TRUE))
|
|
{
|
|
DeleteMenu(hMenu, IDM_HELPANDSUPPORT, MF_BYCOMMAND);
|
|
}
|
|
|
|
/* Run */
|
|
if (SHRestricted(REST_NORUN) ||
|
|
!GetAdvancedBool(L"StartMenuRun", TRUE))
|
|
{
|
|
DeleteMenu(hMenu, IDM_RUN, MF_BYCOMMAND);
|
|
}
|
|
|
|
/* Synchronize */
|
|
if (!ShowSynchronizeMenuItem())
|
|
{
|
|
DeleteMenu(hMenu, IDM_SYNCHRONIZE, MF_BYCOMMAND);
|
|
uLastItemsCount--;
|
|
}
|
|
|
|
/* Log off */
|
|
dwLogoff = SHRestricted(REST_STARTMENULOGOFF);
|
|
bWantLogoff = (dwLogoff == 2 ||
|
|
SHRestricted(REST_FORCESTARTMENULOGOFF) ||
|
|
GetAdvancedBool(L"StartMenuLogoff", FALSE));
|
|
if (dwLogoff != 1 && bWantLogoff)
|
|
{
|
|
/* FIXME: We need a more sophisticated way to determine whether to show
|
|
or hide it, it might be hidden in too many cases!!! */
|
|
|
|
/* Update Log Off menu item */
|
|
if (!GetCurrentLoggedOnUserName(szUser, _countof(szUser)))
|
|
{
|
|
szUser[0] = _T('\0');
|
|
}
|
|
|
|
if (!FormatMenuString(hMenu,
|
|
IDM_LOGOFF,
|
|
MF_BYCOMMAND,
|
|
szUser))
|
|
{
|
|
/* We couldn't update the menu item, delete it... */
|
|
DeleteMenu(hMenu, IDM_LOGOFF, MF_BYCOMMAND);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DeleteMenu(hMenu, IDM_LOGOFF, MF_BYCOMMAND);
|
|
uLastItemsCount--;
|
|
}
|
|
|
|
/* Disconnect */
|
|
if (SHRestricted(REST_NODISCONNECT) ||
|
|
GetSystemMetrics(SM_REMOTECONTROL) == 0)
|
|
{
|
|
DeleteMenu(hMenu, IDM_DISCONNECT, MF_BYCOMMAND);
|
|
uLastItemsCount--;
|
|
}
|
|
|
|
/* Undock computer */
|
|
if (!ShowUndockMenuItem())
|
|
{
|
|
DeleteMenu(hMenu, IDM_UNDOCKCOMPUTER, MF_BYCOMMAND);
|
|
uLastItemsCount--;
|
|
}
|
|
|
|
/* Shut down */
|
|
if (SHRestricted(REST_NOCLOSE))
|
|
{
|
|
DeleteMenu(hMenu, IDM_SHUTDOWN, MF_BYCOMMAND);
|
|
uLastItemsCount--;
|
|
}
|
|
|
|
if (uLastItemsCount == 0)
|
|
{
|
|
/* Remove the separator at the end of the menu */
|
|
DeleteMenu(hMenu, IDM_LASTSTARTMENU_SEPARATOR, MF_BYCOMMAND);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
/*******************************************************************/
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE QueryStatus(
|
|
IN const GUID *pguidCmdGroup OPTIONAL,
|
|
IN ULONG cCmds,
|
|
IN OUT OLECMD *prgCmds,
|
|
IN OUT OLECMDTEXT *pCmdText OPTIONAL)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE Exec(
|
|
IN const GUID *pguidCmdGroup OPTIONAL,
|
|
IN DWORD nCmdID,
|
|
IN DWORD nCmdExecOpt,
|
|
IN VARIANTARG *pvaIn OPTIONAL,
|
|
IN VARIANTARG *pvaOut OPTIONAL)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
/*******************************************************************/
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE SetClient(IUnknown *punkClient)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetClient(IUnknown ** ppunkClient)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE OnPosRectChangeDB(RECT *prc)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE Popup(POINTL *ppt, RECTL *prcExclude, MP_POPUPFLAGS dwFlags)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE OnSelect(DWORD dwSelectType)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE SetSubMenu(IMenuPopup *pmp, BOOL fSet)
|
|
{
|
|
if (!fSet)
|
|
{
|
|
return Tray_OnStartMenuDismissed(m_Tray);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
/*******************************************************************/
|
|
|
|
HRESULT Initialize(IN ITrayWindow *tray)
|
|
{
|
|
m_Tray = tray;
|
|
return S_OK;
|
|
}
|
|
|
|
DECLARE_NOT_AGGREGATABLE(CStartMenuSite)
|
|
|
|
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
|
BEGIN_COM_MAP(CStartMenuSite)
|
|
COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider)
|
|
COM_INTERFACE_ENTRY_IID(IID_ITrayPriv, ITrayPriv)
|
|
COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget)
|
|
COM_INTERFACE_ENTRY_IID(IID_IMenuPopup, IMenuPopup)
|
|
COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
|
|
END_COM_MAP()
|
|
};
|
|
|
|
HRESULT CStartMenuSite_CreateInstance(IN OUT ITrayWindow *Tray, const IID & riid, PVOID * ppv)
|
|
{
|
|
return ShellObjectCreatorInit<CStartMenuSite>(Tray, riid, ppv);
|
|
}
|