mirror of
https://github.com/reactos/reactos.git
synced 2025-05-31 06:58:10 +00:00
[BROWSEUI][SHELL32] Fix FindFolder icons (#7756)
- Shortcut icons require the correct IShellFolder because it needs the full path. - Items in a drive root needs the final backslash to be part of the path. CORE-18692
This commit is contained in:
parent
acbadb9fba
commit
f844296b0a
4 changed files with 216 additions and 67 deletions
|
@ -84,7 +84,7 @@ struct FolderViewColumns
|
|||
int cxChar;
|
||||
};
|
||||
|
||||
static FolderViewColumns g_ColumnDefs[] =
|
||||
static const FolderViewColumns g_ColumnDefs[] =
|
||||
{
|
||||
{IDS_COL_NAME, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 30},
|
||||
{IDS_COL_LOCATION, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 30},
|
||||
|
@ -92,6 +92,7 @@ static FolderViewColumns g_ColumnDefs[] =
|
|||
};
|
||||
|
||||
CFindFolder::CFindFolder() :
|
||||
m_pidl(NULL),
|
||||
m_hStopEvent(NULL)
|
||||
{
|
||||
}
|
||||
|
@ -106,26 +107,32 @@ static LPITEMIDLIST _ILCreate(LPCWSTR lpszPath)
|
|||
}
|
||||
LPITEMIDLIST lpLastFSPidl = ILFindLastID(lpFSPidl);
|
||||
|
||||
int pathLen = (PathFindFileNameW(lpszPath) - lpszPath) * sizeof(WCHAR);
|
||||
int cbData = sizeof(WORD) + pathLen + lpLastFSPidl->mkid.cb;
|
||||
SIZE_T cbPath = (PathFindFileNameW(lpszPath) - lpszPath + 1) * sizeof(WCHAR);
|
||||
SIZE_T cbData = sizeof(WORD) + cbPath + lpLastFSPidl->mkid.cb;
|
||||
if (cbData > 0xffff)
|
||||
return NULL;
|
||||
LPITEMIDLIST pidl = (LPITEMIDLIST) SHAlloc(cbData + sizeof(WORD));
|
||||
if (!pidl)
|
||||
return NULL;
|
||||
|
||||
LPBYTE p = (LPBYTE) pidl;
|
||||
*((WORD *) p) = cbData;
|
||||
p += sizeof(WORD);
|
||||
p += sizeof(WORD); // mkid.cb
|
||||
|
||||
memcpy(p, lpszPath, pathLen);
|
||||
p += pathLen - sizeof(WCHAR);
|
||||
*((WCHAR *) p) = '\0';
|
||||
p += sizeof(WCHAR);
|
||||
PWSTR path = (PWSTR)p;
|
||||
memcpy(p, lpszPath, cbPath);
|
||||
p += cbPath;
|
||||
((PWSTR)p)[-1] = UNICODE_NULL; // "C:\" not "C:" (required by ILCreateFromPathW and matches Windows)
|
||||
if (!PathIsRootW(path))
|
||||
{
|
||||
p -= sizeof(WCHAR);
|
||||
((PWSTR)p)[-1] = UNICODE_NULL; // "C:\folder"
|
||||
}
|
||||
|
||||
memcpy(p, lpLastFSPidl, lpLastFSPidl->mkid.cb);
|
||||
p += lpLastFSPidl->mkid.cb;
|
||||
|
||||
*((WORD *) p) = 0;
|
||||
|
||||
pidl->mkid.cb = p - (LPBYTE)pidl;
|
||||
((LPITEMIDLIST)p)->mkid.cb = 0; // Terminator
|
||||
return pidl;
|
||||
}
|
||||
|
||||
|
@ -144,6 +151,74 @@ static LPCITEMIDLIST _ILGetFSPidl(LPCITEMIDLIST pidl)
|
|||
+ ((wcslen((LPCWSTR) pidl->mkid.abID) + 1) * sizeof(WCHAR)));
|
||||
}
|
||||
|
||||
static PIDLIST_ABSOLUTE _ILCreateAbsolute(LPCITEMIDLIST pidlChild)
|
||||
{
|
||||
PIDLIST_ABSOLUTE pidl = NULL;
|
||||
if (PIDLIST_ABSOLUTE pidlFolder = SHSimpleIDListFromPath(_ILGetPath(pidl))) // FIXME: SHELL32_CreateSimpleIDListFromPath(, DIRECTORY)
|
||||
{
|
||||
pidl = ILCombine(pidlFolder, _ILGetFSPidl(pidl));
|
||||
ILFree(pidlFolder);
|
||||
}
|
||||
return pidl;
|
||||
}
|
||||
|
||||
HRESULT CFindFolder::GetFSFolderAndChild(LPCITEMIDLIST pidl, IShellFolder **ppSF, PCUITEMID_CHILD *ppidlLast)
|
||||
{
|
||||
ATLASSERT(m_pSfDesktop);
|
||||
PCWSTR path = _ILGetPath(pidl);
|
||||
if (!path || !path[0])
|
||||
return E_INVALIDARG;
|
||||
PIDLIST_ABSOLUTE pidlFolder = ILCreateFromPathW(path); // FIXME: SHELL32_CreateSimpleIDListFromPath(, DIRECTORY);
|
||||
if (!pidlFolder)
|
||||
return E_FAIL;
|
||||
HRESULT hr = m_pSfDesktop->BindToObject(pidlFolder, NULL, IID_PPV_ARG(IShellFolder, ppSF));
|
||||
ILFree(pidlFolder);
|
||||
if (ppidlLast)
|
||||
*ppidlLast = _ILGetFSPidl(pidl);
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT CFindFolder::GetFSFolder2AndChild(LPCITEMIDLIST pidl, IShellFolder2 **ppSF, PCUITEMID_CHILD *ppidlLast)
|
||||
{
|
||||
CComPtr<IShellFolder> pSF1;
|
||||
HRESULT hr = GetFSFolderAndChild(pidl, &pSF1, ppidlLast);
|
||||
if (SUCCEEDED(hr))
|
||||
hr = pSF1->QueryInterface(IID_PPV_ARG(IShellFolder2, ppSF));
|
||||
return hr;
|
||||
}
|
||||
|
||||
static int CALLBACK ILFreeHelper(void *pItem, void *pCaller)
|
||||
{
|
||||
ILFree((LPITEMIDLIST)pItem);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CFindFolder::FreePidlArray(HDPA hDpa)
|
||||
{
|
||||
DPA_DestroyCallback(hDpa, ILFreeHelper, NULL);
|
||||
}
|
||||
|
||||
HDPA CFindFolder::CreateAbsolutePidlArray(UINT cidl, PCUITEMID_CHILD_ARRAY apidl)
|
||||
{
|
||||
HDPA hDpa = DPA_Create(cidl / 2);
|
||||
if (hDpa)
|
||||
{
|
||||
for (UINT i = 0; i < cidl; ++i)
|
||||
{
|
||||
PIDLIST_ABSOLUTE pidl = _ILCreateAbsolute(apidl[i]);
|
||||
if (pidl)
|
||||
{
|
||||
if (DPA_InsertPtr(hDpa, i, pidl) >= 0)
|
||||
continue;
|
||||
ILFree(pidl);
|
||||
}
|
||||
FreePidlArray(hDpa);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return hDpa;
|
||||
}
|
||||
|
||||
struct _SearchData
|
||||
{
|
||||
HWND hwnd;
|
||||
|
@ -666,9 +741,9 @@ STDMETHODIMP CFindFolder::EnumSearches(IEnumExtraSearch **ppenum)
|
|||
STDMETHODIMP CFindFolder::GetDefaultColumn(DWORD, ULONG *pSort, ULONG *pDisplay)
|
||||
{
|
||||
if (pSort)
|
||||
*pSort = 0;
|
||||
*pSort = COL_NAME_INDEX;
|
||||
if (pDisplay)
|
||||
*pDisplay = 0;
|
||||
*pDisplay = COL_NAME_INDEX;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -684,17 +759,31 @@ STDMETHODIMP CFindFolder::GetDefaultColumnState(UINT iColumn, DWORD *pcsFlags)
|
|||
|
||||
STDMETHODIMP CFindFolder::GetDetailsEx(PCUITEMID_CHILD pidl, const SHCOLUMNID *pscid, VARIANT *pv)
|
||||
{
|
||||
return m_pisfInner->GetDetailsEx(pidl, pscid, pv);
|
||||
// FIXME: Handle COL_LOCATION_INDEX and COL_RELEVANCE_INDEX
|
||||
CComPtr<IShellFolder2> pFolder;
|
||||
PCUITEMID_CHILD pChild;
|
||||
if (SUCCEEDED(GetFSFolder2AndChild(pidl, &pFolder, &pChild)))
|
||||
return pFolder->GetDetailsEx(pChild, pscid, pv);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
STDMETHODIMP CFindFolder::GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, SHELLDETAILS *pDetails)
|
||||
{
|
||||
if (iColumn >= _countof(g_ColumnDefs))
|
||||
return m_pisfInner->GetDetailsOf(_ILGetFSPidl(pidl), iColumn - _countof(g_ColumnDefs) + 1, pDetails);
|
||||
{
|
||||
UINT FSColumn = iColumn - _countof(g_ColumnDefs) + 1;
|
||||
if (pidl)
|
||||
{
|
||||
CComPtr<IShellFolder2> pFolder;
|
||||
PCUITEMID_CHILD pChild;
|
||||
if (SUCCEEDED(GetFSFolder2AndChild(pidl, &pFolder, &pChild)))
|
||||
return pFolder->GetDetailsOf(pChild, FSColumn, pDetails);
|
||||
}
|
||||
return m_pisfInner->GetDetailsOf(pidl, FSColumn, pDetails); // Column header info
|
||||
}
|
||||
|
||||
pDetails->cxChar = g_ColumnDefs[iColumn].cxChar;
|
||||
pDetails->fmt = g_ColumnDefs[iColumn].fmt;
|
||||
|
||||
if (!pidl)
|
||||
return SHSetStrRet(&pDetails->str, _AtlBaseModule.GetResourceInstance(), g_ColumnDefs[iColumn].iResource);
|
||||
|
||||
|
@ -709,7 +798,8 @@ STDMETHODIMP CFindFolder::GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, SHELL
|
|||
return SHSetStrRet(&pDetails->str, "");
|
||||
}
|
||||
|
||||
return GetDisplayNameOf(pidl, SHGDN_NORMAL, &pDetails->str);
|
||||
ATLASSERT(iColumn == COL_NAME_INDEX);
|
||||
return GetDisplayNameOf(pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &pDetails->str);
|
||||
}
|
||||
|
||||
STDMETHODIMP CFindFolder::MapColumnToSCID(UINT iColumn, SHCOLUMNID *pscid)
|
||||
|
@ -734,8 +824,12 @@ STDMETHODIMP CFindFolder::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIS
|
|||
|
||||
STDMETHODIMP CFindFolder::BindToObject(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return E_NOTIMPL;
|
||||
HRESULT hr;
|
||||
CComPtr<IShellFolder> pInnerFolder;
|
||||
PCUITEMID_CHILD pidlChild;
|
||||
if (FAILED_UNEXPECTEDLY(hr = GetFSFolderAndChild(pidl, &pInnerFolder, &pidlChild)))
|
||||
return hr;
|
||||
return pInnerFolder->BindToObject(pidlChild, pbcReserved, riid, ppvOut);
|
||||
}
|
||||
|
||||
STDMETHODIMP CFindFolder::BindToStorage(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
|
||||
|
@ -759,6 +853,7 @@ STDMETHODIMP CFindFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PC
|
|||
wColumn -= _countof(g_ColumnDefs) - 1;
|
||||
break;
|
||||
}
|
||||
// FIXME: DefView does not like the way we sort
|
||||
return m_pisfInner->CompareIDs(HIWORD(lParam) | wColumn, _ILGetFSPidl(pidl1), _ILGetFSPidl(pidl2));
|
||||
}
|
||||
|
||||
|
@ -783,14 +878,24 @@ STDMETHODIMP CFindFolder::CreateViewObject(HWND hwndOwner, REFIID riid, LPVOID *
|
|||
|
||||
STDMETHODIMP CFindFolder::GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, DWORD *rgfInOut)
|
||||
{
|
||||
CComHeapPtr<PCITEMID_CHILD> aFSPidl;
|
||||
aFSPidl.Allocate(cidl);
|
||||
for (UINT i = 0; i < cidl; i++)
|
||||
if (!cidl)
|
||||
{
|
||||
aFSPidl[i] = _ILGetFSPidl(apidl[i]);
|
||||
*rgfInOut &= SFGAO_BROWSABLE; // TODO: SFGAO_CANRENAME?
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return m_pisfInner->GetAttributesOf(cidl, aFSPidl, rgfInOut);
|
||||
HRESULT hr = E_INVALIDARG;
|
||||
for (UINT i = 0; i < cidl; ++i)
|
||||
{
|
||||
CComPtr<IShellFolder> pFolder;
|
||||
PCUITEMID_CHILD pidlChild;
|
||||
if (FAILED_UNEXPECTEDLY(hr = GetFSFolderAndChild(apidl[i], &pFolder, &pidlChild)))
|
||||
break;
|
||||
if (FAILED(hr = pFolder->GetAttributesOf(1, &pidlChild, rgfInOut)))
|
||||
break;
|
||||
}
|
||||
*rgfInOut &= ~SFGAO_CANRENAME; // FIXME: Handle SetNameOf
|
||||
return hr;
|
||||
}
|
||||
|
||||
class CFindFolderContextMenu :
|
||||
|
@ -805,7 +910,7 @@ class CFindFolderContextMenu :
|
|||
//// *** IContextMenu methods ***
|
||||
STDMETHODIMP QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
|
||||
{
|
||||
m_firstCmdId = indexMenu;
|
||||
m_firstCmdId = idCmdFirst;
|
||||
_InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst++, MFT_STRING, MAKEINTRESOURCEW(IDS_SEARCH_OPEN_FOLDER), MFS_ENABLED);
|
||||
_InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst++, MFT_SEPARATOR, NULL, 0);
|
||||
return m_pInner->QueryContextMenu(hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags);
|
||||
|
@ -818,7 +923,7 @@ class CFindFolderContextMenu :
|
|||
return m_pInner->InvokeCommand(lpcmi);
|
||||
}
|
||||
|
||||
if (LOWORD(lpcmi->lpVerb) < m_firstCmdId + ADDITIONAL_MENU_ITEMS)
|
||||
if (LOWORD(lpcmi->lpVerb) >= m_firstCmdId && LOWORD(lpcmi->lpVerb) < m_firstCmdId + ADDITIONAL_MENU_ITEMS)
|
||||
{
|
||||
PCUITEMID_CHILD *apidl;
|
||||
UINT cidl;
|
||||
|
@ -838,9 +943,11 @@ class CFindFolderContextMenu :
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
// FIXME: We can't block FCIDM_SHVIEW_REFRESH here, add items on SFVM_LISTREFRESHED instead
|
||||
CMINVOKECOMMANDINFOEX actualCmdInfo;
|
||||
memcpy(&actualCmdInfo, lpcmi, lpcmi->cbSize);
|
||||
actualCmdInfo.lpVerb -= ADDITIONAL_MENU_ITEMS;
|
||||
if (LOWORD(lpcmi->lpVerb) < FCIDM_SHVIEW_ARRANGE) // HACKFIX for DefView using direct FCIDM_SHVIEW ids
|
||||
actualCmdInfo.lpVerb -= ADDITIONAL_MENU_ITEMS;
|
||||
return m_pInner->InvokeCommand((CMINVOKECOMMANDINFO *)&actualCmdInfo);
|
||||
}
|
||||
|
||||
|
@ -866,16 +973,39 @@ public:
|
|||
END_COM_MAP()
|
||||
};
|
||||
|
||||
int CALLBACK CFindFolder::SortItemsForDataObject(void *p1, void *p2, LPARAM lparam)
|
||||
{
|
||||
// For Delete/Move operations, a subfolder/file needs to come before the parent folder
|
||||
return ::ILGetSize((LPCITEMIDLIST)p1) - ::ILGetSize((LPCITEMIDLIST)p2);
|
||||
}
|
||||
|
||||
STDMETHODIMP CFindFolder::GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid,
|
||||
UINT *prgfInOut, LPVOID *ppvOut)
|
||||
{
|
||||
HRESULT hr;
|
||||
if (cidl <= 0)
|
||||
{
|
||||
return m_pisfInner->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, ppvOut);
|
||||
}
|
||||
return E_INVALIDARG;
|
||||
|
||||
CComHeapPtr<PCITEMID_CHILD> aFSPidl;
|
||||
aFSPidl.Allocate(cidl);
|
||||
CComHeapPtr<PCITEMID_CHILD> aFSPidlAlloc;
|
||||
PCITEMID_CHILD pidlSingleBuffer, *aFSPidl = &pidlSingleBuffer; // Optimize for single item callers
|
||||
if (cidl != 1)
|
||||
{
|
||||
if (riid == IID_IDataObject)
|
||||
{
|
||||
if (HDPA hDpa = CreateAbsolutePidlArray(cidl, apidl))
|
||||
{
|
||||
DPA_Sort(hDpa, SortItemsForDataObject, NULL);
|
||||
ITEMIDLIST pidlRoot = {};
|
||||
hr = SHCreateFileDataObject(&pidlRoot, cidl, (PCUITEMID_CHILD_ARRAY)DPA_GetPtrPtr(hDpa),
|
||||
NULL, (IDataObject**)ppvOut);
|
||||
FreePidlArray(hDpa);
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
aFSPidlAlloc.Allocate(cidl);
|
||||
aFSPidl = aFSPidlAlloc;
|
||||
}
|
||||
for (UINT i = 0; i < cidl; i++)
|
||||
{
|
||||
aFSPidl[i] = _ILGetFSPidl(apidl[i]);
|
||||
|
@ -883,30 +1013,38 @@ STDMETHODIMP CFindFolder::GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CHI
|
|||
|
||||
if (riid == IID_IContextMenu)
|
||||
{
|
||||
// FIXME: Use CDefFolderMenu_Create2(..., AddFSClassKeysToArray())
|
||||
CComHeapPtr<ITEMIDLIST> folderPidl(ILCreateFromPathW(_ILGetPath(apidl[0])));
|
||||
if (!folderPidl)
|
||||
return E_OUTOFMEMORY;
|
||||
CComPtr<IShellFolder> pDesktopFolder;
|
||||
HRESULT hResult = SHGetDesktopFolder(&pDesktopFolder);
|
||||
if (FAILED_UNEXPECTEDLY(hResult))
|
||||
return hResult;
|
||||
if (FAILED_UNEXPECTEDLY(hr = SHGetDesktopFolder(&pDesktopFolder)))
|
||||
return hr;
|
||||
CComPtr<IShellFolder> pShellFolder;
|
||||
hResult = pDesktopFolder->BindToObject(folderPidl, NULL, IID_PPV_ARG(IShellFolder, &pShellFolder));
|
||||
if (FAILED_UNEXPECTEDLY(hResult))
|
||||
return hResult;
|
||||
hr = pDesktopFolder->BindToObject(folderPidl, NULL, IID_PPV_ARG(IShellFolder, &pShellFolder));
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
CComPtr<IContextMenu> pContextMenu;
|
||||
hResult = pShellFolder->GetUIObjectOf(hwndOwner, cidl, aFSPidl, riid, prgfInOut, (LPVOID *)&pContextMenu);
|
||||
if (FAILED_UNEXPECTEDLY(hResult))
|
||||
return hResult;
|
||||
hr = pShellFolder->GetUIObjectOf(hwndOwner, cidl, aFSPidl, riid, prgfInOut, (void**)&pContextMenu);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
return CFindFolderContextMenu::Create(m_shellFolderView, pContextMenu, (IContextMenu **)ppvOut);
|
||||
}
|
||||
|
||||
return m_pisfInner->GetUIObjectOf(hwndOwner, cidl, aFSPidl, riid, prgfInOut, ppvOut);
|
||||
CComPtr<IShellFolder> pFolder;
|
||||
if (FAILED_UNEXPECTEDLY(hr = GetFSFolderAndChild(apidl[0], &pFolder)))
|
||||
return hr;
|
||||
return pFolder->GetUIObjectOf(hwndOwner, cidl, aFSPidl, riid, prgfInOut, ppvOut);
|
||||
}
|
||||
|
||||
STDMETHODIMP CFindFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET pName)
|
||||
{
|
||||
return m_pisfInner->GetDisplayNameOf(_ILGetFSPidl(pidl), dwFlags, pName);
|
||||
HRESULT hr;
|
||||
CComPtr<IShellFolder> pFolder;
|
||||
PCUITEMID_CHILD pidlChild;
|
||||
if (FAILED_UNEXPECTEDLY(hr = GetFSFolderAndChild(pidl, &pFolder, &pidlChild)))
|
||||
return hr;
|
||||
return pFolder->GetDisplayNameOf(pidlChild, dwFlags, pName);
|
||||
}
|
||||
|
||||
STDMETHODIMP CFindFolder::SetNameOf(HWND hwndOwner, PCUITEMID_CHILD pidl, LPCOLESTR lpName, DWORD dwFlags,
|
||||
|
@ -933,11 +1071,7 @@ STDMETHODIMP CFindFolder::MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|||
SubclassWindow((HWND) wParam);
|
||||
|
||||
// Get shell browser for updating status bar text
|
||||
CComPtr<IServiceProvider> pServiceProvider;
|
||||
HRESULT hr = m_shellFolderView->QueryInterface(IID_PPV_ARG(IServiceProvider, &pServiceProvider));
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
hr = pServiceProvider->QueryService(SID_SShellBrowser, IID_PPV_ARG(IShellBrowser, &m_shellBrowser));
|
||||
HRESULT hr = IUnknown_QueryService(m_shellFolderView, SID_SShellBrowser, IID_PPV_ARG(IShellBrowser, &m_shellBrowser));
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
|
@ -946,9 +1080,9 @@ STDMETHODIMP CFindFolder::MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|||
hr = m_shellBrowser->QueryInterface(IID_PPV_ARG(IWebBrowser2, &pWebBrowser2));
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
WCHAR pwszGuid[MAX_PATH];
|
||||
StringFromGUID2(CLSID_FileSearchBand, pwszGuid, _countof(pwszGuid));
|
||||
CComVariant searchBar(pwszGuid);
|
||||
WCHAR wszGuid[39];
|
||||
StringFromGUID2(CLSID_FileSearchBand, wszGuid, _countof(wszGuid));
|
||||
CComVariant searchBar(wszGuid);
|
||||
return pWebBrowser2->ShowBrowserBar(&searchBar, NULL, NULL);
|
||||
}
|
||||
case SFVM_WINDOWCLOSING:
|
||||
|
@ -973,6 +1107,7 @@ STDMETHODIMP CFindFolder::MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|||
}
|
||||
return hr;
|
||||
}
|
||||
// TODO: SFVM_GETCOLUMNSTREAM
|
||||
}
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
@ -980,21 +1115,20 @@ STDMETHODIMP CFindFolder::MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|||
//// *** IPersistFolder2 methods ***
|
||||
STDMETHODIMP CFindFolder::GetCurFolder(PIDLIST_ABSOLUTE *pidl)
|
||||
{
|
||||
*pidl = ILClone(m_pidl);
|
||||
return S_OK;
|
||||
return SHILClone(m_pidl, pidl);
|
||||
}
|
||||
|
||||
// *** IPersistFolder methods ***
|
||||
STDMETHODIMP CFindFolder::Initialize(PCIDLIST_ABSOLUTE pidl)
|
||||
{
|
||||
m_pidl = ILClone(pidl);
|
||||
if (!m_pidl)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
return SHELL32_CoCreateInitSF(m_pidl,
|
||||
NULL,
|
||||
NULL,
|
||||
&CLSID_ShellFSFolder,
|
||||
if (m_pidl)
|
||||
return E_UNEXPECTED;
|
||||
HRESULT hr;
|
||||
if (FAILED(hr = SHGetDesktopFolder((IShellFolder**)&m_pSfDesktop)))
|
||||
return hr;
|
||||
if (FAILED(hr = SHILClone(pidl, &m_pidl)))
|
||||
return hr;
|
||||
return SHELL32_CoCreateInitSF(m_pidl, NULL, NULL, &CLSID_ShellFSFolder,
|
||||
IID_PPV_ARG(IShellFolder2, &m_pisfInner));
|
||||
}
|
||||
|
||||
|
|
|
@ -64,11 +64,16 @@ class CFindFolder :
|
|||
|
||||
private:
|
||||
LPITEMIDLIST m_pidl;
|
||||
CComPtr<IShellFolder2> m_pisfInner;
|
||||
CComPtr<IShellFolder2> m_pisfInner, m_pSfDesktop;
|
||||
CComPtr<IShellFolderView> m_shellFolderView;
|
||||
CComPtr<IShellBrowser> m_shellBrowser;
|
||||
HANDLE m_hStopEvent;
|
||||
|
||||
HRESULT GetFSFolderAndChild(LPCITEMIDLIST pidl, IShellFolder **ppSF, PCUITEMID_CHILD *ppidlLast = NULL);
|
||||
HRESULT GetFSFolder2AndChild(LPCITEMIDLIST pidl, IShellFolder2 **ppSF, PCUITEMID_CHILD *ppidlLast = NULL);
|
||||
void FreePidlArray(HDPA hDpa);
|
||||
HDPA CreateAbsolutePidlArray(UINT cidl, PCUITEMID_CHILD_ARRAY apidl);
|
||||
static int CALLBACK SortItemsForDataObject(void *p1, void *p2, LPARAM lparam);
|
||||
void NotifyConnections(DISPID id);
|
||||
static DWORD WINAPI SearchThreadProc(LPVOID lpParameter);
|
||||
|
||||
|
|
|
@ -336,6 +336,7 @@ public:
|
|||
HRESULT CheckViewMode(HMENU hmenuView);
|
||||
LRESULT DoColumnContextMenu(LRESULT lParam);
|
||||
UINT GetSelections();
|
||||
SFGAOF GetSelectionAttributes(SFGAOF Query);
|
||||
HRESULT OpenSelectedItems();
|
||||
void OnDeactivate();
|
||||
void DoActivate(UINT uState);
|
||||
|
@ -1841,7 +1842,7 @@ HRESULT CDefView::FillFileMenu()
|
|||
|
||||
HMENU hmenu = CreatePopupMenu();
|
||||
|
||||
UINT cmf = GetContextMenuFlags(m_pShellBrowser, SFGAO_CANRENAME);
|
||||
UINT cmf = GetContextMenuFlags(m_pShellBrowser, GetSelectionAttributes(SFGAO_CANRENAME));
|
||||
hr = m_pFileMenu->QueryContextMenu(hmenu, 0, DVIDM_CONTEXTMENU_FIRST, DVIDM_CONTEXTMENU_LAST, cmf);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
@ -2101,6 +2102,14 @@ UINT CDefView::GetSelections()
|
|||
return m_cidl;
|
||||
}
|
||||
|
||||
SFGAOF CDefView::GetSelectionAttributes(SFGAOF Query)
|
||||
{
|
||||
if (!GetSelections())
|
||||
return 0;
|
||||
SFGAOF Attr = Query;
|
||||
return SUCCEEDED(m_pSFParent->GetAttributesOf(m_cidl, m_apidl, &Attr)) ? (Attr & Query) : 0;
|
||||
}
|
||||
|
||||
HRESULT CDefView::InvokeContextMenuCommand(CComPtr<IContextMenu>& pCM, LPCSTR lpVerb, POINT* pt)
|
||||
{
|
||||
CMINVOKECOMMANDINFOEX cmi;
|
||||
|
@ -2232,7 +2241,7 @@ LRESULT CDefView::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &b
|
|||
if (FAILED_UNEXPECTEDLY(hResult))
|
||||
return 0;
|
||||
|
||||
UINT cmf = GetContextMenuFlags(m_pShellBrowser, SFGAO_CANRENAME);
|
||||
UINT cmf = GetContextMenuFlags(m_pShellBrowser, GetSelectionAttributes(SFGAO_CANRENAME));
|
||||
// Use 1 as the first id we want. 0 means that user canceled the menu
|
||||
hResult = m_pCM->QueryContextMenu(m_hContextMenu, 0, CONTEXT_MENU_BASE_ID, DVIDM_CONTEXTMENU_LAST, cmf);
|
||||
if (FAILED_UNEXPECTEDLY(hResult))
|
||||
|
@ -3350,7 +3359,7 @@ HRESULT CDefView::SaveViewState(IStream *pStream)
|
|||
cols.Signature = PERSISTCOLUMNS::SIG;
|
||||
cols.Count = 0;
|
||||
LVCOLUMN lvc;
|
||||
lvc.mask = LVCF_WIDTH | LVCF_SUBITEM;
|
||||
lvc.mask = LVCF_WIDTH;
|
||||
for (UINT i = 0, j = 0; i < PERSISTCOLUMNS::MAXCOUNT && ListView_GetColumn(m_ListView, j, &lvc); ++j)
|
||||
{
|
||||
HRESULT hr = MapListColumnToFolderColumn(j);
|
||||
|
@ -3405,6 +3414,7 @@ HRESULT CDefView::SaveViewState(IStream *pStream)
|
|||
if (SUCCEEDED(hr))
|
||||
hr = pStream->Write(&cols, cbColumns, &written);
|
||||
}
|
||||
// TODO: else if (SUCCEEDED(_DoFolderViewCB(SFVM_GETCOLUMNSTREAM)))
|
||||
if (pStream)
|
||||
pStream->Release();
|
||||
return hr;
|
||||
|
|
|
@ -1790,6 +1790,7 @@ HRESULT STDMETHODCALLTYPE CShellLink::GetIconLocation(UINT uFlags, PWSTR pszIcon
|
|||
}
|
||||
else
|
||||
{
|
||||
// TODO: If GetIconLocation succeeded, why are we setting GIL_NOTFILENAME? And are we not PERINSTANCE?
|
||||
*pwFlags = GIL_NOTFILENAME | GIL_PERCLASS;
|
||||
}
|
||||
|
||||
|
@ -2575,13 +2576,12 @@ HRESULT STDMETHODCALLTYPE CShellLink::QueryContextMenu(HMENU hMenu, UINT indexMe
|
|||
if (!InsertMenuItemW(hMenu, indexMenu++, TRUE, &mii))
|
||||
return E_FAIL;
|
||||
|
||||
UNREFERENCED_PARAMETER(indexMenu);
|
||||
|
||||
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, id);
|
||||
}
|
||||
|
||||
HRESULT CShellLink::DoOpenFileLocation()
|
||||
{
|
||||
// TODO: SHOpenFolderAndSelectItems
|
||||
WCHAR szParams[MAX_PATH + 64];
|
||||
StringCbPrintfW(szParams, sizeof(szParams), L"/select,%s", m_sPath);
|
||||
|
||||
|
|
Loading…
Reference in a new issue