ReactOS 0.4.16-dev-329-g9223134
CDefViewBckgrndMenu.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: shell32
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/win32/shell32/CDefViewBckgrndMenu.cpp
5 * PURPOSE: background context menu of the CDefView
6 * PROGRAMMERS: Giannis Adamopoulos
7 */
8
9#include <precomp.h>
10
12
14 public CComObjectRootEx<CComMultiThreadModelNoCS>,
15 public IContextMenu3,
16 public IObjectWithSite
17{
18 private:
22
25
28 public:
32
33 // IContextMenu
34 STDMETHOD(QueryContextMenu)(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags) override;
36 STDMETHOD(GetCommandString)(UINT_PTR idCommand, UINT uFlags, UINT *lpReserved, LPSTR lpszName, UINT uMaxNameLen) override;
37
38 // IContextMenu2
40
41 // IContextMenu3
42 STDMETHOD(HandleMenuMsg2)(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *plResult) override;
43
44 // IObjectWithSite
45 STDMETHOD(SetSite)(IUnknown *pUnkSite) override;
46 STDMETHOD(GetSite)(REFIID riid, void **ppvSite) override;
47
49 COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
50 COM_INTERFACE_ENTRY_IID(IID_IContextMenu2, IContextMenu2)
51 COM_INTERFACE_ENTRY_IID(IID_IContextMenu3, IContextMenu3)
54};
55
57{
58 m_idCmdFirst = 0;
60}
61
63{
64}
65
67{
68 if (!m_site)
69 return FALSE;
70
71 /* Get a pointer to the shell browser */
75 return FALSE;
76
77 FOLDERSETTINGS FolderSettings;
78 hr = psv->GetCurrentInfo(&FolderSettings);
80 return FALSE;
81
82 return ((FolderSettings.fFlags & FWF_DESKTOP) == FWF_DESKTOP);
83}
84
86{
87 /* If the folder doesn't have a drop target we can't paste */
89 HRESULT hr = m_psf->CreateViewObject(NULL, IID_PPV_ARG(IDropTarget, &pdt));
90 if (FAILED(hr))
91 return FALSE;
92
93 /* We can only paste if CFSTR_SHELLIDLIST is present in the clipboard */
94 CComPtr<IDataObject> pDataObj;
95 hr = OleGetClipboard(&pDataObj);
96 if (FAILED(hr))
97 return FALSE;
98
99 STGMEDIUM medium;
100 FORMATETC formatetc;
101
102 /* Set the FORMATETC structure*/
103 InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_SHELLIDLIST), TYMED_HGLOBAL);
104 hr = pDataObj->GetData(&formatetc, &medium);
105 if (FAILED(hr))
106 return FALSE;
107
108 ReleaseStgMedium(&medium);
109 return TRUE;
110}
111
114{
115 m_psf = psf;
116
117 /* Get the context menu of the folder. Do it here because someone may call
118 InvokeCommand without calling QueryContextMenu. It is fine if this fails */
119 m_psf->CreateViewObject(NULL, IID_PPV_ARG(IContextMenu, &m_folderCM));
120
121 return S_OK;
122}
123
125WINAPI
127{
128 m_site = pUnkSite;
129
130 if(m_folderCM)
131 IUnknown_SetSite(m_folderCM, pUnkSite);
132
133 return S_OK;
134}
135
137WINAPI
139{
140 if (!m_site)
141 return E_FAIL;
142
143 return m_site->QueryInterface(riid, ppvSite);
144}
145
147WINAPI
148CDefViewBckgrndMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
149{
150 HRESULT hr;
151 HMENU hMenuPart;
152 UINT cIds = 0;
153
154 /* This is something the implementations of IContextMenu should never really do.
155 However CDefViewBckgrndMenu is more or less an overengineering result, its code could really be part of the
156 CDefView. Given this, I think that abusing the interface here is not that bad since only CDefView is the ony
157 user of this class. Here we need to do two things to keep things as simple as possible.
158 First we want the menu part added by the shell folder to be the first to add so as to make as few id translations
159 as possible. Second, we want to add the default part of the background menu without shifted ids, so as
160 to let the CDefView fill some parts like filling the arrange modes or checking the view mode. In order
161 for that to work we need to save idCmdFirst because our caller will pass id offsets to InvokeCommand.
162 This makes it impossible to concatenate the CDefViewBckgrndMenu with other menus since it abuses IContextMenu
163 but as stated above, its sole user is CDefView and should really be that way. */
164 m_idCmdFirst = idCmdFirst;
165
166 /* Let the shell folder add any items it wants to add in the background context menu */
167 if (m_folderCM)
168 {
169 hr = m_folderCM->QueryContextMenu(hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags);
170 if (SUCCEEDED(hr))
171 {
173 cIds = m_LastFolderCMId;
174 }
175 else
176 {
177 WARN("QueryContextMenu failed!\n");
178 }
179 }
180 else
181 {
182 WARN("GetUIObjectOf didn't give any context menu!\n");
183 }
184
185 /* Load the default part of the background context menu */
186 hMenuPart = LoadMenuW(shell32_hInstance, L"MENU_002");
187 if (hMenuPart)
188 {
189 /* Don't show the view submenu for the desktop */
191 {
193 }
194
195 /* Disable the paste options if it is not possible */
196 if (!_bCanPaste())
197 {
200 }
201
202 /* merge general background context menu in */
203 Shell_MergeMenus(hMenu, GetSubMenu(hMenuPart, 0), indexMenu, 0, idCmdLast, MM_DONTREMOVESEPS | MM_SUBMENUSHAVEIDS | MM_ADDSEPARATOR);
204 DestroyMenu(hMenuPart);
205 }
206 else
207 {
208 ERR("Failed to load menu from resource!\n");
209 }
210
211 return MAKE_HRESULT(SEVERITY_SUCCESS, 0, cIds);
212}
213
215WINAPI
217{
218 UINT idCmd = LOWORD(lpcmi->lpVerb);
219
220 if (HIWORD(lpcmi->lpVerb) && !strcmp(lpcmi->lpVerb, CMDSTR_VIEWLISTA))
221 {
222 idCmd = FCIDM_SHVIEW_LISTVIEW;
223 }
224 else if (HIWORD(lpcmi->lpVerb) && !strcmp(lpcmi->lpVerb, CMDSTR_VIEWDETAILSA))
225 {
227 }
228 else if(HIWORD(lpcmi->lpVerb) != 0 || idCmd < m_LastFolderCMId)
229 {
230 if (m_folderCM)
231 {
232 return m_folderCM->InvokeCommand(lpcmi);
233 }
234 WARN("m_folderCM is NULL!\n");
235 return E_NOTIMPL;
236 }
237 else
238 {
239 /* The default part of the background menu doesn't have shifted ids so we need to convert the id offset to the real id */
240 idCmd += m_idCmdFirst;
241 }
242
243 /* The commands that are handled by the def view are forwarded to it */
244 switch (idCmd)
245 {
248 if (m_folderCM)
249 {
250 lpcmi->lpVerb = MAKEINTRESOURCEA(idCmd);
251 return m_folderCM->InvokeCommand(lpcmi);
252 }
253 WARN("m_folderCM is NULL!\n");
254 return E_NOTIMPL;
263 if (!m_site)
264 return E_FAIL;
265
266 /* Get a pointer to the shell browser */
270 return hr;
271
272 HWND hwndSV = NULL;
273 if (SUCCEEDED(psv->GetWindow(&hwndSV)))
274 SendMessageW(hwndSV, WM_COMMAND, MAKEWPARAM(idCmd, 0), 0);
275 return S_OK;
276 }
277
278 ERR("Got unknown command id %ul\n", LOWORD(lpcmi->lpVerb));
279 return E_FAIL;
280}
281
283WINAPI
284CDefViewBckgrndMenu::GetCommandString(UINT_PTR idCommand, UINT uFlags, UINT *lpReserved, LPSTR lpszName, UINT uMaxNameLen)
285{
286 if (m_folderCM)
287 {
288 return m_folderCM->GetCommandString(idCommand, uFlags, lpReserved, lpszName, uMaxNameLen);
289 }
290
291 return E_NOTIMPL;
292}
293
295WINAPI
297{
298 if(m_folderCM)
299 {
300 CComPtr<IContextMenu2> pfolderCM2;
301 HRESULT hr = m_folderCM->QueryInterface(IID_PPV_ARG(IContextMenu2, &pfolderCM2));
303 return hr;
304
305 return pfolderCM2->HandleMenuMsg(uMsg, wParam, lParam);
306 }
307
308 return E_NOTIMPL;
309}
310
312WINAPI
314{
315 if(m_folderCM)
316 {
317 CComPtr<IContextMenu3> pfolderCM3;
318 HRESULT hr = m_folderCM->QueryInterface(IID_PPV_ARG(IContextMenu3, &pfolderCM3));
320 return hr;
321
322 return pfolderCM3->HandleMenuMsg2(uMsg, wParam, lParam, plResult);
323 }
324
325 return E_NOTIMPL;
326}
327
328
331{
332 return ShellObjectCreatorInit<CDefViewBckgrndMenu>(psf, riid, ppv);
333}
HRESULT CDefViewBckgrndMenu_CreateInstance(IShellFolder *psf, REFIID riid, void **ppv)
#define shell32_hInstance
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
void shell(int argc, const char *argv[])
Definition: cmds.c:1231
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
#define STDMETHOD(m)
Definition: basetyps.h:62
STDMETHOD() QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags) override
CComPtr< IShellFolder > m_psf
CComPtr< IUnknown > m_site
STDMETHOD() HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam) override
CComPtr< IContextMenu > m_folderCM
STDMETHOD() HandleMenuMsg2(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *plResult) override
HRESULT Initialize(IShellFolder *psf)
STDMETHOD() InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi) override
STDMETHOD() GetSite(REFIID riid, void **ppvSite) override
STDMETHOD() SetSite(IUnknown *pUnkSite) override
STDMETHOD() GetCommandString(UINT_PTR idCommand, UINT uFlags, UINT *lpReserved, LPSTR lpszName, UINT uMaxNameLen) override
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
#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
#define FALSE
Definition: types.h:117
UINT uFlags
Definition: api.c:59
#define FAILED_UNEXPECTEDLY(hr)
Definition: precomp.h:121
HRESULT WINAPI OleGetClipboard(IDataObject **obj)
Definition: clipboard.c:2249
void WINAPI ReleaseStgMedium(STGMEDIUM *pmedium)
Definition: ole2.c:2033
HRESULT WINAPI IUnknown_QueryService(IUnknown *, REFGUID, REFIID, LPVOID *)
Definition: ordinal.c:1501
HRESULT WINAPI IUnknown_SetSite(IUnknown *obj, IUnknown *site)
Definition: ordinal.c:1411
#define MAKE_HRESULT(sev, fac, code)
Definition: dmerror.h:30
#define InitFormatEtc(fe, cf, med)
Definition: editor.h:32
unsigned int BOOL
Definition: ntddk_ex.h:94
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#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
const IID IID_IObjectWithSite
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
#define L(x)
Definition: ntvdm.h:50
#define LOWORD(l)
Definition: pedump.c:82
#define REFIID
Definition: guiddef.h:118
HRESULT hr
Definition: shlfolder.c:183
#define SID_IFolderView
UINT WINAPI Shell_MergeMenus(HMENU hmDst, HMENU hmSrc, UINT uInsert, UINT uIDAdjust, UINT uIDAdjustMax, ULONG uFlags)
Definition: shlmenu.c:856
#define CFSTR_SHELLIDLIST
Definition: shlobj.h:550
#define MM_SUBMENUSHAVEIDS
Definition: shlobj.h:2529
#define MM_DONTREMOVESEPS
Definition: shlobj.h:2530
#define MM_ADDSEPARATOR
Definition: shlobj.h:2528
@ FWF_DESKTOP
Definition: shobjidl.idl:647
#define FCIDM_SHVIEW_AUTOARRANGE
Definition: shresdef.h:843
#define FCIDM_SHVIEW_LISTVIEW
Definition: shresdef.h:840
#define FCIDM_SHVIEW_ALIGNTOGRID
Definition: shresdef.h:845
#define FCIDM_SHVIEW_BIGICON
Definition: shresdef.h:838
#define FCIDM_SHVIEW_INSERTLINK
Definition: shresdef.h:832
#define FCIDM_SHVIEW_REFRESH
Definition: shresdef.h:853
#define FCIDM_SHVIEW_SMALLICON
Definition: shresdef.h:839
#define FCIDM_SHVIEW_SNAPTOGRID
Definition: shresdef.h:844
#define FCIDM_SHVIEW_VIEW
Definition: shresdef.h:825
#define FCIDM_SHVIEW_REPORTVIEW
Definition: shresdef.h:841
#define FCIDM_SHVIEW_INSERT
Definition: shresdef.h:830
#define HIWORD(l)
Definition: typedefs.h:247
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
UINT_PTR WPARAM
Definition: windef.h:207
#define WINAPI
Definition: msvc.h:6
#define SEVERITY_SUCCESS
Definition: winerror.h:64
#define MAKEWPARAM(l, h)
Definition: winuser.h:4012
#define MF_BYCOMMAND
Definition: winuser.h:202
#define WM_COMMAND
Definition: winuser.h:1743
UINT WINAPI RegisterClipboardFormatW(_In_ LPCWSTR)
BOOL WINAPI DeleteMenu(_In_ HMENU, _In_ UINT, _In_ UINT)
HMENU WINAPI GetSubMenu(_In_ HMENU, _In_ int)
#define MAKEINTRESOURCEA(i)
Definition: winuser.h:581
BOOL WINAPI DestroyMenu(_In_ HMENU)
HMENU WINAPI LoadMenuW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
BOOL WINAPI EnableMenuItem(_In_ HMENU, _In_ UINT, _In_ UINT)
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define MF_GRAYED
Definition: winuser.h:129
static void Initialize()
Definition: xlate.c:212
#define IID_PPV_ARG(Itype, ppType)
char * LPSTR
Definition: xmlstorage.h:182