*/
#include "CFindFolder.h"
+#include <exdispid.h>
WINE_DEFAULT_DEBUG_CHANNEL(shellfind);
PCUITEMID_CHILD_ARRAY apidl,
DWORD dwFlags);
+static HRESULT SHELL32_CoCreateInitSF(LPCITEMIDLIST pidlRoot, PERSIST_FOLDER_TARGET_INFO* ppfti,
+ LPCITEMIDLIST pidlChild, const GUID* clsid, REFIID riid, LPVOID *ppvOut)
+{
+ HRESULT hr;
+ CComPtr<IShellFolder> pShellFolder;
+
+ hr = SHCoCreateInstance(NULL, clsid, NULL, IID_PPV_ARG(IShellFolder, &pShellFolder));
+ if (FAILED(hr))
+ return hr;
+
+ LPITEMIDLIST pidlAbsolute = ILCombine (pidlRoot, pidlChild);
+ CComPtr<IPersistFolder> ppf;
+ CComPtr<IPersistFolder3> ppf3;
+
+ if (ppfti && SUCCEEDED(pShellFolder->QueryInterface(IID_PPV_ARG(IPersistFolder3, &ppf3))))
+ {
+ ppf3->InitializeEx(NULL, pidlAbsolute, ppfti);
+ }
+ else if (SUCCEEDED(pShellFolder->QueryInterface(IID_PPV_ARG(IPersistFolder, &ppf))))
+ {
+ ppf->Initialize(pidlAbsolute);
+ }
+ ILFree (pidlAbsolute);
+
+ return pShellFolder->QueryInterface(riid, ppvOut);
+}
+
+static void WINAPI _InsertMenuItemW(
+ HMENU hMenu,
+ UINT indexMenu,
+ BOOL fByPosition,
+ UINT wID,
+ UINT fType,
+ LPCWSTR dwTypeData,
+ UINT fState)
+{
+ MENUITEMINFOW mii;
+ WCHAR wszText[100];
+
+ ZeroMemory(&mii, sizeof(mii));
+ mii.cbSize = sizeof(mii);
+ if (fType == MFT_SEPARATOR)
+ mii.fMask = MIIM_ID | MIIM_TYPE;
+ else if (fType == MFT_STRING)
+ {
+ mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
+ if (IS_INTRESOURCE(dwTypeData))
+ {
+ if (LoadStringW(_AtlBaseModule.GetResourceInstance(), LOWORD((ULONG_PTR)dwTypeData), wszText, _countof(wszText)))
+ mii.dwTypeData = wszText;
+ else
+ {
+ ERR("failed to load string %p\n", dwTypeData);
+ return;
+ }
+ }
+ else
+ mii.dwTypeData = (LPWSTR)dwTypeData;
+ mii.fState = fState;
+ }
+
+ mii.wID = wID;
+ mii.fType = fType;
+ InsertMenuItemW(hMenu, indexMenu, fByPosition, &mii);
+}
+
struct FolderViewColumns
{
- LPCWSTR wzColumnName;
+ int iResource;
DWORD dwDefaultState;
int fmt;
int cxChar;
static FolderViewColumns g_ColumnDefs[] =
{
- {L"Name", SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 30},
- {L"In Folder", SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 30},
- {L"Relevance", SHCOLSTATE_TYPE_STR, LVCFMT_LEFT, 0}
+ {IDS_COL_NAME, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 30},
+ {IDS_COL_LOCATION, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 30},
+ {IDS_COL_RELEVANCE, SHCOLSTATE_TYPE_STR, LVCFMT_LEFT, 0}
};
CFindFolder::CFindFolder() :
{
}
-static LPITEMIDLIST _ILCreate(LPCWSTR lpszPath, LPCITEMIDLIST lpcFindDataPidl)
+static LPITEMIDLIST _ILCreate(LPCWSTR lpszPath)
{
- int pathLen = (wcslen(lpszPath) + 1) * sizeof(WCHAR);
- int cbData = sizeof(WORD) + pathLen + lpcFindDataPidl->mkid.cb;
+ CComHeapPtr<ITEMIDLIST> lpFSPidl(ILCreateFromPathW(lpszPath));
+ if (!lpFSPidl)
+ {
+ ERR("Failed to create pidl from path\n");
+ return NULL;
+ }
+ LPITEMIDLIST lpLastFSPidl = ILFindLastID(lpFSPidl);
+
+ int pathLen = (PathFindFileNameW(lpszPath) - lpszPath) * sizeof(WCHAR);
+ int cbData = sizeof(WORD) + pathLen + lpLastFSPidl->mkid.cb;
LPITEMIDLIST pidl = (LPITEMIDLIST) SHAlloc(cbData + sizeof(WORD));
if (!pidl)
return NULL;
p += sizeof(WORD);
memcpy(p, lpszPath, pathLen);
- p += pathLen;
+ p += pathLen - sizeof(WCHAR);
+ *((WCHAR *) p) = '\0';
+ p += sizeof(WCHAR);
- memcpy(p, lpcFindDataPidl, lpcFindDataPidl->mkid.cb);
- p += lpcFindDataPidl->mkid.cb;
+ memcpy(p, lpLastFSPidl, lpLastFSPidl->mkid.cb);
+ p += lpLastFSPidl->mkid.cb;
*((WORD *) p) = 0;
+ ((wcslen((LPCWSTR) pidl->mkid.abID) + 1) * sizeof(WCHAR)));
}
-LRESULT CFindFolder::AddItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
+struct _SearchData
{
- if (!lParam)
+ HWND hwnd;
+ HANDLE hStopEvent;
+ CStringW szPath;
+ CStringW szFileName;
+ CStringA szQueryA;
+ CStringW szQueryW;
+ CComPtr<CFindFolder> pFindFolder;
+};
+
+template<typename TChar, typename TString, int (&StrNCmp)(const TChar *, const TChar *, size_t)>
+static const TChar* StrStrN(const TChar *lpFirst, const TString &lpSrch, UINT cchMax)
+{
+ if (!lpFirst || lpSrch.IsEmpty() || !cchMax)
+ return NULL;
+
+ for (UINT i = cchMax; i > 0 && *lpFirst; i--, lpFirst++)
+ {
+ if (!StrNCmp(lpFirst, lpSrch, lpSrch.GetLength()))
+ return (const TChar*)lpFirst;
+ }
+
+ return NULL;
+}
+
+template<typename TChar, typename TString, int (&StrNCmp)(const TChar *, const TChar *, size_t)>
+static UINT StrStrNCount(const TChar *lpFirst, const TString &lpSrch, UINT cchMax)
+{
+ const TChar *lpSearchEnd = lpFirst + cchMax;
+ UINT uCount = 0;
+ while (lpFirst < lpSearchEnd && (lpFirst = StrStrN<TChar, TString, StrNCmp>(lpFirst, lpSrch, cchMax)))
+ {
+ uCount++;
+ lpFirst += lpSrch.GetLength();
+ cchMax = lpSearchEnd - lpFirst;
+ }
+ return uCount;
+}
+
+static UINT StrStrCountNIA(const CHAR *lpFirst, const CStringA &lpSrch, UINT cchMax)
+{
+ return StrStrNCount<CHAR, CStringA, _strnicmp>(lpFirst, lpSrch, cchMax);
+}
+
+static UINT StrStrCountNIW(const WCHAR *lpFirst, const CStringW &lpSrch, UINT cchMax)
+{
+ return StrStrNCount<WCHAR, CStringW, _wcsnicmp>(lpFirst, lpSrch, cchMax);
+}
+
+static UINT SearchFile(LPCWSTR lpFilePath, _SearchData *pSearchData)
+{
+ HANDLE hFile = CreateFileW(lpFilePath, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
+ if (hFile == INVALID_HANDLE_VALUE)
return 0;
- HRESULT hr;
- LPWSTR path = (LPWSTR) lParam;
+ DWORD size = GetFileSize(hFile, NULL);
+ HANDLE hFileMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
+ CloseHandle(hFile);
+ if (hFileMap == INVALID_HANDLE_VALUE)
+ return 0;
- CComPtr<IShellFolder> pShellFolder;
- hr = SHGetDesktopFolder(&pShellFolder);
- if (FAILED_UNEXPECTEDLY(hr))
+ LPBYTE lpFileContent = (LPBYTE) MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);
+ CloseHandle(hFileMap);
+ if (!lpFileContent)
+ return 0;
+
+ UINT uMatches = 0;
+ // Check for UTF-16 BOM
+ if (size >= 2 && lpFileContent[0] == 0xFF && lpFileContent[1] == 0xFE)
{
- LocalFree(path);
- return hr;
+ uMatches = StrStrCountNIW((LPCWSTR) lpFileContent, pSearchData->szQueryW, size / sizeof(WCHAR));
}
+ else
+ {
+ uMatches = StrStrCountNIA((LPCSTR) lpFileContent, pSearchData->szQueryA, size / sizeof(CHAR));
+ }
+
+ UnmapViewOfFile(lpFileContent);
- CComHeapPtr<ITEMIDLIST> lpFSPidl;
- DWORD pchEaten;
- hr = pShellFolder->ParseDisplayName(NULL, NULL, path, &pchEaten, &lpFSPidl, NULL);
- if (FAILED_UNEXPECTEDLY(hr))
+ return uMatches;
+}
+
+static UINT RecursiveFind(LPCWSTR lpPath, _SearchData *pSearchData)
+{
+ if (WaitForSingleObject(pSearchData->hStopEvent, 0) != WAIT_TIMEOUT)
+ return 0;
+
+ WCHAR szPath[MAX_PATH];
+ WIN32_FIND_DATAW FindData;
+ HANDLE hFindFile;
+ BOOL bMoreFiles = TRUE;
+ UINT uTotalFound = 0;
+
+ PathCombineW(szPath, lpPath, L"*.*");
+
+ for (hFindFile = FindFirstFileW(szPath, &FindData);
+ bMoreFiles && hFindFile != INVALID_HANDLE_VALUE;
+ bMoreFiles = FindNextFileW(hFindFile, &FindData))
{
- LocalFree(path);
- return hr;
+ if (!wcscmp(FindData.cFileName, L".") || !wcscmp(FindData.cFileName, L".."))
+ continue;
+
+ PathCombineW(szPath, lpPath, FindData.cFileName);
+
+ if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ CStringW status;
+ status.Format(IDS_SEARCH_FOLDER, FindData.cFileName);
+ PostMessageW(pSearchData->hwnd, WM_SEARCH_UPDATE_STATUS, 0, (LPARAM) StrDupW(status.GetBuffer()));
+
+ uTotalFound += RecursiveFind(szPath, pSearchData);
+ }
+ else if ((pSearchData->szFileName.IsEmpty() || PathMatchSpecW(FindData.cFileName, pSearchData->szFileName))
+ && (pSearchData->szQueryA.IsEmpty() || SearchFile(szPath, pSearchData)))
+ {
+ uTotalFound++;
+ PostMessageW(pSearchData->hwnd, WM_SEARCH_ADD_RESULT, 0, (LPARAM) StrDupW(szPath));
+ }
}
- LPITEMIDLIST lpLastFSPidl = ILFindLastID(lpFSPidl);
- CComHeapPtr<ITEMIDLIST> lpSearchPidl(_ILCreate(path, lpLastFSPidl));
- LocalFree(path);
- if (!lpSearchPidl)
+ if (hFindFile != INVALID_HANDLE_VALUE)
+ FindClose(hFindFile);
+
+ return uTotalFound;
+}
+
+DWORD WINAPI CFindFolder::SearchThreadProc(LPVOID lpParameter)
+{
+ _SearchData *data = static_cast<_SearchData*>(lpParameter);
+
+ data->pFindFolder->NotifyConnections(DISPID_SEARCHSTART);
+
+ UINT uTotalFound = RecursiveFind(data->szPath, data);
+
+ data->pFindFolder->NotifyConnections(DISPID_SEARCHCOMPLETE);
+
+ CStringW status;
+ status.Format(IDS_SEARCH_FILES_FOUND, uTotalFound);
+ ::PostMessageW(data->hwnd, WM_SEARCH_UPDATE_STATUS, 0, (LPARAM) StrDupW(status.GetBuffer()));
+ ::SendMessageW(data->hwnd, WM_SEARCH_STOP, 0, 0);
+
+ CloseHandle(data->hStopEvent);
+ delete data;
+
+ return 0;
+}
+
+void CFindFolder::NotifyConnections(DISPID id)
+{
+ DISPPARAMS dispatchParams = {0};
+ CComDynamicUnkArray &subscribers =
+ IConnectionPointImpl<CFindFolder, &DIID_DSearchCommandEvents>::m_vec;
+ for (IUnknown** pSubscriber = subscribers.begin(); pSubscriber < subscribers.end(); pSubscriber++)
{
- return E_OUTOFMEMORY;
+ if (!*pSubscriber)
+ continue;
+
+ CComPtr<IDispatch> pDispatch;
+ HRESULT hResult = (*pSubscriber)->QueryInterface(IID_PPV_ARG(IDispatch, &pDispatch));
+ if (!FAILED_UNEXPECTEDLY(hResult))
+ pDispatch->Invoke(id, GUID_NULL, 0, DISPATCH_METHOD, &dispatchParams, NULL, NULL, NULL);
}
+}
+
+LRESULT CFindFolder::StartSearch(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
+{
+ if (!lParam)
+ return 0;
+ // Clear all previous search results
UINT uItemIndex;
- hr = m_shellFolderView->AddObject(lpSearchPidl, &uItemIndex);
+ m_shellFolderView->RemoveObject(NULL, &uItemIndex);
+
+ _SearchData* pSearchData = new _SearchData();
+ pSearchData->pFindFolder = this;
+ pSearchData->hwnd = m_hWnd;
+
+ SearchStart *pSearchParams = (SearchStart *) lParam;
+ pSearchData->szPath = pSearchParams->szPath;
+ pSearchData->szFileName = pSearchParams->szFileName;
+ pSearchData->szQueryA = pSearchParams->szQuery;
+ pSearchData->szQueryW = pSearchParams->szQuery;
+ SHFree(pSearchParams);
+
+ if (m_hStopEvent)
+ SetEvent(m_hStopEvent);
+ pSearchData->hStopEvent = m_hStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+ if (!SHCreateThread(SearchThreadProc, pSearchData, NULL, NULL))
+ {
+ SHFree(pSearchData);
+ return 0;
+ }
+
+ return 0;
+}
+
+LRESULT CFindFolder::StopSearch(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
+{
+ if (m_hStopEvent)
+ {
+ SetEvent(m_hStopEvent);
+ m_hStopEvent = NULL;
+ }
+ return 0;
+}
+
+LRESULT CFindFolder::AddResult(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
+{
+ if (!lParam)
+ return 0;
+
+ CComHeapPtr<WCHAR> lpPath((LPWSTR) lParam);
+
+ CComHeapPtr<ITEMIDLIST> lpSearchPidl(_ILCreate(lpPath));
+ if (lpSearchPidl)
+ {
+ UINT uItemIndex;
+ m_shellFolderView->AddObject(lpSearchPidl, &uItemIndex);
+ }
- return hr;
+ return 0;
}
LRESULT CFindFolder::UpdateStatus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
{
- LPWSTR status = (LPWSTR) lParam;
+ CComHeapPtr<WCHAR> status((LPWSTR) lParam);
if (m_shellBrowser)
{
m_shellBrowser->SetStatusTextSB(status);
}
- LocalFree(status);
- return S_OK;
+ return 0;
}
// *** IShellFolder2 methods ***
pDetails->fmt = g_ColumnDefs[iColumn].fmt;
if (!pidl)
- return SHSetStrRet(&pDetails->str, g_ColumnDefs[iColumn].wzColumnName);
+ return SHSetStrRet(&pDetails->str, _AtlBaseModule.GetResourceInstance(), g_ColumnDefs[iColumn].iResource);
if (iColumn == 1)
{
- WCHAR path[MAX_PATH];
- wcscpy(path, _ILGetPath(pidl));
- PathRemoveFileSpecW(path);
- return SHSetStrRet(&pDetails->str, path);
+ return SHSetStrRet(&pDetails->str, _ILGetPath(pidl));
}
return GetDisplayNameOf(pidl, SHGDN_NORMAL, &pDetails->str);
return m_pisfInner->GetAttributesOf(cidl, aFSPidl, rgfInOut);
}
-STDMETHODIMP CFindFolder::GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid,
- UINT *prgfInOut, LPVOID *ppvOut)
+class CFindFolderContextMenu :
+ public IContextMenu,
+ public CComObjectRootEx<CComMultiThreadModelNoCS>
{
- if (riid == IID_IDataObject && cidl == 1)
+ CComPtr<IContextMenu> m_pInner;
+ CComPtr<IShellFolderView> m_shellFolderView;
+ UINT m_firstCmdId;
+ static const UINT ADDITIONAL_MENU_ITEMS = 2;
+
+ //// *** IContextMenu methods ***
+ STDMETHODIMP QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
{
- WCHAR path[MAX_PATH];
- wcscpy(path, (LPCWSTR) apidl[0]->mkid.abID);
- PathRemoveFileSpecW(path);
- CComHeapPtr<ITEMIDLIST> 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);
+ m_firstCmdId = indexMenu;
+ _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);
}
+ STDMETHODIMP InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi)
+ {
+ if (!IS_INTRESOURCE(lpcmi->lpVerb))
+ {
+ return m_pInner->InvokeCommand(lpcmi);
+ }
+
+ if (LOWORD(lpcmi->lpVerb) < m_firstCmdId + ADDITIONAL_MENU_ITEMS)
+ {
+ PCUITEMID_CHILD *apidl;
+ UINT cidl;
+ HRESULT hResult = m_shellFolderView->GetSelectedObjects(&apidl, &cidl);
+ if (FAILED_UNEXPECTEDLY(hResult))
+ return hResult;
+
+ for (UINT i = 0; i < cidl; i++)
+ {
+ CComHeapPtr<ITEMIDLIST> folderPidl(ILCreateFromPathW(_ILGetPath(apidl[i])));
+ if (!folderPidl)
+ return E_OUTOFMEMORY;
+ LPCITEMIDLIST pidl = _ILGetFSPidl(apidl[i]);
+ SHOpenFolderAndSelectItems(folderPidl, 1, &pidl, 0);
+ }
+ return S_OK;
+ }
+
+ CMINVOKECOMMANDINFOEX actualCmdInfo;
+ memcpy(&actualCmdInfo, lpcmi, lpcmi->cbSize);
+ actualCmdInfo.lpVerb -= ADDITIONAL_MENU_ITEMS;
+ return m_pInner->InvokeCommand((CMINVOKECOMMANDINFO *)&actualCmdInfo);
+ }
+
+ STDMETHODIMP GetCommandString(UINT_PTR idCommand, UINT uFlags, UINT *lpReserved, LPSTR lpszName, UINT uMaxNameLen)
+ {
+ return m_pInner->GetCommandString(idCommand, uFlags, lpReserved, lpszName, uMaxNameLen);
+ }
+
+public:
+ static HRESULT Create(IShellFolderView *pShellFolderView, IContextMenu *pInnerContextMenu, IContextMenu **pContextMenu)
+ {
+ CComObject<CFindFolderContextMenu> *pObj;
+ HRESULT hResult = CComObject<CFindFolderContextMenu>::CreateInstance(&pObj);
+ if (FAILED_UNEXPECTEDLY(hResult))
+ return hResult;
+ pObj->m_shellFolderView = pShellFolderView;
+ pObj->m_pInner = pInnerContextMenu;
+ return pObj->QueryInterface(IID_PPV_ARG(IContextMenu, pContextMenu));
+ }
+
+ BEGIN_COM_MAP(CFindFolderContextMenu)
+ COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
+ END_COM_MAP()
+};
+
+STDMETHODIMP CFindFolder::GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid,
+ UINT *prgfInOut, LPVOID *ppvOut)
+{
if (cidl <= 0)
{
return m_pisfInner->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, ppvOut);
}
- PCITEMID_CHILD *aFSPidl = new PCITEMID_CHILD[cidl];
+ CComHeapPtr<PCITEMID_CHILD> aFSPidl;
+ aFSPidl.Allocate(cidl);
for (UINT i = 0; i < cidl; i++)
{
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;
+ 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;
+ CComPtr<IShellFolder> pShellFolder;
+ hResult = pDesktopFolder->BindToObject(folderPidl, NULL, IID_PPV_ARG(IShellFolder, &pShellFolder));
+ if (FAILED_UNEXPECTEDLY(hResult))
+ return hResult;
+ CComPtr<IContextMenu> pContextMenu;
+ hResult = pShellFolder->GetUIObjectOf(hwndOwner, cidl, aFSPidl, riid, prgfInOut, (LPVOID *)&pContextMenu);
+ if (FAILED_UNEXPECTEDLY(hResult))
+ return hResult;
+ return CFindFolderContextMenu::Create(m_shellFolderView, pContextMenu, (IContextMenu **)ppvOut);
}
- HRESULT hr = m_pisfInner->GetUIObjectOf(hwndOwner, cidl, aFSPidl, riid, prgfInOut, ppvOut);
- delete[] aFSPidl;
-
- return hr;
+ return m_pisfInner->GetUIObjectOf(hwndOwner, cidl, aFSPidl, riid, prgfInOut, ppvOut);
}
STDMETHODIMP CFindFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET pName)
}
case SFVM_WINDOWCREATED:
{
+ // Subclass window to receive window messages
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;
- }
- return pServiceProvider->QueryService(SID_SShellBrowser, IID_PPV_ARG(IShellBrowser, &m_shellBrowser));
- }
- }
- 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);
+ hr = pServiceProvider->QueryService(SID_SShellBrowser, IID_PPV_ARG(IShellBrowser, &m_shellBrowser));
if (FAILED_UNEXPECTEDLY(hr))
return hr;
- for (UINT i = 0; i < cidl; i++)
- {
- CComHeapPtr<ITEMIDLIST> pidl;
- DWORD attrs = 0;
- hr = SHILCreateFromPathW((LPCWSTR) apidl[i]->mkid.abID, &pidl, &attrs);
- if (SUCCEEDED(hr))
- {
- SHOpenFolderAndSelectItems(NULL, 1, &pidl, 0);
- }
- }
-
- return S_OK;
+ // Open search bar
+ CComPtr<IWebBrowser2> pWebBrowser2;
+ 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);
+ return pWebBrowser2->ShowBrowserBar(&searchBar, NULL, NULL);
}
- case DFM_GETDEFSTATICID:
- return S_FALSE;
}
- return Shell_DefaultContextMenuCallBack(m_pisfInner, pdtobj);
+ return E_NOTIMPL;
}
//// *** IPersistFolder2 methods ***
-STDMETHODIMP CFindFolder::GetCurFolder(LPITEMIDLIST *pidl)
+STDMETHODIMP CFindFolder::GetCurFolder(PIDLIST_ABSOLUTE *pidl)
{
*pidl = ILClone(m_pidl);
return S_OK;
}
// *** IPersistFolder methods ***
-STDMETHODIMP CFindFolder::Initialize(LPCITEMIDLIST pidl)
+STDMETHODIMP CFindFolder::Initialize(PCIDLIST_ABSOLUTE pidl)
{
m_pidl = ILClone(pidl);
if (!m_pidl)
{
if (pClassId == NULL)
return E_INVALIDARG;
- memcpy(pClassId, &CLSID_FindFolder, sizeof(CLSID));
+ *pClassId = CLSID_FindFolder;
return S_OK;
}