2 * PROJECT: ReactOS Search Shell Extension
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Search results folder
5 * COPYRIGHT: Copyright 2019 Brock Mammen
8 #include "CFindFolder.h"
11 WINE_DEFAULT_DEBUG_CHANNEL(shellfind
);
13 // FIXME: Remove this declaration after the function has been fully implemented
16 SHOpenFolderAndSelectItems(LPITEMIDLIST pidlFolder
,
18 PCUITEMID_CHILD_ARRAY apidl
,
21 static HRESULT
SHELL32_CoCreateInitSF(LPCITEMIDLIST pidlRoot
, PERSIST_FOLDER_TARGET_INFO
* ppfti
,
22 LPCITEMIDLIST pidlChild
, const GUID
* clsid
, REFIID riid
, LPVOID
*ppvOut
)
25 CComPtr
<IShellFolder
> pShellFolder
;
27 hr
= SHCoCreateInstance(NULL
, clsid
, NULL
, IID_PPV_ARG(IShellFolder
, &pShellFolder
));
31 LPITEMIDLIST pidlAbsolute
= ILCombine (pidlRoot
, pidlChild
);
32 CComPtr
<IPersistFolder
> ppf
;
33 CComPtr
<IPersistFolder3
> ppf3
;
35 if (ppfti
&& SUCCEEDED(pShellFolder
->QueryInterface(IID_PPV_ARG(IPersistFolder3
, &ppf3
))))
37 ppf3
->InitializeEx(NULL
, pidlAbsolute
, ppfti
);
39 else if (SUCCEEDED(pShellFolder
->QueryInterface(IID_PPV_ARG(IPersistFolder
, &ppf
))))
41 ppf
->Initialize(pidlAbsolute
);
43 ILFree (pidlAbsolute
);
45 return pShellFolder
->QueryInterface(riid
, ppvOut
);
48 static void WINAPI
_InsertMenuItemW(
60 ZeroMemory(&mii
, sizeof(mii
));
61 mii
.cbSize
= sizeof(mii
);
62 if (fType
== MFT_SEPARATOR
)
63 mii
.fMask
= MIIM_ID
| MIIM_TYPE
;
64 else if (fType
== MFT_STRING
)
66 mii
.fMask
= MIIM_ID
| MIIM_TYPE
| MIIM_STATE
;
67 if (IS_INTRESOURCE(dwTypeData
))
69 if (LoadStringW(_AtlBaseModule
.GetResourceInstance(), LOWORD((ULONG_PTR
)dwTypeData
), wszText
, _countof(wszText
)))
70 mii
.dwTypeData
= wszText
;
73 ERR("failed to load string %p\n", dwTypeData
);
78 mii
.dwTypeData
= (LPWSTR
)dwTypeData
;
84 InsertMenuItemW(hMenu
, indexMenu
, fByPosition
, &mii
);
87 struct FolderViewColumns
95 static FolderViewColumns g_ColumnDefs
[] =
97 {IDS_COL_NAME
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_LEFT
, 30},
98 {IDS_COL_LOCATION
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_LEFT
, 30},
99 {IDS_COL_RELEVANCE
, SHCOLSTATE_TYPE_STR
, LVCFMT_LEFT
, 0}
102 CFindFolder::CFindFolder() :
107 static LPITEMIDLIST
_ILCreate(LPCWSTR lpszPath
)
109 CComHeapPtr
<ITEMIDLIST
> lpFSPidl(ILCreateFromPathW(lpszPath
));
112 ERR("Failed to create pidl from path\n");
115 LPITEMIDLIST lpLastFSPidl
= ILFindLastID(lpFSPidl
);
117 int pathLen
= (PathFindFileNameW(lpszPath
) - lpszPath
) * sizeof(WCHAR
);
118 int cbData
= sizeof(WORD
) + pathLen
+ lpLastFSPidl
->mkid
.cb
;
119 LPITEMIDLIST pidl
= (LPITEMIDLIST
) SHAlloc(cbData
+ sizeof(WORD
));
123 LPBYTE p
= (LPBYTE
) pidl
;
124 *((WORD
*) p
) = cbData
;
127 memcpy(p
, lpszPath
, pathLen
);
128 p
+= pathLen
- sizeof(WCHAR
);
129 *((WCHAR
*) p
) = '\0';
132 memcpy(p
, lpLastFSPidl
, lpLastFSPidl
->mkid
.cb
);
133 p
+= lpLastFSPidl
->mkid
.cb
;
140 static LPCWSTR
_ILGetPath(LPCITEMIDLIST pidl
)
142 if (!pidl
|| !pidl
->mkid
.cb
)
144 return (LPCWSTR
) pidl
->mkid
.abID
;
147 static LPCITEMIDLIST
_ILGetFSPidl(LPCITEMIDLIST pidl
)
149 if (!pidl
|| !pidl
->mkid
.cb
)
151 return (LPCITEMIDLIST
) ((LPBYTE
) pidl
->mkid
.abID
152 + ((wcslen((LPCWSTR
) pidl
->mkid
.abID
) + 1) * sizeof(WCHAR
)));
163 CComPtr
<CFindFolder
> pFindFolder
;
166 template<typename TChar
, typename TString
, int (&StrNCmp
)(const TChar
*, const TChar
*, size_t)>
167 static const TChar
* StrStrN(const TChar
*lpFirst
, const TString
&lpSrch
, UINT cchMax
)
169 if (!lpFirst
|| lpSrch
.IsEmpty() || !cchMax
)
172 for (UINT i
= cchMax
; i
> 0 && *lpFirst
; i
--, lpFirst
++)
174 if (!StrNCmp(lpFirst
, lpSrch
, lpSrch
.GetLength()))
175 return (const TChar
*)lpFirst
;
181 template<typename TChar
, typename TString
, int (&StrNCmp
)(const TChar
*, const TChar
*, size_t)>
182 static UINT
StrStrNCount(const TChar
*lpFirst
, const TString
&lpSrch
, UINT cchMax
)
184 const TChar
*lpSearchEnd
= lpFirst
+ cchMax
;
186 while (lpFirst
< lpSearchEnd
&& (lpFirst
= StrStrN
<TChar
, TString
, StrNCmp
>(lpFirst
, lpSrch
, cchMax
)))
189 lpFirst
+= lpSrch
.GetLength();
190 cchMax
= lpSearchEnd
- lpFirst
;
195 static UINT
StrStrCountNIA(const CHAR
*lpFirst
, const CStringA
&lpSrch
, UINT cchMax
)
197 return StrStrNCount
<CHAR
, CStringA
, _strnicmp
>(lpFirst
, lpSrch
, cchMax
);
200 static UINT
StrStrCountNIW(const WCHAR
*lpFirst
, const CStringW
&lpSrch
, UINT cchMax
)
202 return StrStrNCount
<WCHAR
, CStringW
, _wcsnicmp
>(lpFirst
, lpSrch
, cchMax
);
205 static UINT
SearchFile(LPCWSTR lpFilePath
, _SearchData
*pSearchData
)
207 HANDLE hFile
= CreateFileW(lpFilePath
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_READONLY
, NULL
);
208 if (hFile
== INVALID_HANDLE_VALUE
)
211 DWORD size
= GetFileSize(hFile
, NULL
);
212 HANDLE hFileMap
= CreateFileMappingW(hFile
, NULL
, PAGE_READONLY
, 0, 0, NULL
);
214 if (hFileMap
== INVALID_HANDLE_VALUE
)
217 LPBYTE lpFileContent
= (LPBYTE
) MapViewOfFile(hFileMap
, FILE_MAP_READ
, 0, 0, 0);
218 CloseHandle(hFileMap
);
223 // Check for UTF-16 BOM
224 if (size
>= 2 && lpFileContent
[0] == 0xFF && lpFileContent
[1] == 0xFE)
226 uMatches
= StrStrCountNIW((LPCWSTR
) lpFileContent
, pSearchData
->szQueryW
, size
/ sizeof(WCHAR
));
230 uMatches
= StrStrCountNIA((LPCSTR
) lpFileContent
, pSearchData
->szQueryA
, size
/ sizeof(CHAR
));
233 UnmapViewOfFile(lpFileContent
);
238 static UINT
RecursiveFind(LPCWSTR lpPath
, _SearchData
*pSearchData
)
240 if (WaitForSingleObject(pSearchData
->hStopEvent
, 0) != WAIT_TIMEOUT
)
243 WCHAR szPath
[MAX_PATH
];
244 WIN32_FIND_DATAW FindData
;
246 BOOL bMoreFiles
= TRUE
;
247 UINT uTotalFound
= 0;
249 PathCombineW(szPath
, lpPath
, L
"*.*");
251 for (hFindFile
= FindFirstFileW(szPath
, &FindData
);
252 bMoreFiles
&& hFindFile
!= INVALID_HANDLE_VALUE
;
253 bMoreFiles
= FindNextFileW(hFindFile
, &FindData
))
255 if (!wcscmp(FindData
.cFileName
, L
".") || !wcscmp(FindData
.cFileName
, L
".."))
258 PathCombineW(szPath
, lpPath
, FindData
.cFileName
);
260 if (FindData
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
263 status
.Format(IDS_SEARCH_FOLDER
, FindData
.cFileName
);
264 PostMessageW(pSearchData
->hwnd
, WM_SEARCH_UPDATE_STATUS
, 0, (LPARAM
) StrDupW(status
.GetBuffer()));
266 uTotalFound
+= RecursiveFind(szPath
, pSearchData
);
268 else if ((pSearchData
->szFileName
.IsEmpty() || PathMatchSpecW(FindData
.cFileName
, pSearchData
->szFileName
))
269 && (pSearchData
->szQueryA
.IsEmpty() || SearchFile(szPath
, pSearchData
)))
272 PostMessageW(pSearchData
->hwnd
, WM_SEARCH_ADD_RESULT
, 0, (LPARAM
) StrDupW(szPath
));
276 if (hFindFile
!= INVALID_HANDLE_VALUE
)
277 FindClose(hFindFile
);
282 DWORD WINAPI
CFindFolder::SearchThreadProc(LPVOID lpParameter
)
284 _SearchData
*data
= static_cast<_SearchData
*>(lpParameter
);
286 data
->pFindFolder
->NotifyConnections(DISPID_SEARCHSTART
);
288 UINT uTotalFound
= RecursiveFind(data
->szPath
, data
);
290 data
->pFindFolder
->NotifyConnections(DISPID_SEARCHCOMPLETE
);
293 status
.Format(IDS_SEARCH_FILES_FOUND
, uTotalFound
);
294 ::PostMessageW(data
->hwnd
, WM_SEARCH_UPDATE_STATUS
, 0, (LPARAM
) StrDupW(status
.GetBuffer()));
295 ::SendMessageW(data
->hwnd
, WM_SEARCH_STOP
, 0, 0);
297 CloseHandle(data
->hStopEvent
);
303 void CFindFolder::NotifyConnections(DISPID id
)
305 DISPPARAMS dispatchParams
= {0};
306 CComDynamicUnkArray
&subscribers
=
307 IConnectionPointImpl
<CFindFolder
, &DIID_DSearchCommandEvents
>::m_vec
;
308 for (IUnknown
** pSubscriber
= subscribers
.begin(); pSubscriber
< subscribers
.end(); pSubscriber
++)
313 CComPtr
<IDispatch
> pDispatch
;
314 HRESULT hResult
= (*pSubscriber
)->QueryInterface(IID_PPV_ARG(IDispatch
, &pDispatch
));
315 if (!FAILED_UNEXPECTEDLY(hResult
))
316 pDispatch
->Invoke(id
, GUID_NULL
, 0, DISPATCH_METHOD
, &dispatchParams
, NULL
, NULL
, NULL
);
320 LRESULT
CFindFolder::StartSearch(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
325 // Clear all previous search results
327 m_shellFolderView
->RemoveObject(NULL
, &uItemIndex
);
329 _SearchData
* pSearchData
= new _SearchData();
330 pSearchData
->pFindFolder
= this;
331 pSearchData
->hwnd
= m_hWnd
;
333 SearchStart
*pSearchParams
= (SearchStart
*) lParam
;
334 pSearchData
->szPath
= pSearchParams
->szPath
;
335 pSearchData
->szFileName
= pSearchParams
->szFileName
;
336 pSearchData
->szQueryA
= pSearchParams
->szQuery
;
337 pSearchData
->szQueryW
= pSearchParams
->szQuery
;
338 SHFree(pSearchParams
);
341 SetEvent(m_hStopEvent
);
342 pSearchData
->hStopEvent
= m_hStopEvent
= CreateEvent(NULL
, TRUE
, FALSE
, NULL
);
344 if (!SHCreateThread(SearchThreadProc
, pSearchData
, NULL
, NULL
))
353 LRESULT
CFindFolder::StopSearch(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
357 SetEvent(m_hStopEvent
);
363 LRESULT
CFindFolder::AddResult(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
368 CComHeapPtr
<WCHAR
> lpPath((LPWSTR
) lParam
);
370 CComHeapPtr
<ITEMIDLIST
> lpSearchPidl(_ILCreate(lpPath
));
374 m_shellFolderView
->AddObject(lpSearchPidl
, &uItemIndex
);
380 LRESULT
CFindFolder::UpdateStatus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
382 CComHeapPtr
<WCHAR
> status((LPWSTR
) lParam
);
385 m_shellBrowser
->SetStatusTextSB(status
);
391 // *** IShellFolder2 methods ***
392 STDMETHODIMP
CFindFolder::GetDefaultSearchGUID(GUID
*pguid
)
398 STDMETHODIMP
CFindFolder::EnumSearches(IEnumExtraSearch
**ppenum
)
404 STDMETHODIMP
CFindFolder::GetDefaultColumn(DWORD
, ULONG
*pSort
, ULONG
*pDisplay
)
413 STDMETHODIMP
CFindFolder::GetDefaultColumnState(UINT iColumn
, DWORD
*pcsFlags
)
417 if (iColumn
>= _countof(g_ColumnDefs
))
418 return m_pisfInner
->GetDefaultColumnState(iColumn
- _countof(g_ColumnDefs
) + 1, pcsFlags
);
419 *pcsFlags
= g_ColumnDefs
[iColumn
].dwDefaultState
;
423 STDMETHODIMP
CFindFolder::GetDetailsEx(PCUITEMID_CHILD pidl
, const SHCOLUMNID
*pscid
, VARIANT
*pv
)
425 return m_pisfInner
->GetDetailsEx(pidl
, pscid
, pv
);
428 STDMETHODIMP
CFindFolder::GetDetailsOf(PCUITEMID_CHILD pidl
, UINT iColumn
, SHELLDETAILS
*pDetails
)
430 if (iColumn
>= _countof(g_ColumnDefs
))
431 return m_pisfInner
->GetDetailsOf(_ILGetFSPidl(pidl
), iColumn
- _countof(g_ColumnDefs
) + 1, pDetails
);
433 pDetails
->cxChar
= g_ColumnDefs
[iColumn
].cxChar
;
434 pDetails
->fmt
= g_ColumnDefs
[iColumn
].fmt
;
437 return SHSetStrRet(&pDetails
->str
, _AtlBaseModule
.GetResourceInstance(), g_ColumnDefs
[iColumn
].iResource
);
441 return SHSetStrRet(&pDetails
->str
, _ILGetPath(pidl
));
444 return GetDisplayNameOf(pidl
, SHGDN_NORMAL
, &pDetails
->str
);
447 STDMETHODIMP
CFindFolder::MapColumnToSCID(UINT iColumn
, SHCOLUMNID
*pscid
)
453 // *** IShellFolder methods ***
454 STDMETHODIMP
CFindFolder::ParseDisplayName(HWND hwndOwner
, LPBC pbc
, LPOLESTR lpszDisplayName
, ULONG
*pchEaten
,
455 PIDLIST_RELATIVE
*ppidl
, ULONG
*pdwAttributes
)
461 STDMETHODIMP
CFindFolder::EnumObjects(HWND hwndOwner
, DWORD dwFlags
, LPENUMIDLIST
*ppEnumIDList
)
463 *ppEnumIDList
= NULL
;
467 STDMETHODIMP
CFindFolder::BindToObject(PCUIDLIST_RELATIVE pidl
, LPBC pbcReserved
, REFIID riid
, LPVOID
*ppvOut
)
473 STDMETHODIMP
CFindFolder::BindToStorage(PCUIDLIST_RELATIVE pidl
, LPBC pbcReserved
, REFIID riid
, LPVOID
*ppvOut
)
479 STDMETHODIMP
CFindFolder::CompareIDs(LPARAM lParam
, PCUIDLIST_RELATIVE pidl1
, PCUIDLIST_RELATIVE pidl2
)
481 return m_pisfInner
->CompareIDs(lParam
, _ILGetFSPidl(pidl1
), _ILGetFSPidl(pidl2
));
484 STDMETHODIMP
CFindFolder::CreateViewObject(HWND hwndOwner
, REFIID riid
, LPVOID
*ppvOut
)
486 if (riid
== IID_IShellView
)
488 SFV_CREATE sfvparams
= {};
489 sfvparams
.cbSize
= sizeof(SFV_CREATE
);
490 sfvparams
.pshf
= this;
491 sfvparams
.psfvcb
= this;
492 HRESULT hr
= SHCreateShellFolderView(&sfvparams
, (IShellView
**) ppvOut
);
493 if (FAILED_UNEXPECTEDLY(hr
))
498 return ((IShellView
* ) * ppvOut
)->QueryInterface(IID_PPV_ARG(IShellFolderView
, &m_shellFolderView
));
500 return E_NOINTERFACE
;
503 STDMETHODIMP
CFindFolder::GetAttributesOf(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, DWORD
*rgfInOut
)
505 CComHeapPtr
<PCITEMID_CHILD
> aFSPidl
;
506 aFSPidl
.Allocate(cidl
);
507 for (UINT i
= 0; i
< cidl
; i
++)
509 aFSPidl
[i
] = _ILGetFSPidl(apidl
[i
]);
512 return m_pisfInner
->GetAttributesOf(cidl
, aFSPidl
, rgfInOut
);
515 class CFindFolderContextMenu
:
517 public CComObjectRootEx
<CComMultiThreadModelNoCS
>
519 CComPtr
<IContextMenu
> m_pInner
;
520 CComPtr
<IShellFolderView
> m_shellFolderView
;
522 static const UINT ADDITIONAL_MENU_ITEMS
= 2;
524 //// *** IContextMenu methods ***
525 STDMETHODIMP
QueryContextMenu(HMENU hMenu
, UINT indexMenu
, UINT idCmdFirst
, UINT idCmdLast
, UINT uFlags
)
527 m_firstCmdId
= indexMenu
;
528 _InsertMenuItemW(hMenu
, indexMenu
++, TRUE
, idCmdFirst
++, MFT_STRING
, MAKEINTRESOURCEW(IDS_SEARCH_OPEN_FOLDER
), MFS_ENABLED
);
529 _InsertMenuItemW(hMenu
, indexMenu
++, TRUE
, idCmdFirst
++, MFT_SEPARATOR
, NULL
, 0);
530 return m_pInner
->QueryContextMenu(hMenu
, indexMenu
, idCmdFirst
, idCmdLast
, uFlags
);
533 STDMETHODIMP
InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi
)
535 if (!IS_INTRESOURCE(lpcmi
->lpVerb
))
537 return m_pInner
->InvokeCommand(lpcmi
);
540 if (LOWORD(lpcmi
->lpVerb
) < m_firstCmdId
+ ADDITIONAL_MENU_ITEMS
)
542 PCUITEMID_CHILD
*apidl
;
544 HRESULT hResult
= m_shellFolderView
->GetSelectedObjects(&apidl
, &cidl
);
545 if (FAILED_UNEXPECTEDLY(hResult
))
548 for (UINT i
= 0; i
< cidl
; i
++)
550 CComHeapPtr
<ITEMIDLIST
> folderPidl(ILCreateFromPathW(_ILGetPath(apidl
[i
])));
552 return E_OUTOFMEMORY
;
553 LPCITEMIDLIST pidl
= _ILGetFSPidl(apidl
[i
]);
554 SHOpenFolderAndSelectItems(folderPidl
, 1, &pidl
, 0);
559 CMINVOKECOMMANDINFOEX actualCmdInfo
;
560 memcpy(&actualCmdInfo
, lpcmi
, lpcmi
->cbSize
);
561 actualCmdInfo
.lpVerb
-= ADDITIONAL_MENU_ITEMS
;
562 return m_pInner
->InvokeCommand((CMINVOKECOMMANDINFO
*)&actualCmdInfo
);
565 STDMETHODIMP
GetCommandString(UINT_PTR idCommand
, UINT uFlags
, UINT
*lpReserved
, LPSTR lpszName
, UINT uMaxNameLen
)
567 return m_pInner
->GetCommandString(idCommand
, uFlags
, lpReserved
, lpszName
, uMaxNameLen
);
571 static HRESULT
Create(IShellFolderView
*pShellFolderView
, IContextMenu
*pInnerContextMenu
, IContextMenu
**pContextMenu
)
573 CComObject
<CFindFolderContextMenu
> *pObj
;
574 HRESULT hResult
= CComObject
<CFindFolderContextMenu
>::CreateInstance(&pObj
);
575 if (FAILED_UNEXPECTEDLY(hResult
))
577 pObj
->m_shellFolderView
= pShellFolderView
;
578 pObj
->m_pInner
= pInnerContextMenu
;
579 return pObj
->QueryInterface(IID_PPV_ARG(IContextMenu
, pContextMenu
));
582 BEGIN_COM_MAP(CFindFolderContextMenu
)
583 COM_INTERFACE_ENTRY_IID(IID_IContextMenu
, IContextMenu
)
587 STDMETHODIMP
CFindFolder::GetUIObjectOf(HWND hwndOwner
, UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, REFIID riid
,
588 UINT
*prgfInOut
, LPVOID
*ppvOut
)
592 return m_pisfInner
->GetUIObjectOf(hwndOwner
, cidl
, apidl
, riid
, prgfInOut
, ppvOut
);
595 CComHeapPtr
<PCITEMID_CHILD
> aFSPidl
;
596 aFSPidl
.Allocate(cidl
);
597 for (UINT i
= 0; i
< cidl
; i
++)
599 aFSPidl
[i
] = _ILGetFSPidl(apidl
[i
]);
602 if (riid
== IID_IContextMenu
)
604 CComHeapPtr
<ITEMIDLIST
> folderPidl(ILCreateFromPathW(_ILGetPath(apidl
[0])));
606 return E_OUTOFMEMORY
;
607 CComPtr
<IShellFolder
> pDesktopFolder
;
608 HRESULT hResult
= SHGetDesktopFolder(&pDesktopFolder
);
609 if (FAILED_UNEXPECTEDLY(hResult
))
611 CComPtr
<IShellFolder
> pShellFolder
;
612 hResult
= pDesktopFolder
->BindToObject(folderPidl
, NULL
, IID_PPV_ARG(IShellFolder
, &pShellFolder
));
613 if (FAILED_UNEXPECTEDLY(hResult
))
615 CComPtr
<IContextMenu
> pContextMenu
;
616 hResult
= pShellFolder
->GetUIObjectOf(hwndOwner
, cidl
, aFSPidl
, riid
, prgfInOut
, (LPVOID
*)&pContextMenu
);
617 if (FAILED_UNEXPECTEDLY(hResult
))
619 return CFindFolderContextMenu::Create(m_shellFolderView
, pContextMenu
, (IContextMenu
**)ppvOut
);
622 return m_pisfInner
->GetUIObjectOf(hwndOwner
, cidl
, aFSPidl
, riid
, prgfInOut
, ppvOut
);
625 STDMETHODIMP
CFindFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl
, DWORD dwFlags
, LPSTRRET pName
)
627 return m_pisfInner
->GetDisplayNameOf(_ILGetFSPidl(pidl
), dwFlags
, pName
);
630 STDMETHODIMP
CFindFolder::SetNameOf(HWND hwndOwner
, PCUITEMID_CHILD pidl
, LPCOLESTR lpName
, DWORD dwFlags
,
631 PITEMID_CHILD
*pPidlOut
)
637 //// *** IShellFolderViewCB method ***
638 STDMETHODIMP
CFindFolder::MessageSFVCB(UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
642 case SFVM_DEFVIEWMODE
:
644 FOLDERVIEWMODE
*pViewMode
= (FOLDERVIEWMODE
*) lParam
;
645 *pViewMode
= FVM_DETAILS
;
648 case SFVM_WINDOWCREATED
:
650 // Subclass window to receive window messages
651 SubclassWindow((HWND
) wParam
);
653 // Get shell browser for updating status bar text
654 CComPtr
<IServiceProvider
> pServiceProvider
;
655 HRESULT hr
= m_shellFolderView
->QueryInterface(IID_PPV_ARG(IServiceProvider
, &pServiceProvider
));
656 if (FAILED_UNEXPECTEDLY(hr
))
658 hr
= pServiceProvider
->QueryService(SID_SShellBrowser
, IID_PPV_ARG(IShellBrowser
, &m_shellBrowser
));
659 if (FAILED_UNEXPECTEDLY(hr
))
663 CComPtr
<IWebBrowser2
> pWebBrowser2
;
664 hr
= m_shellBrowser
->QueryInterface(IID_PPV_ARG(IWebBrowser2
, &pWebBrowser2
));
665 if (FAILED_UNEXPECTEDLY(hr
))
667 WCHAR pwszGuid
[MAX_PATH
];
668 StringFromGUID2(CLSID_FileSearchBand
, pwszGuid
, _countof(pwszGuid
));
669 CComVariant
searchBar(pwszGuid
);
670 return pWebBrowser2
->ShowBrowserBar(&searchBar
, NULL
, NULL
);
676 //// *** IPersistFolder2 methods ***
677 STDMETHODIMP
CFindFolder::GetCurFolder(PIDLIST_ABSOLUTE
*pidl
)
679 *pidl
= ILClone(m_pidl
);
683 // *** IPersistFolder methods ***
684 STDMETHODIMP
CFindFolder::Initialize(LPCITEMIDLIST pidl
)
686 m_pidl
= ILClone(pidl
);
688 return E_OUTOFMEMORY
;
690 return SHELL32_CoCreateInitSF(m_pidl
,
693 &CLSID_ShellFSFolder
,
694 IID_PPV_ARG(IShellFolder2
, &m_pisfInner
));
697 // *** IPersist methods ***
698 STDMETHODIMP
CFindFolder::GetClassID(CLSID
*pClassId
)
700 if (pClassId
== NULL
)
702 *pClassId
= CLSID_FindFolder
;