49d6f87b846ae26448544ab3a4a6664a589a80e4
[reactos.git] / dll / win32 / browseui / shellfind / CSearchBar.cpp
1 /*
2 * ReactOS Explorer
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19 #include "CSearchBar.h"
20 #include <psdk/wingdi.h>
21
22 WINE_DEFAULT_DEBUG_CHANNEL(shellfind);
23
24 #if 1
25 #undef UNIMPLEMENTED
26
27 #define UNIMPLEMENTED DbgPrint("%s is UNIMPLEMENTED!\n", __FUNCTION__)
28 #endif
29
30 CSearchBar::CSearchBar() :
31 pSite(NULL),
32 fVisible(FALSE),
33 bFocused(FALSE)
34 {
35 }
36
37 CSearchBar::~CSearchBar()
38 {
39 }
40
41 void CSearchBar::InitializeSearchBar()
42 {
43 CreateWindowExW(0, WC_STATIC, L"Search by any or all of the criteria below.",
44 WS_CHILD | WS_VISIBLE,
45 10, 10, 200, 40,
46 m_hWnd, NULL,
47 _AtlBaseModule.GetModuleInstance(), NULL);
48
49 CreateWindowExW(0, WC_STATIC, L"A &word or phrase in the file:",
50 WS_CHILD | WS_VISIBLE,
51 10, 50, 500, 20,
52 m_hWnd, NULL,
53 _AtlBaseModule.GetModuleInstance(), NULL);
54 CreateWindowExW(WS_EX_CLIENTEDGE, WC_EDITW, NULL,
55 WS_BORDER | WS_CHILD | WS_VISIBLE,
56 10, 70, 100, 20,
57 m_hWnd, NULL,
58 _AtlBaseModule.GetModuleInstance(), NULL);
59
60 CreateWindowExW(0, WC_STATIC, L"&Look in:",
61 WS_CHILD | WS_VISIBLE,
62 10, 100, 500, 20,
63 m_hWnd, NULL,
64 _AtlBaseModule.GetModuleInstance(), NULL);
65 CreateWindowExW(WS_EX_CLIENTEDGE, WC_EDITW, NULL,
66 WS_BORDER | WS_CHILD | WS_VISIBLE,
67 10, 120, 100, 20,
68 m_hWnd, NULL,
69 _AtlBaseModule.GetModuleInstance(), NULL);
70
71 CreateWindowExW(0, WC_STATIC, L"&Look in:",
72 WS_CHILD | WS_VISIBLE,
73 10, 150, 500, 20,
74 m_hWnd, NULL,
75 _AtlBaseModule.GetModuleInstance(), NULL);
76 CreateWindowExW(WS_EX_CLIENTEDGE, WC_EDITW, NULL,
77 WS_BORDER | WS_CHILD | WS_VISIBLE,
78 10, 180, 100, 20,
79 m_hWnd, NULL,
80 _AtlBaseModule.GetModuleInstance(), NULL);
81
82 CreateWindowExW(0, WC_BUTTON, L"Sea&rch",
83 WS_BORDER | WS_CHILD | WS_VISIBLE,
84 10, 210, 100, 20,
85 m_hWnd, NULL,
86 _AtlBaseModule.GetModuleInstance(), NULL);
87 }
88
89 HRESULT CSearchBar::ExecuteCommand(CComPtr<IContextMenu>& menu, UINT nCmd)
90 {
91 CComPtr<IOleWindow> pBrowserOleWnd;
92 CMINVOKECOMMANDINFO cmi;
93 HWND browserWnd;
94 HRESULT hr;
95
96 hr = IUnknown_QueryService(pSite, SID_SShellBrowser, IID_PPV_ARG(IOleWindow, &pBrowserOleWnd));
97 if (FAILED_UNEXPECTEDLY(hr))
98 return hr;
99
100 hr = pBrowserOleWnd->GetWindow(&browserWnd);
101 if (FAILED_UNEXPECTEDLY(hr))
102 return hr;
103
104 ZeroMemory(&cmi, sizeof(cmi));
105 cmi.cbSize = sizeof(cmi);
106 cmi.lpVerb = MAKEINTRESOURCEA(nCmd);
107 cmi.hwnd = browserWnd;
108 if (GetKeyState(VK_SHIFT) & 0x8000)
109 cmi.fMask |= CMIC_MASK_SHIFT_DOWN;
110 if (GetKeyState(VK_CONTROL) & 0x8000)
111 cmi.fMask |= CMIC_MASK_CONTROL_DOWN;
112
113 return menu->InvokeCommand(&cmi);
114 }
115
116
117 // *** ATL event handlers ***
118 LRESULT CSearchBar::OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
119 {
120 bFocused = TRUE;
121 IUnknown_OnFocusChangeIS(pSite, reinterpret_cast<IUnknown*>(this), TRUE);
122 bHandled = FALSE;
123 return TRUE;
124 }
125
126 HRESULT CSearchBar::GetSearchResultsFolder(IShellBrowser **ppShellBrowser, HWND *pHwnd, IShellFolder **ppShellFolder)
127 {
128 HRESULT hr;
129 CComPtr<IShellBrowser> pShellBrowser;
130 if (!ppShellBrowser)
131 ppShellBrowser = &pShellBrowser;
132 if (!*ppShellBrowser)
133 {
134 hr = IUnknown_QueryService(m_pSite, SID_SShellBrowser, IID_PPV_ARG(IShellBrowser, ppShellBrowser));
135 if (FAILED_UNEXPECTEDLY(hr))
136 return hr;
137 }
138
139 CComPtr<IShellView> pShellView;
140 hr = (*ppShellBrowser)->QueryActiveShellView(&pShellView);
141 if (FAILED(hr) || !pShellView)
142 return hr;
143
144 CComPtr<IFolderView> pFolderView;
145 hr = pShellView->QueryInterface(IID_PPV_ARG(IFolderView, &pFolderView));
146 if (FAILED(hr) || !pFolderView)
147 return hr;
148
149 CComPtr<IShellFolder> pShellFolder;
150 if (!ppShellFolder)
151 ppShellFolder = &pShellFolder;
152 hr = pFolderView->GetFolder(IID_PPV_ARG(IShellFolder, ppShellFolder));
153 if (FAILED(hr) || !pShellFolder)
154 return hr;
155
156 CLSID clsid;
157 hr = IUnknown_GetClassID(*ppShellFolder, &clsid);
158 if (FAILED(hr))
159 return hr;
160 if (clsid != CLSID_FindFolder)
161 return E_FAIL;
162
163 if (pHwnd)
164 {
165 hr = pShellView->GetWindow(pHwnd);
166 if (FAILED_UNEXPECTEDLY(hr))
167 return hr;
168 }
169
170 return S_OK;
171 }
172
173 LRESULT CSearchBar::OnSearchButtonClicked(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
174 {
175 CComPtr<IShellBrowser> pShellBrowser;
176 HRESULT hr = IUnknown_QueryService(pSite, SID_SShellBrowser, IID_PPV_ARG(IShellBrowser, &pShellBrowser));
177 if (FAILED_UNEXPECTEDLY(hr))
178 return hr;
179
180 HWND hwnd;
181 if (FAILED(GetSearchResultsFolder(&pShellBrowser, &hwnd, NULL)))
182 {
183 WCHAR szShellGuid[MAX_PATH];
184 const WCHAR shellGuidPrefix[] = L"shell:::";
185 memcpy(szShellGuid, shellGuidPrefix, sizeof(shellGuidPrefix));
186 hr = StringFromGUID2(CLSID_FindFolder, szShellGuid + _countof(shellGuidPrefix) - 1,
187 _countof(szShellGuid) - _countof(shellGuidPrefix));
188 if (FAILED_UNEXPECTEDLY(hr))
189 return hr;
190
191 CComHeapPtr<ITEMIDLIST> findFolderPidl;
192 hr = SHParseDisplayName(szShellGuid, NULL, &findFolderPidl, 0, NULL);
193 if (FAILED_UNEXPECTEDLY(hr))
194 return hr;
195
196 hr = pShellBrowser->BrowseObject(findFolderPidl, 0);
197 if (FAILED_UNEXPECTEDLY(hr))
198 return hr;
199 }
200
201 GetSearchResultsFolder(&pShellBrowser, &hwnd, NULL);
202 if (hwnd)
203 ::PostMessageW(hwnd, WM_SEARCH_START, 0, (LPARAM) StrDupW(L"Starting search..."));
204
205 return S_OK;
206 }
207
208 LRESULT CSearchBar::OnClicked(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
209 {
210 HWND hwnd;
211 HRESULT hr = GetSearchResultsFolder(NULL, &hwnd, NULL);
212 if (SUCCEEDED(hr))
213 {
214 LPCWSTR path = L"C:\\readme.txt";
215 ::PostMessageW(hwnd, WM_SEARCH_ADD_RESULT, 0, (LPARAM) StrDupW(path));
216 }
217
218 return 0;
219 }
220
221
222 // *** IOleWindow methods ***
223 HRESULT STDMETHODCALLTYPE CSearchBar::GetWindow(HWND *lphwnd)
224 {
225 if (!lphwnd)
226 return E_INVALIDARG;
227 *lphwnd = m_hWnd;
228 return S_OK;
229 }
230
231 HRESULT STDMETHODCALLTYPE CSearchBar::ContextSensitiveHelp(BOOL fEnterMode)
232 {
233 UNIMPLEMENTED;
234 return E_NOTIMPL;
235 }
236
237
238 // *** IDockingWindow methods ***
239 HRESULT STDMETHODCALLTYPE CSearchBar::CloseDW(DWORD dwReserved)
240 {
241 // We do nothing, we don't have anything to save yet
242 TRACE("CloseDW called\n");
243 return S_OK;
244 }
245
246 HRESULT STDMETHODCALLTYPE CSearchBar::ResizeBorderDW(const RECT *prcBorder, IUnknown *punkToolbarSite, BOOL fReserved)
247 {
248 /* Must return E_NOTIMPL according to MSDN */
249 return E_NOTIMPL;
250 }
251
252 HRESULT STDMETHODCALLTYPE CSearchBar::ShowDW(BOOL fShow)
253 {
254 fVisible = fShow;
255 ShowWindow(fShow);
256 return S_OK;
257 }
258
259
260 // *** IDeskBand methods ***
261 HRESULT STDMETHODCALLTYPE CSearchBar::GetBandInfo(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO *pdbi)
262 {
263 if (!pdbi)
264 {
265 return E_INVALIDARG;
266 }
267
268 if (pdbi->dwMask & DBIM_MINSIZE)
269 {
270 pdbi->ptMinSize.x = 200;
271 pdbi->ptMinSize.y = 30;
272 }
273
274 if (pdbi->dwMask & DBIM_MAXSIZE)
275 {
276 pdbi->ptMaxSize.y = -1;
277 }
278
279 if (pdbi->dwMask & DBIM_INTEGRAL)
280 {
281 pdbi->ptIntegral.y = 1;
282 }
283
284 if (pdbi->dwMask & DBIM_ACTUAL)
285 {
286 pdbi->ptActual.x = 200;
287 pdbi->ptActual.y = 30;
288 }
289
290 if (pdbi->dwMask & DBIM_TITLE)
291 {
292 if (!LoadStringW(_AtlBaseModule.GetResourceInstance(), IDS_SEARCHLABEL, pdbi->wszTitle, _countof(pdbi->wszTitle)))
293 return HRESULT_FROM_WIN32(GetLastError());
294 }
295
296 if (pdbi->dwMask & DBIM_MODEFLAGS)
297 {
298 pdbi->dwModeFlags = DBIMF_NORMAL | DBIMF_VARIABLEHEIGHT;
299 }
300
301 if (pdbi->dwMask & DBIM_BKCOLOR)
302 {
303 pdbi->dwMask &= ~DBIM_BKCOLOR;
304 }
305 return S_OK;
306 }
307
308 LRESULT CALLBACK MyWindowProc(
309 _In_ HWND hwnd,
310 _In_ UINT uMsg,
311 _In_ WPARAM wParam,
312 _In_ LPARAM lParam
313 )
314 {
315 return 0;
316 }
317
318 // *** IObjectWithSite methods ***
319 HRESULT STDMETHODCALLTYPE CSearchBar::SetSite(IUnknown *pUnkSite)
320 {
321 HRESULT hr;
322 HWND parentWnd;
323
324 if (pUnkSite == pSite)
325 return S_OK;
326
327 TRACE("SetSite called \n");
328 if (!pUnkSite)
329 {
330 DestroyWindow();
331 m_hWnd = NULL;
332 }
333
334 if (pUnkSite != pSite)
335 {
336 pSite = NULL;
337 }
338
339 if(!pUnkSite)
340 return S_OK;
341
342 hr = IUnknown_GetWindow(pUnkSite, &parentWnd);
343 if (!SUCCEEDED(hr))
344 {
345 ERR("Could not get parent's window ! Status: %08lx\n", hr);
346 return E_INVALIDARG;
347 }
348
349 pSite = pUnkSite;
350
351 if (m_hWnd)
352 {
353 // Change its parent
354 SetParent(parentWnd);
355 }
356 else
357 {
358 CWindowImpl::Create(parentWnd);
359
360 InitializeSearchBar();
361 }
362 return S_OK;
363 }
364
365 HRESULT STDMETHODCALLTYPE CSearchBar::GetSite(REFIID riid, void **ppvSite)
366 {
367 if (!ppvSite)
368 return E_POINTER;
369 *ppvSite = pSite;
370 return S_OK;
371 }
372
373
374 // *** IOleCommandTarget methods ***
375 HRESULT STDMETHODCALLTYPE CSearchBar::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText)
376 {
377 UNIMPLEMENTED;
378 return E_NOTIMPL;
379 }
380
381 HRESULT STDMETHODCALLTYPE CSearchBar::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
382 {
383 UNIMPLEMENTED;
384 return E_NOTIMPL;
385 }
386
387
388 // *** IServiceProvider methods ***
389 HRESULT STDMETHODCALLTYPE CSearchBar::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
390 {
391 /* FIXME: we probably want to handle more services here */
392 return IUnknown_QueryService(pSite, SID_SShellBrowser, riid, ppvObject);
393 }
394
395
396 // *** IInputObject methods ***
397 HRESULT STDMETHODCALLTYPE CSearchBar::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
398 {
399 if (fActivate)
400 {
401 //SetFocus();
402 SetActiveWindow();
403 }
404 // TODO: handle message
405 if(lpMsg)
406 {
407 TranslateMessage(lpMsg);
408 DispatchMessage(lpMsg);
409 }
410 return S_OK;
411 }
412
413 HRESULT STDMETHODCALLTYPE CSearchBar::HasFocusIO()
414 {
415 return bFocused ? S_OK : S_FALSE;
416 }
417
418 HRESULT STDMETHODCALLTYPE CSearchBar::TranslateAcceleratorIO(LPMSG lpMsg)
419 {
420 if (lpMsg->hwnd == m_hWnd)
421 {
422 TranslateMessage(lpMsg);
423 DispatchMessage(lpMsg);
424 return S_OK;
425 }
426
427 return S_FALSE;
428 }
429
430 // *** IPersist methods ***
431 HRESULT STDMETHODCALLTYPE CSearchBar::GetClassID(CLSID *pClassID)
432 {
433 if (!pClassID)
434 return E_POINTER;
435 memcpy(pClassID, &CLSID_FileSearchBand, sizeof(CLSID));
436 return S_OK;
437 }
438
439
440 // *** IPersistStream methods ***
441 HRESULT STDMETHODCALLTYPE CSearchBar::IsDirty()
442 {
443 UNIMPLEMENTED;
444 return E_NOTIMPL;
445 }
446
447 HRESULT STDMETHODCALLTYPE CSearchBar::Load(IStream *pStm)
448 {
449 UNIMPLEMENTED;
450 return E_NOTIMPL;
451 }
452
453 HRESULT STDMETHODCALLTYPE CSearchBar::Save(IStream *pStm, BOOL fClearDirty)
454 {
455 UNIMPLEMENTED;
456 return E_NOTIMPL;
457 }
458
459 HRESULT STDMETHODCALLTYPE CSearchBar::GetSizeMax(ULARGE_INTEGER *pcbSize)
460 {
461 // TODO: calculate max size
462 UNIMPLEMENTED;
463 return E_NOTIMPL;
464 }
465
466
467 // *** IWinEventHandler methods ***
468 HRESULT STDMETHODCALLTYPE CSearchBar::OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
469 {
470 return S_OK;
471 }
472
473 HRESULT STDMETHODCALLTYPE CSearchBar::IsWindowOwner(HWND hWnd)
474 {
475 return (hWnd == m_hWnd) ? S_OK : S_FALSE;
476 }
477
478 // *** IBandNavigate methods ***
479 HRESULT STDMETHODCALLTYPE CSearchBar::Select(long paramC)
480 {
481 UNIMPLEMENTED;
482 return E_NOTIMPL;
483 }
484
485 // *** INamespaceProxy ***
486 HRESULT STDMETHODCALLTYPE CSearchBar::GetNavigateTarget(long paramC, long param10, long param14)
487 {
488 UNIMPLEMENTED;
489 return E_NOTIMPL;
490 }
491
492 HRESULT STDMETHODCALLTYPE CSearchBar::Invoke(long paramC)
493 {
494 UNIMPLEMENTED;
495 return E_NOTIMPL;
496 }
497
498 HRESULT STDMETHODCALLTYPE CSearchBar::OnSelectionChanged(long paramC)
499 {
500 UNIMPLEMENTED;
501 return E_NOTIMPL;
502 }
503
504 HRESULT STDMETHODCALLTYPE CSearchBar::RefreshFlags(long paramC, long param10, long param14)
505 {
506 UNIMPLEMENTED;
507 return E_NOTIMPL;
508 }
509
510 HRESULT STDMETHODCALLTYPE CSearchBar::CacheItem(long paramC)
511 {
512 UNIMPLEMENTED;
513 return E_NOTIMPL;
514 }
515
516 // *** IDispatch methods ***
517 HRESULT STDMETHODCALLTYPE CSearchBar::GetTypeInfoCount(UINT *pctinfo)
518 {
519 UNIMPLEMENTED;
520 return E_NOTIMPL;
521 }
522
523 HRESULT STDMETHODCALLTYPE CSearchBar::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
524 {
525 UNIMPLEMENTED;
526 return E_NOTIMPL;
527 }
528
529 HRESULT STDMETHODCALLTYPE CSearchBar::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
530 {
531 UNIMPLEMENTED;
532 return E_NOTIMPL;
533 }
534
535 HRESULT STDMETHODCALLTYPE CSearchBar::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
536 {
537 TRACE("Unknown dispid requested: %08x\n", dispIdMember);
538 return E_INVALIDARG;
539 }