mirror of
https://github.com/reactos/reactos.git
synced 2025-04-22 05:00:27 +00:00
[SHELLFIND] Add search functionality
This commit is contained in:
parent
3583900b17
commit
2f3db8d9a3
4 changed files with 215 additions and 48 deletions
|
@ -37,10 +37,18 @@ CFindFolder::CFindFolder() :
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static LPITEMIDLIST _ILCreate(LPCWSTR lpszPath, LPCITEMIDLIST lpcFindDataPidl)
|
static LPITEMIDLIST _ILCreate(LPCWSTR lpszPath)
|
||||||
{
|
{
|
||||||
|
CComHeapPtr<ITEMIDLIST> lpFSPidl(ILCreateFromPathW(lpszPath));
|
||||||
|
if (!(LPITEMIDLIST)lpFSPidl)
|
||||||
|
{
|
||||||
|
ERR("Failed to create pidl from path\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
LPITEMIDLIST lpLastFSPidl = ILFindLastID(lpFSPidl);
|
||||||
|
|
||||||
int pathLen = (wcslen(lpszPath) + 1) * sizeof(WCHAR);
|
int pathLen = (wcslen(lpszPath) + 1) * sizeof(WCHAR);
|
||||||
int cbData = sizeof(WORD) + pathLen + lpcFindDataPidl->mkid.cb;
|
int cbData = sizeof(WORD) + pathLen + lpLastFSPidl->mkid.cb;
|
||||||
LPITEMIDLIST pidl = (LPITEMIDLIST) SHAlloc(cbData + sizeof(WORD));
|
LPITEMIDLIST pidl = (LPITEMIDLIST) SHAlloc(cbData + sizeof(WORD));
|
||||||
if (!pidl)
|
if (!pidl)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -52,8 +60,8 @@ static LPITEMIDLIST _ILCreate(LPCWSTR lpszPath, LPCITEMIDLIST lpcFindDataPidl)
|
||||||
memcpy(p, lpszPath, pathLen);
|
memcpy(p, lpszPath, pathLen);
|
||||||
p += pathLen;
|
p += pathLen;
|
||||||
|
|
||||||
memcpy(p, lpcFindDataPidl, lpcFindDataPidl->mkid.cb);
|
memcpy(p, lpLastFSPidl, lpLastFSPidl->mkid.cb);
|
||||||
p += lpcFindDataPidl->mkid.cb;
|
p += lpLastFSPidl->mkid.cb;
|
||||||
|
|
||||||
*((WORD *) p) = 0;
|
*((WORD *) p) = 0;
|
||||||
|
|
||||||
|
@ -75,53 +83,199 @@ static LPCITEMIDLIST _ILGetFSPidl(LPCITEMIDLIST pidl)
|
||||||
+ ((wcslen((LPCWSTR) pidl->mkid.abID) + 1) * sizeof(WCHAR)));
|
+ ((wcslen((LPCWSTR) pidl->mkid.abID) + 1) * sizeof(WCHAR)));
|
||||||
}
|
}
|
||||||
|
|
||||||
LRESULT CFindFolder::AddItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
|
struct _SearchData
|
||||||
|
{
|
||||||
|
HWND hwnd;
|
||||||
|
HANDLE hStopEvent;
|
||||||
|
SearchStart *pSearchParams;
|
||||||
|
};
|
||||||
|
|
||||||
|
static LPCSTR WINAPI StrStrNA(LPCSTR lpFirst, LPCSTR lpSrch, UINT cchMax)
|
||||||
|
{
|
||||||
|
UINT i;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if (!lpFirst || !lpSrch || !*lpSrch || !cchMax)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
len = strlen(lpSrch);
|
||||||
|
|
||||||
|
for (i = cchMax; *lpFirst && (i > 0); i--, lpFirst++)
|
||||||
|
{
|
||||||
|
if (!strncmp(lpFirst, lpSrch, len))
|
||||||
|
return (LPCSTR)lpFirst;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
DWORD size = GetFileSize(hFile, NULL);
|
||||||
|
HANDLE hFileMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
|
||||||
|
CloseHandle(hFile);
|
||||||
|
if (hFileMap == INVALID_HANDLE_VALUE)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
LPBYTE lpFileContent = (LPBYTE) MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);
|
||||||
|
CloseHandle(hFileMap);
|
||||||
|
if (!lpFileContent)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
UINT uMatches = 0;
|
||||||
|
if ((size >= 2) && (lpFileContent[0] == 0xFF) && (lpFileContent[1] == 0xFE))
|
||||||
|
{
|
||||||
|
// UTF16 LE
|
||||||
|
LPCWSTR lpSearchPos = (LPCWSTR) lpFileContent;
|
||||||
|
DWORD dwCharsRemaining = size / sizeof(WCHAR);
|
||||||
|
const LPCWSTR lpSearchEnd = (LPCWSTR) lpFileContent + dwCharsRemaining;
|
||||||
|
const LPCWSTR lpszQuery = pSearchData->pSearchParams->szQuery;
|
||||||
|
const size_t queryLen = wcslen(lpszQuery);
|
||||||
|
while ((lpSearchPos = StrStrNW(lpSearchPos, lpszQuery, dwCharsRemaining))
|
||||||
|
&& lpSearchPos < lpSearchEnd)
|
||||||
|
{
|
||||||
|
uMatches++;
|
||||||
|
lpSearchPos += queryLen;
|
||||||
|
dwCharsRemaining -= queryLen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DWORD len = WideCharToMultiByte(CP_ACP, 0, pSearchData->pSearchParams->szQuery, -1, NULL, 0, NULL, NULL);
|
||||||
|
const LPSTR lpszQuery = new CHAR[len];
|
||||||
|
WideCharToMultiByte(CP_ACP, 0, pSearchData->pSearchParams->szQuery, -1, lpszQuery, len, NULL, NULL);
|
||||||
|
LPCSTR lpSearchPos = (LPCSTR) lpFileContent;
|
||||||
|
DWORD dwCharsRemaining = size;
|
||||||
|
const LPCSTR lpSearchEnd = (LPCSTR) lpFileContent + dwCharsRemaining;
|
||||||
|
const size_t queryLen = len;
|
||||||
|
while ((lpSearchPos = StrStrNA(lpSearchPos, lpszQuery, dwCharsRemaining))
|
||||||
|
&& lpSearchPos < lpSearchEnd)
|
||||||
|
{
|
||||||
|
uMatches++;
|
||||||
|
lpSearchPos += queryLen;
|
||||||
|
dwCharsRemaining -= queryLen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UnmapViewOfFile(lpFileContent);
|
||||||
|
|
||||||
|
return uMatches;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VOID RecursiveFind(LPCWSTR lpPath, _SearchData *pSearchData)
|
||||||
|
{
|
||||||
|
if (WaitForSingleObject(pSearchData->hStopEvent, 0) != WAIT_TIMEOUT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
WCHAR szPath[MAX_PATH];
|
||||||
|
WIN32_FIND_DATAW FindData;
|
||||||
|
HANDLE hFindFile;
|
||||||
|
BOOL bMoreFiles = TRUE;
|
||||||
|
|
||||||
|
PathCombineW(szPath, lpPath, L"*.*");
|
||||||
|
|
||||||
|
for (hFindFile = FindFirstFileW(szPath, &FindData);
|
||||||
|
bMoreFiles && hFindFile != INVALID_HANDLE_VALUE;
|
||||||
|
bMoreFiles = FindNextFileW(hFindFile, &FindData))
|
||||||
|
{
|
||||||
|
if (!wcscmp(FindData.cFileName, L".") || !wcscmp(FindData.cFileName, L".."))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
PathCombineW(szPath, lpPath, FindData.cFileName);
|
||||||
|
|
||||||
|
if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||||
|
{
|
||||||
|
CStringW* status = new CStringW();
|
||||||
|
status->Format(L"Searching '%s'", FindData.cFileName);
|
||||||
|
PostMessageW(pSearchData->hwnd, WM_SEARCH_UPDATE_STATUS, 0, (LPARAM) status);
|
||||||
|
|
||||||
|
RecursiveFind(szPath, pSearchData);
|
||||||
|
}
|
||||||
|
else if (pSearchData->szFileName.IsEmpty() || PathMatchSpecW(FindData.cFileName, pSearchData->szFileName))
|
||||||
|
{
|
||||||
|
DbgPrint("Searching file: '%S'\n", szPath);
|
||||||
|
UINT uMatches = SearchFile(szPath, pSearchData);
|
||||||
|
if (uMatches)
|
||||||
|
{
|
||||||
|
::PostMessageW(pSearchData->hwnd, WM_SEARCH_ADD_RESULT, 0, (LPARAM) StrDupW(szPath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hFindFile != INVALID_HANDLE_VALUE)
|
||||||
|
FindClose(hFindFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DWORD WINAPI _SearchThreadProc(LPVOID lpParameter)
|
||||||
|
{
|
||||||
|
_SearchData *data = static_cast<_SearchData*>(lpParameter);
|
||||||
|
|
||||||
|
SearchStart* params = (SearchStart *) data->pSearchParams;
|
||||||
|
|
||||||
|
RecursiveFind(params->szPath, data);
|
||||||
|
|
||||||
|
SHFree(params);
|
||||||
|
SHFree(lpParameter);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LRESULT CFindFolder::StartSearch(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
|
||||||
{
|
{
|
||||||
if (!lParam)
|
if (!lParam)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
HRESULT hr;
|
// Clear all previous search results
|
||||||
LPWSTR path = (LPWSTR) lParam;
|
|
||||||
|
|
||||||
CComPtr<IShellFolder> pShellFolder;
|
|
||||||
hr = SHGetDesktopFolder(&pShellFolder);
|
|
||||||
if (FAILED_UNEXPECTEDLY(hr))
|
|
||||||
{
|
|
||||||
LocalFree(path);
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
CComHeapPtr<ITEMIDLIST> lpFSPidl;
|
|
||||||
DWORD pchEaten;
|
|
||||||
hr = pShellFolder->ParseDisplayName(NULL, NULL, path, &pchEaten, &lpFSPidl, NULL);
|
|
||||||
if (FAILED_UNEXPECTEDLY(hr))
|
|
||||||
{
|
|
||||||
LocalFree(path);
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
LPITEMIDLIST lpLastFSPidl = ILFindLastID(lpFSPidl);
|
|
||||||
CComHeapPtr<ITEMIDLIST> lpSearchPidl(_ILCreate(path, lpLastFSPidl));
|
|
||||||
LocalFree(path);
|
|
||||||
if (!lpSearchPidl)
|
|
||||||
{
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT uItemIndex;
|
UINT uItemIndex;
|
||||||
hr = m_shellFolderView->AddObject(lpSearchPidl, &uItemIndex);
|
m_shellFolderView->RemoveObject(NULL, &uItemIndex);
|
||||||
|
|
||||||
return hr;
|
_SearchData* pSearchData = new _SearchData();
|
||||||
|
pSearchData->pFindFolder = this;
|
||||||
|
pSearchData->hwnd = m_hWnd;
|
||||||
|
if (m_hStopEvent)
|
||||||
|
SetEvent(m_hStopEvent);
|
||||||
|
pSearchData->hStopEvent = m_hStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||||
|
pSearchData->pSearchParams = (SearchStart *) lParam;
|
||||||
|
|
||||||
|
if (!SHCreateThread(_SearchThreadProc, pSearchData, NULL, NULL))
|
||||||
|
{
|
||||||
|
SHFree(pSearchData->pSearchParams);
|
||||||
|
SHFree(pSearchData);
|
||||||
|
return HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
LRESULT CFindFolder::UpdateStatus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
|
LRESULT CFindFolder::UpdateStatus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
|
||||||
{
|
{
|
||||||
LPWSTR status = (LPWSTR) lParam;
|
CStringW *status = (CStringW *) lParam;
|
||||||
if (m_shellBrowser)
|
if (m_shellBrowser)
|
||||||
{
|
{
|
||||||
m_shellBrowser->SetStatusTextSB(status);
|
m_shellBrowser->SetStatusTextSB(status->GetBuffer());
|
||||||
}
|
}
|
||||||
LocalFree(status);
|
delete status;
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,7 @@ private:
|
||||||
CComPtr<IShellFolder2> m_pisfInner;
|
CComPtr<IShellFolder2> m_pisfInner;
|
||||||
CComPtr<IShellFolderView> m_shellFolderView;
|
CComPtr<IShellFolderView> m_shellFolderView;
|
||||||
CComPtr<IShellBrowser> m_shellBrowser;
|
CComPtr<IShellBrowser> m_shellBrowser;
|
||||||
|
HANDLE m_hStopEvent;
|
||||||
|
|
||||||
//// *** IPersistFolder2 methods ***
|
//// *** IPersistFolder2 methods ***
|
||||||
STDMETHODIMP GetCurFolder(LPITEMIDLIST *pidl);
|
STDMETHODIMP GetCurFolder(LPITEMIDLIST *pidl);
|
||||||
|
@ -78,11 +79,16 @@ private:
|
||||||
// *** IPersist methods ***
|
// *** IPersist methods ***
|
||||||
STDMETHODIMP GetClassID(CLSID *pClassId);
|
STDMETHODIMP GetClassID(CLSID *pClassId);
|
||||||
|
|
||||||
LRESULT AddItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
// *** Message handlers ***
|
||||||
|
LRESULT StartSearch(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||||
|
|
||||||
|
LRESULT AddResult(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||||
|
|
||||||
LRESULT UpdateStatus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
LRESULT UpdateStatus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
CFindFolder();
|
||||||
|
|
||||||
DECLARE_REGISTRY_RESOURCEID(IDR_FINDFOLDER)
|
DECLARE_REGISTRY_RESOURCEID(IDR_FINDFOLDER)
|
||||||
|
|
||||||
DECLARE_NOT_AGGREGATABLE(CFindFolder)
|
DECLARE_NOT_AGGREGATABLE(CFindFolder)
|
||||||
|
@ -90,8 +96,9 @@ public:
|
||||||
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
||||||
|
|
||||||
BEGIN_MSG_MAP(CFindFolder)
|
BEGIN_MSG_MAP(CFindFolder)
|
||||||
MESSAGE_HANDLER(SWM_ADD_ITEM, AddItem)
|
MESSAGE_HANDLER(WM_SEARCH_START, StartSearch)
|
||||||
MESSAGE_HANDLER(SWM_UPDATE_STATUS, UpdateStatus)
|
MESSAGE_HANDLER(WM_SEARCH_ADD_RESULT, AddResult)
|
||||||
|
MESSAGE_HANDLER(WM_SEARCH_UPDATE_STATUS, UpdateStatus)
|
||||||
END_MSG_MAP()
|
END_MSG_MAP()
|
||||||
|
|
||||||
BEGIN_COM_MAP(CFindFolder)
|
BEGIN_COM_MAP(CFindFolder)
|
||||||
|
|
|
@ -46,34 +46,35 @@ void CSearchBar::InitializeSearchBar()
|
||||||
m_hWnd, NULL,
|
m_hWnd, NULL,
|
||||||
_AtlBaseModule.GetModuleInstance(), NULL);
|
_AtlBaseModule.GetModuleInstance(), NULL);
|
||||||
|
|
||||||
CreateWindowExW(0, WC_STATIC, L"A &word or phrase in the file:",
|
CreateWindowExW(0, WC_STATIC, L"All or part &of the file name:",
|
||||||
WS_CHILD | WS_VISIBLE,
|
WS_CHILD | WS_VISIBLE,
|
||||||
10, 50, 500, 20,
|
10, 50, 500, 20,
|
||||||
m_hWnd, NULL,
|
m_hWnd, NULL,
|
||||||
_AtlBaseModule.GetModuleInstance(), NULL);
|
_AtlBaseModule.GetModuleInstance(), NULL);
|
||||||
CreateWindowExW(WS_EX_CLIENTEDGE, WC_EDITW, NULL,
|
m_fileName = CreateWindowExW(WS_EX_CLIENTEDGE, WC_EDITW, NULL,
|
||||||
WS_BORDER | WS_CHILD | WS_VISIBLE,
|
WS_BORDER | WS_CHILD | WS_VISIBLE,
|
||||||
10, 70, 100, 20,
|
10, 70, 100, 20,
|
||||||
m_hWnd, NULL,
|
m_hWnd, NULL,
|
||||||
_AtlBaseModule.GetModuleInstance(), NULL);
|
_AtlBaseModule.GetModuleInstance(), NULL);
|
||||||
|
|
||||||
CreateWindowExW(0, WC_STATIC, L"&Look in:",
|
CreateWindowExW(0, WC_STATIC, L"A &word or phrase in the file:",
|
||||||
WS_CHILD | WS_VISIBLE,
|
WS_CHILD | WS_VISIBLE,
|
||||||
10, 100, 500, 20,
|
10, 100, 500, 20,
|
||||||
m_hWnd, NULL,
|
m_hWnd, NULL,
|
||||||
_AtlBaseModule.GetModuleInstance(), NULL);
|
_AtlBaseModule.GetModuleInstance(), NULL);
|
||||||
CreateWindowExW(WS_EX_CLIENTEDGE, WC_EDITW, NULL,
|
m_query = CreateWindowExW(WS_EX_CLIENTEDGE, WC_EDITW, NULL,
|
||||||
WS_BORDER | WS_CHILD | WS_VISIBLE,
|
WS_BORDER | WS_CHILD | WS_VISIBLE,
|
||||||
10, 120, 100, 20,
|
10, 120, 100, 20,
|
||||||
m_hWnd, NULL,
|
m_hWnd, NULL,
|
||||||
_AtlBaseModule.GetModuleInstance(), NULL);
|
_AtlBaseModule.GetModuleInstance(), NULL);
|
||||||
|
Edit_LimitText(m_query, MAX_PATH);
|
||||||
|
|
||||||
CreateWindowExW(0, WC_STATIC, L"&Look in:",
|
CreateWindowExW(0, WC_STATIC, L"&Look in:",
|
||||||
WS_CHILD | WS_VISIBLE,
|
WS_CHILD | WS_VISIBLE,
|
||||||
10, 150, 500, 20,
|
10, 150, 500, 20,
|
||||||
m_hWnd, NULL,
|
m_hWnd, NULL,
|
||||||
_AtlBaseModule.GetModuleInstance(), NULL);
|
_AtlBaseModule.GetModuleInstance(), NULL);
|
||||||
CreateWindowExW(WS_EX_CLIENTEDGE, WC_EDITW, NULL,
|
m_path = CreateWindowExW(WS_EX_CLIENTEDGE, WC_EDITW, NULL,
|
||||||
WS_BORDER | WS_CHILD | WS_VISIBLE,
|
WS_BORDER | WS_CHILD | WS_VISIBLE,
|
||||||
10, 180, 100, 20,
|
10, 180, 100, 20,
|
||||||
m_hWnd, NULL,
|
m_hWnd, NULL,
|
||||||
|
@ -198,8 +199,10 @@ LRESULT CSearchBar::OnSearchButtonClicked(WORD wNotifyCode, WORD wID, HWND hWndC
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
GetSearchResultsFolder(&pShellBrowser, &hwnd, NULL);
|
hr = GetSearchResultsFolder(*pShellBrowser, &hwnd, NULL);
|
||||||
if (hwnd)
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
::PostMessageW(hwnd, WM_SEARCH_START, 0, (LPARAM) StrDupW(L"Starting search..."));
|
::PostMessageW(hwnd, WM_SEARCH_START, 0, (LPARAM) StrDupW(L"Starting search..."));
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
|
@ -41,6 +41,9 @@ private:
|
||||||
CComPtr<IUnknown> pSite;
|
CComPtr<IUnknown> pSite;
|
||||||
BOOL fVisible;
|
BOOL fVisible;
|
||||||
BOOL bFocused;
|
BOOL bFocused;
|
||||||
|
HWND m_fileName;
|
||||||
|
HWND m_query;
|
||||||
|
HWND m_path;
|
||||||
|
|
||||||
void InitializeSearchBar();
|
void InitializeSearchBar();
|
||||||
HRESULT GetSearchResultsFolder(IShellBrowser **ppShellBrowser, HWND *pHwnd, IShellFolder **ppShellFolder);
|
HRESULT GetSearchResultsFolder(IShellBrowser **ppShellBrowser, HWND *pHwnd, IShellFolder **ppShellFolder);
|
||||||
|
|
Loading…
Reference in a new issue