[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:
Whindmar Saksit 2025-03-08 14:30:04 +01:00 committed by GitHub
parent acbadb9fba
commit f844296b0a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 216 additions and 67 deletions

View file

@ -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));
}

View file

@ -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);

View file

@ -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;

View file

@ -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);