2 * ExplorerBrowser Control implementation.
4 * Copyright 2010 David Hedberg
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.
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.
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
24 #define NONAMELESSUNION
25 #define NONAMELESSSTRUCT
31 #include "wine/list.h"
32 #include "wine/debug.h"
35 #include "shell32_main.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
40 typedef struct _event_client
{
42 IExplorerBrowserEvents
*pebe
;
46 typedef struct _travellog_entry
{
51 typedef struct _ExplorerBrowserImpl
{
52 const IExplorerBrowserVtbl
*lpVtbl
;
53 const IShellBrowserVtbl
*lpsbVtbl
;
54 const ICommDlgBrowser3Vtbl
*lpcdb3Vtbl
;
55 const IObjectWithSiteVtbl
*lpowsVtbl
;
62 EXPLORER_BROWSER_OPTIONS eb_options
;
65 struct list event_clients
;
66 DWORD events_next_cookie
;
67 struct list travellog
;
68 travellog_entry
*travellog_cursor
;
73 LPITEMIDLIST current_pidl
;
76 } ExplorerBrowserImpl
;
78 /**************************************************************************
81 static void events_unadvise_all(ExplorerBrowserImpl
*This
)
83 event_client
*client
, *curs
;
86 LIST_FOR_EACH_ENTRY_SAFE(client
, curs
, &This
->event_clients
, event_client
, entry
)
88 TRACE("Removing %p\n", client
);
89 list_remove(&client
->entry
);
90 IExplorerBrowserEvents_Release(client
->pebe
);
91 HeapFree(GetProcessHeap(), 0, client
);
95 static HRESULT
events_NavigationPending(ExplorerBrowserImpl
*This
, PCIDLIST_ABSOLUTE pidl
)
102 LIST_FOR_EACH_ENTRY(cursor
, &This
->event_clients
, event_client
, entry
)
104 TRACE("Notifying %p\n", cursor
);
105 hres
= IExplorerBrowserEvents_OnNavigationPending(cursor
->pebe
, pidl
);
107 /* If this failed for any reason, the browsing is supposed to be aborted. */
115 static void events_NavigationComplete(ExplorerBrowserImpl
*This
, PCIDLIST_ABSOLUTE pidl
)
117 event_client
*cursor
;
121 LIST_FOR_EACH_ENTRY(cursor
, &This
->event_clients
, event_client
, entry
)
123 TRACE("Notifying %p\n", cursor
);
124 IExplorerBrowserEvents_OnNavigationComplete(cursor
->pebe
, pidl
);
128 static void events_NavigationFailed(ExplorerBrowserImpl
*This
, PCIDLIST_ABSOLUTE pidl
)
130 event_client
*cursor
;
134 LIST_FOR_EACH_ENTRY(cursor
, &This
->event_clients
, event_client
, entry
)
136 TRACE("Notifying %p\n", cursor
);
137 IExplorerBrowserEvents_OnNavigationFailed(cursor
->pebe
, pidl
);
141 static void events_ViewCreated(ExplorerBrowserImpl
*This
, IShellView
*psv
)
143 event_client
*cursor
;
147 LIST_FOR_EACH_ENTRY(cursor
, &This
->event_clients
, event_client
, entry
)
149 TRACE("Notifying %p\n", cursor
);
150 IExplorerBrowserEvents_OnViewCreated(cursor
->pebe
, psv
);
154 /**************************************************************************
155 * Travellog functions.
157 static void travellog_remove_entry(ExplorerBrowserImpl
*This
, travellog_entry
*entry
)
159 TRACE("Removing %p\n", entry
);
161 list_remove(&entry
->entry
);
162 HeapFree(GetProcessHeap(), 0, entry
);
163 This
->travellog_count
--;
166 static void travellog_remove_all_entries(ExplorerBrowserImpl
*This
)
168 travellog_entry
*cursor
, *cursor2
;
171 LIST_FOR_EACH_ENTRY_SAFE(cursor
, cursor2
, &This
->travellog
, travellog_entry
, entry
)
172 travellog_remove_entry(This
, cursor
);
174 This
->travellog_cursor
= NULL
;
177 static void travellog_add_entry(ExplorerBrowserImpl
*This
, LPITEMIDLIST pidl
)
179 travellog_entry
*new, *cursor
, *cursor2
;
180 TRACE("%p (old count %d)\n", pidl
, This
->travellog_count
);
182 /* Replace the old tail, if any, with the new entry */
183 if(This
->travellog_cursor
)
185 LIST_FOR_EACH_ENTRY_SAFE_REV(cursor
, cursor2
, &This
->travellog
, travellog_entry
, entry
)
187 if(cursor
== This
->travellog_cursor
)
189 travellog_remove_entry(This
, cursor
);
193 /* Create and add the new entry */
194 new = HeapAlloc(GetProcessHeap(), 0, sizeof(travellog_entry
));
195 new->pidl
= ILClone(pidl
);
196 list_add_tail(&This
->travellog
, &new->entry
);
197 This
->travellog_cursor
= new;
198 This
->travellog_count
++;
200 /* Remove the first few entries if the size limit is reached. */
201 if(This
->travellog_count
> 200)
204 LIST_FOR_EACH_ENTRY_SAFE(cursor
, cursor2
, &This
->travellog
, travellog_entry
, entry
)
208 travellog_remove_entry(This
, cursor
);
213 static LPCITEMIDLIST
travellog_go_back(ExplorerBrowserImpl
*This
)
215 travellog_entry
*prev
;
216 TRACE("%p, %p\n", This
, This
->travellog_cursor
);
218 if(!This
->travellog_cursor
)
221 prev
= LIST_ENTRY(list_prev(&This
->travellog
, &This
->travellog_cursor
->entry
),
222 travellog_entry
, entry
);
226 This
->travellog_cursor
= prev
;
230 static LPCITEMIDLIST
travellog_go_forward(ExplorerBrowserImpl
*This
)
232 travellog_entry
*next
;
233 TRACE("%p, %p\n", This
, This
->travellog_cursor
);
235 if(!This
->travellog_cursor
)
238 next
= LIST_ENTRY(list_next(&This
->travellog
, &This
->travellog_cursor
->entry
),
239 travellog_entry
, entry
);
243 This
->travellog_cursor
= next
;
247 /**************************************************************************
250 static void update_layout(ExplorerBrowserImpl
*This
)
255 GetClientRect(This
->hwnd_main
, &rc
);
256 CopyRect(&This
->sv_rc
, &rc
);
259 static void size_panes(ExplorerBrowserImpl
*This
)
261 MoveWindow(This
->hwnd_sv
,
262 This
->sv_rc
.left
, This
->sv_rc
.top
,
263 This
->sv_rc
.right
- This
->sv_rc
.left
, This
->sv_rc
.bottom
- This
->sv_rc
.top
,
267 static HRESULT
change_viewmode(ExplorerBrowserImpl
*This
, UINT viewmode
)
275 hr
= IShellView_QueryInterface(This
->psv
, &IID_IFolderView
, (void*)&pfv
);
278 hr
= IFolderView_SetCurrentViewMode(pfv
, This
->fs
.ViewMode
);
279 IFolderView_Release(pfv
);
285 static HRESULT
create_new_shellview(ExplorerBrowserImpl
*This
, IShellItem
*psi
)
287 IShellBrowser
*psb
= (IShellBrowser
*)&This
->lpsbVtbl
;
293 TRACE("%p, %p\n", This
, psi
);
295 hr
= IShellItem_BindToHandler(psi
, NULL
, &BHID_SFObject
, &IID_IShellFolder
, (void**)&psf
);
298 hr
= IShellFolder_CreateViewObject(psf
, This
->hwnd_main
, &IID_IShellView
, (void**)&psv
);
303 IShellView_DestroyViewWindow(This
->psv
);
304 This
->hwnd_sv
= NULL
;
307 hr
= IShellView_CreateViewWindow(psv
, This
->psv
, &This
->fs
, psb
, &This
->sv_rc
, &hwnd_new
);
310 /* Replace the old shellview */
311 if(This
->psv
) IShellView_Release(This
->psv
);
314 This
->hwnd_sv
= hwnd_new
;
315 events_ViewCreated(This
, psv
);
319 ERR("CreateViewWindow failed (0x%x)\n", hr
);
320 IShellView_Release(psv
);
324 ERR("CreateViewObject failed (0x%x)\n", hr
);
326 IShellFolder_Release(psf
);
329 ERR("SI::BindToHandler failed (0x%x)\n", hr
);
334 static void get_interfaces_from_site(ExplorerBrowserImpl
*This
)
336 IServiceProvider
*psp
;
339 /* Calling this with This->punk_site set to NULL should properly
340 * release any previously fetched interfaces.
345 hr
= IUnknown_QueryInterface(This
->punk_site
, &IID_IServiceProvider
, (void**)&psp
);
348 FIXME("Not requesting any interfaces.\n");
349 IServiceProvider_Release(psp
);
352 ERR("Failed to get IServiceProvider from site.\n");
356 /**************************************************************************
357 * Main window related functions.
359 static LRESULT
main_on_wm_create(HWND hWnd
, CREATESTRUCTW
*crs
)
361 ExplorerBrowserImpl
*This
= crs
->lpCreateParams
;
364 SetWindowLongPtrW(hWnd
, GWLP_USERDATA
, (LPARAM
)This
);
365 This
->hwnd_main
= hWnd
;
370 static LRESULT
main_on_wm_size(ExplorerBrowserImpl
*This
)
378 static LRESULT CALLBACK
main_wndproc(HWND hWnd
, UINT uMessage
, WPARAM wParam
, LPARAM lParam
)
380 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)GetWindowLongPtrW(hWnd
, GWLP_USERDATA
);
384 case WM_CREATE
: return main_on_wm_create(hWnd
, (CREATESTRUCTW
*)lParam
);
385 case WM_SIZE
: return main_on_wm_size(This
);
386 default: return DefWindowProcW(hWnd
, uMessage
, wParam
, lParam
);
392 /**************************************************************************
393 * IExplorerBrowser Implementation
395 static HRESULT WINAPI
IExplorerBrowser_fnQueryInterface(IExplorerBrowser
*iface
,
396 REFIID riid
, void **ppvObject
)
398 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
399 TRACE("%p (%s, %p)\n", This
, shdebugstr_guid(riid
), ppvObject
);
402 if(IsEqualIID(riid
, &IID_IExplorerBrowser
) ||
403 IsEqualIID(riid
, &IID_IUnknown
))
407 else if(IsEqualIID(riid
, &IID_IShellBrowser
))
409 *ppvObject
= &This
->lpsbVtbl
;
411 else if(IsEqualIID(riid
, &IID_ICommDlgBrowser
) ||
412 IsEqualIID(riid
, &IID_ICommDlgBrowser2
) ||
413 IsEqualIID(riid
, &IID_ICommDlgBrowser3
))
415 *ppvObject
= &This
->lpcdb3Vtbl
;
417 else if(IsEqualIID(riid
, &IID_IObjectWithSite
))
419 *ppvObject
= &This
->lpowsVtbl
;
424 IUnknown_AddRef((IUnknown
*)*ppvObject
);
428 return E_NOINTERFACE
;
431 static ULONG WINAPI
IExplorerBrowser_fnAddRef(IExplorerBrowser
*iface
)
433 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
434 LONG ref
= InterlockedIncrement(&This
->ref
);
435 TRACE("%p - ref %d\n", This
, ref
);
440 static ULONG WINAPI
IExplorerBrowser_fnRelease(IExplorerBrowser
*iface
)
442 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
443 LONG ref
= InterlockedDecrement(&This
->ref
);
444 TRACE("%p - ref %d\n", This
, ref
);
451 IExplorerBrowser_Destroy(iface
);
453 IObjectWithSite_SetSite((IObjectWithSite
*)&This
->lpowsVtbl
, NULL
);
455 HeapFree(GetProcessHeap(), 0, This
);
462 static HRESULT WINAPI
IExplorerBrowser_fnInitialize(IExplorerBrowser
*iface
,
463 HWND hwndParent
, const RECT
*prc
,
464 const FOLDERSETTINGS
*pfs
)
466 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
469 static const WCHAR EB_CLASS_NAME
[] =
470 {'E','x','p','l','o','r','e','r','B','r','o','w','s','e','r','C','o','n','t','r','o','l',0};
472 TRACE("%p (%p, %p, %p)\n", This
, hwndParent
, prc
, pfs
);
480 if( !GetClassInfoW(shell32_hInstance
, EB_CLASS_NAME
, &wc
) )
482 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
483 wc
.lpfnWndProc
= main_wndproc
;
486 wc
.hInstance
= shell32_hInstance
;
488 wc
.hCursor
= LoadCursorW(0, (LPWSTR
)IDC_ARROW
);
489 wc
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1);
490 wc
.lpszMenuName
= NULL
;
491 wc
.lpszClassName
= EB_CLASS_NAME
;
493 if (!RegisterClassW(&wc
)) return E_FAIL
;
496 style
= WS_CHILD
| WS_VISIBLE
| WS_CLIPSIBLINGS
| WS_BORDER
;
497 This
->hwnd_main
= CreateWindowExW(WS_EX_CONTROLPARENT
, EB_CLASS_NAME
, NULL
, style
,
499 prc
->right
- prc
->left
, prc
->bottom
- prc
->top
,
500 hwndParent
, 0, shell32_hInstance
, This
);
504 ERR("Failed to create the window.\n");
508 This
->fs
.ViewMode
= pfs
? pfs
->ViewMode
: FVM_DETAILS
;
509 This
->fs
.fFlags
= pfs
? (pfs
->fFlags
| FWF_NOCLIENTEDGE
) : FWF_NOCLIENTEDGE
;
514 static HRESULT WINAPI
IExplorerBrowser_fnDestroy(IExplorerBrowser
*iface
)
516 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
521 IShellView_DestroyViewWindow(This
->psv
);
522 IShellView_Release(This
->psv
);
524 This
->hwnd_sv
= NULL
;
527 events_unadvise_all(This
);
528 travellog_remove_all_entries(This
);
530 ILFree(This
->current_pidl
);
531 This
->current_pidl
= NULL
;
533 DestroyWindow(This
->hwnd_main
);
534 This
->destroyed
= TRUE
;
539 static HRESULT WINAPI
IExplorerBrowser_fnSetRect(IExplorerBrowser
*iface
,
540 HDWP
*phdwp
, RECT rcBrowser
)
542 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
543 TRACE("%p (%p, %s)\n", This
, phdwp
, wine_dbgstr_rect(&rcBrowser
));
547 *phdwp
= DeferWindowPos(*phdwp
, This
->hwnd_main
, NULL
, rcBrowser
.left
, rcBrowser
.top
,
548 rcBrowser
.right
- rcBrowser
.left
, rcBrowser
.bottom
- rcBrowser
.top
,
549 SWP_NOZORDER
| SWP_NOACTIVATE
);
553 MoveWindow(This
->hwnd_main
, rcBrowser
.left
, rcBrowser
.top
,
554 rcBrowser
.right
- rcBrowser
.left
, rcBrowser
.bottom
- rcBrowser
.top
, TRUE
);
560 static HRESULT WINAPI
IExplorerBrowser_fnSetPropertyBag(IExplorerBrowser
*iface
,
561 LPCWSTR pszPropertyBag
)
563 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
564 FIXME("stub, %p (%s)\n", This
, debugstr_w(pszPropertyBag
));
569 static HRESULT WINAPI
IExplorerBrowser_fnSetEmptyText(IExplorerBrowser
*iface
,
570 LPCWSTR pszEmptyText
)
572 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
573 FIXME("stub, %p (%s)\n", This
, debugstr_w(pszEmptyText
));
578 static HRESULT WINAPI
IExplorerBrowser_fnSetFolderSettings(IExplorerBrowser
*iface
,
579 const FOLDERSETTINGS
*pfs
)
581 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
582 TRACE("%p (%p)\n", This
, pfs
);
587 This
->fs
.ViewMode
= pfs
->ViewMode
;
588 This
->fs
.fFlags
= pfs
->fFlags
| FWF_NOCLIENTEDGE
;
590 /* Change the settings of the current view, if any. */
591 return change_viewmode(This
, This
->fs
.ViewMode
);
594 static HRESULT WINAPI
IExplorerBrowser_fnAdvise(IExplorerBrowser
*iface
,
595 IExplorerBrowserEvents
*psbe
,
598 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
599 event_client
*client
;
600 TRACE("%p (%p, %p)\n", This
, psbe
, pdwCookie
);
602 client
= HeapAlloc(GetProcessHeap(), 0, sizeof(event_client
));
604 client
->cookie
= ++This
->events_next_cookie
;
606 IExplorerBrowserEvents_AddRef(psbe
);
607 *pdwCookie
= client
->cookie
;
609 list_add_tail(&This
->event_clients
, &client
->entry
);
614 static HRESULT WINAPI
IExplorerBrowser_fnUnadvise(IExplorerBrowser
*iface
,
617 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
618 event_client
*client
;
619 TRACE("%p (0x%x)\n", This
, dwCookie
);
621 LIST_FOR_EACH_ENTRY(client
, &This
->event_clients
, event_client
, entry
)
623 if(client
->cookie
== dwCookie
)
625 list_remove(&client
->entry
);
626 IExplorerBrowserEvents_Release(client
->pebe
);
627 HeapFree(GetProcessHeap(), 0, client
);
635 static HRESULT WINAPI
IExplorerBrowser_fnSetOptions(IExplorerBrowser
*iface
,
636 EXPLORER_BROWSER_OPTIONS dwFlag
)
638 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
639 static const EXPLORER_BROWSER_OPTIONS unsupported_options
=
640 EBO_SHOWFRAMES
| EBO_ALWAYSNAVIGATE
| EBO_NOWRAPPERWINDOW
| EBO_HTMLSHAREPOINTVIEW
;
642 TRACE("%p (0x%x)\n", This
, dwFlag
);
644 if(dwFlag
& unsupported_options
)
645 FIXME("Flags 0x%08x contains unsupported options.\n", dwFlag
);
647 This
->eb_options
= dwFlag
;
652 static HRESULT WINAPI
IExplorerBrowser_fnGetOptions(IExplorerBrowser
*iface
,
653 EXPLORER_BROWSER_OPTIONS
*pdwFlag
)
655 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
656 TRACE("%p (%p)\n", This
, pdwFlag
);
658 *pdwFlag
= This
->eb_options
;
663 static HRESULT WINAPI
IExplorerBrowser_fnBrowseToIDList(IExplorerBrowser
*iface
,
664 PCUIDLIST_RELATIVE pidl
,
667 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
668 LPITEMIDLIST absolute_pidl
= NULL
;
670 static const UINT unsupported_browse_flags
=
671 SBSP_NEWBROWSER
| EBF_SELECTFROMDATAOBJECT
| EBF_NODROPTARGET
;
672 TRACE("%p (%p, 0x%x)\n", This
, pidl
, uFlags
);
678 return HRESULT_FROM_WIN32(ERROR_BUSY
);
680 if(This
->current_pidl
&& (This
->eb_options
& EBO_NAVIGATEONCE
))
683 if(uFlags
& SBSP_EXPLOREMODE
)
686 if(uFlags
& unsupported_browse_flags
)
687 FIXME("Argument 0x%x contains unsupported flags.\n", uFlags
);
689 if(uFlags
& SBSP_NAVIGATEBACK
)
691 TRACE("SBSP_NAVIGATEBACK\n");
692 absolute_pidl
= ILClone(travellog_go_back(This
));
693 if(!absolute_pidl
&& !This
->current_pidl
)
695 else if(!absolute_pidl
)
699 else if(uFlags
& SBSP_NAVIGATEFORWARD
)
701 TRACE("SBSP_NAVIGATEFORWARD\n");
702 absolute_pidl
= ILClone(travellog_go_forward(This
));
703 if(!absolute_pidl
&& !This
->current_pidl
)
705 else if(!absolute_pidl
)
709 else if(uFlags
& SBSP_PARENT
)
711 if(This
->current_pidl
)
713 if(_ILIsPidlSimple(This
->current_pidl
))
715 absolute_pidl
= _ILCreateDesktop();
719 absolute_pidl
= ILClone(This
->current_pidl
);
720 ILRemoveLastID(absolute_pidl
);
725 ERR("Failed to get parent pidl.\n");
730 else if(uFlags
& SBSP_RELATIVE
)
732 /* SBSP_RELATIVE has precedence over SBSP_ABSOLUTE */
733 TRACE("SBSP_RELATIVE\n");
734 if(This
->current_pidl
)
736 absolute_pidl
= ILCombine(This
->current_pidl
, pidl
);
740 ERR("Failed to get absolute pidl.\n");
746 TRACE("SBSP_ABSOLUTE\n");
747 absolute_pidl
= ILClone(pidl
);
748 if(!absolute_pidl
&& !This
->current_pidl
)
750 else if(!absolute_pidl
)
754 /* TODO: Asynchronous browsing. Return S_OK here and finish in
757 hr
= events_NavigationPending(This
, absolute_pidl
);
760 TRACE("Browsing aborted.\n");
761 ILFree(absolute_pidl
);
765 get_interfaces_from_site(This
);
767 /* Only browse if the new pidl differs from the old */
768 if(!ILIsEqual(This
->current_pidl
, absolute_pidl
))
771 hr
= SHCreateItemFromIDList(absolute_pidl
, &IID_IShellItem
, (void**)&psi
);
774 hr
= create_new_shellview(This
, psi
);
777 events_NavigationFailed(This
, absolute_pidl
);
778 ILFree(absolute_pidl
);
779 IShellItem_Release(psi
);
783 /* Add to travellog */
784 if( !(This
->eb_options
& EBO_NOTRAVELLOG
) &&
785 !(uFlags
& (SBSP_NAVIGATEFORWARD
|SBSP_NAVIGATEBACK
)) )
787 travellog_add_entry(This
, absolute_pidl
);
790 IShellItem_Release(psi
);
794 events_NavigationComplete(This
, absolute_pidl
);
795 ILFree(This
->current_pidl
);
796 This
->current_pidl
= absolute_pidl
;
801 static HRESULT WINAPI
IExplorerBrowser_fnBrowseToObject(IExplorerBrowser
*iface
,
802 IUnknown
*punk
, UINT uFlags
)
804 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
807 TRACE("%p (%p, 0x%x)\n", This
, punk
, uFlags
);
810 return IExplorerBrowser_fnBrowseToIDList(iface
, NULL
, uFlags
);
812 hr
= SHGetIDListFromObject(punk
, &pidl
);
815 hr
= IExplorerBrowser_BrowseToIDList(iface
, pidl
, uFlags
);
822 static HRESULT WINAPI
IExplorerBrowser_fnFillFromObject(IExplorerBrowser
*iface
,
824 EXPLORER_BROWSER_FILL_FLAGS dwFlags
)
826 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
827 FIXME("stub, %p (%p, 0x%x)\n", This
, punk
, dwFlags
);
832 static HRESULT WINAPI
IExplorerBrowser_fnRemoveAll(IExplorerBrowser
*iface
)
834 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
835 FIXME("stub, %p\n", This
);
840 static HRESULT WINAPI
IExplorerBrowser_fnGetCurrentView(IExplorerBrowser
*iface
,
841 REFIID riid
, void **ppv
)
843 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
844 TRACE("%p (%s, %p)\n", This
, shdebugstr_guid(riid
), ppv
);
849 return IShellView_QueryInterface(This
->psv
, riid
, ppv
);
852 static const IExplorerBrowserVtbl vt_IExplorerBrowser
=
854 IExplorerBrowser_fnQueryInterface
,
855 IExplorerBrowser_fnAddRef
,
856 IExplorerBrowser_fnRelease
,
857 IExplorerBrowser_fnInitialize
,
858 IExplorerBrowser_fnDestroy
,
859 IExplorerBrowser_fnSetRect
,
860 IExplorerBrowser_fnSetPropertyBag
,
861 IExplorerBrowser_fnSetEmptyText
,
862 IExplorerBrowser_fnSetFolderSettings
,
863 IExplorerBrowser_fnAdvise
,
864 IExplorerBrowser_fnUnadvise
,
865 IExplorerBrowser_fnSetOptions
,
866 IExplorerBrowser_fnGetOptions
,
867 IExplorerBrowser_fnBrowseToIDList
,
868 IExplorerBrowser_fnBrowseToObject
,
869 IExplorerBrowser_fnFillFromObject
,
870 IExplorerBrowser_fnRemoveAll
,
871 IExplorerBrowser_fnGetCurrentView
874 /**************************************************************************
875 * IShellBrowser Implementation
878 static inline ExplorerBrowserImpl
*impl_from_IShellBrowser(IShellBrowser
*iface
)
880 return (ExplorerBrowserImpl
*)((char*)iface
- FIELD_OFFSET(ExplorerBrowserImpl
, lpsbVtbl
));
883 static HRESULT WINAPI
IShellBrowser_fnQueryInterface(IShellBrowser
*iface
,
884 REFIID riid
, void **ppvObject
)
886 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
888 return IUnknown_QueryInterface((IUnknown
*) This
, riid
, ppvObject
);
891 static ULONG WINAPI
IShellBrowser_fnAddRef(IShellBrowser
*iface
)
893 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
895 return IUnknown_AddRef((IUnknown
*) This
);
898 static ULONG WINAPI
IShellBrowser_fnRelease(IShellBrowser
*iface
)
900 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
902 return IUnknown_Release((IUnknown
*) This
);
905 static HRESULT WINAPI
IShellBrowser_fnGetWindow(IShellBrowser
*iface
, HWND
*phwnd
)
907 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
908 TRACE("%p (%p)\n", This
, phwnd
);
913 *phwnd
= This
->hwnd_main
;
917 static HRESULT WINAPI
IShellBrowser_fnContextSensitiveHelp(IShellBrowser
*iface
,
920 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
921 FIXME("stub, %p (%d)\n", This
, fEnterMode
);
926 static HRESULT WINAPI
IShellBrowser_fnInsertMenusSB(IShellBrowser
*iface
,
928 LPOLEMENUGROUPWIDTHS lpMenuWidths
)
930 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
931 TRACE("%p (%p, %p)\n", This
, hmenuShared
, lpMenuWidths
);
933 /* Not implemented. */
937 static HRESULT WINAPI
IShellBrowser_fnSetMenuSB(IShellBrowser
*iface
,
939 HOLEMENU holemenuReserved
,
940 HWND hwndActiveObject
)
942 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
943 TRACE("%p (%p, %p, %p)\n", This
, hmenuShared
, holemenuReserved
, hwndActiveObject
);
945 /* Not implemented. */
949 static HRESULT WINAPI
IShellBrowser_fnRemoveMenusSB(IShellBrowser
*iface
,
952 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
953 TRACE("%p (%p)\n", This
, hmenuShared
);
955 /* Not implemented. */
959 static HRESULT WINAPI
IShellBrowser_fnSetStatusTextSB(IShellBrowser
*iface
,
960 LPCOLESTR pszStatusText
)
962 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
963 FIXME("stub, %p (%s)\n", This
, debugstr_w(pszStatusText
));
968 static HRESULT WINAPI
IShellBrowser_fnEnableModelessSB(IShellBrowser
*iface
,
971 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
972 FIXME("stub, %p (%d)\n", This
, fEnable
);
977 static HRESULT WINAPI
IShellBrowser_fnTranslateAcceleratorSB(IShellBrowser
*iface
,
980 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
981 FIXME("stub, %p (%p, 0x%x)\n", This
, pmsg
, wID
);
986 static HRESULT WINAPI
IShellBrowser_fnBrowseObject(IShellBrowser
*iface
,
987 LPCITEMIDLIST pidl
, UINT wFlags
)
989 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
990 TRACE("%p (%p, %x)\n", This
, pidl
, wFlags
);
992 return IExplorerBrowser_fnBrowseToIDList((IExplorerBrowser
*)This
, pidl
, wFlags
);
995 static HRESULT WINAPI
IShellBrowser_fnGetViewStateStream(IShellBrowser
*iface
,
999 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
1000 FIXME("stub, %p (0x%x, %p)\n", This
, grfMode
, ppStrm
);
1006 static HRESULT WINAPI
IShellBrowser_fnGetControlWindow(IShellBrowser
*iface
,
1007 UINT id
, HWND
*phwnd
)
1009 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
1010 TRACE("%p (%d, %p)\n", This
, id
, phwnd
);
1012 /* Not implemented. */
1016 static HRESULT WINAPI
IShellBrowser_fnSendControlMsg(IShellBrowser
*iface
,
1018 WPARAM wParam
, LPARAM lParam
,
1021 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
1022 FIXME("stub, %p (%d, %d, %lx, %lx, %p)\n", This
, id
, uMsg
, wParam
, lParam
, pret
);
1027 static HRESULT WINAPI
IShellBrowser_fnQueryActiveShellView(IShellBrowser
*iface
,
1030 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
1031 TRACE("%p (%p)\n", This
, ppshv
);
1037 IShellView_AddRef(This
->psv
);
1042 static HRESULT WINAPI
IShellBrowser_fnOnViewWindowActive(IShellBrowser
*iface
,
1045 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
1046 FIXME("stub, %p (%p)\n", This
, pshv
);
1051 static HRESULT WINAPI
IShellBrowser_fnSetToolbarItems(IShellBrowser
*iface
,
1052 LPTBBUTTONSB lpButtons
,
1053 UINT nButtons
, UINT uFlags
)
1055 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
1056 FIXME("stub, %p (%p, %d, 0x%x)\n", This
, lpButtons
, nButtons
, uFlags
);
1061 static const IShellBrowserVtbl vt_IShellBrowser
= {
1062 IShellBrowser_fnQueryInterface
,
1063 IShellBrowser_fnAddRef
,
1064 IShellBrowser_fnRelease
,
1065 IShellBrowser_fnGetWindow
,
1066 IShellBrowser_fnContextSensitiveHelp
,
1067 IShellBrowser_fnInsertMenusSB
,
1068 IShellBrowser_fnSetMenuSB
,
1069 IShellBrowser_fnRemoveMenusSB
,
1070 IShellBrowser_fnSetStatusTextSB
,
1071 IShellBrowser_fnEnableModelessSB
,
1072 IShellBrowser_fnTranslateAcceleratorSB
,
1073 IShellBrowser_fnBrowseObject
,
1074 IShellBrowser_fnGetViewStateStream
,
1075 IShellBrowser_fnGetControlWindow
,
1076 IShellBrowser_fnSendControlMsg
,
1077 IShellBrowser_fnQueryActiveShellView
,
1078 IShellBrowser_fnOnViewWindowActive
,
1079 IShellBrowser_fnSetToolbarItems
1082 /**************************************************************************
1083 * ICommDlgBrowser3 Implementation
1086 static inline ExplorerBrowserImpl
*impl_from_ICommDlgBrowser3(ICommDlgBrowser3
*iface
)
1088 return (ExplorerBrowserImpl
*)((char*)iface
- FIELD_OFFSET(ExplorerBrowserImpl
, lpcdb3Vtbl
));
1091 static HRESULT WINAPI
ICommDlgBrowser3_fnQueryInterface(ICommDlgBrowser3
*iface
,
1095 ExplorerBrowserImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
1096 TRACE("%p\n", This
);
1097 return IUnknown_QueryInterface((IUnknown
*) This
, riid
, ppvObject
);
1100 static ULONG WINAPI
ICommDlgBrowser3_fnAddRef(ICommDlgBrowser3
*iface
)
1102 ExplorerBrowserImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
1103 TRACE("%p\n", This
);
1104 return IUnknown_AddRef((IUnknown
*) This
);
1107 static ULONG WINAPI
ICommDlgBrowser3_fnRelease(ICommDlgBrowser3
*iface
)
1109 ExplorerBrowserImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
1110 TRACE("%p\n", This
);
1111 return IUnknown_Release((IUnknown
*) This
);
1114 static HRESULT WINAPI
ICommDlgBrowser3_fnOnDefaultCommand(ICommDlgBrowser3
*iface
,
1117 ExplorerBrowserImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
1120 HRESULT ret
= S_FALSE
;
1122 TRACE("%p (%p)\n", This
, shv
);
1124 hr
= IShellView_GetItemObject(shv
, SVGIO_SELECTION
, &IID_IDataObject
, (void**)&pdo
);
1130 fmt
.cfFormat
= RegisterClipboardFormatW(CFSTR_SHELLIDLISTW
);
1132 fmt
.dwAspect
= DVASPECT_CONTENT
;
1134 fmt
.tymed
= TYMED_HGLOBAL
;
1136 hr
= IDataObject_GetData(pdo
, &fmt
,&medium
);
1137 IDataObject_Release(pdo
);
1140 LPIDA pida
= GlobalLock(medium
.u
.hGlobal
);
1141 LPCITEMIDLIST pidl_child
= (LPCITEMIDLIST
) ((LPBYTE
)pida
+pida
->aoffset
[1]);
1143 /* Handle folders by browsing to them. */
1144 if(_ILIsFolder(pidl_child
) || _ILIsDrive(pidl_child
) || _ILIsSpecialFolder(pidl_child
))
1146 IExplorerBrowser_BrowseToIDList((IExplorerBrowser
*)This
, pidl_child
, SBSP_RELATIVE
);
1149 GlobalUnlock(medium
.u
.hGlobal
);
1150 GlobalFree(medium
.u
.hGlobal
);
1153 ERR("Failed to get data from IDataObject.\n");
1155 ERR("Failed to get IDataObject.\n");
1159 static HRESULT WINAPI
ICommDlgBrowser3_fnOnStateChange(ICommDlgBrowser3
*iface
,
1160 IShellView
*shv
, ULONG uChange
)
1162 ExplorerBrowserImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
1163 FIXME("stub, %p (%p, %d)\n", This
, shv
, uChange
);
1166 static HRESULT WINAPI
ICommDlgBrowser3_fnIncludeObject(ICommDlgBrowser3
*iface
,
1167 IShellView
*pshv
, LPCITEMIDLIST pidl
)
1169 ExplorerBrowserImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
1170 FIXME("stub, %p (%p, %p)\n", This
, pshv
, pidl
);
1174 static HRESULT WINAPI
ICommDlgBrowser3_fnNotify(ICommDlgBrowser3
*iface
,
1178 ExplorerBrowserImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
1179 FIXME("stub, %p (%p, 0x%x)\n", This
, pshv
, dwNotifyType
);
1183 static HRESULT WINAPI
ICommDlgBrowser3_fnGetDefaultMenuText(ICommDlgBrowser3
*iface
,
1185 LPWSTR pszText
, int cchMax
)
1187 ExplorerBrowserImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
1188 FIXME("stub, %p (%p, %s, %d)\n", This
, pshv
, debugstr_w(pszText
), cchMax
);
1192 static HRESULT WINAPI
ICommDlgBrowser3_fnGetViewFlags(ICommDlgBrowser3
*iface
,
1195 ExplorerBrowserImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
1196 FIXME("stub, %p (%p)\n", This
, pdwFlags
);
1200 static HRESULT WINAPI
ICommDlgBrowser3_fnOnColumnClicked(ICommDlgBrowser3
*iface
,
1201 IShellView
*pshv
, int iColumn
)
1203 ExplorerBrowserImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
1204 FIXME("stub, %p (%p, %d)\n", This
, pshv
, iColumn
);
1208 static HRESULT WINAPI
ICommDlgBrowser3_fnGetCurrentFilter(ICommDlgBrowser3
*iface
,
1212 ExplorerBrowserImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
1213 FIXME("stub, %p (%s, %d)\n", This
, debugstr_w(pszFileSpec
), cchFileSpec
);
1217 static HRESULT WINAPI
ICommDlgBrowser3_fnOnPreviewCreated(ICommDlgBrowser3
*iface
,
1220 ExplorerBrowserImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
1221 FIXME("stub, %p (%p)\n", This
, pshv
);
1225 static const ICommDlgBrowser3Vtbl vt_ICommDlgBrowser3
= {
1226 ICommDlgBrowser3_fnQueryInterface
,
1227 ICommDlgBrowser3_fnAddRef
,
1228 ICommDlgBrowser3_fnRelease
,
1229 ICommDlgBrowser3_fnOnDefaultCommand
,
1230 ICommDlgBrowser3_fnOnStateChange
,
1231 ICommDlgBrowser3_fnIncludeObject
,
1232 ICommDlgBrowser3_fnNotify
,
1233 ICommDlgBrowser3_fnGetDefaultMenuText
,
1234 ICommDlgBrowser3_fnGetViewFlags
,
1235 ICommDlgBrowser3_fnOnColumnClicked
,
1236 ICommDlgBrowser3_fnGetCurrentFilter
,
1237 ICommDlgBrowser3_fnOnPreviewCreated
1240 /**************************************************************************
1241 * IObjectWithSite Implementation
1244 static inline ExplorerBrowserImpl
*impl_from_IObjectWithSite(IObjectWithSite
*iface
)
1246 return (ExplorerBrowserImpl
*)((char*)iface
- FIELD_OFFSET(ExplorerBrowserImpl
, lpowsVtbl
));
1249 static HRESULT WINAPI
IObjectWithSite_fnQueryInterface(IObjectWithSite
*iface
,
1250 REFIID riid
, void **ppvObject
)
1252 ExplorerBrowserImpl
*This
= impl_from_IObjectWithSite(iface
);
1253 TRACE("%p\n", This
);
1254 return IUnknown_QueryInterface((IUnknown
*)This
, riid
, ppvObject
);
1257 static ULONG WINAPI
IObjectWithSite_fnAddRef(IObjectWithSite
*iface
)
1259 ExplorerBrowserImpl
*This
= impl_from_IObjectWithSite(iface
);
1260 TRACE("%p\n", This
);
1261 return IUnknown_AddRef((IUnknown
*)This
);
1264 static ULONG WINAPI
IObjectWithSite_fnRelease(IObjectWithSite
*iface
)
1266 ExplorerBrowserImpl
*This
= impl_from_IObjectWithSite(iface
);
1267 TRACE("%p\n", This
);
1268 return IUnknown_Release((IUnknown
*)This
);
1271 static HRESULT WINAPI
IObjectWithSite_fnSetSite(IObjectWithSite
*iface
, IUnknown
*punk_site
)
1273 ExplorerBrowserImpl
*This
= impl_from_IObjectWithSite(iface
);
1274 TRACE("%p (%p)\n", This
, punk_site
);
1278 IUnknown_Release(This
->punk_site
);
1279 This
->punk_site
= NULL
;
1280 get_interfaces_from_site(This
);
1283 This
->punk_site
= punk_site
;
1286 IUnknown_AddRef(This
->punk_site
);
1291 static HRESULT WINAPI
IObjectWithSite_fnGetSite(IObjectWithSite
*iface
, REFIID riid
, void **ppvSite
)
1293 ExplorerBrowserImpl
*This
= impl_from_IObjectWithSite(iface
);
1294 TRACE("%p (%s, %p)\n", This
, shdebugstr_guid(riid
), ppvSite
);
1296 if(!This
->punk_site
)
1299 return IUnknown_QueryInterface(This
->punk_site
, riid
, ppvSite
);
1302 static const IObjectWithSiteVtbl vt_IObjectWithSite
= {
1303 IObjectWithSite_fnQueryInterface
,
1304 IObjectWithSite_fnAddRef
,
1305 IObjectWithSite_fnRelease
,
1306 IObjectWithSite_fnSetSite
,
1307 IObjectWithSite_fnGetSite
1310 HRESULT WINAPI
ExplorerBrowser_Constructor(IUnknown
*pUnkOuter
, REFIID riid
, void **ppv
)
1312 ExplorerBrowserImpl
*eb
;
1315 TRACE("%p %s %p\n", pUnkOuter
, shdebugstr_guid (riid
), ppv
);
1320 return CLASS_E_NOAGGREGATION
;
1322 eb
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(ExplorerBrowserImpl
));
1324 eb
->lpVtbl
= &vt_IExplorerBrowser
;
1325 eb
->lpsbVtbl
= &vt_IShellBrowser
;
1326 eb
->lpcdb3Vtbl
= &vt_ICommDlgBrowser3
;
1327 eb
->lpowsVtbl
= &vt_IObjectWithSite
;
1329 list_init(&eb
->event_clients
);
1330 list_init(&eb
->travellog
);
1332 ret
= IExplorerBrowser_QueryInterface((IExplorerBrowser
*)eb
, riid
, ppv
);
1333 IExplorerBrowser_Release((IExplorerBrowser
*)eb
);
1335 TRACE("--(%p)\n", ppv
);