mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 00:45:24 +00:00
[SHELLFIND] Add "Open Containing Folder" to right-click menu
This commit is contained in:
parent
7c937bd9ef
commit
2fdaa386d2
2 changed files with 95 additions and 2 deletions
|
@ -9,6 +9,14 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(shellfind);
|
||||
|
||||
// FIXME: Remove this declaration after the function has been fully implemented
|
||||
EXTERN_C HRESULT
|
||||
WINAPI
|
||||
SHOpenFolderAndSelectItems(LPITEMIDLIST pidlFolder,
|
||||
UINT cidl,
|
||||
PCUITEMID_CHILD_ARRAY apidl,
|
||||
DWORD dwFlags);
|
||||
|
||||
struct FolderViewColumns
|
||||
{
|
||||
LPCWSTR wzColumnName;
|
||||
|
@ -233,6 +241,19 @@ STDMETHODIMP CFindFolder::GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY apidl
|
|||
STDMETHODIMP CFindFolder::GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid,
|
||||
UINT *prgfInOut, LPVOID *ppvOut)
|
||||
{
|
||||
if (riid == IID_IDataObject && cidl == 1)
|
||||
{
|
||||
WCHAR path[MAX_PATH];
|
||||
wcscpy(path, (LPCWSTR) apidl[0]->mkid.abID);
|
||||
PathRemoveFileSpecW(path);
|
||||
LPITEMIDLIST rootPidl = ILCreateFromPathW(path);
|
||||
if (!rootPidl)
|
||||
return E_OUTOFMEMORY;
|
||||
PCITEMID_CHILD aFSPidl[1];
|
||||
aFSPidl[0] = _ILGetFSPidl(apidl[0]);
|
||||
return IDataObject_Constructor(hwndOwner, rootPidl, aFSPidl, cidl, (IDataObject **) ppvOut);
|
||||
}
|
||||
|
||||
if (cidl <= 0)
|
||||
{
|
||||
return m_pisfInner->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, ppvOut);
|
||||
|
@ -244,6 +265,28 @@ STDMETHODIMP CFindFolder::GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CHI
|
|||
aFSPidl[i] = _ILGetFSPidl(apidl[i]);
|
||||
}
|
||||
|
||||
if (riid == IID_IContextMenu)
|
||||
{
|
||||
HKEY hKeys[16];
|
||||
UINT cKeys = 0;
|
||||
AddFSClassKeysToArray(aFSPidl[0], hKeys, &cKeys);
|
||||
|
||||
DEFCONTEXTMENU dcm;
|
||||
dcm.hwnd = hwndOwner;
|
||||
dcm.pcmcb = this;
|
||||
dcm.pidlFolder = m_pidl;
|
||||
dcm.psf = this;
|
||||
dcm.cidl = cidl;
|
||||
dcm.apidl = apidl;
|
||||
dcm.cKeys = cKeys;
|
||||
dcm.aKeys = hKeys;
|
||||
dcm.punkAssociationInfo = NULL;
|
||||
HRESULT hr = SHCreateDefaultContextMenu(&dcm, riid, ppvOut);
|
||||
delete[] aFSPidl;
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT hr = m_pisfInner->GetUIObjectOf(hwndOwner, cidl, aFSPidl, riid, prgfInOut, ppvOut);
|
||||
delete[] aFSPidl;
|
||||
|
||||
|
@ -282,6 +325,50 @@ STDMETHODIMP CFindFolder::MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
//// *** IContextMenuCB method ***
|
||||
STDMETHODIMP CFindFolder::CallBack(IShellFolder *psf, HWND hwndOwner, IDataObject *pdtobj, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (uMsg)
|
||||
{
|
||||
case DFM_MERGECONTEXTMENU:
|
||||
{
|
||||
QCMINFO *pqcminfo = (QCMINFO *) lParam;
|
||||
_InsertMenuItemW(pqcminfo->hmenu, pqcminfo->indexMenu++, TRUE, pqcminfo->idCmdFirst++, MFT_SEPARATOR, NULL, 0);
|
||||
_InsertMenuItemW(pqcminfo->hmenu, pqcminfo->indexMenu++, TRUE, pqcminfo->idCmdFirst++, MFT_STRING, L"Open Containing Folder", MFS_ENABLED);
|
||||
_InsertMenuItemW(pqcminfo->hmenu, pqcminfo->indexMenu++, TRUE, pqcminfo->idCmdFirst++, MFT_SEPARATOR, NULL, 0);
|
||||
return S_OK;
|
||||
}
|
||||
case DFM_INVOKECOMMAND:
|
||||
case DFM_INVOKECOMMANDEX:
|
||||
{
|
||||
if (wParam != 1)
|
||||
break;
|
||||
|
||||
PCUITEMID_CHILD *apidl;
|
||||
UINT cidl;
|
||||
HRESULT hr = m_shellFolderView->GetSelectedObjects(&apidl, &cidl);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
for (UINT i = 0; i < cidl; i++)
|
||||
{
|
||||
LPITEMIDLIST pidl;
|
||||
DWORD attrs = 0;
|
||||
hr = SHILCreateFromPathW((LPCWSTR) apidl[i]->mkid.abID, &pidl, &attrs);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
SHOpenFolderAndSelectItems(NULL, 1, &pidl, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
case DFM_GETDEFSTATICID:
|
||||
return S_FALSE;
|
||||
}
|
||||
return Shell_DefaultContextMenuCallBack(m_pisfInner, pdtobj);
|
||||
}
|
||||
|
||||
//// *** IPersistFolder2 methods ***
|
||||
STDMETHODIMP CFindFolder::GetCurFolder(LPITEMIDLIST *pidl)
|
||||
{
|
||||
|
|
|
@ -9,8 +9,9 @@ class CFindFolder :
|
|||
public CComCoClass<CFindFolder, &CLSID_FindFolder>,
|
||||
public CComObjectRootEx<CComMultiThreadModelNoCS>,
|
||||
public IShellFolder2,
|
||||
public IPersistFolder2,
|
||||
public IShellFolderViewCB,
|
||||
public IPersistFolder2
|
||||
public IContextMenuCB
|
||||
{
|
||||
// *** IShellFolder2 methods ***
|
||||
STDMETHODIMP GetDefaultSearchGUID(GUID *pguid);
|
||||
|
@ -47,14 +48,18 @@ class CFindFolder :
|
|||
STDMETHODIMP GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid, UINT *prgfInOut,
|
||||
LPVOID *ppvOut);
|
||||
|
||||
STDMETHODIMP GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET pName);
|
||||
|
||||
STDMETHODIMP GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET pName);
|
||||
STDMETHODIMP SetNameOf(HWND hwndOwner, PCUITEMID_CHILD pidl, LPCOLESTR lpName, DWORD dwFlags,
|
||||
PITEMID_CHILD *pPidlOut);
|
||||
|
||||
//// *** IShellFolderViewCB methods ***
|
||||
STDMETHODIMP MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
//// *** IContextMenuCB method ***
|
||||
STDMETHODIMP CallBack(IShellFolder *psf, HWND hwndOwner, IDataObject *pdtobj, UINT uMsg, WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
|
||||
private:
|
||||
LPITEMIDLIST m_pidl;
|
||||
CComPtr<IShellFolder2> m_pisfInner;
|
||||
|
@ -91,6 +96,7 @@ public:
|
|||
COM_INTERFACE_ENTRY_IID(IID_IPersistFolder2, IPersistFolder2)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IPersistFolder, IPersistFolder)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IContextMenuCB, IContextMenuCB)
|
||||
END_COM_MAP()
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue