From 87c1f457eb2c5fa4da5b159b1070d62f22294733 Mon Sep 17 00:00:00 2001 From: Brock Mammen Date: Tue, 20 Aug 2019 21:17:01 -0500 Subject: [PATCH] [SHELLFIND] Improve search bar UI --- dll/win32/browseui/lang/en-US.rc | 22 +++ dll/win32/browseui/shellfind/CSearchBar.cpp | 189 ++++++++++++++------ dll/win32/browseui/shellfind/CSearchBar.h | 26 +-- 3 files changed, 167 insertions(+), 70 deletions(-) diff --git a/dll/win32/browseui/lang/en-US.rc b/dll/win32/browseui/lang/en-US.rc index d7970d6f687..f541cfa0261 100644 --- a/dll/win32/browseui/lang/en-US.rc +++ b/dll/win32/browseui/lang/en-US.rc @@ -150,6 +150,27 @@ BEGIN COMBOBOX IDC_ICONOPTIONS, 52, 18, 123, 57, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END +IDD_SEARCH_DLG DIALOGEX 0, 0, 260, 85 +STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_VISIBLE | WS_CAPTION | WS_DLGFRAME +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "Search by any or all of the criteria below.", IDC_SEARCH_LABEL, 4, 2, 120, 20 + + LTEXT "All or part &of the file name:", -1, 10, 30, 500, 10 + EDITTEXT IDC_SEARCH_FILENAME, 10, 40, 100, 12, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP + + LTEXT "A &word or phrase in the file:", -1, 10, 60, 500, 10 + EDITTEXT IDC_SEARCH_QUERY, 10, 70, 100, 12, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP + + LTEXT "&Look in:", -1, 10, 90, 500, 10 + CONTROL "", IDC_SEARCH_COMBOBOX, WC_COMBOBOXEXW, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_TABSTOP | CCS_NODIVIDER | CCS_NOMOVEY | CBS_OWNERDRAWFIXED, 10, 100, 200, 200 + + DEFPUSHBUTTON "Sea&rch", IDC_SEARCH_BUTTON, 80, 130, 40, 15, WS_GROUP | WS_TABSTOP | WS_VISIBLE + PUSHBUTTON "&Stop", IDC_SEARCH_STOP_BUTTON, 80, 130, 40, 15, WS_GROUP | WS_TABSTOP + + CONTROL "", IDC_PROGRESS_BAR, PROGRESS_CLASSA, WS_BORDER | PBS_MARQUEE, 10, 150, 200, 8 +END + /* Accelerators */ IDR_ACCELERATORS ACCELERATORS @@ -321,6 +342,7 @@ END STRINGTABLE BEGIN + IDS_SEARCHINVALID "'%1' is not a valid folder." IDS_SEARCH_FOLDER "Searching %s" IDS_SEARCH_FILES_FOUND "%u files found" END diff --git a/dll/win32/browseui/shellfind/CSearchBar.cpp b/dll/win32/browseui/shellfind/CSearchBar.cpp index d09c4784f97..8ab28b65fd1 100644 --- a/dll/win32/browseui/shellfind/CSearchBar.cpp +++ b/dll/win32/browseui/shellfind/CSearchBar.cpp @@ -18,6 +18,10 @@ #include "CSearchBar.h" #include +#include +#include <../browseui.h> +#include +#include WINE_DEFAULT_DEBUG_CHANNEL(shellfind); @@ -38,53 +42,42 @@ CSearchBar::~CSearchBar() { } -void CSearchBar::InitializeSearchBar() -{ - CreateWindowExW(0, WC_STATIC, L"Search by any or all of the criteria below.", - WS_CHILD | WS_VISIBLE, - 10, 10, 200, 40, - m_hWnd, NULL, - _AtlBaseModule.GetModuleInstance(), NULL); - - CreateWindowExW(0, WC_STATIC, L"All or part &of the file name:", - WS_CHILD | WS_VISIBLE, - 10, 50, 500, 20, - m_hWnd, NULL, - _AtlBaseModule.GetModuleInstance(), NULL); - m_fileName = CreateWindowExW(WS_EX_CLIENTEDGE, WC_EDITW, NULL, - WS_BORDER | WS_CHILD | WS_VISIBLE, - 10, 70, 100, 20, - m_hWnd, NULL, - _AtlBaseModule.GetModuleInstance(), NULL); - - CreateWindowExW(0, WC_STATIC, L"A &word or phrase in the file:", - WS_CHILD | WS_VISIBLE, - 10, 100, 500, 20, - m_hWnd, NULL, - _AtlBaseModule.GetModuleInstance(), NULL); - m_query = CreateWindowExW(WS_EX_CLIENTEDGE, WC_EDITW, NULL, - WS_BORDER | WS_CHILD | WS_VISIBLE, - 10, 120, 100, 20, - m_hWnd, NULL, - _AtlBaseModule.GetModuleInstance(), NULL); - Edit_LimitText(m_query, MAX_PATH); - - CreateWindowExW(0, WC_STATIC, L"&Look in:", - WS_CHILD | WS_VISIBLE, - 10, 150, 500, 20, - m_hWnd, NULL, - _AtlBaseModule.GetModuleInstance(), NULL); - m_path = CreateWindowExW(WS_EX_CLIENTEDGE, WC_EDITW, NULL, - WS_BORDER | WS_CHILD | WS_VISIBLE, - 10, 180, 100, 20, - m_hWnd, NULL, - _AtlBaseModule.GetModuleInstance(), NULL); - - CreateWindowExW(0, WC_BUTTON, L"Sea&rch", - WS_BORDER | WS_CHILD | WS_VISIBLE, - 10, 210, 100, 20, - m_hWnd, NULL, - _AtlBaseModule.GetModuleInstance(), NULL); +LRESULT CSearchBar::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) +{ + SetSearchInProgress(FALSE); + + HWND hCombobox = GetDlgItem(IDC_SEARCH_COMBOBOX); + IImageList *pImageList; + HRESULT hResult = SHGetImageList(SHIL_SMALL, IID_PPV_ARG(IImageList, &pImageList)); + SendMessage(hCombobox, CBEM_SETIMAGELIST, 0, FAILED_UNEXPECTEDLY(hResult) ? 0 : reinterpret_cast(pImageList)); + + SendMessage(hCombobox, CBEM_SETEXTENDEDSTYLE, + CBES_EX_CASESENSITIVE | CBES_EX_NOSIZELIMIT, CBES_EX_CASESENSITIVE | CBES_EX_NOSIZELIMIT); + HWND hEditControl = reinterpret_cast(SendMessage(hCombobox, CBEM_GETEDITCONTROL, 0, 0)); + hResult = CAddressEditBox_CreateInstance(IID_PPV_ARG(IAddressEditBox, &m_AddressEditBox)); + if (FAILED_UNEXPECTEDLY(hResult)) + return hResult; + + CComPtr pShellService; + hResult = fAddressEditBox->QueryInterface(IID_PPV_ARG(IShellService, &pShellService)); + if (FAILED_UNEXPECTEDLY(hResult)) + return hResult; + hResult = fAddressEditBox->Init(hCombobox, fEditControl, 0, pSite); + if (FAILED_UNEXPECTEDLY(hResult)) + return hResult; + + CComPtr pDispatch; + hResult = fAddressEditBox->QueryInterface(IID_PPV_ARG(IDispatch, &pDispatch)); + if (FAILED_UNEXPECTEDLY(hResult)) + return hResult; + DISPPARAMS params = {0}; + hResult = pDispatch->Invoke(DISPID_NAVIGATECOMPLETE2, GUID_NULL, 0, DISPATCH_METHOD, ¶ms, NULL, NULL, NULL); + + hResult = pShellService->SetOwner(NULL); + if (FAILED_UNEXPECTEDLY(hResult)) + return hResult; + + return 0; } HRESULT CSearchBar::ExecuteCommand(CComPtr& menu, UINT nCmd) @@ -173,6 +166,15 @@ HRESULT CSearchBar::GetSearchResultsFolder(IShellBrowser **ppShellBrowser, HWND LRESULT CSearchBar::OnSearchButtonClicked(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { + CComHeapPtr pSearchStart((SearchStart *)SHAlloc(sizeof(SearchStart))); + GetDlgItemText(IDC_SEARCH_FILENAME, pSearchStart->szFileName, _countof(pSearchStart->szFileName)); + GetDlgItemText(IDC_SEARCH_QUERY, pSearchStart->szQuery, _countof(pSearchStart->szQuery)); + if (!GetAddressEditBoxPath(pSearchStart->szPath)) + { + ShellMessageBoxW(_AtlBaseModule.GetResourceInstance(), m_hWnd, MAKEINTRESOURCEW(IDS_SEARCHINVALID), MAKEINTRESOURCEW(IDS_SEARCHLABEL), MB_OK | MB_ICONERROR, pSearchStart->szPath); + return TRUE; + } + CComPtr pShellBrowser; HRESULT hr = IUnknown_QueryService(pSite, SID_SShellBrowser, IID_PPV_ARG(IShellBrowser, &pShellBrowser)); if (FAILED_UNEXPECTEDLY(hr)) @@ -181,6 +183,7 @@ LRESULT CSearchBar::OnSearchButtonClicked(WORD wNotifyCode, WORD wID, HWND hWndC HWND hwnd; if (FAILED(GetSearchResultsFolder(&pShellBrowser, &hwnd, NULL))) { + // Open a new search results folder WCHAR szShellGuid[MAX_PATH]; const WCHAR shellGuidPrefix[] = L"shell:::"; memcpy(szShellGuid, shellGuidPrefix, sizeof(shellGuidPrefix)); @@ -197,25 +200,78 @@ LRESULT CSearchBar::OnSearchButtonClicked(WORD wNotifyCode, WORD wID, HWND hWndC hr = pShellBrowser->BrowseObject(findFolderPidl, 0); if (FAILED_UNEXPECTEDLY(hr)) return hr; + + CComPtr pShellFolder; + hr = GetSearchResultsFolder(*pShellBrowser, &hwnd, &pShellFolder); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + // Subscribe to search events + DWORD fAdviseCookie; + hr = AtlAdvise(pShellFolder, static_cast(this), DIID_DSearchCommandEvents, &fAdviseCookie); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; } - hr = GetSearchResultsFolder(*pShellBrowser, &hwnd, NULL); - if (FAILED_UNEXPECTEDLY(hr)) - return hr; + ::PostMessageW(hwnd, WM_SEARCH_START, 0, (LPARAM) pSearchStart.Detach()); - ::PostMessageW(hwnd, WM_SEARCH_START, 0, (LPARAM) StrDupW(L"Starting search...")); + SetSearchInProgress(TRUE); - return S_OK; + return TRUE; } -LRESULT CSearchBar::OnClicked(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) +LRESULT CSearchBar::OnStopButtonClicked(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { HWND hwnd; HRESULT hr = GetSearchResultsFolder(NULL, &hwnd, NULL); if (SUCCEEDED(hr)) + ::PostMessageW(hwnd, WM_SEARCH_STOP, 0, 0); + + return TRUE; +} + +BOOL CSearchBar::GetAddressEditBoxPath(WCHAR (&szPath)[MAX_PATH]) +{ + HWND hComboboxEx = GetDlgItem(IDC_SEARCH_COMBOBOX); + ::GetWindowTextW(hComboboxEx, szPath, _countof(szPath)); + INT iSelectedIndex = SendMessageW(hComboboxEx, CB_GETCURSEL, 0, 0); + if (iSelectedIndex != CB_ERR) { - LPCWSTR path = L"C:\\readme.txt"; - ::PostMessageW(hwnd, WM_SEARCH_ADD_RESULT, 0, (LPARAM) StrDupW(path)); + WCHAR szItemText[MAX_PATH]; + COMBOBOXEXITEMW item = {0}; + 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, szPath)) + { + return TRUE; + } + } + + DWORD dwAttributes = GetFileAttributesW(szPath); + return dwAttributes != INVALID_FILE_ATTRIBUTES + && (dwAttributes & FILE_ATTRIBUTE_DIRECTORY); +} + +LRESULT CSearchBar::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) +{ + INT iWidth = LOWORD(lParam); + INT iPadding = 10; + + ((CWindow)GetDlgItem(IDC_SEARCH_LABEL)).SetWindowPos(NULL, 0, 0, iWidth - iPadding, 40, SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER); + + HWND inputs[] = { GetDlgItem(IDC_SEARCH_FILENAME), GetDlgItem(IDC_SEARCH_QUERY), GetDlgItem(IDC_SEARCH_COMBOBOX), GetDlgItem(IDC_SEARCH_BUTTON), GetDlgItem(IDC_SEARCH_STOP_BUTTON), GetDlgItem(IDC_PROGRESS_BAR) }; + for (SIZE_T i = 0; i < _countof(inputs); i++) + { + CWindow wFileName = (CWindow) inputs[i]; + RECT rect; + wFileName.GetWindowRect(&rect); + POINT pt = { rect.left, rect.top }; + ScreenToClient(&pt); + wFileName.MoveWindow(iPadding, pt.y, iWidth - iPadding * 2, rect.bottom - rect.top); } return 0; @@ -358,9 +414,8 @@ HRESULT STDMETHODCALLTYPE CSearchBar::SetSite(IUnknown *pUnkSite) } else { - CWindowImpl::Create(parentWnd); + CDialogImpl::Create(parentWnd); - InitializeSearchBar(); } return S_OK; } @@ -420,7 +475,10 @@ HRESULT STDMETHODCALLTYPE CSearchBar::HasFocusIO() HRESULT STDMETHODCALLTYPE CSearchBar::TranslateAcceleratorIO(LPMSG lpMsg) { - if (lpMsg->hwnd == m_hWnd) + if (IsDialogMessage(lpMsg)) + return S_OK; + + if ((lpMsg->hwnd == m_hWnd || IsChild(lpMsg->hwnd))) { TranslateMessage(lpMsg); DispatchMessage(lpMsg); @@ -535,8 +593,21 @@ HRESULT STDMETHODCALLTYPE CSearchBar::GetIDsOfNames(REFIID riid, LPOLESTR *rgszN return E_NOTIMPL; } +void CSearchBar::SetSearchInProgress(BOOL bInProgress) +{ + ::ShowWindow(GetDlgItem(IDC_SEARCH_BUTTON), bInProgress ? SW_HIDE : SW_SHOW); + ::ShowWindow(GetDlgItem(IDC_SEARCH_STOP_BUTTON), bInProgress ? SW_SHOW : SW_HIDE); + HWND hProgressBar = GetDlgItem(IDC_PROGRESS_BAR); + ::ShowWindow(hProgressBar, bInProgress ? SW_SHOW : SW_HIDE); + ::PostMessage(hProgressBar, PBM_SETMARQUEE, bInProgress, 0); +} + HRESULT STDMETHODCALLTYPE CSearchBar::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { - TRACE("Unknown dispid requested: %08x\n", dispIdMember); + if (dispIdMember == DISPID_SEARCHCOMPLETE || dispIdMember == DISPID_SEARCHABORT) + { + SetSearchInProgress(FALSE); + return S_OK; + } return E_INVALIDARG; } diff --git a/dll/win32/browseui/shellfind/CSearchBar.h b/dll/win32/browseui/shellfind/CSearchBar.h index 0613a317ab8..a94466fd78a 100644 --- a/dll/win32/browseui/shellfind/CSearchBar.h +++ b/dll/win32/browseui/shellfind/CSearchBar.h @@ -33,26 +33,27 @@ class CSearchBar : public IWinEventHandler, public INamespaceProxy, public IDispatch, - public CWindowImpl + public CDialogImpl { private: // *** BaseBarSite information *** CComPtr pSite; + CComPtr fAddressEditBox; BOOL fVisible; BOOL bFocused; - HWND m_fileName; - HWND m_query; - HWND m_path; - void InitializeSearchBar(); HRESULT GetSearchResultsFolder(IShellBrowser **ppShellBrowser, HWND *pHwnd, IShellFolder **ppShellFolder); + BOOL GetAddressEditBoxPath(WCHAR (&szPath)[MAX_PATH]); + void SetSearchInProgress(BOOL bInProgress); HRESULT ExecuteCommand(CComPtr& menu, UINT nCmd); // *** ATL event handlers *** + LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); LRESULT OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); - LRESULT OnSearchButtonClicked(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); - LRESULT OnClicked(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 OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); public: CSearchBar(); @@ -115,6 +116,8 @@ public: virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId); virtual HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr); + enum { IDD = IDD_SEARCH_DLG }; + DECLARE_REGISTRY_RESOURCEID(IDR_EXPLORERBAND) DECLARE_NOT_AGGREGATABLE(CSearchBar) @@ -122,6 +125,7 @@ public: BEGIN_COM_MAP(CSearchBar) COM_INTERFACE_ENTRY_IID(IID_IDispatch, IDispatch) + COM_INTERFACE_ENTRY_IID(DIID_DSearchCommandEvents, IDispatch) COM_INTERFACE_ENTRY_IID(IID_IWinEventHandler, IWinEventHandler) COM_INTERFACE_ENTRY_IID(IID_IBandNavigate, IBandNavigate) COM_INTERFACE_ENTRY_IID(IID_INamespaceProxy, INamespaceProxy) @@ -136,11 +140,11 @@ public: COM_INTERFACE_ENTRY_IID(IID_IPersistStream, IPersistStream) END_COM_MAP() - DECLARE_WND_CLASS_EX(_T("SrchCompExplorerBar"), 0, COLOR_WINDOW) - BEGIN_MSG_MAP(CSearchBar) + MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus) - COMMAND_CODE_HANDLER(BN_CLICKED, OnSearchButtonClicked) - MESSAGE_HANDLER(WM_LBUTTONDOWN, OnClicked) + MESSAGE_HANDLER(WM_SIZE, OnSize) + COMMAND_HANDLER(IDC_SEARCH_BUTTON, BN_CLICKED, OnSearchButtonClicked) + COMMAND_HANDLER(IDC_SEARCH_STOP_BUTTON, BN_CLICKED, OnStopButtonClicked) END_MSG_MAP() }; -- 2.17.1