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);