[SHELLFIND] Remove redundant check
[reactos.git] / dll / win32 / browseui / shellfind / CSearchBar.cpp
1 /*
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 UI
5 * COPYRIGHT: Copyright 2019 Brock Mammen
6 */
7
8 #include "CSearchBar.h"
9 #include <psdk/wingdi.h>
10 #include <commoncontrols.h>
11 #include <../browseui.h>
12 #include <shellapi.h>
13 #include <exdispid.h>
14
15 WINE_DEFAULT_DEBUG_CHANNEL(shellfind);
16
17 #if 1
18 #undef UNIMPLEMENTED
19
20 #define UNIMPLEMENTED DbgPrint("%s is UNIMPLEMENTED!\n", __FUNCTION__)
21 #endif
22
23 CSearchBar::CSearchBar() :
24 m_pSite(NULL),
25 m_bVisible(FALSE)
26 {
27 }
28
29 CSearchBar::~CSearchBar()
30 {
31 }
32
33 LRESULT CSearchBar::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
34 {
35 SetSearchInProgress(FALSE);
36
37 HWND hCombobox = GetDlgItem(IDC_SEARCH_COMBOBOX);
38 CComPtr<IImageList> pImageList;
39 HRESULT hResult = SHGetImageList(SHIL_SMALL, IID_PPV_ARG(IImageList, &pImageList));
40 SendMessage(hCombobox, CBEM_SETIMAGELIST, 0, FAILED_UNEXPECTEDLY(hResult) ? 0 : reinterpret_cast<LPARAM>(pImageList.p));
41
42 SendMessage(hCombobox, CBEM_SETEXTENDEDSTYLE,
43 CBES_EX_CASESENSITIVE | CBES_EX_NOSIZELIMIT, CBES_EX_CASESENSITIVE | CBES_EX_NOSIZELIMIT);
44 HWND hEditControl = reinterpret_cast<HWND>(SendMessage(hCombobox, CBEM_GETEDITCONTROL, 0, 0));
45 hResult = CAddressEditBox_CreateInstance(IID_PPV_ARG(IAddressEditBox, &m_AddressEditBox));
46 if (FAILED_UNEXPECTEDLY(hResult))
47 return hResult;
48
49 hResult = m_AddressEditBox->Init(hCombobox, hEditControl, 0, m_pSite);
50 if (FAILED_UNEXPECTEDLY(hResult))
51 return hResult;
52
53 // Subscribe to navigation events
54 CComPtr<IShellBrowser> pShellBrowser;
55 hResult = IUnknown_QueryService(m_pSite, SID_SShellBrowser, IID_PPV_ARG(IShellBrowser, &pShellBrowser));
56 DWORD dwAdviseCookie;
57 if (SUCCEEDED(hResult))
58 AtlAdvise(pShellBrowser, static_cast<IDispatch *>(this), DIID_DWebBrowserEvents, &dwAdviseCookie);
59
60 // Invoke the navigate event in case a search results folder is already open
61 DISPPARAMS params = {0};
62 Invoke(DISPID_NAVIGATECOMPLETE2, GUID_NULL, 0, DISPATCH_METHOD, &params, NULL, NULL, NULL);
63
64 return 0;
65 }
66
67 HRESULT CSearchBar::ExecuteCommand(CComPtr<IContextMenu>& menu, UINT nCmd)
68 {
69 CComPtr<IOleWindow> pBrowserOleWnd;
70 CMINVOKECOMMANDINFO cmi;
71 HWND browserWnd;
72 HRESULT hr;
73
74 hr = IUnknown_QueryService(m_pSite, SID_SShellBrowser, IID_PPV_ARG(IOleWindow, &pBrowserOleWnd));
75 if (FAILED_UNEXPECTEDLY(hr))
76 return hr;
77
78 hr = pBrowserOleWnd->GetWindow(&browserWnd);
79 if (FAILED_UNEXPECTEDLY(hr))
80 return hr;
81
82 ZeroMemory(&cmi, sizeof(cmi));
83 cmi.cbSize = sizeof(cmi);
84 cmi.lpVerb = MAKEINTRESOURCEA(nCmd);
85 cmi.hwnd = browserWnd;
86 if (GetKeyState(VK_SHIFT) & 0x8000)
87 cmi.fMask |= CMIC_MASK_SHIFT_DOWN;
88 if (GetKeyState(VK_CONTROL) & 0x8000)
89 cmi.fMask |= CMIC_MASK_CONTROL_DOWN;
90
91 return menu->InvokeCommand(&cmi);
92 }
93
94
95 // *** ATL event handlers ***
96 LRESULT CSearchBar::OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
97 {
98 IUnknown_OnFocusChangeIS(m_pSite, static_cast<IDeskBand *>(this), TRUE);
99 bHandled = FALSE;
100 return TRUE;
101 }
102
103 HRESULT CSearchBar::GetSearchResultsFolder(IShellBrowser **ppShellBrowser, HWND *pHwnd, IShellFolder **ppShellFolder)
104 {
105 HRESULT hr;
106 CComPtr<IShellBrowser> pShellBrowser;
107 if (!ppShellBrowser)
108 ppShellBrowser = &pShellBrowser;
109 if (!*ppShellBrowser)
110 {
111 hr = IUnknown_QueryService(m_pSite, SID_SShellBrowser, IID_PPV_ARG(IShellBrowser, ppShellBrowser));
112 if (FAILED_UNEXPECTEDLY(hr))
113 return hr;
114 }
115
116 CComPtr<IShellView> pShellView;
117 hr = (*ppShellBrowser)->QueryActiveShellView(&pShellView);
118 if (FAILED(hr) || !pShellView)
119 return hr;
120
121 CComPtr<IFolderView> pFolderView;
122 hr = pShellView->QueryInterface(IID_PPV_ARG(IFolderView, &pFolderView));
123 if (FAILED(hr) || !pFolderView)
124 return hr;
125
126 CComPtr<IShellFolder> pShellFolder;
127 if (!ppShellFolder)
128 ppShellFolder = &pShellFolder;
129 hr = pFolderView->GetFolder(IID_PPV_ARG(IShellFolder, ppShellFolder));
130 if (FAILED(hr) || !pShellFolder)
131 return hr;
132
133 CLSID clsid;
134 hr = IUnknown_GetClassID(*ppShellFolder, &clsid);
135 if (FAILED(hr))
136 return hr;
137 if (clsid != CLSID_FindFolder)
138 return E_FAIL;
139
140 if (pHwnd)
141 {
142 hr = pShellView->GetWindow(pHwnd);
143 if (FAILED_UNEXPECTEDLY(hr))
144 return hr;
145 }
146
147 return S_OK;
148 }
149
150 LRESULT CSearchBar::OnSearchButtonClicked(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
151 {
152 CComHeapPtr<SearchStart> pSearchStart(static_cast<SearchStart *>(CoTaskMemAlloc(sizeof(SearchStart))));
153 GetDlgItemText(IDC_SEARCH_FILENAME, pSearchStart->szFileName, _countof(pSearchStart->szFileName));
154 GetDlgItemText(IDC_SEARCH_QUERY, pSearchStart->szQuery, _countof(pSearchStart->szQuery));
155 if (!GetAddressEditBoxPath(pSearchStart->szPath))
156 {
157 ShellMessageBoxW(_AtlBaseModule.GetResourceInstance(), m_hWnd, MAKEINTRESOURCEW(IDS_SEARCHINVALID), MAKEINTRESOURCEW(IDS_SEARCHLABEL), MB_OK | MB_ICONERROR, pSearchStart->szPath);
158 return TRUE;
159 }
160
161 CComPtr<IShellBrowser> pShellBrowser;
162 HRESULT hr = IUnknown_QueryService(m_pSite, SID_SShellBrowser, IID_PPV_ARG(IShellBrowser, &pShellBrowser));
163 if (FAILED_UNEXPECTEDLY(hr))
164 return hr;
165
166 HWND hwnd;
167 if (FAILED(GetSearchResultsFolder(&pShellBrowser, &hwnd, NULL)))
168 {
169 // Open a new search results folder
170 WCHAR szShellGuid[MAX_PATH];
171 const WCHAR shellGuidPrefix[] = L"shell:::";
172 memcpy(szShellGuid, shellGuidPrefix, sizeof(shellGuidPrefix));
173 hr = StringFromGUID2(CLSID_FindFolder, szShellGuid + _countof(shellGuidPrefix) - 1,
174 _countof(szShellGuid) - _countof(shellGuidPrefix));
175 if (FAILED_UNEXPECTEDLY(hr))
176 return hr;
177
178 CComHeapPtr<ITEMIDLIST> findFolderPidl;
179 hr = SHParseDisplayName(szShellGuid, NULL, &findFolderPidl, 0, NULL);
180 if (FAILED_UNEXPECTEDLY(hr))
181 return hr;
182
183 hr = pShellBrowser->BrowseObject(findFolderPidl, 0);
184 if (FAILED_UNEXPECTEDLY(hr))
185 return hr;
186
187 hr = GetSearchResultsFolder(&pShellBrowser, &hwnd, NULL);
188 if (FAILED_UNEXPECTEDLY(hr))
189 return hr;
190 }
191
192 ::PostMessageW(hwnd, WM_SEARCH_START, 0, (LPARAM) pSearchStart.Detach());
193
194 SetSearchInProgress(TRUE);
195
196 return TRUE;
197 }
198
199 LRESULT CSearchBar::OnStopButtonClicked(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
200 {
201 HWND hwnd;
202 HRESULT hr = GetSearchResultsFolder(NULL, &hwnd, NULL);
203 if (SUCCEEDED(hr))
204 ::PostMessageW(hwnd, WM_SEARCH_STOP, 0, 0);
205
206 return TRUE;
207 }
208
209 BOOL CSearchBar::GetAddressEditBoxPath(WCHAR (&szPath)[MAX_PATH])
210 {
211 HWND hComboboxEx = GetDlgItem(IDC_SEARCH_COMBOBOX);
212 ::GetWindowTextW(hComboboxEx, szPath, _countof(szPath));
213 INT iSelectedIndex = SendMessageW(hComboboxEx, CB_GETCURSEL, 0, 0);
214 if (iSelectedIndex != CB_ERR)
215 {
216 WCHAR szItemText[MAX_PATH];
217 COMBOBOXEXITEMW item = {0};
218 item.mask = CBEIF_LPARAM | CBEIF_TEXT;
219 item.iItem = iSelectedIndex;
220 item.pszText = szItemText;
221 item.cchTextMax = _countof(szItemText);
222 SendMessageW(hComboboxEx, CBEM_GETITEMW, 0, (LPARAM)&item);
223
224 if (!wcscmp(szItemText, szPath) && SHGetPathFromIDListW((LPCITEMIDLIST)item.lParam, szItemText))
225 {
226 StringCbCopyW(szPath, MAX_PATH * sizeof(WCHAR), szItemText);
227 return TRUE;
228 }
229 }
230
231 DWORD dwAttributes = GetFileAttributesW(szPath);
232 return dwAttributes != INVALID_FILE_ATTRIBUTES
233 && (dwAttributes & FILE_ATTRIBUTE_DIRECTORY);
234 }
235
236 LRESULT CSearchBar::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
237 {
238 INT iWidth = LOWORD(lParam);
239 INT iPadding = 10;
240
241 ((CWindow)GetDlgItem(IDC_SEARCH_LABEL)).SetWindowPos(NULL, 0, 0, iWidth - iPadding, 40, SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER);
242
243 int inputs[] = { IDC_SEARCH_FILENAME, IDC_SEARCH_QUERY, IDC_SEARCH_COMBOBOX, IDC_SEARCH_BUTTON, IDC_SEARCH_STOP_BUTTON, IDC_PROGRESS_BAR };
244 HDWP hdwp = BeginDeferWindowPos(_countof(inputs));
245 for (SIZE_T i = 0; i < _countof(inputs); i++)
246 {
247 CWindow wnd = (CWindow) GetDlgItem(inputs[i]);
248 RECT rect;
249 wnd.GetWindowRect(&rect);
250 POINT pt = { rect.left, rect.top };
251 ScreenToClient(&pt);
252 hdwp = wnd.DeferWindowPos(hdwp,
253 HWND_TOP,
254 iPadding,
255 pt.y,
256 iWidth - iPadding * 2,
257 rect.bottom - rect.top,
258 SWP_NOZORDER | SWP_NOACTIVATE);
259 }
260 EndDeferWindowPos(hdwp);
261
262 return 0;
263 }
264
265
266 // *** IOleWindow methods ***
267 HRESULT STDMETHODCALLTYPE CSearchBar::GetWindow(HWND *lphwnd)
268 {
269 if (!lphwnd)
270 return E_INVALIDARG;
271 *lphwnd = m_hWnd;
272 return S_OK;
273 }
274
275 HRESULT STDMETHODCALLTYPE CSearchBar::ContextSensitiveHelp(BOOL fEnterMode)
276 {
277 UNIMPLEMENTED;
278 return E_NOTIMPL;
279 }
280
281
282 // *** IDockingWindow methods ***
283 HRESULT STDMETHODCALLTYPE CSearchBar::CloseDW(DWORD dwReserved)
284 {
285 // We do nothing, we don't have anything to save yet
286 TRACE("CloseDW called\n");
287 return S_OK;
288 }
289
290 HRESULT STDMETHODCALLTYPE CSearchBar::ResizeBorderDW(const RECT *prcBorder, IUnknown *punkToolbarSite, BOOL fReserved)
291 {
292 /* Must return E_NOTIMPL according to MSDN */
293 return E_NOTIMPL;
294 }
295
296 HRESULT STDMETHODCALLTYPE CSearchBar::ShowDW(BOOL fShow)
297 {
298 m_bVisible = fShow;
299 ShowWindow(fShow);
300 return S_OK;
301 }
302
303
304 // *** IDeskBand methods ***
305 HRESULT STDMETHODCALLTYPE CSearchBar::GetBandInfo(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO *pdbi)
306 {
307 if (!pdbi)
308 {
309 return E_INVALIDARG;
310 }
311
312 if (pdbi->dwMask & DBIM_MINSIZE)
313 {
314 pdbi->ptMinSize.x = 200;
315 pdbi->ptMinSize.y = 30;
316 }
317
318 if (pdbi->dwMask & DBIM_MAXSIZE)
319 {
320 pdbi->ptMaxSize.y = -1;
321 }
322
323 if (pdbi->dwMask & DBIM_INTEGRAL)
324 {
325 pdbi->ptIntegral.y = 1;
326 }
327
328 if (pdbi->dwMask & DBIM_ACTUAL)
329 {
330 pdbi->ptActual.x = 200;
331 pdbi->ptActual.y = 30;
332 }
333
334 if (pdbi->dwMask & DBIM_TITLE)
335 {
336 if (!LoadStringW(_AtlBaseModule.GetResourceInstance(), IDS_SEARCHLABEL, pdbi->wszTitle, _countof(pdbi->wszTitle)))
337 return HRESULT_FROM_WIN32(GetLastError());
338 }
339
340 if (pdbi->dwMask & DBIM_MODEFLAGS)
341 {
342 pdbi->dwModeFlags = DBIMF_NORMAL | DBIMF_VARIABLEHEIGHT;
343 }
344
345 if (pdbi->dwMask & DBIM_BKCOLOR)
346 {
347 pdbi->dwMask &= ~DBIM_BKCOLOR;
348 }
349 return S_OK;
350 }
351
352
353 // *** IObjectWithSite methods ***
354 HRESULT STDMETHODCALLTYPE CSearchBar::SetSite(IUnknown *pUnkSite)
355 {
356 HRESULT hr;
357 HWND parentWnd;
358
359 if (pUnkSite == m_pSite)
360 return S_OK;
361
362 TRACE("SetSite called \n");
363 if (!pUnkSite)
364 {
365 DestroyWindow();
366 m_hWnd = NULL;
367 return S_OK;
368 }
369
370 hr = IUnknown_GetWindow(pUnkSite, &parentWnd);
371 if (!SUCCEEDED(hr))
372 {
373 ERR("Could not get parent's window ! Status: %08lx\n", hr);
374 return E_INVALIDARG;
375 }
376
377 m_pSite = pUnkSite;
378
379 if (m_hWnd)
380 {
381 // Change its parent
382 SetParent(parentWnd);
383 }
384 else
385 {
386 CDialogImpl::Create(parentWnd);
387
388 }
389 return S_OK;
390 }
391
392 HRESULT STDMETHODCALLTYPE CSearchBar::GetSite(REFIID riid, void **ppvSite)
393 {
394 if (!ppvSite)
395 return E_POINTER;
396 *ppvSite = m_pSite;
397 return S_OK;
398 }
399
400
401 // *** IOleCommandTarget methods ***
402 HRESULT STDMETHODCALLTYPE CSearchBar::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText)
403 {
404 UNIMPLEMENTED;
405 return E_NOTIMPL;
406 }
407
408 HRESULT STDMETHODCALLTYPE CSearchBar::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
409 {
410 UNIMPLEMENTED;
411 return E_NOTIMPL;
412 }
413
414
415 // *** IServiceProvider methods ***
416 HRESULT STDMETHODCALLTYPE CSearchBar::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
417 {
418 /* FIXME: we probably want to handle more services here */
419 return IUnknown_QueryService(m_pSite, SID_SShellBrowser, riid, ppvObject);
420 }
421
422
423 // *** IInputObject methods ***
424 HRESULT STDMETHODCALLTYPE CSearchBar::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
425 {
426 if (fActivate)
427 {
428 //SetFocus();
429 SetActiveWindow();
430 }
431 // TODO: handle message
432 if(lpMsg)
433 {
434 TranslateMessage(lpMsg);
435 DispatchMessage(lpMsg);
436 }
437 return S_OK;
438 }
439
440 HRESULT STDMETHODCALLTYPE CSearchBar::HasFocusIO()
441 {
442 return S_OK;
443 }
444
445 HRESULT STDMETHODCALLTYPE CSearchBar::TranslateAcceleratorIO(LPMSG lpMsg)
446 {
447 if (IsDialogMessage(lpMsg))
448 return S_OK;
449
450 if ((lpMsg->hwnd == m_hWnd || IsChild(lpMsg->hwnd)))
451 {
452 TranslateMessage(lpMsg);
453 DispatchMessage(lpMsg);
454 return S_OK;
455 }
456
457 return S_FALSE;
458 }
459
460 // *** IPersist methods ***
461 HRESULT STDMETHODCALLTYPE CSearchBar::GetClassID(CLSID *pClassID)
462 {
463 if (!pClassID)
464 return E_POINTER;
465 *pClassID = CLSID_FileSearchBand;
466 return S_OK;
467 }
468
469
470 // *** IPersistStream methods ***
471 HRESULT STDMETHODCALLTYPE CSearchBar::IsDirty()
472 {
473 UNIMPLEMENTED;
474 return E_NOTIMPL;
475 }
476
477 HRESULT STDMETHODCALLTYPE CSearchBar::Load(IStream *pStm)
478 {
479 UNIMPLEMENTED;
480 return E_NOTIMPL;
481 }
482
483 HRESULT STDMETHODCALLTYPE CSearchBar::Save(IStream *pStm, BOOL fClearDirty)
484 {
485 UNIMPLEMENTED;
486 return E_NOTIMPL;
487 }
488
489 HRESULT STDMETHODCALLTYPE CSearchBar::GetSizeMax(ULARGE_INTEGER *pcbSize)
490 {
491 // TODO: calculate max size
492 UNIMPLEMENTED;
493 return E_NOTIMPL;
494 }
495
496
497 // *** IWinEventHandler methods ***
498 HRESULT STDMETHODCALLTYPE CSearchBar::OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
499 {
500 return S_OK;
501 }
502
503 HRESULT STDMETHODCALLTYPE CSearchBar::IsWindowOwner(HWND hWnd)
504 {
505 return (hWnd == m_hWnd) ? S_OK : S_FALSE;
506 }
507
508 // *** IBandNavigate methods ***
509 HRESULT STDMETHODCALLTYPE CSearchBar::Select(long paramC)
510 {
511 UNIMPLEMENTED;
512 return E_NOTIMPL;
513 }
514
515 // *** INamespaceProxy ***
516 HRESULT STDMETHODCALLTYPE CSearchBar::GetNavigateTarget(long paramC, long param10, long param14)
517 {
518 UNIMPLEMENTED;
519 return E_NOTIMPL;
520 }
521
522 HRESULT STDMETHODCALLTYPE CSearchBar::Invoke(long paramC)
523 {
524 UNIMPLEMENTED;
525 return E_NOTIMPL;
526 }
527
528 HRESULT STDMETHODCALLTYPE CSearchBar::OnSelectionChanged(long paramC)
529 {
530 UNIMPLEMENTED;
531 return E_NOTIMPL;
532 }
533
534 HRESULT STDMETHODCALLTYPE CSearchBar::RefreshFlags(long paramC, long param10, long param14)
535 {
536 UNIMPLEMENTED;
537 return E_NOTIMPL;
538 }
539
540 HRESULT STDMETHODCALLTYPE CSearchBar::CacheItem(long paramC)
541 {
542 UNIMPLEMENTED;
543 return E_NOTIMPL;
544 }
545
546 // *** IDispatch methods ***
547 HRESULT STDMETHODCALLTYPE CSearchBar::GetTypeInfoCount(UINT *pctinfo)
548 {
549 UNIMPLEMENTED;
550 return E_NOTIMPL;
551 }
552
553 HRESULT STDMETHODCALLTYPE CSearchBar::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
554 {
555 UNIMPLEMENTED;
556 return E_NOTIMPL;
557 }
558
559 HRESULT STDMETHODCALLTYPE CSearchBar::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
560 {
561 UNIMPLEMENTED;
562 return E_NOTIMPL;
563 }
564
565 void CSearchBar::SetSearchInProgress(BOOL bInProgress)
566 {
567 ::ShowWindow(GetDlgItem(IDC_SEARCH_BUTTON), bInProgress ? SW_HIDE : SW_SHOW);
568 ::ShowWindow(GetDlgItem(IDC_SEARCH_STOP_BUTTON), bInProgress ? SW_SHOW : SW_HIDE);
569 HWND hProgressBar = GetDlgItem(IDC_PROGRESS_BAR);
570 ::ShowWindow(hProgressBar, bInProgress ? SW_SHOW : SW_HIDE);
571 ::PostMessage(hProgressBar, PBM_SETMARQUEE, bInProgress, 0);
572 }
573
574 HRESULT CSearchBar::TrySubscribeToSearchEvents()
575 {
576 CComPtr<IShellFolder> pShellFolder;
577 HRESULT hr = GetSearchResultsFolder(NULL, NULL, &pShellFolder);
578 if (FAILED(hr))
579 return hr;
580
581 DWORD fAdviseCookie;
582 hr = AtlAdvise(pShellFolder, static_cast<IDispatch *>(this), DIID_DSearchCommandEvents, &fAdviseCookie);
583 if (FAILED_UNEXPECTEDLY(hr))
584 return hr;
585
586 return S_OK;
587 }
588
589 HRESULT STDMETHODCALLTYPE CSearchBar::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
590 {
591 switch (dispIdMember)
592 {
593 case DISPID_NAVIGATECOMPLETE2:
594 case DISPID_DOCUMENTCOMPLETE:
595 {
596 TrySubscribeToSearchEvents();
597
598 // Remove the search results folder from the address box
599 CComPtr<IDispatch> pDispatch;
600 HRESULT hResult = m_AddressEditBox->QueryInterface(IID_PPV_ARG(IDispatch, &pDispatch));
601 if (FAILED_UNEXPECTEDLY(hResult))
602 return hResult;
603 pDispatch->Invoke(dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
604 CComPtr<IShellService> pShellService;
605 hResult = m_AddressEditBox->QueryInterface(IID_PPV_ARG(IShellService, &pShellService));
606 if (FAILED_UNEXPECTEDLY(hResult))
607 return hResult;
608 hResult = pShellService->SetOwner(NULL);
609 if (FAILED_UNEXPECTEDLY(hResult))
610 return hResult;
611 HWND hComboboxEx = GetDlgItem(IDC_SEARCH_COMBOBOX);
612 int index = SendMessageW(hComboboxEx, CB_GETCOUNT, 0, 0);
613 if (index <= 0)
614 return S_OK;
615 COMBOBOXEXITEMW item = {0};
616 item.mask = CBEIF_LPARAM;
617 item.iItem = index - 1;
618 SendMessageW(hComboboxEx, CBEM_GETITEMW, 0, (LPARAM)&item);
619 if (!item.lParam)
620 return S_OK;
621 CComPtr<IShellFolder> pDesktopFolder;
622 hResult = SHGetDesktopFolder(&pDesktopFolder);
623 if (FAILED_UNEXPECTEDLY(hResult))
624 return hResult;
625 CComPtr<IShellFolder> pShellFolder;
626 hResult = pDesktopFolder->BindToObject((LPCITEMIDLIST)item.lParam, NULL, IID_PPV_ARG(IShellFolder, &pShellFolder));
627 if (FAILED(hResult))
628 return S_OK;
629 CLSID clsid;
630 hResult = IUnknown_GetClassID(pShellFolder, &clsid);
631 if (SUCCEEDED(hResult) && clsid == CLSID_FindFolder)
632 {
633 SendMessageW(hComboboxEx, CBEM_DELETEITEM, item.iItem, 0);
634 SendMessageW(hComboboxEx, CB_SETCURSEL, 0, 0);
635 }
636 return S_OK;
637 }
638 case DISPID_SEARCHCOMPLETE:
639 case DISPID_SEARCHABORT:
640 SetSearchInProgress(FALSE);
641 return S_OK;
642 default:
643 return E_INVALIDARG;
644 }
645 }