ReactOS 0.4.16-dev-751-g45ed1a9
startctxmnu.cpp
Go to the documentation of this file.
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/*
24 * Start menu button context menu
25 */
26
28 public CComCoClass<CStartMenuBtnCtxMenu>,
29 public CComObjectRootEx<CComMultiThreadModelNoCS>,
30 public IContextMenu
31{
32 /* AddStartContextMenuItems uses ID_SHELL_CMD IDs directly and relies on idCmdFirst being 0.
33 * CTrayWindow::TrackCtxMenu must pass 0 because DeleteMenu ID_SHELL_CMD_UNDO_ACTION would
34 * delete the wrong item if it used 1. m_Inner->QueryContextMenu is not aware of this game
35 * so we have to reserve the entire ID_SHELL_CMD range for ourselves here. */
37 static BOOL IsShellCmdId(UINT_PTR id) { return id < INNERIDOFFSET; }
38
42
45
47 {
48 HRESULT hRet;
49
51 if (SUCCEEDED(hRet))
52 {
53 if (hPopup != NULL)
54 {
55 hRet = m_Inner->QueryContextMenu(
56 hPopup,
57 0,
58 idCmdFirst,
59 idCmdLast,
60 CMF_VERBSONLY);
61
62 if (SUCCEEDED(hRet))
63 {
64 return hRet;
65 }
66 }
67 }
68 return E_FAIL;
69 }
70
72 {
73 WCHAR szBuf[MAX_PATH];
74 HRESULT hRet;
76 /* If this ever asserts, let m_Inner use 1..ID_SHELL_CMD_FIRST-1 instead */
77 C_ASSERT(ID_SHELL_CMD_LAST < 0xffff / 2);
78
79 /* Add the "Open All Users" menu item */
82 szBuf,
83 _countof(szBuf)))
84 {
85 AppendMenu(hPopup,
88 szBuf);
89 }
90
92 {
93 /* Check if we should add menu items for the common start menu */
96 NULL,
98 szBuf);
99 if (SUCCEEDED(hRet) && hRet != S_FALSE)
100 {
101 /* The directory exists, but only show the items if the
102 user can actually make any changes to the common start
103 menu. This is most likely only the case if the user
104 has administrative rights! */
105 if (IsUserAnAdmin())
106 {
107 AppendMenu(hPopup,
109 0,
110 NULL);
111
112 /* Add the "Open All Users" menu item */
115 szBuf,
116 _countof(szBuf)))
117 {
118 AppendMenu(hPopup,
119 MF_STRING,
121 szBuf);
122 }
123
124 /* Add the "Explore All Users" menu item */
127 szBuf,
128 _countof(szBuf)))
129 {
130 AppendMenu(hPopup,
131 MF_STRING,
133 szBuf);
134 }
135 }
136 }
137 }
138 }
139
140public:
141 HRESULT Initialize(ITrayWindow * pTrayWnd, IN HWND hWndOwner)
142 {
143 m_TrayWnd = pTrayWnd;
144 m_Owner = hWndOwner;
145 return S_OK;
146 }
147
150 UINT indexMenu,
151 UINT idCmdFirst,
152 UINT idCmdLast,
153 UINT uFlags) override
154 {
155 LPITEMIDLIST pidlStart;
156 CComPtr<IShellFolder> psfDesktop;
157 HRESULT hRet = S_OK;
158 UINT idInnerFirst = idCmdFirst + INNERIDOFFSET;
159
160 psfDesktop = NULL;
161 m_Inner = NULL;
162
164 if (pidlStart != NULL)
165 {
166 m_FolderPidl = ILClone(ILFindLastID(pidlStart));
167 ILRemoveLastID(pidlStart);
168
169 if (m_FolderPidl != NULL)
170 {
171 hRet = SHGetDesktopFolder(&psfDesktop);
172 if (SUCCEEDED(hRet))
173 {
174 hRet = psfDesktop->BindToObject(pidlStart, NULL, IID_PPV_ARG(IShellFolder, &m_Folder));
175 if (SUCCEEDED(hRet))
176 {
177 hRet = CreateContextMenuFromShellFolderPidl(hPopup, idInnerFirst, idCmdLast);
178 }
179 }
180 }
181
182 ILFree(pidlStart);
183 }
184 if (idCmdLast - idCmdFirst >= ID_SHELL_CMD_LAST - ID_SHELL_CMD_FIRST)
185 {
187 hRet = SUCCEEDED(hRet) ? hRet + idInnerFirst : idInnerFirst;
188 }
189 return hRet;
190 }
191
194 {
195 UINT uiCmdId = PtrToUlong(lpici->lpVerb);
196 if (!IsShellCmdId(uiCmdId))
197 {
198 CMINVOKECOMMANDINFOEX cmici = { sizeof(cmici) };
199
200 /* Setup and invoke the shell command */
201 cmici.hwnd = m_Owner;
202 cmici.nShow = SW_NORMAL;
203 cmici.fMask = CMIC_MASK_UNICODE;
204 WCHAR szVerbW[MAX_PATH];
205 if (IS_INTRESOURCE(lpici->lpVerb))
206 {
207 cmici.lpVerb = MAKEINTRESOURCEA(uiCmdId - INNERIDOFFSET);
208 cmici.lpVerbW = MAKEINTRESOURCEW(uiCmdId - INNERIDOFFSET);
209 }
210 else
211 {
212 cmici.lpVerb = lpici->lpVerb;
213 SHAnsiToUnicode(lpici->lpVerb, szVerbW, _countof(szVerbW));
214 cmici.lpVerbW = szVerbW;
215 }
216
217 CHAR szDirA[MAX_PATH];
218 WCHAR szDirW[MAX_PATH];
220 {
221 SHUnicodeToAnsi(szDirW, szDirA, _countof(szDirA));
222 cmici.lpDirectory = szDirA;
223 cmici.lpDirectoryW = szDirW;
224 }
225
226 return m_Inner->InvokeCommand((LPCMINVOKECOMMANDINFO)&cmici);
227 }
228 m_TrayWnd->ExecContextMenuCmd(uiCmdId);
229 return S_OK;
230 }
231
234 UINT_PTR idCmd,
235 UINT uType,
236 UINT *pwReserved,
237 LPSTR pszName,
238 UINT cchMax) override
239 {
240 if (!IsShellCmdId(idCmd) && m_Inner)
241 return m_Inner->GetCommandString(idCmd, uType, pwReserved, pszName, cchMax);
242 return E_NOTIMPL;
243 }
244
246 {
247 }
248
250 {
251 if (m_FolderPidl)
253 }
254
256 COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
258};
259
260HRESULT CStartMenuBtnCtxMenu_CreateInstance(ITrayWindow * m_TrayWnd, IN HWND m_Owner, IContextMenu ** ppCtxMenu)
261{
262 return ShellObjectCreatorInit<CStartMenuBtnCtxMenu>(m_TrayWnd, m_Owner, IID_PPV_ARG(IContextMenu, ppCtxMenu));
263}
HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
UINT cchMax
HINSTANCE hExplorerInstance
Definition: explorer.cpp:24
#define IDS_PROPERTIES
Definition: resource.h:102
#define ID_SHELL_CMD_PROPERTIES
Definition: resource.h:205
#define ID_SHELL_CMD_FIRST
Definition: resource.h:218
#define IDS_EXPLORE_ALL_USERS
Definition: resource.h:101
#define ID_SHELL_CMD_EXPLORE_ALL_USERS
Definition: resource.h:207
#define IDS_OPEN_ALL_USERS
Definition: resource.h:100
#define ID_SHELL_CMD_OPEN_ALL_USERS
Definition: resource.h:206
#define ID_SHELL_CMD_LAST
Definition: resource.h:219
#define STDMETHODIMP
Definition: basetyps.h:43
LPITEMIDLIST m_FolderPidl
Definition: startctxmnu.cpp:44
HRESULT CreateContextMenuFromShellFolderPidl(HMENU hPopup, UINT idCmdFirst, UINT idCmdLast)
Definition: startctxmnu.cpp:46
STDMETHODIMP QueryContextMenu(HMENU hPopup, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags) override
CComPtr< IShellFolder > m_Folder
Definition: startctxmnu.cpp:41
CComPtr< IContextMenu > m_Inner
Definition: startctxmnu.cpp:40
CComPtr< ITrayWindow > m_TrayWnd
Definition: startctxmnu.cpp:39
VOID AddStartContextMenuItems(IN HMENU hPopup)
Definition: startctxmnu.cpp:71
HRESULT Initialize(ITrayWindow *pTrayWnd, IN HWND hWndOwner)
virtual ~CStartMenuBtnCtxMenu()
STDMETHODIMP InvokeCommand(LPCMINVOKECOMMANDINFO lpici) override
static BOOL IsShellCmdId(UINT_PTR id)
Definition: startctxmnu.cpp:37
STDMETHODIMP GetCommandString(UINT_PTR idCmd, UINT uType, UINT *pwReserved, LPSTR pszName, UINT cchMax) override
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
UINT uFlags
Definition: api.c:59
#define MAX_PATH
Definition: compat.h:34
DWORD WINAPI SHAnsiToUnicode(LPCSTR lpSrcStr, LPWSTR lpDstStr, int iLen)
Definition: string.c:2673
INT WINAPI SHUnicodeToAnsi(LPCWSTR lpSrcStr, LPSTR lpDstStr, INT iLen)
Definition: string.c:2797
#define PtrToUlong(u)
Definition: config.h:107
unsigned int BOOL
Definition: ntddk_ex.h:94
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define C_ASSERT(e)
Definition: intsafe.h:73
#define BEGIN_COM_MAP(x)
Definition: atlcom.h:581
#define COM_INTERFACE_ENTRY_IID(iid, x)
Definition: atlcom.h:601
#define END_COM_MAP()
Definition: atlcom.h:592
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:63
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
unsigned int UINT
Definition: ndis.h:50
LPITEMIDLIST WINAPI SHCloneSpecialIDList(HWND hwndOwner, int nFolder, BOOL fCreate)
Definition: pidl.c:445
LPITEMIDLIST WINAPI ILClone(LPCITEMIDLIST pidl)
Definition: pidl.c:237
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:1044
LPITEMIDLIST WINAPI ILFindLastID(LPCITEMIDLIST pidl)
Definition: pidl.c:198
BOOL WINAPI ILRemoveLastID(LPITEMIDLIST pidl)
Definition: pidl.c:221
BOOL WINAPI SHGetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath)
Definition: pidl.c:1454
#define SHGetFolderPath
Definition: shlobj.h:2171
#define CSIDL_COMMON_STARTMENU
Definition: shlobj.h:2194
@ SHGFP_TYPE_CURRENT
Definition: shlobj.h:2149
BOOL WINAPI IsUserAnAdmin(void)
Definition: shellord.c:2807
#define CSIDL_STARTMENU
Definition: shlobj.h:2184
@ REST_NOCOMMONGROUPS
Definition: shlobj.h:1665
DWORD WINAPI SHRestricted(RESTRICTIONS rest)
Definition: shpolicy.c:150
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
#define _countof(array)
Definition: sndvol32.h:70
HRESULT CStartMenuBtnCtxMenu_CreateInstance(ITrayWindow *m_TrayWnd, IN HWND m_Owner, IContextMenu **ppCtxMenu)
#define IN
Definition: typedefs.h:39
#define S_FALSE
Definition: winerror.h:2357
#define AppendMenu
Definition: winuser.h:5743
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
#define IS_INTRESOURCE(i)
Definition: winuser.h:580
#define MF_STRING
Definition: winuser.h:138
#define MF_SEPARATOR
Definition: winuser.h:137
#define MAKEINTRESOURCEA(i)
Definition: winuser.h:581
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
#define SW_NORMAL
Definition: winuser.h:772
#define IID_PPV_ARG(Itype, ppType)
#define IID_NULL_PPV_ARG(Itype, ppType)
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
char CHAR
Definition: xmlstorage.h:175