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 #define SPLITTER_WIDTH 2
41 #define NP_MIN_WIDTH 60
42 #define SV_MIN_WIDTH 150
44 typedef struct _event_client
{
46 IExplorerBrowserEvents
*pebe
;
50 typedef struct _travellog_entry
{
55 typedef struct _ExplorerBrowserImpl
{
56 const IExplorerBrowserVtbl
*lpVtbl
;
57 const IShellBrowserVtbl
*lpsbVtbl
;
58 const ICommDlgBrowser3Vtbl
*lpcdb3Vtbl
;
59 const IObjectWithSiteVtbl
*lpowsVtbl
;
60 const INameSpaceTreeControlEventsVtbl
*lpnstceVtbl
;
69 INameSpaceTreeControl2
*pnstc2
;
70 HWND hwnd_splitter
, hwnd_nstc
;
77 EXPLORER_BROWSER_OPTIONS eb_options
;
80 struct list event_clients
;
81 DWORD events_next_cookie
;
82 struct list travellog
;
83 travellog_entry
*travellog_cursor
;
88 LPITEMIDLIST current_pidl
;
91 ICommDlgBrowser
*pcdb_site
;
92 ICommDlgBrowser2
*pcdb2_site
;
93 ICommDlgBrowser3
*pcdb3_site
;
94 IExplorerPaneVisibility
*pepv_site
;
95 } ExplorerBrowserImpl
;
97 static void initialize_navpane(ExplorerBrowserImpl
*This
, HWND hwnd_parent
, RECT
*rc
);
99 /**************************************************************************
102 static void events_unadvise_all(ExplorerBrowserImpl
*This
)
104 event_client
*client
, *curs
;
107 LIST_FOR_EACH_ENTRY_SAFE(client
, curs
, &This
->event_clients
, event_client
, entry
)
109 TRACE("Removing %p\n", client
);
110 list_remove(&client
->entry
);
111 IExplorerBrowserEvents_Release(client
->pebe
);
112 HeapFree(GetProcessHeap(), 0, client
);
116 static HRESULT
events_NavigationPending(ExplorerBrowserImpl
*This
, PCIDLIST_ABSOLUTE pidl
)
118 event_client
*cursor
;
123 LIST_FOR_EACH_ENTRY(cursor
, &This
->event_clients
, event_client
, entry
)
125 TRACE("Notifying %p\n", cursor
);
126 hres
= IExplorerBrowserEvents_OnNavigationPending(cursor
->pebe
, pidl
);
128 /* If this failed for any reason, the browsing is supposed to be aborted. */
136 static void events_NavigationComplete(ExplorerBrowserImpl
*This
, PCIDLIST_ABSOLUTE pidl
)
138 event_client
*cursor
;
142 LIST_FOR_EACH_ENTRY(cursor
, &This
->event_clients
, event_client
, entry
)
144 TRACE("Notifying %p\n", cursor
);
145 IExplorerBrowserEvents_OnNavigationComplete(cursor
->pebe
, pidl
);
149 static void events_NavigationFailed(ExplorerBrowserImpl
*This
, PCIDLIST_ABSOLUTE pidl
)
151 event_client
*cursor
;
155 LIST_FOR_EACH_ENTRY(cursor
, &This
->event_clients
, event_client
, entry
)
157 TRACE("Notifying %p\n", cursor
);
158 IExplorerBrowserEvents_OnNavigationFailed(cursor
->pebe
, pidl
);
162 static void events_ViewCreated(ExplorerBrowserImpl
*This
, IShellView
*psv
)
164 event_client
*cursor
;
168 LIST_FOR_EACH_ENTRY(cursor
, &This
->event_clients
, event_client
, entry
)
170 TRACE("Notifying %p\n", cursor
);
171 IExplorerBrowserEvents_OnViewCreated(cursor
->pebe
, psv
);
175 /**************************************************************************
176 * Travellog functions.
178 static void travellog_remove_entry(ExplorerBrowserImpl
*This
, travellog_entry
*entry
)
180 TRACE("Removing %p\n", entry
);
182 list_remove(&entry
->entry
);
183 HeapFree(GetProcessHeap(), 0, entry
);
184 This
->travellog_count
--;
187 static void travellog_remove_all_entries(ExplorerBrowserImpl
*This
)
189 travellog_entry
*cursor
, *cursor2
;
192 LIST_FOR_EACH_ENTRY_SAFE(cursor
, cursor2
, &This
->travellog
, travellog_entry
, entry
)
193 travellog_remove_entry(This
, cursor
);
195 This
->travellog_cursor
= NULL
;
198 static void travellog_add_entry(ExplorerBrowserImpl
*This
, LPITEMIDLIST pidl
)
200 travellog_entry
*new, *cursor
, *cursor2
;
201 TRACE("%p (old count %d)\n", pidl
, This
->travellog_count
);
203 /* Replace the old tail, if any, with the new entry */
204 if(This
->travellog_cursor
)
206 LIST_FOR_EACH_ENTRY_SAFE_REV(cursor
, cursor2
, &This
->travellog
, travellog_entry
, entry
)
208 if(cursor
== This
->travellog_cursor
)
210 travellog_remove_entry(This
, cursor
);
214 /* Create and add the new entry */
215 new = HeapAlloc(GetProcessHeap(), 0, sizeof(travellog_entry
));
216 new->pidl
= ILClone(pidl
);
217 list_add_tail(&This
->travellog
, &new->entry
);
218 This
->travellog_cursor
= new;
219 This
->travellog_count
++;
221 /* Remove the first few entries if the size limit is reached. */
222 if(This
->travellog_count
> 200)
225 LIST_FOR_EACH_ENTRY_SAFE(cursor
, cursor2
, &This
->travellog
, travellog_entry
, entry
)
229 travellog_remove_entry(This
, cursor
);
234 static LPCITEMIDLIST
travellog_go_back(ExplorerBrowserImpl
*This
)
236 travellog_entry
*prev
;
237 TRACE("%p, %p\n", This
, This
->travellog_cursor
);
239 if(!This
->travellog_cursor
)
242 prev
= LIST_ENTRY(list_prev(&This
->travellog
, &This
->travellog_cursor
->entry
),
243 travellog_entry
, entry
);
247 This
->travellog_cursor
= prev
;
251 static LPCITEMIDLIST
travellog_go_forward(ExplorerBrowserImpl
*This
)
253 travellog_entry
*next
;
254 TRACE("%p, %p\n", This
, This
->travellog_cursor
);
256 if(!This
->travellog_cursor
)
259 next
= LIST_ENTRY(list_next(&This
->travellog
, &This
->travellog_cursor
->entry
),
260 travellog_entry
, entry
);
264 This
->travellog_cursor
= next
;
268 /**************************************************************************
271 static void update_layout(ExplorerBrowserImpl
*This
)
274 INT navpane_width_actual
;
275 INT shellview_width_actual
;
276 TRACE("%p (navpane: %d, EBO_SHOWFRAMES: %d)\n",
277 This
, This
->navpane
.show
, This
->eb_options
& EBO_SHOWFRAMES
);
279 GetClientRect(This
->hwnd_main
, &rc
);
281 if((This
->eb_options
& EBO_SHOWFRAMES
) && This
->navpane
.show
)
282 navpane_width_actual
= This
->navpane
.width
;
284 navpane_width_actual
= 0;
286 shellview_width_actual
= rc
.right
- navpane_width_actual
;
287 if(shellview_width_actual
< SV_MIN_WIDTH
&& navpane_width_actual
)
289 INT missing_width
= SV_MIN_WIDTH
- shellview_width_actual
;
290 if(missing_width
< (navpane_width_actual
- NP_MIN_WIDTH
))
292 /* Shrink the navpane */
293 navpane_width_actual
-= missing_width
;
294 shellview_width_actual
+= missing_width
;
298 /* Hide the navpane */
299 shellview_width_actual
+= navpane_width_actual
;
300 navpane_width_actual
= 0;
304 /**************************************************************
305 * Calculate rectangles for the panes. All rectangles contain
306 * the position of the panes relative to hwnd_main.
309 if(navpane_width_actual
)
311 This
->navpane
.rc
.left
= This
->navpane
.rc
.top
= 0;
312 This
->navpane
.rc
.right
= navpane_width_actual
;
313 This
->navpane
.rc
.bottom
= rc
.bottom
;
315 if(!This
->navpane
.hwnd_splitter
)
316 initialize_navpane(This
, This
->hwnd_main
, &This
->navpane
.rc
);
319 ZeroMemory(&This
->navpane
.rc
, sizeof(RECT
));
321 This
->sv_rc
.left
= navpane_width_actual
;
323 This
->sv_rc
.right
= This
->sv_rc
.left
+ shellview_width_actual
;
324 This
->sv_rc
.bottom
= rc
.bottom
;
327 static void size_panes(ExplorerBrowserImpl
*This
)
329 MoveWindow(This
->navpane
.hwnd_splitter
,
330 This
->navpane
.rc
.right
- SPLITTER_WIDTH
, This
->navpane
.rc
.top
,
331 SPLITTER_WIDTH
, This
->navpane
.rc
.bottom
- This
->navpane
.rc
.top
,
334 MoveWindow(This
->hwnd_sv
,
335 This
->sv_rc
.left
, This
->sv_rc
.top
,
336 This
->sv_rc
.right
- This
->sv_rc
.left
, This
->sv_rc
.bottom
- This
->sv_rc
.top
,
340 static HRESULT
change_viewmode(ExplorerBrowserImpl
*This
, UINT viewmode
)
348 hr
= IShellView_QueryInterface(This
->psv
, &IID_IFolderView
, (void*)&pfv
);
351 hr
= IFolderView_SetCurrentViewMode(pfv
, This
->fs
.ViewMode
);
352 IFolderView_Release(pfv
);
358 static HRESULT
create_new_shellview(ExplorerBrowserImpl
*This
, IShellItem
*psi
)
360 IShellBrowser
*psb
= (IShellBrowser
*)&This
->lpsbVtbl
;
366 TRACE("%p, %p\n", This
, psi
);
368 hr
= IShellItem_BindToHandler(psi
, NULL
, &BHID_SFObject
, &IID_IShellFolder
, (void**)&psf
);
371 hr
= IShellFolder_CreateViewObject(psf
, This
->hwnd_main
, &IID_IShellView
, (void**)&psv
);
376 IShellView_DestroyViewWindow(This
->psv
);
377 This
->hwnd_sv
= NULL
;
380 hr
= IShellView_CreateViewWindow(psv
, This
->psv
, &This
->fs
, psb
, &This
->sv_rc
, &hwnd_new
);
383 /* Replace the old shellview */
384 if(This
->psv
) IShellView_Release(This
->psv
);
387 This
->hwnd_sv
= hwnd_new
;
388 events_ViewCreated(This
, psv
);
392 ERR("CreateViewWindow failed (0x%x)\n", hr
);
393 IShellView_Release(psv
);
397 ERR("CreateViewObject failed (0x%x)\n", hr
);
399 IShellFolder_Release(psf
);
402 ERR("SI::BindToHandler failed (0x%x)\n", hr
);
407 static void get_interfaces_from_site(ExplorerBrowserImpl
*This
)
409 IServiceProvider
*psp
;
412 /* Calling this with This->punk_site set to NULL should properly
413 * release any previously fetched interfaces.
418 IUnknown_Release(This
->pcdb_site
);
419 if(This
->pcdb2_site
) IUnknown_Release(This
->pcdb2_site
);
420 if(This
->pcdb3_site
) IUnknown_Release(This
->pcdb3_site
);
422 This
->pcdb_site
= NULL
;
423 This
->pcdb2_site
= NULL
;
424 This
->pcdb3_site
= NULL
;
429 IExplorerPaneVisibility_Release(This
->pepv_site
);
430 This
->pepv_site
= NULL
;
436 hr
= IUnknown_QueryInterface(This
->punk_site
, &IID_IServiceProvider
, (void**)&psp
);
439 ERR("Failed to get IServiceProvider from site.\n");
443 /* ICommDlgBrowser */
444 IServiceProvider_QueryService(psp
, &SID_SExplorerBrowserFrame
, &IID_ICommDlgBrowser
,
445 (void**)&This
->pcdb_site
);
446 IServiceProvider_QueryService(psp
, &SID_SExplorerBrowserFrame
, &IID_ICommDlgBrowser2
,
447 (void**)&This
->pcdb2_site
);
448 IServiceProvider_QueryService(psp
, &SID_SExplorerBrowserFrame
, &IID_ICommDlgBrowser3
,
449 (void**)&This
->pcdb3_site
);
451 /* IExplorerPaneVisibility */
452 IServiceProvider_QueryService(psp
, &SID_ExplorerPaneVisibility
, &IID_IExplorerPaneVisibility
,
453 (void**)&This
->pepv_site
);
455 IServiceProvider_Release(psp
);
458 /**************************************************************************
459 * General pane functionality.
461 static void update_panestate(ExplorerBrowserImpl
*This
)
463 EXPLORERPANESTATE eps
= EPS_DONTCARE
;
467 if(!This
->pepv_site
) return;
469 IExplorerPaneVisibility_GetPaneState(This
->pepv_site
, (REFEXPLORERPANE
) &EP_NavPane
, &eps
);
470 if( !(eps
& EPS_DEFAULT_OFF
) )
473 show_navpane
= FALSE
;
475 if(This
->navpane
.show
^ show_navpane
)
481 This
->navpane
.show
= show_navpane
;
484 static void splitter_draw(HWND hwnd
, RECT
*rc
)
486 HDC hdc
= GetDC(hwnd
);
488 ReleaseDC(hwnd
, hdc
);
491 /**************************************************************************
492 * The Navigation Pane.
494 static LRESULT
navpane_splitter_beginresize(ExplorerBrowserImpl
*This
, HWND hwnd
, LPARAM lParam
)
500 CopyRect(&This
->splitter_rc
, &This
->navpane
.rc
);
501 This
->splitter_rc
.left
= This
->splitter_rc
.right
- SPLITTER_WIDTH
;
503 splitter_draw(GetParent(hwnd
), &This
->splitter_rc
);
508 static LRESULT
navpane_splitter_resizing(ExplorerBrowserImpl
*This
, HWND hwnd
, LPARAM lParam
)
513 if(GetCapture() != hwnd
) return FALSE
;
515 dx
= (SHORT
)LOWORD(lParam
);
518 CopyRect(&rc
, &This
->navpane
.rc
);
520 new_width
= This
->navpane
.width
+ dx
;
521 if(new_width
> NP_MIN_WIDTH
&& This
->sv_rc
.right
- new_width
> SV_MIN_WIDTH
)
523 rc
.right
= new_width
;
524 rc
.left
= rc
.right
- SPLITTER_WIDTH
;
525 splitter_draw(GetParent(hwnd
), &This
->splitter_rc
);
526 splitter_draw(GetParent(hwnd
), &rc
);
527 CopyRect(&This
->splitter_rc
, &rc
);
533 static LRESULT
navpane_splitter_endresize(ExplorerBrowserImpl
*This
, HWND hwnd
, LPARAM lParam
)
537 if(GetCapture() != hwnd
) return FALSE
;
539 dx
= (SHORT
)LOWORD(lParam
);
542 splitter_draw(GetParent(hwnd
), &This
->splitter_rc
);
544 new_width
= This
->navpane
.width
+ dx
;
545 if(new_width
< NP_MIN_WIDTH
)
546 new_width
= NP_MIN_WIDTH
;
547 else if(This
->sv_rc
.right
- new_width
< SV_MIN_WIDTH
)
548 new_width
= This
->sv_rc
.right
- SV_MIN_WIDTH
;
550 This
->navpane
.width
= new_width
;
560 static LRESULT
navpane_on_wm_create(HWND hwnd
, CREATESTRUCTW
*crs
)
562 ExplorerBrowserImpl
*This
= crs
->lpCreateParams
;
563 INameSpaceTreeControl2
*pnstc2
;
568 SetWindowLongPtrW(hwnd
, GWLP_USERDATA
, (LPARAM
)This
);
569 This
->navpane
.hwnd_splitter
= hwnd
;
571 hr
= CoCreateInstance(&CLSID_NamespaceTreeControl
, NULL
, CLSCTX_INPROC_SERVER
,
572 &IID_INameSpaceTreeControl2
, (void**)&pnstc2
);
576 style
= NSTCS_HASEXPANDOS
| NSTCS_ROOTHASEXPANDO
| NSTCS_SHOWSELECTIONALWAYS
;
577 hr
= INameSpaceTreeControl2_Initialize(pnstc2
, GetParent(hwnd
), NULL
, style
);
580 INameSpaceTreeControlEvents
*pnstce
;
581 IShellFolder
*psfdesktop
;
585 DWORD cookie
, style2
= NSTCS2_DISPLAYPADDING
;
587 hr
= INameSpaceTreeControl2_SetControlStyle2(pnstc2
, 0xFF, style2
);
589 ERR("SetControlStyle2 failed (0x%08x)\n", hr
);
591 hr
= INameSpaceTreeControl2_QueryInterface(pnstc2
, &IID_IOleWindow
, (void**)&pow
);
594 IOleWindow_GetWindow(pow
, &This
->navpane
.hwnd_nstc
);
595 IOleWindow_Release(pow
);
598 ERR("QueryInterface(IOleWindow) failed (0x%08x)\n", hr
);
600 pnstce
= (INameSpaceTreeControlEvents
*)&This
->lpnstceVtbl
;
601 hr
= INameSpaceTreeControl2_TreeAdvise(pnstc2
, (IUnknown
*)pnstce
, &cookie
);
603 ERR("TreeAdvise failed. (0x%08x).\n", hr
);
606 * Add the default roots
609 /* TODO: This should be FOLDERID_Links */
610 hr
= SHGetSpecialFolderLocation(NULL
, CSIDL_FAVORITES
, &pidl
);
613 hr
= SHCreateShellItem(NULL
, NULL
, pidl
, &psi
);
616 hr
= INameSpaceTreeControl2_AppendRoot(pnstc2
, psi
, SHCONTF_NONFOLDERS
, NSTCRS_VISIBLE
, NULL
);
617 IShellItem_Release(psi
);
622 SHGetDesktopFolder(&psfdesktop
);
623 hr
= SHGetItemFromObject((IUnknown
*)psfdesktop
, &IID_IShellItem
, (void**)&psi
);
624 IShellFolder_Release(psfdesktop
);
627 hr
= INameSpaceTreeControl2_AppendRoot(pnstc2
, psi
, SHCONTF_FOLDERS
, NSTCRS_EXPANDED
, NULL
);
628 IShellItem_Release(psi
);
632 * We should advertise IID_INameSpaceTreeControl to the site of the
633 * host through its IProfferService interface, if any.
636 This
->navpane
.pnstc2
= pnstc2
;
637 This
->navpane
.nstc_cookie
= cookie
;
643 This
->navpane
.pnstc2
= NULL
;
644 ERR("Failed (0x%08x)\n", hr
);
649 static LRESULT
navpane_on_wm_size_move(ExplorerBrowserImpl
*This
)
654 width
= This
->navpane
.rc
.right
- This
->navpane
.rc
.left
- SPLITTER_WIDTH
;
655 height
= This
->navpane
.rc
.bottom
- This
->navpane
.rc
.top
;
657 MoveWindow(This
->navpane
.hwnd_nstc
,
658 This
->navpane
.rc
.left
, This
->navpane
.rc
.top
,
665 static LRESULT
navpane_on_wm_destroy(ExplorerBrowserImpl
*This
)
667 INameSpaceTreeControl_TreeUnadvise(This
->navpane
.pnstc2
, This
->navpane
.nstc_cookie
);
668 INameSpaceTreeControl_Release(This
->navpane
.pnstc2
);
669 This
->navpane
.pnstc2
= NULL
;
673 static LRESULT CALLBACK
navpane_wndproc(HWND hWnd
, UINT uMessage
, WPARAM wParam
, LPARAM lParam
)
675 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)GetWindowLongPtrW(hWnd
, GWLP_USERDATA
);
678 case WM_CREATE
: return navpane_on_wm_create(hWnd
, (CREATESTRUCTW
*)lParam
);
679 case WM_MOVE
: /* Fall through */
680 case WM_SIZE
: return navpane_on_wm_size_move(This
);
681 case WM_DESTROY
: return navpane_on_wm_destroy(This
);
682 case WM_LBUTTONDOWN
: return navpane_splitter_beginresize(This
, hWnd
, lParam
);
683 case WM_MOUSEMOVE
: return navpane_splitter_resizing(This
, hWnd
, lParam
);
684 case WM_LBUTTONUP
: return navpane_splitter_endresize(This
, hWnd
, lParam
);
686 return DefWindowProcW(hWnd
, uMessage
, wParam
, lParam
);
691 static void initialize_navpane(ExplorerBrowserImpl
*This
, HWND hwnd_parent
, RECT
*rc
)
695 static const WCHAR navpane_classname
[] = {'e','b','_','n','a','v','p','a','n','e',0};
697 if( !GetClassInfoW(shell32_hInstance
, navpane_classname
, &wc
) )
699 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
700 wc
.lpfnWndProc
= navpane_wndproc
;
703 wc
.hInstance
= shell32_hInstance
;
705 wc
.hCursor
= LoadCursorW(0, (LPWSTR
)IDC_SIZEWE
);
706 wc
.hbrBackground
= (HBRUSH
)(COLOR_HIGHLIGHT
+ 1);
707 wc
.lpszMenuName
= NULL
;
708 wc
.lpszClassName
= navpane_classname
;
710 if (!RegisterClassW(&wc
)) return;
713 splitter
= CreateWindowExW(0, navpane_classname
, NULL
,
714 WS_CHILD
| WS_TABSTOP
| WS_VISIBLE
,
715 rc
->right
- SPLITTER_WIDTH
, rc
->top
,
716 SPLITTER_WIDTH
, rc
->bottom
- rc
->top
,
717 hwnd_parent
, 0, shell32_hInstance
, This
);
719 ERR("Failed to create navpane : %d.\n", GetLastError());
722 /**************************************************************************
723 * Main window related functions.
725 static LRESULT
main_on_wm_create(HWND hWnd
, CREATESTRUCTW
*crs
)
727 ExplorerBrowserImpl
*This
= crs
->lpCreateParams
;
730 SetWindowLongPtrW(hWnd
, GWLP_USERDATA
, (LPARAM
)This
);
731 This
->hwnd_main
= hWnd
;
736 static LRESULT
main_on_wm_size(ExplorerBrowserImpl
*This
)
744 static LRESULT CALLBACK
main_wndproc(HWND hWnd
, UINT uMessage
, WPARAM wParam
, LPARAM lParam
)
746 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)GetWindowLongPtrW(hWnd
, GWLP_USERDATA
);
750 case WM_CREATE
: return main_on_wm_create(hWnd
, (CREATESTRUCTW
*)lParam
);
751 case WM_SIZE
: return main_on_wm_size(This
);
752 default: return DefWindowProcW(hWnd
, uMessage
, wParam
, lParam
);
758 /**************************************************************************
759 * IExplorerBrowser Implementation
761 static HRESULT WINAPI
IExplorerBrowser_fnQueryInterface(IExplorerBrowser
*iface
,
762 REFIID riid
, void **ppvObject
)
764 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
765 TRACE("%p (%s, %p)\n", This
, shdebugstr_guid(riid
), ppvObject
);
768 if(IsEqualIID(riid
, &IID_IExplorerBrowser
) ||
769 IsEqualIID(riid
, &IID_IUnknown
))
773 else if(IsEqualIID(riid
, &IID_IShellBrowser
))
775 *ppvObject
= &This
->lpsbVtbl
;
777 else if(IsEqualIID(riid
, &IID_ICommDlgBrowser
) ||
778 IsEqualIID(riid
, &IID_ICommDlgBrowser2
) ||
779 IsEqualIID(riid
, &IID_ICommDlgBrowser3
))
781 *ppvObject
= &This
->lpcdb3Vtbl
;
783 else if(IsEqualIID(riid
, &IID_IObjectWithSite
))
785 *ppvObject
= &This
->lpowsVtbl
;
790 IUnknown_AddRef((IUnknown
*)*ppvObject
);
794 return E_NOINTERFACE
;
797 static ULONG WINAPI
IExplorerBrowser_fnAddRef(IExplorerBrowser
*iface
)
799 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
800 LONG ref
= InterlockedIncrement(&This
->ref
);
801 TRACE("%p - ref %d\n", This
, ref
);
806 static ULONG WINAPI
IExplorerBrowser_fnRelease(IExplorerBrowser
*iface
)
808 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
809 LONG ref
= InterlockedDecrement(&This
->ref
);
810 TRACE("%p - ref %d\n", This
, ref
);
817 IExplorerBrowser_Destroy(iface
);
819 IObjectWithSite_SetSite((IObjectWithSite
*)&This
->lpowsVtbl
, NULL
);
821 HeapFree(GetProcessHeap(), 0, This
);
828 static HRESULT WINAPI
IExplorerBrowser_fnInitialize(IExplorerBrowser
*iface
,
829 HWND hwndParent
, const RECT
*prc
,
830 const FOLDERSETTINGS
*pfs
)
832 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
835 static const WCHAR EB_CLASS_NAME
[] =
836 {'E','x','p','l','o','r','e','r','B','r','o','w','s','e','r','C','o','n','t','r','o','l',0};
838 TRACE("%p (%p, %p, %p)\n", This
, hwndParent
, prc
, pfs
);
846 if( !GetClassInfoW(shell32_hInstance
, EB_CLASS_NAME
, &wc
) )
848 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
849 wc
.lpfnWndProc
= main_wndproc
;
852 wc
.hInstance
= shell32_hInstance
;
854 wc
.hCursor
= LoadCursorW(0, (LPWSTR
)IDC_ARROW
);
855 wc
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1);
856 wc
.lpszMenuName
= NULL
;
857 wc
.lpszClassName
= EB_CLASS_NAME
;
859 if (!RegisterClassW(&wc
)) return E_FAIL
;
862 style
= WS_CHILD
| WS_VISIBLE
| WS_CLIPSIBLINGS
| WS_BORDER
;
863 This
->hwnd_main
= CreateWindowExW(WS_EX_CONTROLPARENT
, EB_CLASS_NAME
, NULL
, style
,
865 prc
->right
- prc
->left
, prc
->bottom
- prc
->top
,
866 hwndParent
, 0, shell32_hInstance
, This
);
870 ERR("Failed to create the window.\n");
874 This
->fs
.ViewMode
= pfs
? pfs
->ViewMode
: FVM_DETAILS
;
875 This
->fs
.fFlags
= pfs
? (pfs
->fFlags
| FWF_NOCLIENTEDGE
) : FWF_NOCLIENTEDGE
;
880 static HRESULT WINAPI
IExplorerBrowser_fnDestroy(IExplorerBrowser
*iface
)
882 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
887 IShellView_DestroyViewWindow(This
->psv
);
888 IShellView_Release(This
->psv
);
890 This
->hwnd_sv
= NULL
;
893 events_unadvise_all(This
);
894 travellog_remove_all_entries(This
);
896 ILFree(This
->current_pidl
);
897 This
->current_pidl
= NULL
;
899 DestroyWindow(This
->hwnd_main
);
900 This
->destroyed
= TRUE
;
905 static HRESULT WINAPI
IExplorerBrowser_fnSetRect(IExplorerBrowser
*iface
,
906 HDWP
*phdwp
, RECT rcBrowser
)
908 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
909 TRACE("%p (%p, %s)\n", This
, phdwp
, wine_dbgstr_rect(&rcBrowser
));
913 *phdwp
= DeferWindowPos(*phdwp
, This
->hwnd_main
, NULL
, rcBrowser
.left
, rcBrowser
.top
,
914 rcBrowser
.right
- rcBrowser
.left
, rcBrowser
.bottom
- rcBrowser
.top
,
915 SWP_NOZORDER
| SWP_NOACTIVATE
);
919 MoveWindow(This
->hwnd_main
, rcBrowser
.left
, rcBrowser
.top
,
920 rcBrowser
.right
- rcBrowser
.left
, rcBrowser
.bottom
- rcBrowser
.top
, TRUE
);
926 static HRESULT WINAPI
IExplorerBrowser_fnSetPropertyBag(IExplorerBrowser
*iface
,
927 LPCWSTR pszPropertyBag
)
929 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
930 FIXME("stub, %p (%s)\n", This
, debugstr_w(pszPropertyBag
));
935 static HRESULT WINAPI
IExplorerBrowser_fnSetEmptyText(IExplorerBrowser
*iface
,
936 LPCWSTR pszEmptyText
)
938 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
939 FIXME("stub, %p (%s)\n", This
, debugstr_w(pszEmptyText
));
944 static HRESULT WINAPI
IExplorerBrowser_fnSetFolderSettings(IExplorerBrowser
*iface
,
945 const FOLDERSETTINGS
*pfs
)
947 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
948 TRACE("%p (%p)\n", This
, pfs
);
953 This
->fs
.ViewMode
= pfs
->ViewMode
;
954 This
->fs
.fFlags
= pfs
->fFlags
| FWF_NOCLIENTEDGE
;
956 /* Change the settings of the current view, if any. */
957 return change_viewmode(This
, This
->fs
.ViewMode
);
960 static HRESULT WINAPI
IExplorerBrowser_fnAdvise(IExplorerBrowser
*iface
,
961 IExplorerBrowserEvents
*psbe
,
964 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
965 event_client
*client
;
966 TRACE("%p (%p, %p)\n", This
, psbe
, pdwCookie
);
968 client
= HeapAlloc(GetProcessHeap(), 0, sizeof(event_client
));
970 client
->cookie
= ++This
->events_next_cookie
;
972 IExplorerBrowserEvents_AddRef(psbe
);
973 *pdwCookie
= client
->cookie
;
975 list_add_tail(&This
->event_clients
, &client
->entry
);
980 static HRESULT WINAPI
IExplorerBrowser_fnUnadvise(IExplorerBrowser
*iface
,
983 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
984 event_client
*client
;
985 TRACE("%p (0x%x)\n", This
, dwCookie
);
987 LIST_FOR_EACH_ENTRY(client
, &This
->event_clients
, event_client
, entry
)
989 if(client
->cookie
== dwCookie
)
991 list_remove(&client
->entry
);
992 IExplorerBrowserEvents_Release(client
->pebe
);
993 HeapFree(GetProcessHeap(), 0, client
);
1001 static HRESULT WINAPI
IExplorerBrowser_fnSetOptions(IExplorerBrowser
*iface
,
1002 EXPLORER_BROWSER_OPTIONS dwFlag
)
1004 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
1005 static const EXPLORER_BROWSER_OPTIONS unsupported_options
=
1006 EBO_ALWAYSNAVIGATE
| EBO_NOWRAPPERWINDOW
| EBO_HTMLSHAREPOINTVIEW
;
1008 TRACE("%p (0x%x)\n", This
, dwFlag
);
1010 if(dwFlag
& unsupported_options
)
1011 FIXME("Flags 0x%08x contains unsupported options.\n", dwFlag
);
1013 This
->eb_options
= dwFlag
;
1018 static HRESULT WINAPI
IExplorerBrowser_fnGetOptions(IExplorerBrowser
*iface
,
1019 EXPLORER_BROWSER_OPTIONS
*pdwFlag
)
1021 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
1022 TRACE("%p (%p)\n", This
, pdwFlag
);
1024 *pdwFlag
= This
->eb_options
;
1029 static HRESULT WINAPI
IExplorerBrowser_fnBrowseToIDList(IExplorerBrowser
*iface
,
1030 PCUIDLIST_RELATIVE pidl
,
1033 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
1034 LPITEMIDLIST absolute_pidl
= NULL
;
1036 static const UINT unsupported_browse_flags
=
1037 SBSP_NEWBROWSER
| EBF_SELECTFROMDATAOBJECT
| EBF_NODROPTARGET
;
1038 TRACE("%p (%p, 0x%x)\n", This
, pidl
, uFlags
);
1040 if(!This
->hwnd_main
)
1044 return HRESULT_FROM_WIN32(ERROR_BUSY
);
1046 if(This
->current_pidl
&& (This
->eb_options
& EBO_NAVIGATEONCE
))
1049 if(uFlags
& SBSP_EXPLOREMODE
)
1050 return E_INVALIDARG
;
1052 if(uFlags
& unsupported_browse_flags
)
1053 FIXME("Argument 0x%x contains unsupported flags.\n", uFlags
);
1055 if(uFlags
& SBSP_NAVIGATEBACK
)
1057 TRACE("SBSP_NAVIGATEBACK\n");
1058 absolute_pidl
= ILClone(travellog_go_back(This
));
1059 if(!absolute_pidl
&& !This
->current_pidl
)
1061 else if(!absolute_pidl
)
1065 else if(uFlags
& SBSP_NAVIGATEFORWARD
)
1067 TRACE("SBSP_NAVIGATEFORWARD\n");
1068 absolute_pidl
= ILClone(travellog_go_forward(This
));
1069 if(!absolute_pidl
&& !This
->current_pidl
)
1071 else if(!absolute_pidl
)
1075 else if(uFlags
& SBSP_PARENT
)
1077 if(This
->current_pidl
)
1079 if(_ILIsPidlSimple(This
->current_pidl
))
1081 absolute_pidl
= _ILCreateDesktop();
1085 absolute_pidl
= ILClone(This
->current_pidl
);
1086 ILRemoveLastID(absolute_pidl
);
1091 ERR("Failed to get parent pidl.\n");
1096 else if(uFlags
& SBSP_RELATIVE
)
1098 /* SBSP_RELATIVE has precedence over SBSP_ABSOLUTE */
1099 TRACE("SBSP_RELATIVE\n");
1100 if(This
->current_pidl
)
1102 absolute_pidl
= ILCombine(This
->current_pidl
, pidl
);
1106 ERR("Failed to get absolute pidl.\n");
1112 TRACE("SBSP_ABSOLUTE\n");
1113 absolute_pidl
= ILClone(pidl
);
1114 if(!absolute_pidl
&& !This
->current_pidl
)
1115 return E_INVALIDARG
;
1116 else if(!absolute_pidl
)
1120 /* TODO: Asynchronous browsing. Return S_OK here and finish in
1121 * another thread. */
1123 hr
= events_NavigationPending(This
, absolute_pidl
);
1126 TRACE("Browsing aborted.\n");
1127 ILFree(absolute_pidl
);
1131 get_interfaces_from_site(This
);
1132 update_panestate(This
);
1134 /* Only browse if the new pidl differs from the old */
1135 if(!ILIsEqual(This
->current_pidl
, absolute_pidl
))
1138 hr
= SHCreateItemFromIDList(absolute_pidl
, &IID_IShellItem
, (void**)&psi
);
1141 hr
= create_new_shellview(This
, psi
);
1144 events_NavigationFailed(This
, absolute_pidl
);
1145 ILFree(absolute_pidl
);
1146 IShellItem_Release(psi
);
1150 /* Add to travellog */
1151 if( !(This
->eb_options
& EBO_NOTRAVELLOG
) &&
1152 !(uFlags
& (SBSP_NAVIGATEFORWARD
|SBSP_NAVIGATEBACK
)) )
1154 travellog_add_entry(This
, absolute_pidl
);
1157 IShellItem_Release(psi
);
1161 events_NavigationComplete(This
, absolute_pidl
);
1162 ILFree(This
->current_pidl
);
1163 This
->current_pidl
= absolute_pidl
;
1165 /* Expand the NameSpaceTree to the current location. */
1166 if(This
->navpane
.show
&& This
->navpane
.pnstc2
)
1169 hr
= SHCreateItemFromIDList(This
->current_pidl
, &IID_IShellItem
, (void**)&psi
);
1172 INameSpaceTreeControl_EnsureItemVisible(This
->navpane
.pnstc2
, psi
);
1173 IShellItem_Release(psi
);
1180 static HRESULT WINAPI
IExplorerBrowser_fnBrowseToObject(IExplorerBrowser
*iface
,
1181 IUnknown
*punk
, UINT uFlags
)
1183 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
1186 TRACE("%p (%p, 0x%x)\n", This
, punk
, uFlags
);
1189 return IExplorerBrowser_fnBrowseToIDList(iface
, NULL
, uFlags
);
1191 hr
= SHGetIDListFromObject(punk
, &pidl
);
1194 hr
= IExplorerBrowser_BrowseToIDList(iface
, pidl
, uFlags
);
1201 static HRESULT WINAPI
IExplorerBrowser_fnFillFromObject(IExplorerBrowser
*iface
,
1203 EXPLORER_BROWSER_FILL_FLAGS dwFlags
)
1205 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
1206 FIXME("stub, %p (%p, 0x%x)\n", This
, punk
, dwFlags
);
1211 static HRESULT WINAPI
IExplorerBrowser_fnRemoveAll(IExplorerBrowser
*iface
)
1213 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
1214 FIXME("stub, %p\n", This
);
1219 static HRESULT WINAPI
IExplorerBrowser_fnGetCurrentView(IExplorerBrowser
*iface
,
1220 REFIID riid
, void **ppv
)
1222 ExplorerBrowserImpl
*This
= (ExplorerBrowserImpl
*)iface
;
1223 TRACE("%p (%s, %p)\n", This
, shdebugstr_guid(riid
), ppv
);
1228 return IShellView_QueryInterface(This
->psv
, riid
, ppv
);
1231 static const IExplorerBrowserVtbl vt_IExplorerBrowser
=
1233 IExplorerBrowser_fnQueryInterface
,
1234 IExplorerBrowser_fnAddRef
,
1235 IExplorerBrowser_fnRelease
,
1236 IExplorerBrowser_fnInitialize
,
1237 IExplorerBrowser_fnDestroy
,
1238 IExplorerBrowser_fnSetRect
,
1239 IExplorerBrowser_fnSetPropertyBag
,
1240 IExplorerBrowser_fnSetEmptyText
,
1241 IExplorerBrowser_fnSetFolderSettings
,
1242 IExplorerBrowser_fnAdvise
,
1243 IExplorerBrowser_fnUnadvise
,
1244 IExplorerBrowser_fnSetOptions
,
1245 IExplorerBrowser_fnGetOptions
,
1246 IExplorerBrowser_fnBrowseToIDList
,
1247 IExplorerBrowser_fnBrowseToObject
,
1248 IExplorerBrowser_fnFillFromObject
,
1249 IExplorerBrowser_fnRemoveAll
,
1250 IExplorerBrowser_fnGetCurrentView
1253 /**************************************************************************
1254 * IShellBrowser Implementation
1257 static inline ExplorerBrowserImpl
*impl_from_IShellBrowser(IShellBrowser
*iface
)
1259 return (ExplorerBrowserImpl
*)((char*)iface
- FIELD_OFFSET(ExplorerBrowserImpl
, lpsbVtbl
));
1262 static HRESULT WINAPI
IShellBrowser_fnQueryInterface(IShellBrowser
*iface
,
1263 REFIID riid
, void **ppvObject
)
1265 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
1266 TRACE("%p\n", This
);
1267 return IUnknown_QueryInterface((IUnknown
*) This
, riid
, ppvObject
);
1270 static ULONG WINAPI
IShellBrowser_fnAddRef(IShellBrowser
*iface
)
1272 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
1273 TRACE("%p\n", This
);
1274 return IUnknown_AddRef((IUnknown
*) This
);
1277 static ULONG WINAPI
IShellBrowser_fnRelease(IShellBrowser
*iface
)
1279 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
1280 TRACE("%p\n", This
);
1281 return IUnknown_Release((IUnknown
*) This
);
1284 static HRESULT WINAPI
IShellBrowser_fnGetWindow(IShellBrowser
*iface
, HWND
*phwnd
)
1286 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
1287 TRACE("%p (%p)\n", This
, phwnd
);
1289 if(!This
->hwnd_main
)
1292 *phwnd
= This
->hwnd_main
;
1296 static HRESULT WINAPI
IShellBrowser_fnContextSensitiveHelp(IShellBrowser
*iface
,
1299 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
1300 FIXME("stub, %p (%d)\n", This
, fEnterMode
);
1305 static HRESULT WINAPI
IShellBrowser_fnInsertMenusSB(IShellBrowser
*iface
,
1307 LPOLEMENUGROUPWIDTHS lpMenuWidths
)
1309 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
1310 TRACE("%p (%p, %p)\n", This
, hmenuShared
, lpMenuWidths
);
1312 /* Not implemented. */
1316 static HRESULT WINAPI
IShellBrowser_fnSetMenuSB(IShellBrowser
*iface
,
1318 HOLEMENU holemenuReserved
,
1319 HWND hwndActiveObject
)
1321 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
1322 TRACE("%p (%p, %p, %p)\n", This
, hmenuShared
, holemenuReserved
, hwndActiveObject
);
1324 /* Not implemented. */
1328 static HRESULT WINAPI
IShellBrowser_fnRemoveMenusSB(IShellBrowser
*iface
,
1331 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
1332 TRACE("%p (%p)\n", This
, hmenuShared
);
1334 /* Not implemented. */
1338 static HRESULT WINAPI
IShellBrowser_fnSetStatusTextSB(IShellBrowser
*iface
,
1339 LPCOLESTR pszStatusText
)
1341 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
1342 FIXME("stub, %p (%s)\n", This
, debugstr_w(pszStatusText
));
1347 static HRESULT WINAPI
IShellBrowser_fnEnableModelessSB(IShellBrowser
*iface
,
1350 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
1351 FIXME("stub, %p (%d)\n", This
, fEnable
);
1356 static HRESULT WINAPI
IShellBrowser_fnTranslateAcceleratorSB(IShellBrowser
*iface
,
1357 MSG
*pmsg
, WORD wID
)
1359 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
1360 FIXME("stub, %p (%p, 0x%x)\n", This
, pmsg
, wID
);
1365 static HRESULT WINAPI
IShellBrowser_fnBrowseObject(IShellBrowser
*iface
,
1366 LPCITEMIDLIST pidl
, UINT wFlags
)
1368 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
1369 TRACE("%p (%p, %x)\n", This
, pidl
, wFlags
);
1371 return IExplorerBrowser_fnBrowseToIDList((IExplorerBrowser
*)This
, pidl
, wFlags
);
1374 static HRESULT WINAPI
IShellBrowser_fnGetViewStateStream(IShellBrowser
*iface
,
1378 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
1379 FIXME("stub, %p (0x%x, %p)\n", This
, grfMode
, ppStrm
);
1385 static HRESULT WINAPI
IShellBrowser_fnGetControlWindow(IShellBrowser
*iface
,
1386 UINT id
, HWND
*phwnd
)
1388 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
1389 TRACE("%p (%d, %p)\n", This
, id
, phwnd
);
1391 /* Not implemented. */
1395 static HRESULT WINAPI
IShellBrowser_fnSendControlMsg(IShellBrowser
*iface
,
1397 WPARAM wParam
, LPARAM lParam
,
1400 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
1401 FIXME("stub, %p (%d, %d, %lx, %lx, %p)\n", This
, id
, uMsg
, wParam
, lParam
, pret
);
1406 static HRESULT WINAPI
IShellBrowser_fnQueryActiveShellView(IShellBrowser
*iface
,
1409 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
1410 TRACE("%p (%p)\n", This
, ppshv
);
1416 IShellView_AddRef(This
->psv
);
1421 static HRESULT WINAPI
IShellBrowser_fnOnViewWindowActive(IShellBrowser
*iface
,
1424 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
1425 FIXME("stub, %p (%p)\n", This
, pshv
);
1430 static HRESULT WINAPI
IShellBrowser_fnSetToolbarItems(IShellBrowser
*iface
,
1431 LPTBBUTTONSB lpButtons
,
1432 UINT nButtons
, UINT uFlags
)
1434 ExplorerBrowserImpl
*This
= impl_from_IShellBrowser(iface
);
1435 FIXME("stub, %p (%p, %d, 0x%x)\n", This
, lpButtons
, nButtons
, uFlags
);
1440 static const IShellBrowserVtbl vt_IShellBrowser
= {
1441 IShellBrowser_fnQueryInterface
,
1442 IShellBrowser_fnAddRef
,
1443 IShellBrowser_fnRelease
,
1444 IShellBrowser_fnGetWindow
,
1445 IShellBrowser_fnContextSensitiveHelp
,
1446 IShellBrowser_fnInsertMenusSB
,
1447 IShellBrowser_fnSetMenuSB
,
1448 IShellBrowser_fnRemoveMenusSB
,
1449 IShellBrowser_fnSetStatusTextSB
,
1450 IShellBrowser_fnEnableModelessSB
,
1451 IShellBrowser_fnTranslateAcceleratorSB
,
1452 IShellBrowser_fnBrowseObject
,
1453 IShellBrowser_fnGetViewStateStream
,
1454 IShellBrowser_fnGetControlWindow
,
1455 IShellBrowser_fnSendControlMsg
,
1456 IShellBrowser_fnQueryActiveShellView
,
1457 IShellBrowser_fnOnViewWindowActive
,
1458 IShellBrowser_fnSetToolbarItems
1461 /**************************************************************************
1462 * ICommDlgBrowser3 Implementation
1465 static inline ExplorerBrowserImpl
*impl_from_ICommDlgBrowser3(ICommDlgBrowser3
*iface
)
1467 return (ExplorerBrowserImpl
*)((char*)iface
- FIELD_OFFSET(ExplorerBrowserImpl
, lpcdb3Vtbl
));
1470 static HRESULT WINAPI
ICommDlgBrowser3_fnQueryInterface(ICommDlgBrowser3
*iface
,
1474 ExplorerBrowserImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
1475 TRACE("%p\n", This
);
1476 return IUnknown_QueryInterface((IUnknown
*) This
, riid
, ppvObject
);
1479 static ULONG WINAPI
ICommDlgBrowser3_fnAddRef(ICommDlgBrowser3
*iface
)
1481 ExplorerBrowserImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
1482 TRACE("%p\n", This
);
1483 return IUnknown_AddRef((IUnknown
*) This
);
1486 static ULONG WINAPI
ICommDlgBrowser3_fnRelease(ICommDlgBrowser3
*iface
)
1488 ExplorerBrowserImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
1489 TRACE("%p\n", This
);
1490 return IUnknown_Release((IUnknown
*) This
);
1493 static HRESULT WINAPI
ICommDlgBrowser3_fnOnDefaultCommand(ICommDlgBrowser3
*iface
,
1496 ExplorerBrowserImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
1499 HRESULT ret
= S_FALSE
;
1501 TRACE("%p (%p)\n", This
, shv
);
1503 hr
= IShellView_GetItemObject(shv
, SVGIO_SELECTION
, &IID_IDataObject
, (void**)&pdo
);
1509 fmt
.cfFormat
= RegisterClipboardFormatW(CFSTR_SHELLIDLISTW
);
1511 fmt
.dwAspect
= DVASPECT_CONTENT
;
1513 fmt
.tymed
= TYMED_HGLOBAL
;
1515 hr
= IDataObject_GetData(pdo
, &fmt
,&medium
);
1516 IDataObject_Release(pdo
);
1519 LPIDA pida
= GlobalLock(medium
.u
.hGlobal
);
1520 LPCITEMIDLIST pidl_child
= (LPCITEMIDLIST
) ((LPBYTE
)pida
+pida
->aoffset
[1]);
1522 /* Handle folders by browsing to them. */
1523 if(_ILIsFolder(pidl_child
) || _ILIsDrive(pidl_child
) || _ILIsSpecialFolder(pidl_child
))
1525 IExplorerBrowser_BrowseToIDList((IExplorerBrowser
*)This
, pidl_child
, SBSP_RELATIVE
);
1528 GlobalUnlock(medium
.u
.hGlobal
);
1529 GlobalFree(medium
.u
.hGlobal
);
1532 ERR("Failed to get data from IDataObject.\n");
1534 ERR("Failed to get IDataObject.\n");
1536 /* If we didn't handle the default command, check if we have a
1537 * client that does */
1538 if(ret
== S_FALSE
&& This
->pcdb_site
)
1539 return ICommDlgBrowser_OnDefaultCommand(This
->pcdb_site
, shv
);
1543 static HRESULT WINAPI
ICommDlgBrowser3_fnOnStateChange(ICommDlgBrowser3
*iface
,
1544 IShellView
*shv
, ULONG uChange
)
1546 ExplorerBrowserImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
1547 TRACE("%p (%p, %d)\n", This
, shv
, uChange
);
1550 return ICommDlgBrowser_OnStateChange(This
->pcdb_site
, shv
, uChange
);
1554 static HRESULT WINAPI
ICommDlgBrowser3_fnIncludeObject(ICommDlgBrowser3
*iface
,
1555 IShellView
*pshv
, LPCITEMIDLIST pidl
)
1557 ExplorerBrowserImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
1558 TRACE("%p (%p, %p)\n", This
, pshv
, pidl
);
1561 return ICommDlgBrowser_IncludeObject(This
->pcdb_site
, pshv
, pidl
);
1566 static HRESULT WINAPI
ICommDlgBrowser3_fnNotify(ICommDlgBrowser3
*iface
,
1570 ExplorerBrowserImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
1571 TRACE("%p (%p, 0x%x)\n", This
, pshv
, dwNotifyType
);
1573 if(This
->pcdb2_site
)
1574 return ICommDlgBrowser2_Notify(This
->pcdb2_site
, pshv
, dwNotifyType
);
1579 static HRESULT WINAPI
ICommDlgBrowser3_fnGetDefaultMenuText(ICommDlgBrowser3
*iface
,
1581 LPWSTR pszText
, int cchMax
)
1583 ExplorerBrowserImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
1584 TRACE("%p (%p, %s, %d)\n", This
, pshv
, debugstr_w(pszText
), cchMax
);
1586 if(This
->pcdb2_site
)
1587 return ICommDlgBrowser2_GetDefaultMenuText(This
->pcdb2_site
, pshv
, pszText
, cchMax
);
1592 static HRESULT WINAPI
ICommDlgBrowser3_fnGetViewFlags(ICommDlgBrowser3
*iface
,
1595 ExplorerBrowserImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
1596 TRACE("%p (%p)\n", This
, pdwFlags
);
1598 if(This
->pcdb2_site
)
1599 return ICommDlgBrowser2_GetViewFlags(This
->pcdb2_site
, pdwFlags
);
1604 static HRESULT WINAPI
ICommDlgBrowser3_fnOnColumnClicked(ICommDlgBrowser3
*iface
,
1605 IShellView
*pshv
, int iColumn
)
1607 ExplorerBrowserImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
1608 TRACE("%p (%p, %d)\n", This
, pshv
, iColumn
);
1610 if(This
->pcdb3_site
)
1611 return ICommDlgBrowser3_OnColumnClicked(This
->pcdb3_site
, pshv
, iColumn
);
1616 static HRESULT WINAPI
ICommDlgBrowser3_fnGetCurrentFilter(ICommDlgBrowser3
*iface
,
1620 ExplorerBrowserImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
1621 TRACE("%p (%s, %d)\n", This
, debugstr_w(pszFileSpec
), cchFileSpec
);
1623 if(This
->pcdb3_site
)
1624 return ICommDlgBrowser3_GetCurrentFilter(This
->pcdb3_site
, pszFileSpec
, cchFileSpec
);
1629 static HRESULT WINAPI
ICommDlgBrowser3_fnOnPreviewCreated(ICommDlgBrowser3
*iface
,
1632 ExplorerBrowserImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
1633 TRACE("%p (%p)\n", This
, pshv
);
1635 if(This
->pcdb3_site
)
1636 return ICommDlgBrowser3_OnPreviewCreated(This
->pcdb3_site
, pshv
);
1641 static const ICommDlgBrowser3Vtbl vt_ICommDlgBrowser3
= {
1642 ICommDlgBrowser3_fnQueryInterface
,
1643 ICommDlgBrowser3_fnAddRef
,
1644 ICommDlgBrowser3_fnRelease
,
1645 ICommDlgBrowser3_fnOnDefaultCommand
,
1646 ICommDlgBrowser3_fnOnStateChange
,
1647 ICommDlgBrowser3_fnIncludeObject
,
1648 ICommDlgBrowser3_fnNotify
,
1649 ICommDlgBrowser3_fnGetDefaultMenuText
,
1650 ICommDlgBrowser3_fnGetViewFlags
,
1651 ICommDlgBrowser3_fnOnColumnClicked
,
1652 ICommDlgBrowser3_fnGetCurrentFilter
,
1653 ICommDlgBrowser3_fnOnPreviewCreated
1656 /**************************************************************************
1657 * IObjectWithSite Implementation
1660 static inline ExplorerBrowserImpl
*impl_from_IObjectWithSite(IObjectWithSite
*iface
)
1662 return (ExplorerBrowserImpl
*)((char*)iface
- FIELD_OFFSET(ExplorerBrowserImpl
, lpowsVtbl
));
1665 static HRESULT WINAPI
IObjectWithSite_fnQueryInterface(IObjectWithSite
*iface
,
1666 REFIID riid
, void **ppvObject
)
1668 ExplorerBrowserImpl
*This
= impl_from_IObjectWithSite(iface
);
1669 TRACE("%p\n", This
);
1670 return IUnknown_QueryInterface((IUnknown
*)This
, riid
, ppvObject
);
1673 static ULONG WINAPI
IObjectWithSite_fnAddRef(IObjectWithSite
*iface
)
1675 ExplorerBrowserImpl
*This
= impl_from_IObjectWithSite(iface
);
1676 TRACE("%p\n", This
);
1677 return IUnknown_AddRef((IUnknown
*)This
);
1680 static ULONG WINAPI
IObjectWithSite_fnRelease(IObjectWithSite
*iface
)
1682 ExplorerBrowserImpl
*This
= impl_from_IObjectWithSite(iface
);
1683 TRACE("%p\n", This
);
1684 return IUnknown_Release((IUnknown
*)This
);
1687 static HRESULT WINAPI
IObjectWithSite_fnSetSite(IObjectWithSite
*iface
, IUnknown
*punk_site
)
1689 ExplorerBrowserImpl
*This
= impl_from_IObjectWithSite(iface
);
1690 TRACE("%p (%p)\n", This
, punk_site
);
1694 IUnknown_Release(This
->punk_site
);
1695 This
->punk_site
= NULL
;
1696 get_interfaces_from_site(This
);
1699 This
->punk_site
= punk_site
;
1702 IUnknown_AddRef(This
->punk_site
);
1707 static HRESULT WINAPI
IObjectWithSite_fnGetSite(IObjectWithSite
*iface
, REFIID riid
, void **ppvSite
)
1709 ExplorerBrowserImpl
*This
= impl_from_IObjectWithSite(iface
);
1710 TRACE("%p (%s, %p)\n", This
, shdebugstr_guid(riid
), ppvSite
);
1712 if(!This
->punk_site
)
1715 return IUnknown_QueryInterface(This
->punk_site
, riid
, ppvSite
);
1718 static const IObjectWithSiteVtbl vt_IObjectWithSite
= {
1719 IObjectWithSite_fnQueryInterface
,
1720 IObjectWithSite_fnAddRef
,
1721 IObjectWithSite_fnRelease
,
1722 IObjectWithSite_fnSetSite
,
1723 IObjectWithSite_fnGetSite
1726 /**************************************************************************
1727 * INameSpaceTreeControlEvents Implementation
1729 static inline ExplorerBrowserImpl
*impl_from_INameSpaceTreeControlEvents(INameSpaceTreeControlEvents
*iface
)
1731 return (ExplorerBrowserImpl
*)((char*)iface
- FIELD_OFFSET(ExplorerBrowserImpl
, lpnstceVtbl
));
1734 static HRESULT WINAPI
NSTCEvents_fnQueryInterface(INameSpaceTreeControlEvents
*iface
,
1735 REFIID riid
, void **ppvObject
)
1737 ExplorerBrowserImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
1738 TRACE("%p (%s, %p)\n", This
, shdebugstr_guid(riid
), ppvObject
);
1741 if(IsEqualIID(riid
, &IID_INameSpaceTreeControlEvents
) ||
1742 IsEqualIID(riid
, &IID_IUnknown
))
1749 IUnknown_AddRef((IUnknown
*)*ppvObject
);
1753 return E_NOINTERFACE
;
1756 static ULONG WINAPI
NSTCEvents_fnAddRef(INameSpaceTreeControlEvents
*iface
)
1758 ExplorerBrowserImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
1759 TRACE("%p\n", This
);
1760 return IUnknown_AddRef((IUnknown
*)This
);
1763 static ULONG WINAPI
NSTCEvents_fnRelease(INameSpaceTreeControlEvents
*iface
)
1765 ExplorerBrowserImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
1766 TRACE("%p\n", This
);
1767 return IUnknown_Release((IUnknown
*)This
);
1770 static HRESULT WINAPI
NSTCEvents_fnOnItemClick(INameSpaceTreeControlEvents
*iface
,
1772 NSTCEHITTEST nstceHitTest
,
1773 NSTCECLICKTYPE nstceClickType
)
1775 ExplorerBrowserImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
1776 TRACE("%p (%p, 0x%x, 0x%x)\n", This
, psi
, nstceHitTest
, nstceClickType
);
1780 static HRESULT WINAPI
NSTCEvents_fnOnPropertyItemCommit(INameSpaceTreeControlEvents
*iface
,
1783 ExplorerBrowserImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
1784 TRACE("%p (%p)\n", This
, psi
);
1788 static HRESULT WINAPI
NSTCEvents_fnOnItemStateChanging(INameSpaceTreeControlEvents
*iface
,
1790 NSTCITEMSTATE nstcisMask
,
1791 NSTCITEMSTATE nstcisState
)
1793 ExplorerBrowserImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
1794 TRACE("%p (%p, 0x%x, 0x%x)\n", This
, psi
, nstcisMask
, nstcisState
);
1798 static HRESULT WINAPI
NSTCEvents_fnOnItemStateChanged(INameSpaceTreeControlEvents
*iface
,
1800 NSTCITEMSTATE nstcisMask
,
1801 NSTCITEMSTATE nstcisState
)
1803 ExplorerBrowserImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
1804 TRACE("%p (%p, 0x%x, 0x%x)\n", This
, psi
, nstcisMask
, nstcisState
);
1808 static HRESULT WINAPI
NSTCEvents_fnOnSelectionChanged(INameSpaceTreeControlEvents
*iface
,
1809 IShellItemArray
*psiaSelection
)
1811 ExplorerBrowserImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
1812 TRACE("%p (%p)\n", This
, psiaSelection
);
1816 static HRESULT WINAPI
NSTCEvents_fnOnKeyboardInput(INameSpaceTreeControlEvents
*iface
,
1817 UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
1819 ExplorerBrowserImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
1820 TRACE("%p (%d, 0x%lx, 0x%lx)\n", This
, uMsg
, wParam
, lParam
);
1824 static HRESULT WINAPI
NSTCEvents_fnOnBeforeExpand(INameSpaceTreeControlEvents
*iface
,
1827 ExplorerBrowserImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
1828 TRACE("%p (%p)\n", This
, psi
);
1832 static HRESULT WINAPI
NSTCEvents_fnOnAfterExpand(INameSpaceTreeControlEvents
*iface
,
1835 ExplorerBrowserImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
1836 TRACE("%p (%p)\n", This
, psi
);
1840 static HRESULT WINAPI
NSTCEvents_fnOnBeginLabelEdit(INameSpaceTreeControlEvents
*iface
,
1843 ExplorerBrowserImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
1844 TRACE("%p (%p)\n", This
, psi
);
1848 static HRESULT WINAPI
NSTCEvents_fnOnEndLabelEdit(INameSpaceTreeControlEvents
*iface
,
1851 ExplorerBrowserImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
1852 TRACE("%p (%p)\n", This
, psi
);
1856 static HRESULT WINAPI
NSTCEvents_fnOnGetToolTip(INameSpaceTreeControlEvents
*iface
,
1857 IShellItem
*psi
, LPWSTR pszTip
, int cchTip
)
1859 ExplorerBrowserImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
1860 TRACE("%p (%p, %p, %d)\n", This
, psi
, pszTip
, cchTip
);
1864 static HRESULT WINAPI
NSTCEvents_fnOnBeforeItemDelete(INameSpaceTreeControlEvents
*iface
,
1867 ExplorerBrowserImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
1868 TRACE("%p (%p)\n", This
, psi
);
1872 static HRESULT WINAPI
NSTCEvents_fnOnItemAdded(INameSpaceTreeControlEvents
*iface
,
1873 IShellItem
*psi
, BOOL fIsRoot
)
1875 ExplorerBrowserImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
1876 TRACE("%p (%p, %d)\n", This
, psi
, fIsRoot
);
1880 static HRESULT WINAPI
NSTCEvents_fnOnItemDeleted(INameSpaceTreeControlEvents
*iface
,
1881 IShellItem
*psi
, BOOL fIsRoot
)
1883 ExplorerBrowserImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
1884 TRACE("%p (%p, %d)\n", This
, psi
, fIsRoot
);
1888 static HRESULT WINAPI
NSTCEvents_fnOnBeforeContextMenu(INameSpaceTreeControlEvents
*iface
,
1889 IShellItem
*psi
, REFIID riid
, void **ppv
)
1891 ExplorerBrowserImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
1892 TRACE("%p (%p, %s, %p)\n", This
, psi
, shdebugstr_guid(riid
), ppv
);
1896 static HRESULT WINAPI
NSTCEvents_fnOnAfterContextMenu(INameSpaceTreeControlEvents
*iface
,
1897 IShellItem
*psi
, IContextMenu
*pcmIn
,
1898 REFIID riid
, void **ppv
)
1900 ExplorerBrowserImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
1901 TRACE("%p (%p, %p, %s, %p)\n", This
, psi
, pcmIn
, shdebugstr_guid(riid
), ppv
);
1905 static HRESULT WINAPI
NSTCEvents_fnOnBeforeStateImageChange(INameSpaceTreeControlEvents
*iface
,
1908 ExplorerBrowserImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
1909 TRACE("%p (%p)\n", This
, psi
);
1913 static HRESULT WINAPI
NSTCEvents_fnOnGetDefaultIconIndex(INameSpaceTreeControlEvents
* iface
,
1915 int *piDefaultIcon
, int *piOpenIcon
)
1917 ExplorerBrowserImpl
*This
= impl_from_INameSpaceTreeControlEvents(iface
);
1918 TRACE("%p (%p, %p, %p)\n", This
, psi
, piDefaultIcon
, piOpenIcon
);
1923 const INameSpaceTreeControlEventsVtbl vt_INameSpaceTreeControlEvents
= {
1924 NSTCEvents_fnQueryInterface
,
1925 NSTCEvents_fnAddRef
,
1926 NSTCEvents_fnRelease
,
1927 NSTCEvents_fnOnItemClick
,
1928 NSTCEvents_fnOnPropertyItemCommit
,
1929 NSTCEvents_fnOnItemStateChanging
,
1930 NSTCEvents_fnOnItemStateChanged
,
1931 NSTCEvents_fnOnSelectionChanged
,
1932 NSTCEvents_fnOnKeyboardInput
,
1933 NSTCEvents_fnOnBeforeExpand
,
1934 NSTCEvents_fnOnAfterExpand
,
1935 NSTCEvents_fnOnBeginLabelEdit
,
1936 NSTCEvents_fnOnEndLabelEdit
,
1937 NSTCEvents_fnOnGetToolTip
,
1938 NSTCEvents_fnOnBeforeItemDelete
,
1939 NSTCEvents_fnOnItemAdded
,
1940 NSTCEvents_fnOnItemDeleted
,
1941 NSTCEvents_fnOnBeforeContextMenu
,
1942 NSTCEvents_fnOnAfterContextMenu
,
1943 NSTCEvents_fnOnBeforeStateImageChange
,
1944 NSTCEvents_fnOnGetDefaultIconIndex
1947 HRESULT WINAPI
ExplorerBrowser_Constructor(IUnknown
*pUnkOuter
, REFIID riid
, void **ppv
)
1949 ExplorerBrowserImpl
*eb
;
1952 TRACE("%p %s %p\n", pUnkOuter
, shdebugstr_guid (riid
), ppv
);
1957 return CLASS_E_NOAGGREGATION
;
1959 eb
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(ExplorerBrowserImpl
));
1961 eb
->lpVtbl
= &vt_IExplorerBrowser
;
1962 eb
->lpsbVtbl
= &vt_IShellBrowser
;
1963 eb
->lpcdb3Vtbl
= &vt_ICommDlgBrowser3
;
1964 eb
->lpowsVtbl
= &vt_IObjectWithSite
;
1965 eb
->lpnstceVtbl
= &vt_INameSpaceTreeControlEvents
;
1967 /* Default settings */
1968 eb
->navpane
.width
= 150;
1969 eb
->navpane
.show
= TRUE
;
1971 list_init(&eb
->event_clients
);
1972 list_init(&eb
->travellog
);
1974 ret
= IExplorerBrowser_QueryInterface((IExplorerBrowser
*)eb
, riid
, ppv
);
1975 IExplorerBrowser_Release((IExplorerBrowser
*)eb
);
1977 TRACE("--(%p)\n", ppv
);