[SHELLFIND] Add search bar click handler for testing search results
[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_BUTTON, L"Sea&rch",
72 WS_BORDER | WS_CHILD | WS_VISIBLE,
73 10, 150, 100, 20,
74 m_hWnd, NULL,
75 _AtlBaseModule.GetModuleInstance(), NULL);
76 }
77
78 HRESULT CSearchBar::ExecuteCommand(CComPtr<IContextMenu>& menu, UINT nCmd)
79 {
80 CComPtr<IOleWindow> pBrowserOleWnd;
81 CMINVOKECOMMANDINFO cmi;
82 HWND browserWnd;
83 HRESULT hr;
84
85 hr = IUnknown_QueryService(pSite, SID_SShellBrowser, IID_PPV_ARG(IOleWindow, &pBrowserOleWnd));
86 if (FAILED_UNEXPECTEDLY(hr))
87 return hr;
88
89 hr = pBrowserOleWnd->GetWindow(&browserWnd);
90 if (FAILED_UNEXPECTEDLY(hr))
91 return hr;
92
93 ZeroMemory(&cmi, sizeof(cmi));
94 cmi.cbSize = sizeof(cmi);
95 cmi.lpVerb = MAKEINTRESOURCEA(nCmd);
96 cmi.hwnd = browserWnd;
97 if (GetKeyState(VK_SHIFT) & 0x8000)
98 cmi.fMask |= CMIC_MASK_SHIFT_DOWN;
99 if (GetKeyState(VK_CONTROL) & 0x8000)
100 cmi.fMask |= CMIC_MASK_CONTROL_DOWN;
101
102 return menu->InvokeCommand(&cmi);
103 }
104
105
106 // *** ATL event handlers ***
107 LRESULT CSearchBar::OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
108 {
109 bFocused = TRUE;
110 IUnknown_OnFocusChangeIS(pSite, reinterpret_cast<IUnknown*>(this), TRUE);
111 bHandled = FALSE;
112 return TRUE;
113 }
114
115 LRESULT CSearchBar::OnSearchButtonClicked(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
116 {
117 CComPtr<IShellBrowser> pShellBrowser;
118 HRESULT hr = IUnknown_QueryService(pSite, SID_SShellBrowser, IID_PPV_ARG(IShellBrowser, &pShellBrowser));
119 if (FAILED_UNEXPECTEDLY(hr))
120 return hr;
121
122 WCHAR szShellGuid[MAX_PATH];
123 const WCHAR shellGuidPrefix[] = L"shell:::";
124 memcpy(szShellGuid, shellGuidPrefix, sizeof(shellGuidPrefix));
125 hr = StringFromGUID2(CLSID_FindFolder, szShellGuid + _countof(shellGuidPrefix) - 1, _countof(szShellGuid) - _countof(shellGuidPrefix));
126 if (FAILED_UNEXPECTEDLY(hr))
127 return hr;
128
129 LPITEMIDLIST findFolderPidl;
130 hr = SHParseDisplayName(szShellGuid, NULL, &findFolderPidl, 0, NULL);
131 if (FAILED_UNEXPECTEDLY(hr))
132 return hr;
133
134 return pShellBrowser->BrowseObject(findFolderPidl, 0);
135 }
136
137 LRESULT CSearchBar::OnClicked(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
138 {
139 HRESULT hr;
140 CComPtr<IShellBrowser> pShellBrowser;
141 hr = IUnknown_QueryService(pSite, SID_SShellBrowser, IID_PPV_ARG(IShellBrowser, &pShellBrowser));
142 if (FAILED_UNEXPECTEDLY(hr))
143 return hr;
144 CComPtr<IShellView> pShellView;
145 hr = pShellBrowser->QueryActiveShellView(&pShellView);
146 if (FAILED_UNEXPECTEDLY(hr))
147 return hr;
148 HWND hwnd;
149 hr = pShellView->GetWindow(&hwnd);
150 if (FAILED_UNEXPECTEDLY(hr))
151 return hr;
152
153 LPWSTR path = (LPWSTR) L"C:\\readme.txt";
154
155 // TODO: Use message ID in header file
156 ::PostMessageW(hwnd, WM_USER, 0, (LPARAM) StrDupW(path));
157 return 0;
158 }
159
160
161 // *** IOleWindow methods ***
162 HRESULT STDMETHODCALLTYPE CSearchBar::GetWindow(HWND *lphwnd)
163 {
164 if (!lphwnd)
165 return E_INVALIDARG;
166 *lphwnd = m_hWnd;
167 return S_OK;
168 }
169
170 HRESULT STDMETHODCALLTYPE CSearchBar::ContextSensitiveHelp(BOOL fEnterMode)
171 {
172 UNIMPLEMENTED;
173 return E_NOTIMPL;
174 }
175
176
177 // *** IDockingWindow methods ***
178 HRESULT STDMETHODCALLTYPE CSearchBar::CloseDW(DWORD dwReserved)
179 {
180 // We do nothing, we don't have anything to save yet
181 TRACE("CloseDW called\n");
182 return S_OK;
183 }
184
185 HRESULT STDMETHODCALLTYPE CSearchBar::ResizeBorderDW(const RECT *prcBorder, IUnknown *punkToolbarSite, BOOL fReserved)
186 {
187 /* Must return E_NOTIMPL according to MSDN */
188 return E_NOTIMPL;
189 }
190
191 HRESULT STDMETHODCALLTYPE CSearchBar::ShowDW(BOOL fShow)
192 {
193 fVisible = fShow;
194 ShowWindow(fShow);
195 return S_OK;
196 }
197
198
199 // *** IDeskBand methods ***
200 HRESULT STDMETHODCALLTYPE CSearchBar::GetBandInfo(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO *pdbi)
201 {
202 if (!pdbi)
203 {
204 return E_INVALIDARG;
205 }
206
207 if (pdbi->dwMask & DBIM_MINSIZE)
208 {
209 pdbi->ptMinSize.x = 200;
210 pdbi->ptMinSize.y = 30;
211 }
212
213 if (pdbi->dwMask & DBIM_MAXSIZE)
214 {
215 pdbi->ptMaxSize.y = -1;
216 }
217
218 if (pdbi->dwMask & DBIM_INTEGRAL)
219 {
220 pdbi->ptIntegral.y = 1;
221 }
222
223 if (pdbi->dwMask & DBIM_ACTUAL)
224 {
225 pdbi->ptActual.x = 200;
226 pdbi->ptActual.y = 30;
227 }
228
229 if (pdbi->dwMask & DBIM_TITLE)
230 {
231 if (!LoadStringW(_AtlBaseModule.GetResourceInstance(), IDS_SEARCHLABEL, pdbi->wszTitle, _countof(pdbi->wszTitle)))
232 return HRESULT_FROM_WIN32(GetLastError());
233 }
234
235 if (pdbi->dwMask & DBIM_MODEFLAGS)
236 {
237 pdbi->dwModeFlags = DBIMF_NORMAL | DBIMF_VARIABLEHEIGHT;
238 }
239
240 if (pdbi->dwMask & DBIM_BKCOLOR)
241 {
242 pdbi->dwMask &= ~DBIM_BKCOLOR;
243 }
244 return S_OK;
245 }
246
247 LRESULT CALLBACK MyWindowProc(
248 _In_ HWND hwnd,
249 _In_ UINT uMsg,
250 _In_ WPARAM wParam,
251 _In_ LPARAM lParam
252 )
253 {
254 return 0;
255 }
256
257 // *** IObjectWithSite methods ***
258 HRESULT STDMETHODCALLTYPE CSearchBar::SetSite(IUnknown *pUnkSite)
259 {
260 HRESULT hr;
261 HWND parentWnd;
262
263 if (pUnkSite == pSite)
264 return S_OK;
265
266 TRACE("SetSite called \n");
267 if (!pUnkSite)
268 {
269 DestroyWindow();
270 m_hWnd = NULL;
271 }
272
273 if (pUnkSite != pSite)
274 {
275 pSite = NULL;
276 }
277
278 if(!pUnkSite)
279 return S_OK;
280
281 hr = IUnknown_GetWindow(pUnkSite, &parentWnd);
282 if (!SUCCEEDED(hr))
283 {
284 ERR("Could not get parent's window ! Status: %08lx\n", hr);
285 return E_INVALIDARG;
286 }
287
288 pSite = pUnkSite;
289
290 if (m_hWnd)
291 {
292 // Change its parent
293 SetParent(parentWnd);
294 }
295 else
296 {
297 CWindowImpl::Create(parentWnd);
298
299 InitializeSearchBar();
300 }
301 return S_OK;
302 }
303
304 HRESULT STDMETHODCALLTYPE CSearchBar::GetSite(REFIID riid, void **ppvSite)
305 {
306 if (!ppvSite)
307 return E_POINTER;
308 *ppvSite = pSite;
309 return S_OK;
310 }
311
312
313 // *** IOleCommandTarget methods ***
314 HRESULT STDMETHODCALLTYPE CSearchBar::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText)
315 {
316 UNIMPLEMENTED;
317 return E_NOTIMPL;
318 }
319
320 HRESULT STDMETHODCALLTYPE CSearchBar::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
321 {
322 UNIMPLEMENTED;
323 return E_NOTIMPL;
324 }
325
326
327 // *** IServiceProvider methods ***
328 HRESULT STDMETHODCALLTYPE CSearchBar::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
329 {
330 /* FIXME: we probably want to handle more services here */
331 return IUnknown_QueryService(pSite, SID_SShellBrowser, riid, ppvObject);
332 }
333
334
335 // *** IInputObject methods ***
336 HRESULT STDMETHODCALLTYPE CSearchBar::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
337 {
338 if (fActivate)
339 {
340 //SetFocus();
341 SetActiveWindow();
342 }
343 // TODO: handle message
344 if(lpMsg)
345 {
346 TranslateMessage(lpMsg);
347 DispatchMessage(lpMsg);
348 }
349 return S_OK;
350 }
351
352 HRESULT STDMETHODCALLTYPE CSearchBar::HasFocusIO()
353 {
354 return bFocused ? S_OK : S_FALSE;
355 }
356
357 HRESULT STDMETHODCALLTYPE CSearchBar::TranslateAcceleratorIO(LPMSG lpMsg)
358 {
359 if (lpMsg->hwnd == m_hWnd)
360 {
361 TranslateMessage(lpMsg);
362 DispatchMessage(lpMsg);
363 return S_OK;
364 }
365
366 return S_FALSE;
367 }
368
369 // *** IPersist methods ***
370 HRESULT STDMETHODCALLTYPE CSearchBar::GetClassID(CLSID *pClassID)
371 {
372 if (!pClassID)
373 return E_POINTER;
374 memcpy(pClassID, &CLSID_FileSearchBand, sizeof(CLSID));
375 return S_OK;
376 }
377
378
379 // *** IPersistStream methods ***
380 HRESULT STDMETHODCALLTYPE CSearchBar::IsDirty()
381 {
382 UNIMPLEMENTED;
383 return E_NOTIMPL;
384 }
385
386 HRESULT STDMETHODCALLTYPE CSearchBar::Load(IStream *pStm)
387 {
388 UNIMPLEMENTED;
389 return E_NOTIMPL;
390 }
391
392 HRESULT STDMETHODCALLTYPE CSearchBar::Save(IStream *pStm, BOOL fClearDirty)
393 {
394 UNIMPLEMENTED;
395 return E_NOTIMPL;
396 }
397
398 HRESULT STDMETHODCALLTYPE CSearchBar::GetSizeMax(ULARGE_INTEGER *pcbSize)
399 {
400 // TODO: calculate max size
401 UNIMPLEMENTED;
402 return E_NOTIMPL;
403 }
404
405
406 // *** IWinEventHandler methods ***
407 HRESULT STDMETHODCALLTYPE CSearchBar::OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
408 {
409 return S_OK;
410 }
411
412 HRESULT STDMETHODCALLTYPE CSearchBar::IsWindowOwner(HWND hWnd)
413 {
414 return (hWnd == m_hWnd) ? S_OK : S_FALSE;
415 }
416
417 // *** IBandNavigate methods ***
418 HRESULT STDMETHODCALLTYPE CSearchBar::Select(long paramC)
419 {
420 UNIMPLEMENTED;
421 return E_NOTIMPL;
422 }
423
424 // *** INamespaceProxy ***
425 HRESULT STDMETHODCALLTYPE CSearchBar::GetNavigateTarget(long paramC, long param10, long param14)
426 {
427 UNIMPLEMENTED;
428 return E_NOTIMPL;
429 }
430
431 HRESULT STDMETHODCALLTYPE CSearchBar::Invoke(long paramC)
432 {
433 UNIMPLEMENTED;
434 return E_NOTIMPL;
435 }
436
437 HRESULT STDMETHODCALLTYPE CSearchBar::OnSelectionChanged(long paramC)
438 {
439 UNIMPLEMENTED;
440 return E_NOTIMPL;
441 }
442
443 HRESULT STDMETHODCALLTYPE CSearchBar::RefreshFlags(long paramC, long param10, long param14)
444 {
445 UNIMPLEMENTED;
446 return E_NOTIMPL;
447 }
448
449 HRESULT STDMETHODCALLTYPE CSearchBar::CacheItem(long paramC)
450 {
451 UNIMPLEMENTED;
452 return E_NOTIMPL;
453 }
454
455 // *** IDispatch methods ***
456 HRESULT STDMETHODCALLTYPE CSearchBar::GetTypeInfoCount(UINT *pctinfo)
457 {
458 UNIMPLEMENTED;
459 return E_NOTIMPL;
460 }
461
462 HRESULT STDMETHODCALLTYPE CSearchBar::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
463 {
464 UNIMPLEMENTED;
465 return E_NOTIMPL;
466 }
467
468 HRESULT STDMETHODCALLTYPE CSearchBar::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
469 {
470 UNIMPLEMENTED;
471 return E_NOTIMPL;
472 }
473
474 HRESULT STDMETHODCALLTYPE CSearchBar::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
475 {
476 TRACE("Unknown dispid requested: %08x\n", dispIdMember);
477 return E_INVALIDARG;
478 }