blob: d53d08e16694bbadc227b530a5829e1ad9818220 [file] [log] [blame]
David Hedbergd6626962010-08-20 07:45:56 +02001/*
2 * ExplorerBrowser Control implementation.
3 *
4 * Copyright 2010 David Hedberg
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#include <stdarg.h>
22
23#define COBJMACROS
24#define NONAMELESSUNION
25#define NONAMELESSSTRUCT
26
27#include "winerror.h"
28#include "windef.h"
29#include "winbase.h"
30
David Hedbergb88c3e22010-08-24 10:56:19 +020031#include "wine/list.h"
David Hedbergd6626962010-08-20 07:45:56 +020032#include "wine/debug.h"
33#include "debughlp.h"
34
David Hedberge4e62e72010-08-20 07:45:59 +020035#include "shell32_main.h"
David Hedberg73100ce2010-08-24 10:56:21 +020036#include "pidl.h"
David Hedberge4e62e72010-08-20 07:45:59 +020037
David Hedbergd6626962010-08-20 07:45:56 +020038WINE_DEFAULT_DEBUG_CHANNEL(shell);
39
David Hedbergb88c3e22010-08-24 10:56:19 +020040typedef struct _event_client {
41 struct list entry;
42 IExplorerBrowserEvents *pebe;
43 DWORD cookie;
44} event_client;
45
David Hedbergfdccbd92010-08-25 15:24:33 +020046typedef struct _travellog_entry {
47 struct list entry;
48 LPITEMIDLIST pidl;
49} travellog_entry;
50
David Hedbergd6626962010-08-20 07:45:56 +020051typedef struct _ExplorerBrowserImpl {
52 const IExplorerBrowserVtbl *lpVtbl;
David Hedberg1efc5402010-08-20 07:45:58 +020053 const IShellBrowserVtbl *lpsbVtbl;
David Hedberg59965f92010-08-25 15:24:34 +020054 const ICommDlgBrowser3Vtbl *lpcdb3Vtbl;
David Hedbergd6626962010-08-20 07:45:56 +020055 LONG ref;
56 BOOL destroyed;
David Hedberge4e62e72010-08-20 07:45:59 +020057
58 HWND hwnd_main;
David Hedbergd17d78e2010-08-23 12:55:18 +020059 HWND hwnd_sv;
David Hedberg9c0260f2010-08-23 12:55:17 +020060
61 EXPLORER_BROWSER_OPTIONS eb_options;
David Hedberg270845d2010-08-23 12:55:19 +020062 FOLDERSETTINGS fs;
David Hedbergd17d78e2010-08-23 12:55:18 +020063
David Hedbergb88c3e22010-08-24 10:56:19 +020064 struct list event_clients;
65 DWORD events_next_cookie;
David Hedbergfdccbd92010-08-25 15:24:33 +020066 struct list travellog;
67 travellog_entry *travellog_cursor;
68 int travellog_count;
David Hedbergb88c3e22010-08-24 10:56:19 +020069
David Hedbergd17d78e2010-08-23 12:55:18 +020070 IShellView *psv;
71 RECT sv_rc;
David Hedberg73100ce2010-08-24 10:56:21 +020072 LPITEMIDLIST current_pidl;
David Hedbergd6626962010-08-20 07:45:56 +020073} ExplorerBrowserImpl;
74
75/**************************************************************************
David Hedbergb88c3e22010-08-24 10:56:19 +020076 * Event functions.
77 */
78static void events_unadvise_all(ExplorerBrowserImpl *This)
79{
80 event_client *client, *curs;
81 TRACE("%p\n", This);
82
83 LIST_FOR_EACH_ENTRY_SAFE(client, curs, &This->event_clients, event_client, entry)
84 {
85 TRACE("Removing %p\n", client);
86 list_remove(&client->entry);
87 IExplorerBrowserEvents_Release(client->pebe);
88 HeapFree(GetProcessHeap(), 0, client);
89 }
90}
91
David Hedberg73100ce2010-08-24 10:56:21 +020092static HRESULT events_NavigationPending(ExplorerBrowserImpl *This, PCIDLIST_ABSOLUTE pidl)
93{
94 event_client *cursor;
95 HRESULT hres = S_OK;
96
97 TRACE("%p\n", This);
98
99 LIST_FOR_EACH_ENTRY(cursor, &This->event_clients, event_client, entry)
100 {
101 TRACE("Notifying %p\n", cursor);
102 hres = IExplorerBrowserEvents_OnNavigationPending(cursor->pebe, pidl);
103
104 /* If this failed for any reason, the browsing is supposed to be aborted. */
105 if(FAILED(hres))
106 break;
107 }
108
109 return hres;
110}
111
112static void events_NavigationComplete(ExplorerBrowserImpl *This, PCIDLIST_ABSOLUTE pidl)
113{
114 event_client *cursor;
115
116 TRACE("%p\n", This);
117
118 LIST_FOR_EACH_ENTRY(cursor, &This->event_clients, event_client, entry)
119 {
120 TRACE("Notifying %p\n", cursor);
121 IExplorerBrowserEvents_OnNavigationComplete(cursor->pebe, pidl);
122 }
123}
124
125static void events_NavigationFailed(ExplorerBrowserImpl *This, PCIDLIST_ABSOLUTE pidl)
126{
127 event_client *cursor;
128
129 TRACE("%p\n", This);
130
131 LIST_FOR_EACH_ENTRY(cursor, &This->event_clients, event_client, entry)
132 {
133 TRACE("Notifying %p\n", cursor);
134 IExplorerBrowserEvents_OnNavigationFailed(cursor->pebe, pidl);
135 }
136}
137
138static void events_ViewCreated(ExplorerBrowserImpl *This, IShellView *psv)
139{
140 event_client *cursor;
141
142 TRACE("%p\n", This);
143
144 LIST_FOR_EACH_ENTRY(cursor, &This->event_clients, event_client, entry)
145 {
146 TRACE("Notifying %p\n", cursor);
147 IExplorerBrowserEvents_OnViewCreated(cursor->pebe, psv);
148 }
149}
150
David Hedbergb88c3e22010-08-24 10:56:19 +0200151/**************************************************************************
David Hedbergfdccbd92010-08-25 15:24:33 +0200152 * Travellog functions.
153 */
154static void travellog_remove_entry(ExplorerBrowserImpl *This, travellog_entry *entry)
155{
156 TRACE("Removing %p\n", entry);
157
158 list_remove(&entry->entry);
159 HeapFree(GetProcessHeap(), 0, entry);
160 This->travellog_count--;
161}
162
163static void travellog_remove_all_entries(ExplorerBrowserImpl *This)
164{
165 travellog_entry *cursor, *cursor2;
166 TRACE("%p\n", This);
167
168 LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->travellog, travellog_entry, entry)
169 travellog_remove_entry(This, cursor);
170
171 This->travellog_cursor = NULL;
172}
173
174static void travellog_add_entry(ExplorerBrowserImpl *This, LPITEMIDLIST pidl)
175{
176 travellog_entry *new, *cursor, *cursor2;
177 TRACE("%p (old count %d)\n", pidl, This->travellog_count);
178
179 /* Replace the old tail, if any, with the new entry */
180 if(This->travellog_cursor)
181 {
182 LIST_FOR_EACH_ENTRY_SAFE_REV(cursor, cursor2, &This->travellog, travellog_entry, entry)
183 {
184 if(cursor == This->travellog_cursor)
185 break;
186 travellog_remove_entry(This, cursor);
187 }
188 }
189
190 /* Create and add the new entry */
191 new = HeapAlloc(GetProcessHeap(), 0, sizeof(travellog_entry));
192 new->pidl = ILClone(pidl);
193 list_add_tail(&This->travellog, &new->entry);
194 This->travellog_cursor = new;
195 This->travellog_count++;
196
197 /* Remove the first few entries if the size limit is reached. */
198 if(This->travellog_count > 200)
199 {
200 UINT i = 0;
201 LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->travellog, travellog_entry, entry)
202 {
203 if(i++ > 10)
204 break;
205 travellog_remove_entry(This, cursor);
206 }
207 }
208}
209
210static LPCITEMIDLIST travellog_go_back(ExplorerBrowserImpl *This)
211{
212 travellog_entry *prev;
213 TRACE("%p, %p\n", This, This->travellog_cursor);
214
215 if(!This->travellog_cursor)
216 return NULL;
217
218 prev = LIST_ENTRY(list_prev(&This->travellog, &This->travellog_cursor->entry),
219 travellog_entry, entry);
220 if(!prev)
221 return NULL;
222
223 This->travellog_cursor = prev;
224 return prev->pidl;
225}
226
227static LPCITEMIDLIST travellog_go_forward(ExplorerBrowserImpl *This)
228{
229 travellog_entry *next;
230 TRACE("%p, %p\n", This, This->travellog_cursor);
231
232 if(!This->travellog_cursor)
233 return NULL;
234
235 next = LIST_ENTRY(list_next(&This->travellog, &This->travellog_cursor->entry),
236 travellog_entry, entry);
237 if(!next)
238 return NULL;
239
240 This->travellog_cursor = next;
241 return next->pidl;
242}
243
244/**************************************************************************
David Hedbergd17d78e2010-08-23 12:55:18 +0200245 * Helper functions
246 */
247static void update_layout(ExplorerBrowserImpl *This)
248{
249 RECT rc;
250 TRACE("%p\n", This);
251
252 GetClientRect(This->hwnd_main, &rc);
253 CopyRect(&This->sv_rc, &rc);
254}
255
256static void size_panes(ExplorerBrowserImpl *This)
257{
258 MoveWindow(This->hwnd_sv,
259 This->sv_rc.left, This->sv_rc.top,
260 This->sv_rc.right - This->sv_rc.left, This->sv_rc.bottom - This->sv_rc.top,
261 TRUE);
262}
263
David Hedberg270845d2010-08-23 12:55:19 +0200264static HRESULT change_viewmode(ExplorerBrowserImpl *This, UINT viewmode)
265{
266 IFolderView *pfv;
267 HRESULT hr;
268
269 if(!This->psv)
270 return E_FAIL;
271
272 hr = IShellView_QueryInterface(This->psv, &IID_IFolderView, (void*)&pfv);
273 if(SUCCEEDED(hr))
274 {
275 hr = IFolderView_SetCurrentViewMode(pfv, This->fs.ViewMode);
276 IFolderView_Release(pfv);
277 }
278
279 return hr;
280}
281
David Hedberg73100ce2010-08-24 10:56:21 +0200282static HRESULT create_new_shellview(ExplorerBrowserImpl *This, IShellItem *psi)
283{
284 IShellBrowser *psb = (IShellBrowser*)&This->lpsbVtbl;
285 IShellFolder *psf;
286 IShellView *psv;
287 HWND hwnd_new;
288 HRESULT hr;
289
290 TRACE("%p, %p\n", This, psi);
291
292 hr = IShellItem_BindToHandler(psi, NULL, &BHID_SFObject, &IID_IShellFolder, (void**)&psf);
293 if(SUCCEEDED(hr))
294 {
295 hr = IShellFolder_CreateViewObject(psf, This->hwnd_main, &IID_IShellView, (void**)&psv);
296 if(SUCCEEDED(hr))
297 {
298 if(This->hwnd_sv)
299 {
300 IShellView_DestroyViewWindow(This->psv);
301 This->hwnd_sv = NULL;
302 }
303
304 hr = IShellView_CreateViewWindow(psv, This->psv, &This->fs, psb, &This->sv_rc, &hwnd_new);
305 if(SUCCEEDED(hr))
306 {
307 /* Replace the old shellview */
308 if(This->psv) IShellView_Release(This->psv);
309
310 This->psv = psv;
311 This->hwnd_sv = hwnd_new;
312 events_ViewCreated(This, psv);
313 }
314 else
315 {
316 ERR("CreateViewWindow failed (0x%x)\n", hr);
317 IShellView_Release(psv);
318 }
319 }
320 else
321 ERR("CreateViewObject failed (0x%x)\n", hr);
322
323 IShellFolder_Release(psf);
324 }
325 else
326 ERR("SI::BindToHandler failed (0x%x)\n", hr);
327
328 return hr;
329}
330
David Hedbergd17d78e2010-08-23 12:55:18 +0200331/**************************************************************************
David Hedberge4e62e72010-08-20 07:45:59 +0200332 * Main window related functions.
333 */
334static LRESULT main_on_wm_create(HWND hWnd, CREATESTRUCTW *crs)
335{
336 ExplorerBrowserImpl *This = crs->lpCreateParams;
337 TRACE("%p\n", This);
338
339 SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LPARAM)This);
340 This->hwnd_main = hWnd;
341
342 return TRUE;
343}
344
David Hedbergd17d78e2010-08-23 12:55:18 +0200345static LRESULT main_on_wm_size(ExplorerBrowserImpl *This)
346{
347 update_layout(This);
348 size_panes(This);
349
350 return TRUE;
351}
352
David Hedberge4e62e72010-08-20 07:45:59 +0200353static LRESULT CALLBACK main_wndproc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
354{
David Hedbergd17d78e2010-08-23 12:55:18 +0200355 ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
356
David Hedberge4e62e72010-08-20 07:45:59 +0200357 switch(uMessage)
358 {
359 case WM_CREATE: return main_on_wm_create(hWnd, (CREATESTRUCTW*)lParam);
David Hedbergd17d78e2010-08-23 12:55:18 +0200360 case WM_SIZE: return main_on_wm_size(This);
David Hedberge4e62e72010-08-20 07:45:59 +0200361 default: return DefWindowProcW(hWnd, uMessage, wParam, lParam);
362 }
363
364 return 0;
365}
366
367/**************************************************************************
David Hedbergd6626962010-08-20 07:45:56 +0200368 * IExplorerBrowser Implementation
369 */
370static HRESULT WINAPI IExplorerBrowser_fnQueryInterface(IExplorerBrowser *iface,
371 REFIID riid, void **ppvObject)
372{
373 ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
374 TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppvObject);
375
376 *ppvObject = NULL;
377 if(IsEqualIID(riid, &IID_IExplorerBrowser) ||
378 IsEqualIID(riid, &IID_IUnknown))
379 {
380 *ppvObject = This;
381 }
David Hedberg1efc5402010-08-20 07:45:58 +0200382 else if(IsEqualIID(riid, &IID_IShellBrowser))
383 {
384 *ppvObject = &This->lpsbVtbl;
385 }
David Hedberg59965f92010-08-25 15:24:34 +0200386 else if(IsEqualIID(riid, &IID_ICommDlgBrowser) ||
387 IsEqualIID(riid, &IID_ICommDlgBrowser2) ||
388 IsEqualIID(riid, &IID_ICommDlgBrowser3))
389 {
390 *ppvObject = &This->lpcdb3Vtbl;
391 }
David Hedbergd6626962010-08-20 07:45:56 +0200392
393 if(*ppvObject)
394 {
395 IUnknown_AddRef((IUnknown*)*ppvObject);
396 return S_OK;
397 }
398
399 return E_NOINTERFACE;
400}
401
402static ULONG WINAPI IExplorerBrowser_fnAddRef(IExplorerBrowser *iface)
403{
404 ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
405 LONG ref = InterlockedIncrement(&This->ref);
406 TRACE("%p - ref %d\n", This, ref);
407
408 return ref;
409}
410
411static ULONG WINAPI IExplorerBrowser_fnRelease(IExplorerBrowser *iface)
412{
413 ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
414 LONG ref = InterlockedDecrement(&This->ref);
415 TRACE("%p - ref %d\n", This, ref);
416
417 if(!ref)
418 {
419 TRACE("Freeing.\n");
420
421 if(!This->destroyed)
422 IExplorerBrowser_Destroy(iface);
423
424 HeapFree(GetProcessHeap(), 0, This);
425 return 0;
426 }
427
428 return ref;
429}
430
431static HRESULT WINAPI IExplorerBrowser_fnInitialize(IExplorerBrowser *iface,
432 HWND hwndParent, const RECT *prc,
433 const FOLDERSETTINGS *pfs)
434{
435 ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
David Hedberge4e62e72010-08-20 07:45:59 +0200436 WNDCLASSW wc;
437 LONG style;
438 static const WCHAR EB_CLASS_NAME[] =
439 {'E','x','p','l','o','r','e','r','B','r','o','w','s','e','r','C','o','n','t','r','o','l',0};
440
David Hedbergd6626962010-08-20 07:45:56 +0200441 TRACE("%p (%p, %p, %p)\n", This, hwndParent, prc, pfs);
442
David Hedberge4e62e72010-08-20 07:45:59 +0200443 if(This->hwnd_main)
444 return E_UNEXPECTED;
445
446 if(!hwndParent)
447 return E_INVALIDARG;
448
449 if( !GetClassInfoW(shell32_hInstance, EB_CLASS_NAME, &wc) )
450 {
451 wc.style = CS_HREDRAW | CS_VREDRAW;
452 wc.lpfnWndProc = main_wndproc;
453 wc.cbClsExtra = 0;
454 wc.cbWndExtra = 0;
455 wc.hInstance = shell32_hInstance;
456 wc.hIcon = 0;
457 wc.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW);
458 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
459 wc.lpszMenuName = NULL;
460 wc.lpszClassName = EB_CLASS_NAME;
461
462 if (!RegisterClassW(&wc)) return E_FAIL;
463 }
464
465 style = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_BORDER;
466 This->hwnd_main = CreateWindowExW(WS_EX_CONTROLPARENT, EB_CLASS_NAME, NULL, style,
467 prc->left, prc->top,
468 prc->right - prc->left, prc->bottom - prc->top,
469 hwndParent, 0, shell32_hInstance, This);
470
471 if(!This->hwnd_main)
472 {
473 ERR("Failed to create the window.\n");
474 return E_FAIL;
475 }
476
David Hedberg270845d2010-08-23 12:55:19 +0200477 This->fs.ViewMode = pfs ? pfs->ViewMode : FVM_DETAILS;
478 This->fs.fFlags = pfs ? (pfs->fFlags | FWF_NOCLIENTEDGE) : FWF_NOCLIENTEDGE;
479
David Hedbergd6626962010-08-20 07:45:56 +0200480 return S_OK;
481}
482
483static HRESULT WINAPI IExplorerBrowser_fnDestroy(IExplorerBrowser *iface)
484{
485 ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
486 TRACE("%p\n", This);
487
David Hedbergd17d78e2010-08-23 12:55:18 +0200488 if(This->psv)
489 {
490 IShellView_DestroyViewWindow(This->psv);
491 IShellView_Release(This->psv);
492 This->psv = NULL;
493 This->hwnd_sv = NULL;
494 }
495
David Hedbergb88c3e22010-08-24 10:56:19 +0200496 events_unadvise_all(This);
David Hedbergfdccbd92010-08-25 15:24:33 +0200497 travellog_remove_all_entries(This);
David Hedbergb88c3e22010-08-24 10:56:19 +0200498
David Hedberg73100ce2010-08-24 10:56:21 +0200499 ILFree(This->current_pidl);
500 This->current_pidl = NULL;
501
David Hedberge4e62e72010-08-20 07:45:59 +0200502 DestroyWindow(This->hwnd_main);
David Hedbergd6626962010-08-20 07:45:56 +0200503 This->destroyed = TRUE;
504
505 return S_OK;
506}
507
508static HRESULT WINAPI IExplorerBrowser_fnSetRect(IExplorerBrowser *iface,
509 HDWP *phdwp, RECT rcBrowser)
510{
511 ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
David Hedbergbee7d4b2010-08-20 07:46:00 +0200512 TRACE("%p (%p, %s)\n", This, phdwp, wine_dbgstr_rect(&rcBrowser));
David Hedbergd6626962010-08-20 07:45:56 +0200513
David Hedbergbee7d4b2010-08-20 07:46:00 +0200514 if(phdwp)
515 {
516 *phdwp = DeferWindowPos(*phdwp, This->hwnd_main, NULL, rcBrowser.left, rcBrowser.top,
517 rcBrowser.right - rcBrowser.left, rcBrowser.bottom - rcBrowser.top,
518 SWP_NOZORDER | SWP_NOACTIVATE);
519 }
520 else
521 {
522 MoveWindow(This->hwnd_main, rcBrowser.left, rcBrowser.top,
523 rcBrowser.right - rcBrowser.left, rcBrowser.bottom - rcBrowser.top, TRUE);
524 }
525
526 return S_OK;
David Hedbergd6626962010-08-20 07:45:56 +0200527}
528
529static HRESULT WINAPI IExplorerBrowser_fnSetPropertyBag(IExplorerBrowser *iface,
530 LPCWSTR pszPropertyBag)
531{
532 ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
533 FIXME("stub, %p (%s)\n", This, debugstr_w(pszPropertyBag));
534
535 return E_NOTIMPL;
536}
537
538static HRESULT WINAPI IExplorerBrowser_fnSetEmptyText(IExplorerBrowser *iface,
539 LPCWSTR pszEmptyText)
540{
541 ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
542 FIXME("stub, %p (%s)\n", This, debugstr_w(pszEmptyText));
543
544 return E_NOTIMPL;
545}
546
547static HRESULT WINAPI IExplorerBrowser_fnSetFolderSettings(IExplorerBrowser *iface,
548 const FOLDERSETTINGS *pfs)
549{
550 ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
David Hedberg270845d2010-08-23 12:55:19 +0200551 TRACE("%p (%p)\n", This, pfs);
David Hedbergd6626962010-08-20 07:45:56 +0200552
David Hedberg270845d2010-08-23 12:55:19 +0200553 if(!pfs)
554 return E_INVALIDARG;
555
556 This->fs.ViewMode = pfs->ViewMode;
557 This->fs.fFlags = pfs->fFlags | FWF_NOCLIENTEDGE;
558
559 /* Change the settings of the current view, if any. */
560 return change_viewmode(This, This->fs.ViewMode);
David Hedbergd6626962010-08-20 07:45:56 +0200561}
562
563static HRESULT WINAPI IExplorerBrowser_fnAdvise(IExplorerBrowser *iface,
564 IExplorerBrowserEvents *psbe,
565 DWORD *pdwCookie)
566{
567 ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
David Hedbergb88c3e22010-08-24 10:56:19 +0200568 event_client *client;
569 TRACE("%p (%p, %p)\n", This, psbe, pdwCookie);
David Hedbergd6626962010-08-20 07:45:56 +0200570
David Hedbergb88c3e22010-08-24 10:56:19 +0200571 client = HeapAlloc(GetProcessHeap(), 0, sizeof(event_client));
572 client->pebe = psbe;
573 client->cookie = ++This->events_next_cookie;
574
575 IExplorerBrowserEvents_AddRef(psbe);
576 *pdwCookie = client->cookie;
577
578 list_add_tail(&This->event_clients, &client->entry);
579
580 return S_OK;
David Hedbergd6626962010-08-20 07:45:56 +0200581}
582
583static HRESULT WINAPI IExplorerBrowser_fnUnadvise(IExplorerBrowser *iface,
584 DWORD dwCookie)
585{
586 ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
David Hedbergb88c3e22010-08-24 10:56:19 +0200587 event_client *client;
588 TRACE("%p (0x%x)\n", This, dwCookie);
David Hedbergd6626962010-08-20 07:45:56 +0200589
David Hedbergb88c3e22010-08-24 10:56:19 +0200590 LIST_FOR_EACH_ENTRY(client, &This->event_clients, event_client, entry)
591 {
592 if(client->cookie == dwCookie)
593 {
594 list_remove(&client->entry);
595 IExplorerBrowserEvents_Release(client->pebe);
596 HeapFree(GetProcessHeap(), 0, client);
597 return S_OK;
598 }
599 }
600
601 return E_INVALIDARG;
David Hedbergd6626962010-08-20 07:45:56 +0200602}
603
604static HRESULT WINAPI IExplorerBrowser_fnSetOptions(IExplorerBrowser *iface,
605 EXPLORER_BROWSER_OPTIONS dwFlag)
606{
607 ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
David Hedberg9c0260f2010-08-23 12:55:17 +0200608 static const EXPLORER_BROWSER_OPTIONS unsupported_options =
609 EBO_SHOWFRAMES | EBO_ALWAYSNAVIGATE | EBO_NOWRAPPERWINDOW | EBO_HTMLSHAREPOINTVIEW;
David Hedbergd6626962010-08-20 07:45:56 +0200610
David Hedberg9c0260f2010-08-23 12:55:17 +0200611 TRACE("%p (0x%x)\n", This, dwFlag);
612
613 if(dwFlag & unsupported_options)
614 FIXME("Flags 0x%08x contains unsupported options.\n", dwFlag);
615
616 This->eb_options = dwFlag;
617
618 return S_OK;
David Hedbergd6626962010-08-20 07:45:56 +0200619}
620
621static HRESULT WINAPI IExplorerBrowser_fnGetOptions(IExplorerBrowser *iface,
622 EXPLORER_BROWSER_OPTIONS *pdwFlag)
623{
624 ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
David Hedberg9c0260f2010-08-23 12:55:17 +0200625 TRACE("%p (%p)\n", This, pdwFlag);
David Hedbergd6626962010-08-20 07:45:56 +0200626
David Hedberg9c0260f2010-08-23 12:55:17 +0200627 *pdwFlag = This->eb_options;
628
629 return S_OK;
David Hedbergd6626962010-08-20 07:45:56 +0200630}
631
632static HRESULT WINAPI IExplorerBrowser_fnBrowseToIDList(IExplorerBrowser *iface,
633 PCUIDLIST_RELATIVE pidl,
634 UINT uFlags)
635{
636 ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
David Hedberg73100ce2010-08-24 10:56:21 +0200637 LPITEMIDLIST absolute_pidl = NULL;
638 HRESULT hr;
David Hedbergfdccbd92010-08-25 15:24:33 +0200639 static const UINT unsupported_browse_flags =
640 SBSP_NEWBROWSER | EBF_SELECTFROMDATAOBJECT | EBF_NODROPTARGET;
David Hedberg73100ce2010-08-24 10:56:21 +0200641 TRACE("%p (%p, 0x%x)\n", This, pidl, uFlags);
David Hedbergd6626962010-08-20 07:45:56 +0200642
David Hedberg73100ce2010-08-24 10:56:21 +0200643 if(!This->hwnd_main)
644 return E_FAIL;
645
646 if(This->destroyed)
647 return HRESULT_FROM_WIN32(ERROR_BUSY);
648
649 if(This->current_pidl && (This->eb_options & EBO_NAVIGATEONCE))
650 return E_FAIL;
651
652 if(uFlags & SBSP_EXPLOREMODE)
653 return E_INVALIDARG;
654
655 if(uFlags & unsupported_browse_flags)
656 FIXME("Argument 0x%x contains unsupported flags.\n", uFlags);
657
David Hedbergfdccbd92010-08-25 15:24:33 +0200658 if(uFlags & SBSP_NAVIGATEBACK)
659 {
660 TRACE("SBSP_NAVIGATEBACK\n");
661 absolute_pidl = ILClone(travellog_go_back(This));
662 if(!absolute_pidl && !This->current_pidl)
663 return E_FAIL;
664 else if(!absolute_pidl)
665 return S_OK;
666
667 }
668 else if(uFlags & SBSP_NAVIGATEFORWARD)
669 {
670 TRACE("SBSP_NAVIGATEFORWARD\n");
671 absolute_pidl = ILClone(travellog_go_forward(This));
672 if(!absolute_pidl && !This->current_pidl)
673 return E_FAIL;
674 else if(!absolute_pidl)
675 return S_OK;
676
677 }
678 else if(uFlags & SBSP_PARENT)
David Hedberg73100ce2010-08-24 10:56:21 +0200679 {
680 if(This->current_pidl)
681 {
682 if(_ILIsPidlSimple(This->current_pidl))
683 {
684 absolute_pidl = _ILCreateDesktop();
685 }
686 else
687 {
688 absolute_pidl = ILClone(This->current_pidl);
689 ILRemoveLastID(absolute_pidl);
690 }
691 }
692 if(!absolute_pidl)
693 {
694 ERR("Failed to get parent pidl.\n");
695 return E_FAIL;
696 }
697
698 }
699 else if(uFlags & SBSP_RELATIVE)
700 {
701 /* SBSP_RELATIVE has precedence over SBSP_ABSOLUTE */
702 TRACE("SBSP_RELATIVE\n");
703 if(This->current_pidl)
704 {
705 absolute_pidl = ILCombine(This->current_pidl, pidl);
706 }
707 if(!absolute_pidl)
708 {
709 ERR("Failed to get absolute pidl.\n");
710 return E_FAIL;
711 }
712 }
713 else
714 {
715 TRACE("SBSP_ABSOLUTE\n");
716 absolute_pidl = ILClone(pidl);
717 if(!absolute_pidl && !This->current_pidl)
718 return E_INVALIDARG;
719 else if(!absolute_pidl)
720 return S_OK;
721 }
722
723 /* TODO: Asynchronous browsing. Return S_OK here and finish in
724 * another thread. */
725
726 hr = events_NavigationPending(This, absolute_pidl);
727 if(FAILED(hr))
728 {
729 TRACE("Browsing aborted.\n");
730 ILFree(absolute_pidl);
731 return E_FAIL;
732 }
733
734 /* Only browse if the new pidl differs from the old */
735 if(!ILIsEqual(This->current_pidl, absolute_pidl))
736 {
737 IShellItem *psi;
738 hr = SHCreateItemFromIDList(absolute_pidl, &IID_IShellItem, (void**)&psi);
739 if(SUCCEEDED(hr))
740 {
741 hr = create_new_shellview(This, psi);
742 if(FAILED(hr))
743 {
744 events_NavigationFailed(This, absolute_pidl);
745 ILFree(absolute_pidl);
746 IShellItem_Release(psi);
747 return E_FAIL;
748 }
David Hedbergfdccbd92010-08-25 15:24:33 +0200749
750 /* Add to travellog */
751 if( !(This->eb_options & EBO_NOTRAVELLOG) &&
752 !(uFlags & (SBSP_NAVIGATEFORWARD|SBSP_NAVIGATEBACK)) )
753 {
754 travellog_add_entry(This, absolute_pidl);
755 }
756
David Hedberg73100ce2010-08-24 10:56:21 +0200757 IShellItem_Release(psi);
758 }
759 }
760
761 events_NavigationComplete(This, absolute_pidl);
762 ILFree(This->current_pidl);
763 This->current_pidl = absolute_pidl;
764
765 return S_OK;
David Hedbergd6626962010-08-20 07:45:56 +0200766}
767
768static HRESULT WINAPI IExplorerBrowser_fnBrowseToObject(IExplorerBrowser *iface,
769 IUnknown *punk, UINT uFlags)
770{
771 ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
David Hedberg00889f12010-08-25 15:24:32 +0200772 LPITEMIDLIST pidl;
773 HRESULT hr;
774 TRACE("%p (%p, 0x%x)\n", This, punk, uFlags);
David Hedbergd6626962010-08-20 07:45:56 +0200775
David Hedberg00889f12010-08-25 15:24:32 +0200776 if(!punk)
777 return IExplorerBrowser_fnBrowseToIDList(iface, NULL, uFlags);
778
779 hr = SHGetIDListFromObject(punk, &pidl);
780 if(SUCCEEDED(hr))
781 {
782 hr = IExplorerBrowser_BrowseToIDList(iface, pidl, uFlags);
783 ILFree(pidl);
784 }
785
786 return hr;
David Hedbergd6626962010-08-20 07:45:56 +0200787}
788
789static HRESULT WINAPI IExplorerBrowser_fnFillFromObject(IExplorerBrowser *iface,
790 IUnknown *punk,
791 EXPLORER_BROWSER_FILL_FLAGS dwFlags)
792{
793 ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
794 FIXME("stub, %p (%p, 0x%x)\n", This, punk, dwFlags);
795
796 return E_NOTIMPL;
797}
798
799static HRESULT WINAPI IExplorerBrowser_fnRemoveAll(IExplorerBrowser *iface)
800{
801 ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
802 FIXME("stub, %p\n", This);
803
804 return E_NOTIMPL;
805}
806
807static HRESULT WINAPI IExplorerBrowser_fnGetCurrentView(IExplorerBrowser *iface,
808 REFIID riid, void **ppv)
809{
810 ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
David Hedbergd17d78e2010-08-23 12:55:18 +0200811 TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppv);
David Hedbergd6626962010-08-20 07:45:56 +0200812
David Hedbergd17d78e2010-08-23 12:55:18 +0200813 if(!This->psv)
814 return E_FAIL;
815
816 return IShellView_QueryInterface(This->psv, riid, ppv);
David Hedbergd6626962010-08-20 07:45:56 +0200817}
818
819static const IExplorerBrowserVtbl vt_IExplorerBrowser =
820{
821 IExplorerBrowser_fnQueryInterface,
822 IExplorerBrowser_fnAddRef,
823 IExplorerBrowser_fnRelease,
824 IExplorerBrowser_fnInitialize,
825 IExplorerBrowser_fnDestroy,
826 IExplorerBrowser_fnSetRect,
827 IExplorerBrowser_fnSetPropertyBag,
828 IExplorerBrowser_fnSetEmptyText,
829 IExplorerBrowser_fnSetFolderSettings,
830 IExplorerBrowser_fnAdvise,
831 IExplorerBrowser_fnUnadvise,
832 IExplorerBrowser_fnSetOptions,
833 IExplorerBrowser_fnGetOptions,
834 IExplorerBrowser_fnBrowseToIDList,
835 IExplorerBrowser_fnBrowseToObject,
836 IExplorerBrowser_fnFillFromObject,
837 IExplorerBrowser_fnRemoveAll,
838 IExplorerBrowser_fnGetCurrentView
839};
840
David Hedberg1efc5402010-08-20 07:45:58 +0200841/**************************************************************************
842 * IShellBrowser Implementation
843 */
844
845static inline ExplorerBrowserImpl *impl_from_IShellBrowser(IShellBrowser *iface)
846{
847 return (ExplorerBrowserImpl *)((char*)iface - FIELD_OFFSET(ExplorerBrowserImpl, lpsbVtbl));
848}
849
850static HRESULT WINAPI IShellBrowser_fnQueryInterface(IShellBrowser *iface,
851 REFIID riid, void **ppvObject)
852{
853 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
854 TRACE("%p\n", This);
855 return IUnknown_QueryInterface((IUnknown*) This, riid, ppvObject);
856}
857
858static ULONG WINAPI IShellBrowser_fnAddRef(IShellBrowser *iface)
859{
860 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
861 TRACE("%p\n", This);
862 return IUnknown_AddRef((IUnknown*) This);
863}
864
865static ULONG WINAPI IShellBrowser_fnRelease(IShellBrowser *iface)
866{
867 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
868 TRACE("%p\n", This);
869 return IUnknown_Release((IUnknown*) This);
870}
871
872static HRESULT WINAPI IShellBrowser_fnGetWindow(IShellBrowser *iface, HWND *phwnd)
873{
874 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
David Hedberge4e62e72010-08-20 07:45:59 +0200875 TRACE("%p (%p)\n", This, phwnd);
David Hedberg1efc5402010-08-20 07:45:58 +0200876
David Hedberge4e62e72010-08-20 07:45:59 +0200877 if(!This->hwnd_main)
878 return E_FAIL;
879
880 *phwnd = This->hwnd_main;
881 return S_OK;
David Hedberg1efc5402010-08-20 07:45:58 +0200882}
883
884static HRESULT WINAPI IShellBrowser_fnContextSensitiveHelp(IShellBrowser *iface,
885 BOOL fEnterMode)
886{
887 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
888 FIXME("stub, %p (%d)\n", This, fEnterMode);
889
890 return E_NOTIMPL;
891}
892
893static HRESULT WINAPI IShellBrowser_fnInsertMenusSB(IShellBrowser *iface,
894 HMENU hmenuShared,
895 LPOLEMENUGROUPWIDTHS lpMenuWidths)
896{
897 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
898 TRACE("%p (%p, %p)\n", This, hmenuShared, lpMenuWidths);
899
900 /* Not implemented. */
901 return E_NOTIMPL;
902}
903
904static HRESULT WINAPI IShellBrowser_fnSetMenuSB(IShellBrowser *iface,
905 HMENU hmenuShared,
906 HOLEMENU holemenuReserved,
907 HWND hwndActiveObject)
908{
909 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
910 TRACE("%p (%p, %p, %p)\n", This, hmenuShared, holemenuReserved, hwndActiveObject);
911
912 /* Not implemented. */
913 return E_NOTIMPL;
914}
915
916static HRESULT WINAPI IShellBrowser_fnRemoveMenusSB(IShellBrowser *iface,
917 HMENU hmenuShared)
918{
919 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
920 TRACE("%p (%p)\n", This, hmenuShared);
921
922 /* Not implemented. */
923 return E_NOTIMPL;
924}
925
926static HRESULT WINAPI IShellBrowser_fnSetStatusTextSB(IShellBrowser *iface,
927 LPCOLESTR pszStatusText)
928{
929 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
930 FIXME("stub, %p (%s)\n", This, debugstr_w(pszStatusText));
931
932 return E_NOTIMPL;
933}
934
935static HRESULT WINAPI IShellBrowser_fnEnableModelessSB(IShellBrowser *iface,
936 BOOL fEnable)
937{
938 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
939 FIXME("stub, %p (%d)\n", This, fEnable);
940
941 return E_NOTIMPL;
942}
943
944static HRESULT WINAPI IShellBrowser_fnTranslateAcceleratorSB(IShellBrowser *iface,
945 MSG *pmsg, WORD wID)
946{
947 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
948 FIXME("stub, %p (%p, 0x%x)\n", This, pmsg, wID);
949
950 return E_NOTIMPL;
951}
952
953static HRESULT WINAPI IShellBrowser_fnBrowseObject(IShellBrowser *iface,
954 LPCITEMIDLIST pidl, UINT wFlags)
955{
956 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
David Hedberg73100ce2010-08-24 10:56:21 +0200957 TRACE("%p (%p, %x)\n", This, pidl, wFlags);
David Hedberg1efc5402010-08-20 07:45:58 +0200958
David Hedberg73100ce2010-08-24 10:56:21 +0200959 return IExplorerBrowser_fnBrowseToIDList((IExplorerBrowser*)This, pidl, wFlags);
David Hedberg1efc5402010-08-20 07:45:58 +0200960}
961
962static HRESULT WINAPI IShellBrowser_fnGetViewStateStream(IShellBrowser *iface,
963 DWORD grfMode,
964 IStream **ppStrm)
965{
966 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
967 FIXME("stub, %p (0x%x, %p)\n", This, grfMode, ppStrm);
968
969 *ppStrm = NULL;
970 return E_FAIL;
971}
972
973static HRESULT WINAPI IShellBrowser_fnGetControlWindow(IShellBrowser *iface,
974 UINT id, HWND *phwnd)
975{
976 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
977 TRACE("%p (%d, %p)\n", This, id, phwnd);
978
979 /* Not implemented. */
980 return E_NOTIMPL;
981}
982
983static HRESULT WINAPI IShellBrowser_fnSendControlMsg(IShellBrowser *iface,
984 UINT id, UINT uMsg,
985 WPARAM wParam, LPARAM lParam,
986 LRESULT *pret)
987{
988 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
989 FIXME("stub, %p (%d, %d, %lx, %lx, %p)\n", This, id, uMsg, wParam, lParam, pret);
990
991 return E_NOTIMPL;
992}
993
994static HRESULT WINAPI IShellBrowser_fnQueryActiveShellView(IShellBrowser *iface,
995 IShellView **ppshv)
996{
997 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
David Hedbergd17d78e2010-08-23 12:55:18 +0200998 TRACE("%p (%p)\n", This, ppshv);
David Hedberg1efc5402010-08-20 07:45:58 +0200999
David Hedbergd17d78e2010-08-23 12:55:18 +02001000 if(!This->psv)
1001 return E_FAIL;
1002
1003 *ppshv = This->psv;
1004 IShellView_AddRef(This->psv);
1005
1006 return S_OK;
David Hedberg1efc5402010-08-20 07:45:58 +02001007}
1008
1009static HRESULT WINAPI IShellBrowser_fnOnViewWindowActive(IShellBrowser *iface,
1010 IShellView *pshv)
1011{
1012 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1013 FIXME("stub, %p (%p)\n", This, pshv);
1014
1015 return E_NOTIMPL;
1016}
1017
1018static HRESULT WINAPI IShellBrowser_fnSetToolbarItems(IShellBrowser *iface,
1019 LPTBBUTTONSB lpButtons,
1020 UINT nButtons, UINT uFlags)
1021{
1022 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1023 FIXME("stub, %p (%p, %d, 0x%x)\n", This, lpButtons, nButtons, uFlags);
1024
1025 return E_NOTIMPL;
1026}
1027
1028static const IShellBrowserVtbl vt_IShellBrowser = {
1029 IShellBrowser_fnQueryInterface,
1030 IShellBrowser_fnAddRef,
1031 IShellBrowser_fnRelease,
1032 IShellBrowser_fnGetWindow,
1033 IShellBrowser_fnContextSensitiveHelp,
1034 IShellBrowser_fnInsertMenusSB,
1035 IShellBrowser_fnSetMenuSB,
1036 IShellBrowser_fnRemoveMenusSB,
1037 IShellBrowser_fnSetStatusTextSB,
1038 IShellBrowser_fnEnableModelessSB,
1039 IShellBrowser_fnTranslateAcceleratorSB,
1040 IShellBrowser_fnBrowseObject,
1041 IShellBrowser_fnGetViewStateStream,
1042 IShellBrowser_fnGetControlWindow,
1043 IShellBrowser_fnSendControlMsg,
1044 IShellBrowser_fnQueryActiveShellView,
1045 IShellBrowser_fnOnViewWindowActive,
1046 IShellBrowser_fnSetToolbarItems
1047};
1048
David Hedberg59965f92010-08-25 15:24:34 +02001049/**************************************************************************
1050 * ICommDlgBrowser3 Implementation
1051 */
1052
1053static inline ExplorerBrowserImpl *impl_from_ICommDlgBrowser3(ICommDlgBrowser3 *iface)
1054{
1055 return (ExplorerBrowserImpl *)((char*)iface - FIELD_OFFSET(ExplorerBrowserImpl, lpcdb3Vtbl));
1056}
1057
1058static HRESULT WINAPI ICommDlgBrowser3_fnQueryInterface(ICommDlgBrowser3 *iface,
1059 REFIID riid,
1060 void **ppvObject)
1061{
1062 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1063 TRACE("%p\n", This);
1064 return IUnknown_QueryInterface((IUnknown*) This, riid, ppvObject);
1065}
1066
1067static ULONG WINAPI ICommDlgBrowser3_fnAddRef(ICommDlgBrowser3 *iface)
1068{
1069 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1070 TRACE("%p\n", This);
1071 return IUnknown_AddRef((IUnknown*) This);
1072}
1073
1074static ULONG WINAPI ICommDlgBrowser3_fnRelease(ICommDlgBrowser3 *iface)
1075{
1076 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1077 TRACE("%p\n", This);
1078 return IUnknown_Release((IUnknown*) This);
1079}
1080
1081static HRESULT WINAPI ICommDlgBrowser3_fnOnDefaultCommand(ICommDlgBrowser3 *iface,
1082 IShellView *shv)
1083{
1084 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1085 FIXME("stub, %p (%p)\n", This, shv);
1086 return E_NOTIMPL;
1087}
1088static HRESULT WINAPI ICommDlgBrowser3_fnOnStateChange(ICommDlgBrowser3 *iface,
1089 IShellView *shv, ULONG uChange)
1090{
1091 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1092 FIXME("stub, %p (%p, %d)\n", This, shv, uChange);
1093 return E_NOTIMPL;
1094}
1095static HRESULT WINAPI ICommDlgBrowser3_fnIncludeObject(ICommDlgBrowser3 *iface,
1096 IShellView *pshv, LPCITEMIDLIST pidl)
1097{
1098 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1099 FIXME("stub, %p (%p, %p)\n", This, pshv, pidl);
1100 return S_OK;
1101}
1102
1103static HRESULT WINAPI ICommDlgBrowser3_fnNotify(ICommDlgBrowser3 *iface,
1104 IShellView *pshv,
1105 DWORD dwNotifyType)
1106{
1107 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1108 FIXME("stub, %p (%p, 0x%x)\n", This, pshv, dwNotifyType);
1109 return S_OK;
1110}
1111
1112static HRESULT WINAPI ICommDlgBrowser3_fnGetDefaultMenuText(ICommDlgBrowser3 *iface,
1113 IShellView *pshv,
1114 LPWSTR pszText, int cchMax)
1115{
1116 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1117 FIXME("stub, %p (%p, %s, %d)\n", This, pshv, debugstr_w(pszText), cchMax);
1118 return S_OK;
1119}
1120
1121static HRESULT WINAPI ICommDlgBrowser3_fnGetViewFlags(ICommDlgBrowser3 *iface,
1122 DWORD *pdwFlags)
1123{
1124 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1125 FIXME("stub, %p (%p)\n", This, pdwFlags);
1126 return S_OK;
1127}
1128
1129static HRESULT WINAPI ICommDlgBrowser3_fnOnColumnClicked(ICommDlgBrowser3 *iface,
1130 IShellView *pshv, int iColumn)
1131{
1132 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1133 FIXME("stub, %p (%p, %d)\n", This, pshv, iColumn);
1134 return S_OK;
1135}
1136
1137static HRESULT WINAPI ICommDlgBrowser3_fnGetCurrentFilter(ICommDlgBrowser3 *iface,
1138 LPWSTR pszFileSpec,
1139 int cchFileSpec)
1140{
1141 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1142 FIXME("stub, %p (%s, %d)\n", This, debugstr_w(pszFileSpec), cchFileSpec);
1143 return S_OK;
1144}
1145
1146static HRESULT WINAPI ICommDlgBrowser3_fnOnPreviewCreated(ICommDlgBrowser3 *iface,
1147 IShellView *pshv)
1148{
1149 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1150 FIXME("stub, %p (%p)\n", This, pshv);
1151 return S_OK;
1152}
1153
1154static const ICommDlgBrowser3Vtbl vt_ICommDlgBrowser3 = {
1155 ICommDlgBrowser3_fnQueryInterface,
1156 ICommDlgBrowser3_fnAddRef,
1157 ICommDlgBrowser3_fnRelease,
1158 ICommDlgBrowser3_fnOnDefaultCommand,
1159 ICommDlgBrowser3_fnOnStateChange,
1160 ICommDlgBrowser3_fnIncludeObject,
1161 ICommDlgBrowser3_fnNotify,
1162 ICommDlgBrowser3_fnGetDefaultMenuText,
1163 ICommDlgBrowser3_fnGetViewFlags,
1164 ICommDlgBrowser3_fnOnColumnClicked,
1165 ICommDlgBrowser3_fnGetCurrentFilter,
1166 ICommDlgBrowser3_fnOnPreviewCreated
1167};
1168
David Hedbergd6626962010-08-20 07:45:56 +02001169HRESULT WINAPI ExplorerBrowser_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv)
1170{
1171 ExplorerBrowserImpl *eb;
1172 HRESULT ret;
1173
1174 TRACE("%p %s %p\n", pUnkOuter, shdebugstr_guid (riid), ppv);
1175
1176 if(!ppv)
1177 return E_POINTER;
1178 if(pUnkOuter)
1179 return CLASS_E_NOAGGREGATION;
1180
1181 eb = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ExplorerBrowserImpl));
1182 eb->ref = 1;
1183 eb->lpVtbl = &vt_IExplorerBrowser;
David Hedberg1efc5402010-08-20 07:45:58 +02001184 eb->lpsbVtbl = &vt_IShellBrowser;
David Hedberg59965f92010-08-25 15:24:34 +02001185 eb->lpcdb3Vtbl = &vt_ICommDlgBrowser3;
David Hedbergd6626962010-08-20 07:45:56 +02001186
David Hedbergb88c3e22010-08-24 10:56:19 +02001187 list_init(&eb->event_clients);
David Hedbergfdccbd92010-08-25 15:24:33 +02001188 list_init(&eb->travellog);
David Hedbergb88c3e22010-08-24 10:56:19 +02001189
David Hedbergd6626962010-08-20 07:45:56 +02001190 ret = IExplorerBrowser_QueryInterface((IExplorerBrowser*)eb, riid, ppv);
1191 IExplorerBrowser_Release((IExplorerBrowser*)eb);
1192
1193 TRACE("--(%p)\n", ppv);
1194 return ret;
1195}