Enumerates but does not actually allow you to get CF_HDROP if the desktop PIDL is present in the dataobject.
CDefaultContextMenu::~CDefaultContextMenu()
{
+ for (POSITION it = m_DynamicEntries.GetHeadPosition(); it != NULL;)
+ {
+ const DynamicShellEntry& info = m_DynamicEntries.GetNext(it);
+ IUnknown_SetSite(info.pCM.p, NULL);
+ }
m_DynamicEntries.RemoveAll();
m_StaticEntries.RemoveAll();
return hr;
}
- hr = pExtInit->Initialize(m_pidlFolder, m_pDataObj, hKey);
+ hr = pExtInit->Initialize(m_pDataObj ? NULL : m_pidlFolder, m_pDataObj, hKey);
if (FAILED(hr))
{
WARN("IShellExtInit::Initialize failed.clsid %s hr 0x%x\n", wine_dbgstr_guid(&clsid), hr);
}
}
- hr = LoadDynamicContextMenuHandler(hKey, clsid);
+ hr = LoadDynamicContextMenuHandler(hRootKey, clsid);
if (FAILED(hr))
WARN("Failed to get context menu entires from shell extension! clsid: %S\n", pwszClsid);
}
CSimpleArray<STGMEDIUM> m_Storage;
UINT m_cfShellIDList;
BOOL m_doasync;
+ bool m_FailGetHDrop;
public:
CIDLDataObj();
~CIDLDataObj();
{
m_cfShellIDList = 0;
m_doasync = FALSE;
+ m_FailGetHDrop = false;
}
CIDLDataObj::~CIDLDataObj()
HRESULT hr = SetData(&Format, &medium, TRUE);
if (!FAILED_UNEXPECTEDLY(hr) && bAddAdditionalFormats)
{
+ /* The Windows default shell IDataObject::GetData fails with DV_E_CLIPFORMAT if the desktop is present.
+ * Windows does return HDROP in EnumFormatEtc and does not fail until GetData is called.
+ * Failing GetData causes 7-Zip 23.01 to not add its menu to the desktop folder. */
+ for (UINT i = 0; i < cidlx; ++i)
+ {
+ if (ILIsEmpty(apidlx[i]) && ILIsEmpty(pMyPidl))
+ m_FailGetHDrop = true;
+ }
+
Format.cfFormat = CF_HDROP;
medium.hGlobal = RenderHDROP((LPITEMIDLIST)pMyPidl, (LPITEMIDLIST*)apidlx, cidlx);
hr = SetData(&Format, &medium, TRUE);
fmt.dwAspect == pformatetcIn->dwAspect &&
fmt.tymed == pformatetcIn->tymed)
{
+ if (m_FailGetHDrop && fmt.cfFormat == CF_HDROP)
+ return DV_E_CLIPFORMAT;
+
if (pformatetcIn->tymed != TYMED_HGLOBAL)
{
UNIMPLEMENTED;
return;
info.pContextMenu = pcm;
UINT cmf = ((GetKeyState(VK_SHIFT) < 0) ? CMF_EXTENDEDVERBS : 0) | CMF_CANRENAME;
- hr = pcm->QueryContextMenu(hMenu, 0, ID_FIRSTCMD, ID_LASTCMD, CMF_NODEFAULT | cmf);
+ hr = pcm->QueryContextMenu(hMenu, 0, ID_FIRSTCMD, ID_LASTCMD, CMF_EXPLORE | cmf);
if (hr > 0)
_InsertMenuItemW(hMenu, 0, TRUE, 0, MFT_SEPARATOR, NULL, 0);
_InsertMenuItemW(hMenu, 0, TRUE, IDC_TOGGLE, MFT_STRING,
}
else if (cmd != 0 && GetDfmCmd(pcm, ici.lpVerb) == DFM_CMD_RENAME)
{
- TreeView_SelectItem(info.hwndTreeView, hSelected);
- TreeView_EditLabel(info.hwndTreeView, hSelected);
+ BrFolder_Rename(&info, hSelected);
}
else if (cmd != 0)
{
WINE_DEFAULT_DEBUG_CHANNEL(shell);
+static BOOL IsSelf(UINT cidl, PCUITEMID_CHILD_ARRAY apidl)
+{
+ return cidl == 0 || (cidl == 1 && apidl && _ILIsEmpty(apidl[0]));
+}
+
STDMETHODIMP
CDesktopFolder::ShellUrlParseDisplayName(
HWND hwndOwner,
if (!ppvOut)
return hr;
-
*ppvOut = NULL;
- if (cidl == 1 && !_ILIsSpecialFolder(apidl[0]))
+ BOOL self = IsSelf(cidl, apidl);
+ if (cidl == 1 && !_ILIsSpecialFolder(apidl[0]) && !self)
{
CComPtr<IShellFolder2> psf;
HRESULT hr = _GetSFFromPidl(apidl[0], &psf);
if (IsEqualIID (riid, IID_IContextMenu))
{
- if (cidl > 0 && _ILIsSpecialFolder(apidl[0]))
+ // FIXME: m_regFolder vs AddFSClassKeysToArray is incorrect when the selection includes both regitems and FS items
+ if (!self && cidl > 0 && _ILIsSpecialFolder(apidl[0]))
{
hr = m_regFolder->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, &pObj);
}
/* Otherwise operations like that involve items from both user and shared desktop will not work */
HKEY hKeys[16];
UINT cKeys = 0;
- if (cidl > 0)
+ if (self)
+ {
+ AddClsidKeyToArray(CLSID_ShellDesktop, hKeys, &cKeys);
+ AddClassKeyToArray(L"Folder", hKeys, &cKeys);
+ }
+ else if (cidl > 0)
{
AddFSClassKeysToArray(cidl, apidl, hKeys, &cKeys);
}
HRESULT WINAPI CDesktopFolder::CallBack(IShellFolder *psf, HWND hwndOwner, IDataObject *pdtobj, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
enum { IDC_PROPERTIES };
- /* no data object means no selection */
- if (!pdtobj)
+ if (uMsg == DFM_INVOKECOMMAND && wParam == (pdtobj ? DFM_CMD_PROPERTIES : IDC_PROPERTIES))
{
- if (uMsg == DFM_INVOKECOMMAND && wParam == IDC_PROPERTIES)
- {
- return SHELL_ExecuteControlPanelCPL(hwndOwner, L"desk.cpl") ? S_OK : E_FAIL;
- }
- else if (uMsg == DFM_MERGECONTEXTMENU)
- {
- QCMINFO *pqcminfo = (QCMINFO *)lParam;
- HMENU hpopup = CreatePopupMenu();
- _InsertMenuItemW(hpopup, 0, TRUE, IDC_PROPERTIES, MFT_STRING, MAKEINTRESOURCEW(IDS_PROPERTIES), MFS_ENABLED);
- pqcminfo->idCmdFirst = Shell_MergeMenus(pqcminfo->hmenu, hpopup, pqcminfo->indexMenu, pqcminfo->idCmdFirst, pqcminfo->idCmdLast, MM_ADDSEPARATOR);
- DestroyMenu(hpopup);
- return S_OK;
- }
+ return SHELL_ExecuteControlPanelCPL(hwndOwner, L"desk.cpl") ? S_OK : E_FAIL;
+ }
+ else if (uMsg == DFM_MERGECONTEXTMENU && !pdtobj) // Add Properties item when called for directory background
+ {
+ QCMINFO *pqcminfo = (QCMINFO *)lParam;
+ HMENU hpopup = CreatePopupMenu();
+ _InsertMenuItemW(hpopup, 0, TRUE, IDC_PROPERTIES, MFT_STRING, MAKEINTRESOURCEW(IDS_PROPERTIES), MFS_ENABLED);
+ pqcminfo->idCmdFirst = Shell_MergeMenus(pqcminfo->hmenu, hpopup, pqcminfo->indexMenu, pqcminfo->idCmdFirst, pqcminfo->idCmdLast, MM_ADDSEPARATOR);
+ DestroyMenu(hpopup);
+ return S_OK;
}
return SHELL32_DefaultContextMenuCallBack(psf, pdtobj, uMsg);
}
BOOL SHELL_FS_HideExtension(LPCWSTR pwszPath);
LSTATUS AddClassKeyToArray(const WCHAR* szClass, HKEY* array, UINT* cKeys);
+LSTATUS AddClsidKeyToArray(REFCLSID clsid, HKEY* array, UINT* cKeys);
#ifdef __cplusplus
return result;
}
+LSTATUS AddClsidKeyToArray(REFCLSID clsid, HKEY* array, UINT* cKeys)
+{
+ WCHAR path[6 + 38 + 1] = L"CLSID\\";
+ StringFromGUID2(clsid, path + 6, 38 + 1);
+ return AddClassKeyToArray(path, array, cKeys);
+}
+
void AddFSClassKeysToArray(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, HKEY* array, UINT* cKeys)
{
// This function opens the association array keys in canonical order for filesystem items.