mirror of
https://github.com/reactos/reactos.git
synced 2025-02-28 19:32:59 +00:00
[BROWSEUI][SHELL32] Fix desktop and computer find files locations (#7721)
- Searching the Desktop now searches the two desktop folders. - Searching My Computer now searches all local disks. - Adds a "Browse..." entry to the combobox list.
This commit is contained in:
parent
556cc8a7b2
commit
9a55c931f8
41 changed files with 398 additions and 33 deletions
|
@ -148,7 +148,7 @@ struct _SearchData
|
|||
{
|
||||
HWND hwnd;
|
||||
HANDLE hStopEvent;
|
||||
CStringW szPath;
|
||||
LOCATIONITEM *pPaths;
|
||||
CStringW szFileName;
|
||||
CStringA szQueryA;
|
||||
CStringW szQueryW;
|
||||
|
@ -156,6 +156,11 @@ struct _SearchData
|
|||
CStringA szQueryU8;
|
||||
BOOL SearchHidden;
|
||||
CComPtr<CFindFolder> pFindFolder;
|
||||
|
||||
~_SearchData()
|
||||
{
|
||||
FreeList(pPaths);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename TChar, typename TString, int (&StrNCmp)(const TChar *, const TChar *, size_t)>
|
||||
|
@ -461,11 +466,17 @@ DWORD WINAPI CFindFolder::SearchThreadProc(LPVOID lpParameter)
|
|||
{
|
||||
_SearchData *data = static_cast<_SearchData*>(lpParameter);
|
||||
|
||||
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL);
|
||||
|
||||
HRESULT hrCoInit = CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||
|
||||
data->pFindFolder->NotifyConnections(DISPID_SEARCHSTART);
|
||||
|
||||
UINT uTotalFound = RecursiveFind(data->szPath, data);
|
||||
UINT uTotalFound = 0;
|
||||
for (LOCATIONITEM *pLocation = data->pPaths; pLocation; pLocation = pLocation->pNext)
|
||||
{
|
||||
uTotalFound += RecursiveFind(pLocation->szPath, data);
|
||||
}
|
||||
|
||||
data->pFindFolder->NotifyConnections(DISPID_SEARCHCOMPLETE);
|
||||
|
||||
|
@ -521,7 +532,7 @@ LRESULT CFindFolder::StartSearch(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &
|
|||
pSearchData->hwnd = m_hWnd;
|
||||
|
||||
SearchStart *pSearchParams = (SearchStart *) lParam;
|
||||
pSearchData->szPath = pSearchParams->szPath;
|
||||
pSearchData->pPaths = pSearchParams->pPaths;
|
||||
pSearchData->szFileName = pSearchParams->szFileName;
|
||||
pSearchData->szQueryA = pSearchParams->szQuery;
|
||||
pSearchData->szQueryW = pSearchParams->szQuery;
|
||||
|
@ -589,12 +600,15 @@ LRESULT CFindFolder::StartSearch(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &
|
|||
SetEvent(m_hStopEvent);
|
||||
pSearchData->hStopEvent = m_hStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
if (!SHCreateThread(SearchThreadProc, pSearchData, NULL, NULL))
|
||||
if (!SHCreateThread(SearchThreadProc, pSearchData, 0, NULL))
|
||||
{
|
||||
SHFree(pSearchData);
|
||||
return 0;
|
||||
if (pSearchData->hStopEvent)
|
||||
{
|
||||
CloseHandle(pSearchData->hStopEvent);
|
||||
m_hStopEvent = NULL;
|
||||
}
|
||||
delete pSearchData;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,8 +47,130 @@ static UINT GetShellViewItemCount(IShellView *pSV)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct SPECIALFINDITEMID
|
||||
{
|
||||
WORD cb;
|
||||
BYTE Type, Id;
|
||||
CLSID Cls;
|
||||
WORD Terminator;
|
||||
};
|
||||
enum { SPECIAL_BROWSE = 42 };
|
||||
|
||||
static const SPECIALFINDITEMID g_pidlBrowseDir = { FIELD_OFFSET(SPECIALFINDITEMID, Terminator),
|
||||
0, SPECIAL_BROWSE, CLSID_FindFolder, 0 };
|
||||
|
||||
static BYTE GetSpecial(PCIDLIST_ABSOLUTE pidl)
|
||||
{
|
||||
if (pidl && pidl->mkid.cb == FIELD_OFFSET(SPECIALFINDITEMID, Terminator))
|
||||
{
|
||||
SPECIALFINDITEMID *pSpecial = (SPECIALFINDITEMID*)pidl;
|
||||
if (pSpecial->Type == g_pidlBrowseDir.Type && pSpecial->Cls == g_pidlBrowseDir.Cls &&
|
||||
ILIsEmpty(ILGetNext(pidl)))
|
||||
{
|
||||
return pSpecial->Id;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static HRESULT BindToObject(PCIDLIST_ABSOLUTE pidl, REFIID riid, void **ppv)
|
||||
{
|
||||
PCUITEMID_CHILD pidlChild;
|
||||
CComPtr<IShellFolder> psf;
|
||||
HRESULT hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &psf), &pidlChild);
|
||||
return SUCCEEDED(hr) ? psf->BindToObject(pidlChild, NULL, riid, ppv) : hr;
|
||||
}
|
||||
|
||||
static HRESULT GetClassOfItem(PCIDLIST_ABSOLUTE pidl, CLSID *pCLSID)
|
||||
{
|
||||
CComPtr<IShellFolder> psf;
|
||||
HRESULT hr = BindToObject(pidl, IID_PPV_ARG(IShellFolder, &psf));
|
||||
return SUCCEEDED(hr) ? IUnknown_GetClassID(psf, pCLSID) : hr;
|
||||
}
|
||||
|
||||
void FreeList(LOCATIONITEM *pItems)
|
||||
{
|
||||
while (pItems)
|
||||
{
|
||||
LOCATIONITEM *pNext = pItems->pNext;
|
||||
CoTaskMemFree(pItems);
|
||||
pItems = pNext;
|
||||
}
|
||||
}
|
||||
|
||||
static LOCATIONITEM* CreateLocationListItem(PCWSTR szPath)
|
||||
{
|
||||
const SIZE_T cch = lstrlenW(szPath) + 1;
|
||||
LOCATIONITEM *p = (LOCATIONITEM*)CoTaskMemAlloc(FIELD_OFFSET(LOCATIONITEM, szPath[cch]));
|
||||
if (p)
|
||||
{
|
||||
p->pNext = NULL;
|
||||
CopyMemory(p->szPath, szPath, cch * sizeof(*szPath));
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
template<class T> static LOCATIONITEM* BuildLocationList(T **rgszPaths, SIZE_T nCount)
|
||||
{
|
||||
LOCATIONITEM *pStart = NULL, *pPrev = NULL;
|
||||
for (SIZE_T i = 0; i < nCount; ++i)
|
||||
{
|
||||
LOCATIONITEM *pItem = CreateLocationListItem(rgszPaths[i]);
|
||||
if (!pStart)
|
||||
pStart = pItem;
|
||||
else if (pPrev)
|
||||
pPrev->pNext = pItem;
|
||||
pPrev = pItem;
|
||||
if (!pItem)
|
||||
{
|
||||
FreeList(pStart);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return pStart;
|
||||
}
|
||||
|
||||
static LOCATIONITEM* GetDesktopLocations()
|
||||
{
|
||||
SIZE_T nCount = 0;
|
||||
PCWSTR rgszLocations[2];
|
||||
WCHAR szUser[MAX_PATH], szCommon[MAX_PATH];
|
||||
|
||||
rgszLocations[nCount] = szUser;
|
||||
nCount += !!SHGetSpecialFolderPathW(NULL, szUser, CSIDL_DESKTOPDIRECTORY, TRUE);
|
||||
rgszLocations[nCount] = szCommon;
|
||||
nCount += !!SHGetSpecialFolderPathW(NULL, szCommon, CSIDL_COMMON_DESKTOPDIRECTORY, TRUE);
|
||||
return BuildLocationList(rgszLocations, nCount);
|
||||
}
|
||||
|
||||
static LOCATIONITEM* GetLocalDisksLocations()
|
||||
{
|
||||
PCWSTR rgszLocations[26];
|
||||
WCHAR rgszDrives[_countof(rgszLocations)][4];
|
||||
UINT nCount = 0;
|
||||
for (UINT i = 0, fDrives = GetLogicalDrives(); i < _countof(rgszLocations); ++i)
|
||||
{
|
||||
if (fDrives & (1 << i))
|
||||
{
|
||||
rgszDrives[nCount][0] = 'A' + i;
|
||||
rgszDrives[nCount][1] = ':';
|
||||
rgszDrives[nCount][2] = '\\';
|
||||
rgszDrives[nCount][3] = UNICODE_NULL;
|
||||
UINT fType = GetDriveTypeW(rgszDrives[nCount]);
|
||||
if (fType == DRIVE_FIXED || fType == DRIVE_RAMDISK)
|
||||
{
|
||||
rgszLocations[nCount] = rgszDrives[nCount];
|
||||
nCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return BuildLocationList(rgszLocations, nCount);
|
||||
}
|
||||
|
||||
CSearchBar::CSearchBar() :
|
||||
m_pSite(NULL),
|
||||
m_RealItemIndex(0),
|
||||
m_bVisible(FALSE)
|
||||
{
|
||||
}
|
||||
|
@ -194,11 +316,15 @@ LRESULT CSearchBar::OnSearchButtonClicked(WORD wNotifyCode, WORD wID, HWND hWndC
|
|||
|
||||
pSearchStart->SearchHidden = IsDlgButtonChecked(IDC_SEARCH_HIDDEN);
|
||||
|
||||
if (!GetAddressEditBoxPath(pSearchStart->szPath))
|
||||
WCHAR buf[MAX_PATH];
|
||||
pSearchStart->pPaths = GetAddressEditBoxLocations(buf);
|
||||
if (!pSearchStart->pPaths)
|
||||
{
|
||||
ShellMessageBoxW(_AtlBaseModule.GetResourceInstance(), m_hWnd, MAKEINTRESOURCEW(IDS_SEARCHINVALID), MAKEINTRESOURCEW(IDS_SEARCHLABEL), MB_OK | MB_ICONERROR, pSearchStart->szPath);
|
||||
ShellMessageBoxW(_AtlBaseModule.GetResourceInstance(), m_hWnd, MAKEINTRESOURCEW(IDS_SEARCHINVALID),
|
||||
MAKEINTRESOURCEW(IDS_SEARCHLABEL), MB_OK | MB_ICONERROR, buf);
|
||||
return 0;
|
||||
}
|
||||
ScopedFreeLocationItems FreeLocationsHelper(pSearchStart->pPaths);
|
||||
|
||||
// See if we have an szFileName by testing for its entry lenth > 0 and our searched FileName does not contain
|
||||
// an asterisk or a question mark. If so, then prepend and append an asterisk to the searched FileName.
|
||||
|
@ -255,6 +381,7 @@ LRESULT CSearchBar::OnSearchButtonClicked(WORD wNotifyCode, WORD wID, HWND hWndC
|
|||
return 0;
|
||||
}
|
||||
|
||||
FreeLocationsHelper.Detach();
|
||||
::PostMessageW(hwnd, WM_SEARCH_START, 0, (LPARAM) pSearchStart.Detach());
|
||||
|
||||
SetSearchInProgress(TRUE);
|
||||
|
@ -272,31 +399,89 @@ LRESULT CSearchBar::OnStopButtonClicked(WORD wNotifyCode, WORD wID, HWND hWndCtl
|
|||
return 0;
|
||||
}
|
||||
|
||||
BOOL CSearchBar::GetAddressEditBoxPath(WCHAR *szPath)
|
||||
LRESULT CSearchBar::OnLocationEditChange(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
|
||||
{
|
||||
HWND hComboboxEx = hWndCtl;
|
||||
INT_PTR idx = SendMessageW(hComboboxEx, CB_GETCURSEL, 0, 0);
|
||||
if (idx < 0)
|
||||
return 0;
|
||||
COMBOBOXEXITEMW item;
|
||||
item.mask = CBEIF_LPARAM;
|
||||
item.iItem = idx;
|
||||
item.cchTextMax = 0;
|
||||
if (!SendMessageW(hComboboxEx, CBEM_GETITEMW, 0, (LPARAM)&item) ||
|
||||
GetSpecial((LPITEMIDLIST)item.lParam) != SPECIAL_BROWSE)
|
||||
{
|
||||
m_RealItemIndex = idx;
|
||||
return 0;
|
||||
}
|
||||
|
||||
idx = max(m_RealItemIndex, 0);
|
||||
SendMessageW(hComboboxEx, CB_SETCURSEL, idx, 0); // Reset to previous item
|
||||
|
||||
BROWSEINFOW bi = { hComboboxEx };
|
||||
bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE;
|
||||
if (PIDLIST_ABSOLUTE pidl = SHBrowseForFolderW(&bi))
|
||||
{
|
||||
idx = FindItemInComboEx(hComboboxEx, pidl, ILIsEqual, TRUE);
|
||||
if (idx < 0)
|
||||
{
|
||||
SHFILEINFO shfi;
|
||||
if (SHGetFileInfoW((WCHAR*)pidl, 0, &shfi, sizeof(shfi), SHGFI_PIDL | SHGFI_DISPLAYNAME | SHGFI_SYSICONINDEX))
|
||||
{
|
||||
item.mask = CBEIF_LPARAM | CBEIF_TEXT | CBEIF_SELECTEDIMAGE | CBEIF_IMAGE;
|
||||
item.iItem = -1;
|
||||
item.iImage = item.iSelectedImage = shfi.iIcon;
|
||||
item.pszText = shfi.szDisplayName;
|
||||
item.lParam = (LPARAM)pidl; // IAddressEditBox takes ownership
|
||||
idx = SendMessageW(hComboboxEx, CBEM_INSERTITEMW, 0, (LPARAM)&item);
|
||||
}
|
||||
}
|
||||
if (idx >= 0)
|
||||
SendMessageW(hComboboxEx, CB_SETCURSEL, idx, 0); // Select the browsed item
|
||||
else
|
||||
SHFree(pidl);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
LOCATIONITEM* CSearchBar::GetAddressEditBoxLocations(WCHAR *szPath)
|
||||
{
|
||||
WCHAR szItemText[MAX_PATH], *pszPath = szPath;
|
||||
HWND hComboboxEx = GetDlgItem(IDC_SEARCH_COMBOBOX);
|
||||
::GetWindowTextW(hComboboxEx, szPath, MAX_PATH);
|
||||
INT iSelectedIndex = SendMessageW(hComboboxEx, CB_GETCURSEL, 0, 0);
|
||||
if (iSelectedIndex != CB_ERR)
|
||||
{
|
||||
WCHAR szItemText[MAX_PATH];
|
||||
COMBOBOXEXITEMW item = {0};
|
||||
COMBOBOXEXITEMW item;
|
||||
item.mask = CBEIF_LPARAM | CBEIF_TEXT;
|
||||
item.iItem = iSelectedIndex;
|
||||
item.pszText = szItemText;
|
||||
item.cchTextMax = _countof(szItemText);
|
||||
SendMessageW(hComboboxEx, CBEM_GETITEMW, 0, (LPARAM)&item);
|
||||
|
||||
if (!wcscmp(szItemText, szPath) && SHGetPathFromIDListW((LPCITEMIDLIST)item.lParam, szItemText))
|
||||
if (!wcscmp(szItemText, szPath))
|
||||
{
|
||||
StringCbCopyW(szPath, MAX_PATH * sizeof(WCHAR), szItemText);
|
||||
return TRUE;
|
||||
LPCITEMIDLIST pidl = (LPCITEMIDLIST)item.lParam;
|
||||
CLSID clsid;
|
||||
HRESULT hr = GetClassOfItem(pidl, &clsid);
|
||||
if (SUCCEEDED(hr) && clsid == CLSID_MyComputer)
|
||||
return GetLocalDisksLocations();
|
||||
// TODO: Shell enumerate the network neighborhood if it is chosen
|
||||
if (!pidl || !pidl->mkid.cb)
|
||||
return GetDesktopLocations();
|
||||
if (GetSpecial(pidl) || !SHGetPathFromIDListW(pidl, szItemText))
|
||||
return NULL;
|
||||
pszPath = szItemText;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD dwAttributes = GetFileAttributesW(szPath);
|
||||
return dwAttributes != INVALID_FILE_ATTRIBUTES
|
||||
&& (dwAttributes & FILE_ATTRIBUTE_DIRECTORY);
|
||||
DWORD dwAttributes = GetFileAttributesW(pszPath);
|
||||
if (dwAttributes != INVALID_FILE_ATTRIBUTES && (dwAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
|
||||
PathIsAbsolute(pszPath))
|
||||
{
|
||||
return BuildLocationList(&pszPath, 1);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LRESULT CSearchBar::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
|
||||
|
@ -607,30 +792,70 @@ HRESULT STDMETHODCALLTYPE CSearchBar::Invoke(DISPID dispIdMember, REFIID riid, L
|
|||
if (FAILED_UNEXPECTEDLY(hResult))
|
||||
return hResult;
|
||||
HWND hComboboxEx = GetDlgItem(IDC_SEARCH_COMBOBOX);
|
||||
int index = SendMessageW(hComboboxEx, CB_GETCOUNT, 0, 0);
|
||||
if (index <= 0)
|
||||
INT_PTR count = SendMessageW(hComboboxEx, CB_GETCOUNT, 0, 0);
|
||||
if (count <= 0)
|
||||
return S_OK;
|
||||
COMBOBOXEXITEMW item = {0};
|
||||
item.mask = CBEIF_LPARAM;
|
||||
item.iItem = index - 1;
|
||||
item.iItem = count - 1;
|
||||
SendMessageW(hComboboxEx, CBEM_GETITEMW, 0, (LPARAM)&item);
|
||||
if (!item.lParam)
|
||||
return S_OK;
|
||||
CComPtr<IShellFolder> pDesktopFolder;
|
||||
hResult = SHGetDesktopFolder(&pDesktopFolder);
|
||||
if (FAILED_UNEXPECTEDLY(hResult))
|
||||
return hResult;
|
||||
CComPtr<IShellFolder> pShellFolder;
|
||||
hResult = pDesktopFolder->BindToObject((LPCITEMIDLIST)item.lParam, NULL, IID_PPV_ARG(IShellFolder, &pShellFolder));
|
||||
if (FAILED(hResult))
|
||||
return S_OK;
|
||||
CLSID clsid;
|
||||
hResult = IUnknown_GetClassID(pShellFolder, &clsid);
|
||||
hResult = GetClassOfItem((LPCITEMIDLIST)item.lParam, &clsid);
|
||||
if (SUCCEEDED(hResult) && clsid == CLSID_FindFolder)
|
||||
{
|
||||
SendMessageW(hComboboxEx, CBEM_DELETEITEM, item.iItem, 0);
|
||||
SendMessageW(hComboboxEx, CB_SETCURSEL, 0, 0);
|
||||
// Starting in My Computer is better than just searching the desktop folder
|
||||
PIDLIST_ABSOLUTE pidl;
|
||||
if (SUCCEEDED(SHGetSpecialFolderLocation(NULL, CSIDL_DRIVES, &pidl)))
|
||||
{
|
||||
INT_PTR idx = FindItemInComboEx(hComboboxEx, pidl, ILIsEqual, TRUE);
|
||||
if (idx >= 0)
|
||||
SendMessageW(hComboboxEx, CB_SETCURSEL, idx, 0);
|
||||
SHFree(pidl);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove all non-filesystem items since we currently use FindFirstFile to search
|
||||
BOOL fFoundBrowse = FALSE;
|
||||
for (item.iItem = 0; SendMessageW(hComboboxEx, CBEM_GETITEMW, 0, (LPARAM)&item); item.iItem++)
|
||||
{
|
||||
LPCITEMIDLIST pidl = (LPCITEMIDLIST)item.lParam;
|
||||
BYTE special = GetSpecial(pidl);
|
||||
fFoundBrowse |= special == SPECIAL_BROWSE;
|
||||
if (special)
|
||||
continue;
|
||||
const UINT fQuery = SFGAO_FILESYSTEM | SFGAO_FILESYSANCESTOR;
|
||||
SHFILEINFO shfi;
|
||||
shfi.dwAttributes = fQuery;
|
||||
if (SHGetFileInfoW((WCHAR*)pidl, 0, &shfi, sizeof(shfi), SHGFI_PIDL | SHGFI_ATTRIBUTES | SHGFI_ATTR_SPECIFIED))
|
||||
{
|
||||
if (!(shfi.dwAttributes & fQuery))
|
||||
{
|
||||
if (SendMessageW(hComboboxEx, CBEM_DELETEITEM, item.iItem, 0) != CB_ERR)
|
||||
item.iItem--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add our custom Browse item
|
||||
if (!fFoundBrowse)
|
||||
{
|
||||
WCHAR buf[200];
|
||||
item.mask = CBEIF_LPARAM | CBEIF_TEXT | CBEIF_INDENT;
|
||||
item.iItem = -1;
|
||||
item.iIndent = -2; // Remove space reserved for the non-existing item icon
|
||||
item.lParam = (LPARAM)ILClone((LPITEMIDLIST)&g_pidlBrowseDir);
|
||||
item.pszText = const_cast<PWSTR>(L"...");
|
||||
#define IDS_SEARCH_BROWSEITEM 10244 /* shell32 shresdef.h */
|
||||
if (LoadStringW(GetModuleHandleW(L"SHELL32"), IDS_SEARCH_BROWSEITEM, buf, _countof(buf)))
|
||||
item.pszText = buf;
|
||||
if (item.lParam)
|
||||
SendMessageW(hComboboxEx, CBEM_INSERTITEMW, 0, (LPARAM)&item);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
case DISPID_SEARCHCOMPLETE:
|
||||
|
|
|
@ -24,10 +24,11 @@ private:
|
|||
// *** BaseBarSite information ***
|
||||
CComPtr<IUnknown> m_pSite;
|
||||
CComPtr<IAddressEditBox> m_AddressEditBox;
|
||||
INT_PTR m_RealItemIndex;
|
||||
BOOL m_bVisible;
|
||||
|
||||
HRESULT GetSearchResultsFolder(IShellBrowser **ppShellBrowser, HWND *pHwnd, IShellFolder **ppShellFolder);
|
||||
BOOL GetAddressEditBoxPath(WCHAR *szPath);
|
||||
LOCATIONITEM* GetAddressEditBoxLocations(WCHAR *szPath);
|
||||
void SetSearchInProgress(BOOL bInProgress);
|
||||
HRESULT TrySubscribeToSearchEvents();
|
||||
void TrySetFocus(UINT Source);
|
||||
|
@ -37,6 +38,7 @@ private:
|
|||
LRESULT OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
LRESULT OnSearchButtonClicked(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
|
||||
LRESULT OnStopButtonClicked(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
|
||||
LRESULT OnLocationEditChange(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
|
||||
LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
|
||||
public:
|
||||
|
@ -105,5 +107,6 @@ public:
|
|||
MESSAGE_HANDLER(WM_SIZE, OnSize)
|
||||
COMMAND_HANDLER(IDC_SEARCH_BUTTON, BN_CLICKED, OnSearchButtonClicked)
|
||||
COMMAND_HANDLER(IDC_SEARCH_STOP_BUTTON, BN_CLICKED, OnStopButtonClicked)
|
||||
COMMAND_HANDLER(IDC_SEARCH_COMBOBOX, CBN_EDITCHANGE, OnLocationEditChange)
|
||||
END_MSG_MAP()
|
||||
};
|
||||
|
|
|
@ -31,12 +31,58 @@
|
|||
#define WM_SEARCH_ADD_RESULT WM_USER + 2
|
||||
#define WM_SEARCH_UPDATE_STATUS WM_USER + 3
|
||||
|
||||
typedef struct tagLOCATIONITEM
|
||||
{
|
||||
struct tagLOCATIONITEM *pNext;
|
||||
WCHAR szPath[ANYSIZE_ARRAY];
|
||||
} LOCATIONITEM;
|
||||
|
||||
void FreeList(LOCATIONITEM *pLI);
|
||||
|
||||
struct ScopedFreeLocationItems
|
||||
{
|
||||
LOCATIONITEM *m_ptr;
|
||||
ScopedFreeLocationItems(LOCATIONITEM *ptr) : m_ptr(ptr) {}
|
||||
~ScopedFreeLocationItems() { FreeList(m_ptr); }
|
||||
void Detach() { m_ptr = NULL; }
|
||||
};
|
||||
|
||||
struct SearchStart
|
||||
{
|
||||
WCHAR szPath[MAX_PATH];
|
||||
LOCATIONITEM *pPaths;
|
||||
WCHAR szFileName[MAX_PATH];
|
||||
WCHAR szQuery[MAX_PATH];
|
||||
BOOL SearchHidden;
|
||||
};
|
||||
|
||||
template<class T, class F, class R>
|
||||
static INT_PTR FindItemInComboEx(HWND hCombo, T &FindItem, F CompareFunc, R RetMatch)
|
||||
{
|
||||
COMBOBOXEXITEMW item;
|
||||
item.mask = CBEIF_LPARAM;
|
||||
item.cchTextMax = 0;
|
||||
for (item.iItem = 0; SendMessageW(hCombo, CBEM_GETITEMW, 0, (LPARAM)&item); item.iItem++)
|
||||
{
|
||||
if (CompareFunc((T&)item.lParam, FindItem) == RetMatch)
|
||||
return item.iItem;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline bool PathIsOnDrive(PCWSTR Path)
|
||||
{
|
||||
return PathGetDriveNumberW(Path) >= 0 && (Path[2] == '\\' || !Path[2]);
|
||||
}
|
||||
|
||||
static inline BOOL PathIsOnUnc(PCWSTR Path)
|
||||
{
|
||||
return PathIsUNCW(Path); // FIXME: Verify the path starts with <\\Server\Share>[\]
|
||||
}
|
||||
|
||||
static inline bool PathIsAbsolute(PCWSTR Path)
|
||||
{
|
||||
// Note: PathIsRelativeW is too forgiving
|
||||
return PathIsOnDrive(Path) || PathIsOnUnc(Path);
|
||||
}
|
||||
|
||||
#endif /* _SHELLFIND_PCH_ */
|
||||
|
|
|
@ -998,6 +998,8 @@ BEGIN
|
|||
IDS_OBJECTS "%d Objects"
|
||||
IDS_OBJECTS_SELECTED "%d Objects Selected"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "Обзор..."
|
||||
|
||||
IDS_TITLE_MYCOMP "Моят компютър"
|
||||
IDS_TITLE_MYNET "Моята мрежа"
|
||||
IDS_TITLE_BIN_1 "Кошче (пълно)"
|
||||
|
|
|
@ -998,6 +998,8 @@ BEGIN
|
|||
IDS_OBJECTS "%d Objects"
|
||||
IDS_OBJECTS_SELECTED "%d Objects Selected"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "Browse..."
|
||||
|
||||
IDS_TITLE_MYCOMP "My Computer"
|
||||
IDS_TITLE_MYNET "My Network Places"
|
||||
IDS_TITLE_BIN_1 "Recycle Bin (full)"
|
||||
|
|
|
@ -1006,6 +1006,8 @@ BEGIN
|
|||
IDS_OBJECTS "Položek: %d"
|
||||
IDS_OBJECTS_SELECTED "Položek vybráno: %d"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "Procházet..."
|
||||
|
||||
IDS_TITLE_MYCOMP "Tento počítač"
|
||||
IDS_TITLE_MYNET "Místa v síti"
|
||||
IDS_TITLE_BIN_1 "Koš (plný)"
|
||||
|
|
|
@ -1005,6 +1005,8 @@ BEGIN
|
|||
IDS_OBJECTS "%d Objects"
|
||||
IDS_OBJECTS_SELECTED "%d Objects Selected"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "Gennemse..."
|
||||
|
||||
IDS_TITLE_MYCOMP "Min Computer"
|
||||
IDS_TITLE_MYNET "My Network Places"
|
||||
IDS_TITLE_BIN_1 "Recycle Bin (full)"
|
||||
|
|
|
@ -999,6 +999,8 @@ BEGIN
|
|||
IDS_OBJECTS "%d Objekte"
|
||||
IDS_OBJECTS_SELECTED "%d Objekte ausgewählt"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "Durchsuchen..."
|
||||
|
||||
IDS_TITLE_MYCOMP "Arbeitsplatz"
|
||||
IDS_TITLE_MYNET "Netzwerkumgebung"
|
||||
IDS_TITLE_BIN_1 "Papierkorb (voll)"
|
||||
|
|
|
@ -998,6 +998,8 @@ BEGIN
|
|||
IDS_OBJECTS "%d Objects"
|
||||
IDS_OBJECTS_SELECTED "%d Objects Selected"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "Αναζήτηση..."
|
||||
|
||||
IDS_TITLE_MYCOMP "Ο υπολογιστής μου"
|
||||
IDS_TITLE_MYNET "My Network Places"
|
||||
IDS_TITLE_BIN_1 "Κάδος ανακύκλωσης (γεμάτος)"
|
||||
|
|
|
@ -998,6 +998,8 @@ BEGIN
|
|||
IDS_OBJECTS "%d Objects"
|
||||
IDS_OBJECTS_SELECTED "%d Objects Selected"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "Browse..."
|
||||
|
||||
IDS_TITLE_MYCOMP "My Computer"
|
||||
IDS_TITLE_MYNET "My Network Places"
|
||||
IDS_TITLE_BIN_1 "Recycle Bin (full)"
|
||||
|
|
|
@ -998,6 +998,8 @@ BEGIN
|
|||
IDS_OBJECTS "%d Objects"
|
||||
IDS_OBJECTS_SELECTED "%d Objects Selected"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "Browse..."
|
||||
|
||||
IDS_TITLE_MYCOMP "My Computer"
|
||||
IDS_TITLE_MYNET "My Network Places"
|
||||
IDS_TITLE_BIN_1 "Recycle Bin (full)"
|
||||
|
|
|
@ -1007,6 +1007,8 @@ BEGIN
|
|||
IDS_OBJECTS "%d elementos"
|
||||
IDS_OBJECTS_SELECTED "%d elementos seleccionados"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "Examinar..."
|
||||
|
||||
IDS_TITLE_MYCOMP "Mi equipo"
|
||||
IDS_TITLE_MYNET "Mis sitios de red"
|
||||
IDS_TITLE_BIN_1 "Papelera (llena)"
|
||||
|
|
|
@ -1005,6 +1005,8 @@ BEGIN
|
|||
IDS_OBJECTS "%d objekti"
|
||||
IDS_OBJECTS_SELECTED "%d objekti valitud"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "Sirvi..."
|
||||
|
||||
IDS_TITLE_MYCOMP "Minu arvuti"
|
||||
IDS_TITLE_MYNET "Minu võrgukohad"
|
||||
IDS_TITLE_BIN_1 "Prügikast (täis)"
|
||||
|
|
|
@ -1003,6 +1003,8 @@ BEGIN
|
|||
IDS_OBJECTS "%d elementuak"
|
||||
IDS_OBJECTS_SELECTED "%d elementu hautatuak"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "Arakatu..."
|
||||
|
||||
IDS_TITLE_MYCOMP "Ordenagailua"
|
||||
IDS_TITLE_MYNET "Nire sarelekuak"
|
||||
IDS_TITLE_BIN_1 "Zakarrontzia (betea)"
|
||||
|
|
|
@ -998,6 +998,8 @@ BEGIN
|
|||
IDS_OBJECTS "%d Objects"
|
||||
IDS_OBJECTS_SELECTED "%d Objects Selected"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "Selaa..."
|
||||
|
||||
IDS_TITLE_MYCOMP "Oma Tietokone"
|
||||
IDS_TITLE_MYNET "My Network Places"
|
||||
IDS_TITLE_BIN_1 "Recycle Bin (full)"
|
||||
|
|
|
@ -998,6 +998,8 @@ BEGIN
|
|||
IDS_OBJECTS "%d objet(s)"
|
||||
IDS_OBJECTS_SELECTED "%d objet(s) sélectionné(s)"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "Parcourir..."
|
||||
|
||||
IDS_TITLE_MYCOMP "Poste de travail"
|
||||
IDS_TITLE_MYNET "Mon réseau"
|
||||
IDS_TITLE_BIN_1 "Corbeille (pleine)"
|
||||
|
|
|
@ -1005,6 +1005,9 @@ BEGIN
|
|||
IDS_OBJECTS "%d פריטים"
|
||||
IDS_OBJECTS_SELECTED "%d פריטים נבחרו"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "עיון..."
|
||||
|
||||
|
||||
IDS_TITLE_MYCOMP "המחשב שלי"
|
||||
IDS_TITLE_MYNET "מיקומי הרשת שלי"
|
||||
IDS_TITLE_BIN_1 "Recycle Bin (full)"
|
||||
|
|
|
@ -1000,6 +1000,8 @@ BEGIN
|
|||
IDS_OBJECTS "%d वस्तुओं"
|
||||
IDS_OBJECTS_SELECTED "%d वस्तुओं का चयन किया"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "ब्राउज़ करें..."
|
||||
|
||||
IDS_TITLE_MYCOMP "मेरा कंप्यूटर"
|
||||
IDS_TITLE_MYNET "मेरे नेटवर्क स्थान"
|
||||
IDS_TITLE_BIN_1 "Recycle Bin (full)"
|
||||
|
|
|
@ -997,6 +997,8 @@ BEGIN
|
|||
IDS_OBJECTS "%d elem"
|
||||
IDS_OBJECTS_SELECTED "%d kijelölt elem"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "Böngészés..."
|
||||
|
||||
IDS_TITLE_MYCOMP "Számítógép"
|
||||
IDS_TITLE_MYNET "Hálózati helyek"
|
||||
IDS_TITLE_BIN_1 "Lomtár (tele)"
|
||||
|
|
|
@ -995,6 +995,8 @@ BEGIN
|
|||
IDS_OBJECTS "%d Obyek"
|
||||
IDS_OBJECTS_SELECTED "%d Obyek terpilih"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "Jelajah..."
|
||||
|
||||
IDS_TITLE_MYCOMP "Komputer Saya"
|
||||
IDS_TITLE_MYNET "Tempat Jaringan Saya"
|
||||
IDS_TITLE_BIN_1 "Tampungan Daur Ulang (penuh)"
|
||||
|
|
|
@ -998,6 +998,8 @@ BEGIN
|
|||
IDS_OBJECTS "%d Oggetti"
|
||||
IDS_OBJECTS_SELECTED "%d Oggetti selezionati"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "Esplora..."
|
||||
|
||||
IDS_TITLE_MYCOMP "Risorse del Computer"
|
||||
IDS_TITLE_MYNET "Risorse di rete"
|
||||
IDS_TITLE_BIN_1 "Cestino (pieno)"
|
||||
|
|
|
@ -995,6 +995,8 @@ BEGIN
|
|||
IDS_OBJECTS "%d 個のオブジェクト"
|
||||
IDS_OBJECTS_SELECTED "%d 個のオブジェクトが選択済み"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "参照..."
|
||||
|
||||
IDS_TITLE_MYCOMP "マイ コンピュータ"
|
||||
IDS_TITLE_MYNET "マイ ネットワーク"
|
||||
IDS_TITLE_BIN_1 "ごみ箱 (いっぱい)"
|
||||
|
|
|
@ -1005,6 +1005,8 @@ BEGIN
|
|||
IDS_OBJECTS "%d Objects"
|
||||
IDS_OBJECTS_SELECTED "%d Objects Selected"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "찾아보기..."
|
||||
|
||||
IDS_TITLE_MYCOMP "내 컴퓨터"
|
||||
IDS_TITLE_MYNET "내 네트워크 환경"
|
||||
IDS_TITLE_BIN_1 "Recycle Bin (full)"
|
||||
|
|
|
@ -998,6 +998,8 @@ BEGIN
|
|||
IDS_OBJECTS "%d Objects"
|
||||
IDS_OBJECTS_SELECTED "%d Objects Selected"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "Bladeren..."
|
||||
|
||||
IDS_TITLE_MYCOMP "My Computer"
|
||||
IDS_TITLE_MYNET "My Network Places"
|
||||
IDS_TITLE_BIN_1 "Recycle Bin (full)"
|
||||
|
|
|
@ -998,6 +998,8 @@ BEGIN
|
|||
IDS_OBJECTS "%d Objects"
|
||||
IDS_OBJECTS_SELECTED "%d Objects Selected"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "Bla gjennom..."
|
||||
|
||||
IDS_TITLE_MYCOMP "Min datamaskin"
|
||||
IDS_TITLE_MYNET "Mine nettverkssteder"
|
||||
IDS_TITLE_BIN_1 "Papirkurv (full)"
|
||||
|
|
|
@ -1007,6 +1007,8 @@ BEGIN
|
|||
IDS_OBJECTS "Elementów: %d"
|
||||
IDS_OBJECTS_SELECTED "Zaznaczonych elementów: %d"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "Przeglądaj..."
|
||||
|
||||
IDS_TITLE_MYCOMP "Mój komputer"
|
||||
IDS_TITLE_MYNET "Moje miejsca sieciowe"
|
||||
IDS_TITLE_BIN_1 "Kosz (pełny)"
|
||||
|
|
|
@ -998,6 +998,8 @@ BEGIN
|
|||
IDS_OBJECTS "%d Objects"
|
||||
IDS_OBJECTS_SELECTED "%d Objects Selected"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "Procurar..."
|
||||
|
||||
IDS_TITLE_MYCOMP "Meu Computador"
|
||||
IDS_TITLE_MYNET "Meus Locais de Rede"
|
||||
IDS_TITLE_BIN_1 "Lixeira (cheia)"
|
||||
|
|
|
@ -1007,6 +1007,8 @@ BEGIN
|
|||
IDS_OBJECTS "%d Objectos"
|
||||
IDS_OBJECTS_SELECTED "%d Objectos seleccionados"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "Procurar..."
|
||||
|
||||
IDS_TITLE_MYCOMP "O Meu Computador"
|
||||
IDS_TITLE_MYNET "Os Meus Locais na Rede"
|
||||
IDS_TITLE_BIN_1 "Reciclagem (cheia)"
|
||||
|
|
|
@ -1006,6 +1006,8 @@ BEGIN
|
|||
IDS_OBJECTS "%d Obiecte"
|
||||
IDS_OBJECTS_SELECTED "%d Obiecte selectate"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "Răsfoire..."
|
||||
|
||||
IDS_TITLE_MYCOMP "Computerul meu"
|
||||
IDS_TITLE_MYNET "Locaţii în reţea"
|
||||
IDS_TITLE_BIN_1 "Coş de reciclare (plin)"
|
||||
|
|
|
@ -1007,6 +1007,8 @@ BEGIN
|
|||
IDS_OBJECTS "Объектов: %d"
|
||||
IDS_OBJECTS_SELECTED "Выделено объектов: %d"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "Обзор..."
|
||||
|
||||
IDS_TITLE_MYCOMP "Мой компьютер"
|
||||
IDS_TITLE_MYNET "Сетевое окружение"
|
||||
IDS_TITLE_BIN_1 "Корзина (полная)"
|
||||
|
|
|
@ -998,6 +998,8 @@ BEGIN
|
|||
IDS_OBJECTS "%d Objects"
|
||||
IDS_OBJECTS_SELECTED "%d Objects Selected"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "Prehľadávať..."
|
||||
|
||||
IDS_TITLE_MYCOMP "Tento počítač"
|
||||
IDS_TITLE_MYNET "Miesta v sieti"
|
||||
IDS_TITLE_BIN_1 "Kôš (plný)"
|
||||
|
|
|
@ -998,6 +998,8 @@ BEGIN
|
|||
IDS_OBJECTS "%d Objects"
|
||||
IDS_OBJECTS_SELECTED "%d Objects Selected"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "Prebrskaj..."
|
||||
|
||||
IDS_TITLE_MYCOMP "My Computer"
|
||||
IDS_TITLE_MYNET "My Network Places"
|
||||
IDS_TITLE_BIN_1 "Recycle Bin (full)"
|
||||
|
|
|
@ -1005,6 +1005,8 @@ BEGIN
|
|||
IDS_OBJECTS "%d Objects"
|
||||
IDS_OBJECTS_SELECTED "%d Objects Selected"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "Shfleto..."
|
||||
|
||||
IDS_TITLE_MYCOMP "Kompjuteri Im"
|
||||
IDS_TITLE_MYNET "Vendi Rrjetit Tim"
|
||||
IDS_TITLE_BIN_1 "Plehra (plot)"
|
||||
|
|
|
@ -998,6 +998,8 @@ BEGIN
|
|||
IDS_OBJECTS "%d objekt"
|
||||
IDS_OBJECTS_SELECTED "%d markerade objekt"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "Bläddra..."
|
||||
|
||||
IDS_TITLE_MYCOMP "Den här datorn"
|
||||
IDS_TITLE_MYNET "Mina nätverksplatser"
|
||||
IDS_TITLE_BIN_1 "Papperskorgen (full)"
|
||||
|
|
|
@ -1007,6 +1007,8 @@ BEGIN
|
|||
IDS_OBJECTS "%d Nesne"
|
||||
IDS_OBJECTS_SELECTED "%d Nesne Seçili"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "Gözat..."
|
||||
|
||||
IDS_TITLE_MYCOMP "Bilgisayarım"
|
||||
IDS_TITLE_MYNET "Ağ Bağlantılarım"
|
||||
IDS_TITLE_BIN_1 "Recycle Bin (full)"
|
||||
|
|
|
@ -998,6 +998,8 @@ BEGIN
|
|||
IDS_OBJECTS "%d об'єктів"
|
||||
IDS_OBJECTS_SELECTED "Обрано %d об'єктів"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "Огляд..."
|
||||
|
||||
IDS_TITLE_MYCOMP "Мій комп'ютер"
|
||||
IDS_TITLE_MYNET "Мережне оточення"
|
||||
IDS_TITLE_BIN_1 "Кошик (повний)"
|
||||
|
|
|
@ -1008,6 +1008,8 @@ BEGIN
|
|||
IDS_OBJECTS "%d 个对象"
|
||||
IDS_OBJECTS_SELECTED "已选中 %d 个对象"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "浏览..."
|
||||
|
||||
IDS_TITLE_MYCOMP "我的电脑"
|
||||
IDS_TITLE_MYNET "网上邻居"
|
||||
IDS_TITLE_BIN_1 "回收站(满)"
|
||||
|
|
|
@ -1006,6 +1006,8 @@ BEGIN
|
|||
IDS_OBJECTS "%d 個物件"
|
||||
IDS_OBJECTS_SELECTED "已選擇 %d 個物件"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "瀏覽..."
|
||||
|
||||
IDS_TITLE_MYCOMP "我的電腦"
|
||||
IDS_TITLE_MYNET "網絡上的芳鄰"
|
||||
IDS_TITLE_BIN_1 "Recycle Bin (full)"
|
||||
|
|
|
@ -1007,6 +1007,8 @@ BEGIN
|
|||
IDS_OBJECTS "%d 個物件"
|
||||
IDS_OBJECTS_SELECTED "已選擇 %d 個物件"
|
||||
|
||||
IDS_SEARCH_BROWSEITEM "瀏覽..."
|
||||
|
||||
IDS_TITLE_MYCOMP "我的電腦"
|
||||
IDS_TITLE_MYNET "網路上的芳鄰"
|
||||
IDS_TITLE_BIN_1 "Recycle Bin (full)"
|
||||
|
|
|
@ -282,6 +282,10 @@
|
|||
#define IDS_OBJECTS 6466
|
||||
#define IDS_OBJECTS_SELECTED 6477
|
||||
|
||||
/* Explorer file search */
|
||||
#define IDS_SEARCH_LOCALDRIVES 10241
|
||||
#define IDS_SEARCH_BROWSEITEM 10244
|
||||
|
||||
/* Desktop icon titles */
|
||||
#define IDS_TITLE_MYCOMP 30386
|
||||
#define IDS_TITLE_MYNET 30387
|
||||
|
|
Loading…
Reference in a new issue