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
11 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
13 class CDefViewBckgrndMenu
:
14 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
16 public IObjectWithSite
19 CComPtr
<IUnknown
> m_site
;
20 CComPtr
<IShellFolder
> m_psf
;
21 CComPtr
<IContextMenu
> m_folderCM
;
23 BOOL
_bIsDesktopBrowserMenu();
26 CDefViewBckgrndMenu();
27 ~CDefViewBckgrndMenu();
28 HRESULT
Initialize(IShellFolder
* psf
);
31 virtual HRESULT WINAPI
QueryContextMenu(HMENU hMenu
, UINT indexMenu
, UINT idCmdFirst
, UINT idCmdLast
, UINT uFlags
);
32 virtual HRESULT WINAPI
InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi
);
33 virtual HRESULT WINAPI
GetCommandString(UINT_PTR idCommand
, UINT uFlags
, UINT
*lpReserved
, LPSTR lpszName
, UINT uMaxNameLen
);
36 virtual HRESULT WINAPI
HandleMenuMsg(UINT uMsg
, WPARAM wParam
, LPARAM lParam
);
39 virtual HRESULT WINAPI
HandleMenuMsg2(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, LRESULT
*plResult
);
42 virtual HRESULT STDMETHODCALLTYPE
SetSite(IUnknown
*pUnkSite
);
43 virtual HRESULT STDMETHODCALLTYPE
GetSite(REFIID riid
, void **ppvSite
);
45 BEGIN_COM_MAP(CDefViewBckgrndMenu
)
46 COM_INTERFACE_ENTRY_IID(IID_IContextMenu
, IContextMenu
)
47 COM_INTERFACE_ENTRY_IID(IID_IContextMenu2
, IContextMenu2
)
48 COM_INTERFACE_ENTRY_IID(IID_IContextMenu3
, IContextMenu3
)
49 COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite
, IObjectWithSite
)
53 CDefViewBckgrndMenu::CDefViewBckgrndMenu()
57 CDefViewBckgrndMenu::~CDefViewBckgrndMenu()
61 BOOL
CDefViewBckgrndMenu::_bIsDesktopBrowserMenu()
66 /* Get a pointer to the shell browser */
67 CComPtr
<IShellView
> psv
;
68 HRESULT hr
= IUnknown_QueryService(m_site
, SID_IFolderView
, IID_PPV_ARG(IShellView
, &psv
));
69 if (FAILED_UNEXPECTEDLY(hr
))
72 FOLDERSETTINGS FolderSettings
;
73 hr
= psv
->GetCurrentInfo(&FolderSettings
);
74 if (FAILED_UNEXPECTEDLY(hr
))
77 return ((FolderSettings
.fFlags
& FWF_DESKTOP
) == FWF_DESKTOP
);
80 BOOL
CDefViewBckgrndMenu::_bCanPaste()
82 /* If the folder doesn't have a drop target we can't paste */
83 CComPtr
<IDropTarget
> pdt
;
84 HRESULT hr
= m_psf
->CreateViewObject(NULL
, IID_PPV_ARG(IDropTarget
, &pdt
));
88 /* We can only paste if CFSTR_SHELLIDLIST is present in the clipboard */
89 CComPtr
<IDataObject
> pDataObj
;
90 hr
= OleGetClipboard(&pDataObj
);
97 /* Set the FORMATETC structure*/
98 InitFormatEtc(formatetc
, RegisterClipboardFormatW(CFSTR_SHELLIDLIST
), TYMED_HGLOBAL
);
99 hr
= pDataObj
->GetData(&formatetc
, &medium
);
103 ReleaseStgMedium(&medium
);
108 CDefViewBckgrndMenu::Initialize(IShellFolder
* psf
)
116 CDefViewBckgrndMenu::SetSite(IUnknown
*pUnkSite
)
124 CDefViewBckgrndMenu::GetSite(REFIID riid
, void **ppvSite
)
129 return m_site
->QueryInterface(riid
, ppvSite
);
134 CDefViewBckgrndMenu::QueryContextMenu(HMENU hMenu
, UINT indexMenu
, UINT idCmdFirst
, UINT idCmdLast
, UINT uFlags
)
139 /* Load the default part of the background context menu */
140 hMenuPart
= LoadMenuW(shell32_hInstance
, L
"MENU_002");
143 /* Don't show the view submenu for the desktop */
144 if (_bIsDesktopBrowserMenu())
146 DeleteMenu(hMenuPart
, FCIDM_SHVIEW_VIEW
, MF_BYCOMMAND
);
149 /* Disable the paste options if it is not possible */
152 EnableMenuItem(hMenuPart
, FCIDM_SHVIEW_INSERT
, MF_BYCOMMAND
| MF_GRAYED
);
153 EnableMenuItem(hMenuPart
, FCIDM_SHVIEW_INSERTLINK
, MF_BYCOMMAND
| MF_GRAYED
);
156 /* merge general background context menu in */
157 Shell_MergeMenus(hMenu
, GetSubMenu(hMenuPart
, 0), indexMenu
, 0, 0xFFFF, MM_DONTREMOVESEPS
| MM_SUBMENUSHAVEIDS
);
158 indexMenu
+= GetMenuItemCount(GetSubMenu(hMenuPart
, 0));
159 DestroyMenu(hMenuPart
);
163 ERR("Failed to load menu from resource!\n");
166 /* Query the shell folder to add any items it wants to add in the background context menu */
167 hMenuPart
= CreatePopupMenu();
170 hr
= m_psf
->CreateViewObject(NULL
, IID_PPV_ARG(IContextMenu
, &m_folderCM
));
173 InsertMenuA(hMenu
, indexMenu
++, MF_BYPOSITION
| MF_SEPARATOR
, 0, NULL
);
174 UINT SeparatorIndex
= indexMenu
;
175 UINT count
= GetMenuItemCount(hMenu
);
177 hr
= m_folderCM
->QueryContextMenu(hMenu
, indexMenu
, idCmdFirst
, idCmdLast
, uFlags
);
180 //Shell_MergeMenus(hMenu, hMenuPart, indexMenu, 0, UINT_MAX, MM_ADDSEPARATOR| MM_DONTREMOVESEPS | MM_SUBMENUSHAVEIDS);
181 //DestroyMenu(hMenuPart);
185 WARN("QueryContextMenu failed!\n");
188 /* If no item was added after the separator, remove it */
189 if (count
== GetMenuItemCount(hMenu
))
190 DeleteMenu(hMenu
, SeparatorIndex
, MF_BYPOSITION
);
195 WARN("GetUIObjectOf didn't give any context menu!\n");
200 ERR("CreatePopupMenu failed!\n");
208 CDefViewBckgrndMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi
)
210 /* The commands that are handled by the def view are forwarded to it */
211 switch (LOWORD(lpcmi
->lpVerb
))
213 case FCIDM_SHVIEW_BIGICON
:
214 case FCIDM_SHVIEW_SMALLICON
:
215 case FCIDM_SHVIEW_LISTVIEW
:
216 case FCIDM_SHVIEW_REPORTVIEW
:
217 case 0x30: /* FIX IDS in resource files */
221 case FCIDM_SHVIEW_AUTOARRANGE
:
222 case FCIDM_SHVIEW_SNAPTOGRID
:
223 case FCIDM_SHVIEW_REFRESH
:
227 /* Get a pointer to the shell browser */
228 CComPtr
<IShellView
> psv
;
229 HRESULT hr
= IUnknown_QueryService(m_site
, SID_IFolderView
, IID_PPV_ARG(IShellView
, &psv
));
230 if (FAILED_UNEXPECTEDLY(hr
))
234 if (SUCCEEDED(psv
->GetWindow(&hwndSV
)))
235 SendMessageW(hwndSV
, WM_COMMAND
, MAKEWPARAM(LOWORD(lpcmi
->lpVerb
), 0), 0);
239 /* Unknown commands are added by the folder context menu so forward the invocation */
240 return m_folderCM
->InvokeCommand(lpcmi
);
246 CDefViewBckgrndMenu::GetCommandString(UINT_PTR idCommand
, UINT uFlags
, UINT
*lpReserved
, LPSTR lpszName
, UINT uMaxNameLen
)
250 return m_folderCM
->GetCommandString(idCommand
, uFlags
, lpReserved
, lpszName
, uMaxNameLen
);
258 CDefViewBckgrndMenu::HandleMenuMsg(UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
262 CComPtr
<IContextMenu2
> pfolderCM2
;
263 HRESULT hr
= m_folderCM
->QueryInterface(IID_PPV_ARG(IContextMenu2
, &pfolderCM2
));
264 if (FAILED_UNEXPECTEDLY(hr
))
267 return pfolderCM2
->HandleMenuMsg(uMsg
, wParam
, lParam
);
275 CDefViewBckgrndMenu::HandleMenuMsg2(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, LRESULT
*plResult
)
279 CComPtr
<IContextMenu3
> pfolderCM3
;
280 HRESULT hr
= m_folderCM
->QueryInterface(IID_PPV_ARG(IContextMenu3
, &pfolderCM3
));
281 if (FAILED_UNEXPECTEDLY(hr
))
284 return pfolderCM3
->HandleMenuMsg2(uMsg
, wParam
, lParam
, plResult
);
292 CDefViewBckgrndMenu_CreateInstance(IShellFolder
* psf
, REFIID riid
, void **ppv
)
294 return ShellObjectCreatorInit
<CDefViewBckgrndMenu
>(psf
, riid
, ppv
);