[SHELLFIND] Open search results folder with search button
[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
138 // *** IOleWindow methods ***
139 HRESULT STDMETHODCALLTYPE CSearchBar::GetWindow(HWND *lphwnd)
140 {
141 if (!lphwnd)
142 return E_INVALIDARG;
143 *lphwnd = m_hWnd;
144 return S_OK;
145 }
146
147 HRESULT STDMETHODCALLTYPE CSearchBar::ContextSensitiveHelp(BOOL fEnterMode)
148 {
149 UNIMPLEMENTED;
150 return E_NOTIMPL;
151 }
152
153
154 // *** IDockingWindow methods ***
155 HRESULT STDMETHODCALLTYPE CSearchBar::CloseDW(DWORD dwReserved)
156 {
157 // We do nothing, we don't have anything to save yet
158 TRACE("CloseDW called\n");
159 return S_OK;
160 }
161
162 HRESULT STDMETHODCALLTYPE CSearchBar::ResizeBorderDW(const RECT *prcBorder, IUnknown *punkToolbarSite, BOOL fReserved)
163 {
164 /* Must return E_NOTIMPL according to MSDN */
165 return E_NOTIMPL;
166 }
167
168 HRESULT STDMETHODCALLTYPE CSearchBar::ShowDW(BOOL fShow)
169 {
170 fVisible = fShow;
171 ShowWindow(fShow);
172 return S_OK;
173 }
174
175
176 // *** IDeskBand methods ***
177 HRESULT STDMETHODCALLTYPE CSearchBar::GetBandInfo(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO *pdbi)
178 {
179 if (!pdbi)
180 {
181 return E_INVALIDARG;
182 }
183
184 if (pdbi->dwMask & DBIM_MINSIZE)
185 {
186 pdbi->ptMinSize.x = 200;
187 pdbi->ptMinSize.y = 30;
188 }
189
190 if (pdbi->dwMask & DBIM_MAXSIZE)
191 {
192 pdbi->ptMaxSize.y = -1;
193 }
194
195 if (pdbi->dwMask & DBIM_INTEGRAL)
196 {
197 pdbi->ptIntegral.y = 1;
198 }
199
200 if (pdbi->dwMask & DBIM_ACTUAL)
201 {
202 pdbi->ptActual.x = 200;
203 pdbi->ptActual.y = 30;
204 }
205
206 if (pdbi->dwMask & DBIM_TITLE)
207 {
208 if (!LoadStringW(_AtlBaseModule.GetResourceInstance(), IDS_SEARCHLABEL, pdbi->wszTitle, _countof(pdbi->wszTitle)))
209 return HRESULT_FROM_WIN32(GetLastError());
210 }
211
212 if (pdbi->dwMask & DBIM_MODEFLAGS)
213 {
214 pdbi->dwModeFlags = DBIMF_NORMAL | DBIMF_VARIABLEHEIGHT;
215 }
216
217 if (pdbi->dwMask & DBIM_BKCOLOR)
218 {
219 pdbi->dwMask &= ~DBIM_BKCOLOR;
220 }
221 return S_OK;
222 }
223
224 LRESULT CALLBACK MyWindowProc(
225 _In_ HWND hwnd,
226 _In_ UINT uMsg,
227 _In_ WPARAM wParam,
228 _In_ LPARAM lParam
229 )
230 {
231 return 0;
232 }
233
234 // *** IObjectWithSite methods ***
235 HRESULT STDMETHODCALLTYPE CSearchBar::SetSite(IUnknown *pUnkSite)
236 {
237 HRESULT hr;
238 HWND parentWnd;
239
240 if (pUnkSite == pSite)
241 return S_OK;
242
243 TRACE("SetSite called \n");
244 if (!pUnkSite)
245 {
246 DestroyWindow();
247 m_hWnd = NULL;
248 }
249
250 if (pUnkSite != pSite)
251 {
252 pSite = NULL;
253 }
254
255 if(!pUnkSite)
256 return S_OK;
257
258 hr = IUnknown_GetWindow(pUnkSite, &parentWnd);
259 if (!SUCCEEDED(hr))
260 {
261 ERR("Could not get parent's window ! Status: %08lx\n", hr);
262 return E_INVALIDARG;
263 }
264
265 pSite = pUnkSite;
266
267 if (m_hWnd)
268 {
269 // Change its parent
270 SetParent(parentWnd);
271 }
272 else
273 {
274 CWindowImpl::Create(parentWnd);
275
276 InitializeSearchBar();
277 }
278 return S_OK;
279 }
280
281 HRESULT STDMETHODCALLTYPE CSearchBar::GetSite(REFIID riid, void **ppvSite)
282 {
283 if (!ppvSite)
284 return E_POINTER;
285 *ppvSite = pSite;
286 return S_OK;
287 }
288
289
290 // *** IOleCommandTarget methods ***
291 HRESULT STDMETHODCALLTYPE CSearchBar::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText)
292 {
293 UNIMPLEMENTED;
294 return E_NOTIMPL;
295 }
296
297 HRESULT STDMETHODCALLTYPE CSearchBar::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
298 {
299 UNIMPLEMENTED;
300 return E_NOTIMPL;
301 }
302
303
304 // *** IServiceProvider methods ***
305 HRESULT STDMETHODCALLTYPE CSearchBar::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
306 {
307 /* FIXME: we probably want to handle more services here */
308 return IUnknown_QueryService(pSite, SID_SShellBrowser, riid, ppvObject);
309 }
310
311
312 // *** IInputObject methods ***
313 HRESULT STDMETHODCALLTYPE CSearchBar::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
314 {
315 if (fActivate)
316 {
317 //SetFocus();
318 SetActiveWindow();
319 }
320 // TODO: handle message
321 if(lpMsg)
322 {
323 TranslateMessage(lpMsg);
324 DispatchMessage(lpMsg);
325 }
326 return S_OK;
327 }
328
329 HRESULT STDMETHODCALLTYPE CSearchBar::HasFocusIO()
330 {
331 return bFocused ? S_OK : S_FALSE;
332 }
333
334 HRESULT STDMETHODCALLTYPE CSearchBar::TranslateAcceleratorIO(LPMSG lpMsg)
335 {
336 if (lpMsg->hwnd == m_hWnd)
337 {
338 TranslateMessage(lpMsg);
339 DispatchMessage(lpMsg);
340 return S_OK;
341 }
342
343 return S_FALSE;
344 }
345
346 // *** IPersist methods ***
347 HRESULT STDMETHODCALLTYPE CSearchBar::GetClassID(CLSID *pClassID)
348 {
349 if (!pClassID)
350 return E_POINTER;
351 memcpy(pClassID, &CLSID_FileSearchBand, sizeof(CLSID));
352 return S_OK;
353 }
354
355
356 // *** IPersistStream methods ***
357 HRESULT STDMETHODCALLTYPE CSearchBar::IsDirty()
358 {
359 UNIMPLEMENTED;
360 return E_NOTIMPL;
361 }
362
363 HRESULT STDMETHODCALLTYPE CSearchBar::Load(IStream *pStm)
364 {
365 UNIMPLEMENTED;
366 return E_NOTIMPL;
367 }
368
369 HRESULT STDMETHODCALLTYPE CSearchBar::Save(IStream *pStm, BOOL fClearDirty)
370 {
371 UNIMPLEMENTED;
372 return E_NOTIMPL;
373 }
374
375 HRESULT STDMETHODCALLTYPE CSearchBar::GetSizeMax(ULARGE_INTEGER *pcbSize)
376 {
377 // TODO: calculate max size
378 UNIMPLEMENTED;
379 return E_NOTIMPL;
380 }
381
382
383 // *** IWinEventHandler methods ***
384 HRESULT STDMETHODCALLTYPE CSearchBar::OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
385 {
386 return S_OK;
387 }
388
389 HRESULT STDMETHODCALLTYPE CSearchBar::IsWindowOwner(HWND hWnd)
390 {
391 return (hWnd == m_hWnd) ? S_OK : S_FALSE;
392 }
393
394 // *** IBandNavigate methods ***
395 HRESULT STDMETHODCALLTYPE CSearchBar::Select(long paramC)
396 {
397 UNIMPLEMENTED;
398 return E_NOTIMPL;
399 }
400
401 // *** INamespaceProxy ***
402 HRESULT STDMETHODCALLTYPE CSearchBar::GetNavigateTarget(long paramC, long param10, long param14)
403 {
404 UNIMPLEMENTED;
405 return E_NOTIMPL;
406 }
407
408 HRESULT STDMETHODCALLTYPE CSearchBar::Invoke(long paramC)
409 {
410 UNIMPLEMENTED;
411 return E_NOTIMPL;
412 }
413
414 HRESULT STDMETHODCALLTYPE CSearchBar::OnSelectionChanged(long paramC)
415 {
416 UNIMPLEMENTED;
417 return E_NOTIMPL;
418 }
419
420 HRESULT STDMETHODCALLTYPE CSearchBar::RefreshFlags(long paramC, long param10, long param14)
421 {
422 UNIMPLEMENTED;
423 return E_NOTIMPL;
424 }
425
426 HRESULT STDMETHODCALLTYPE CSearchBar::CacheItem(long paramC)
427 {
428 UNIMPLEMENTED;
429 return E_NOTIMPL;
430 }
431
432 // *** IDispatch methods ***
433 HRESULT STDMETHODCALLTYPE CSearchBar::GetTypeInfoCount(UINT *pctinfo)
434 {
435 UNIMPLEMENTED;
436 return E_NOTIMPL;
437 }
438
439 HRESULT STDMETHODCALLTYPE CSearchBar::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
440 {
441 UNIMPLEMENTED;
442 return E_NOTIMPL;
443 }
444
445 HRESULT STDMETHODCALLTYPE CSearchBar::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
446 {
447 UNIMPLEMENTED;
448 return E_NOTIMPL;
449 }
450
451 HRESULT STDMETHODCALLTYPE CSearchBar::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
452 {
453 TRACE("Unknown dispid requested: %08x\n", dispIdMember);
454 return E_INVALIDARG;
455 }