user32/tests: Fix monitor test failures on some systems.
[wine.git] / dlls / shell32 / ebrowser.c
blob637104c58dcec639d6d3f57a1fe6f34997f9dbf0
1 /*
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
21 #include <stdarg.h>
23 #define COBJMACROS
24 #define NONAMELESSUNION
26 #include "winerror.h"
27 #include "windef.h"
28 #include "winbase.h"
30 #include "wine/list.h"
31 #include "wine/debug.h"
32 #include "debughlp.h"
34 #include "shell32_main.h"
35 #include "pidl.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(shell);
39 #define SPLITTER_WIDTH 2
40 #define NP_MIN_WIDTH 60
41 #define NP_DEFAULT_WIDTH 150
42 #define SV_MIN_WIDTH 150
44 typedef struct _event_client {
45 struct list entry;
46 IExplorerBrowserEvents *pebe;
47 DWORD cookie;
48 } event_client;
50 typedef struct _travellog_entry {
51 struct list entry;
52 LPITEMIDLIST pidl;
53 } travellog_entry;
55 typedef struct _ExplorerBrowserImpl {
56 IExplorerBrowser IExplorerBrowser_iface;
57 IShellBrowser IShellBrowser_iface;
58 ICommDlgBrowser3 ICommDlgBrowser3_iface;
59 IObjectWithSite IObjectWithSite_iface;
60 INameSpaceTreeControlEvents INameSpaceTreeControlEvents_iface;
61 IInputObject IInputObject_iface;
62 LONG ref;
63 BOOL destroyed;
65 HWND hwnd_main;
66 HWND hwnd_sv;
68 RECT splitter_rc;
69 struct {
70 INameSpaceTreeControl2 *pnstc2;
71 HWND hwnd_splitter, hwnd_nstc;
72 DWORD nstc_cookie;
73 UINT width;
74 BOOL show;
75 RECT rc;
76 } navpane;
78 EXPLORER_BROWSER_OPTIONS eb_options;
79 FOLDERSETTINGS fs;
81 struct list event_clients;
82 DWORD events_next_cookie;
83 struct list travellog;
84 travellog_entry *travellog_cursor;
85 int travellog_count;
87 int dpix;
89 IShellView *psv;
90 RECT sv_rc;
91 LPITEMIDLIST current_pidl;
93 IUnknown *punk_site;
94 ICommDlgBrowser *pcdb_site;
95 ICommDlgBrowser2 *pcdb2_site;
96 ICommDlgBrowser3 *pcdb3_site;
97 IExplorerPaneVisibility *pepv_site;
98 } ExplorerBrowserImpl;
100 static void initialize_navpane(ExplorerBrowserImpl *This, HWND hwnd_parent, RECT *rc);
102 /**************************************************************************
103 * Event functions.
105 static void events_unadvise_all(ExplorerBrowserImpl *This)
107 event_client *client, *curs;
108 TRACE("%p\n", This);
110 LIST_FOR_EACH_ENTRY_SAFE(client, curs, &This->event_clients, event_client, entry)
112 TRACE("Removing %p\n", client);
113 list_remove(&client->entry);
114 IExplorerBrowserEvents_Release(client->pebe);
115 heap_free(client);
119 static HRESULT events_NavigationPending(ExplorerBrowserImpl *This, PCIDLIST_ABSOLUTE pidl)
121 event_client *cursor;
122 HRESULT hres = S_OK;
124 TRACE("%p\n", This);
126 LIST_FOR_EACH_ENTRY(cursor, &This->event_clients, event_client, entry)
128 TRACE("Notifying %p\n", cursor);
129 hres = IExplorerBrowserEvents_OnNavigationPending(cursor->pebe, pidl);
131 /* If this failed for any reason, the browsing is supposed to be aborted. */
132 if(FAILED(hres))
133 break;
136 return hres;
139 static void events_NavigationComplete(ExplorerBrowserImpl *This, PCIDLIST_ABSOLUTE pidl)
141 event_client *cursor;
143 TRACE("%p\n", This);
145 LIST_FOR_EACH_ENTRY(cursor, &This->event_clients, event_client, entry)
147 TRACE("Notifying %p\n", cursor);
148 IExplorerBrowserEvents_OnNavigationComplete(cursor->pebe, pidl);
152 static void events_NavigationFailed(ExplorerBrowserImpl *This, PCIDLIST_ABSOLUTE pidl)
154 event_client *cursor;
156 TRACE("%p\n", This);
158 LIST_FOR_EACH_ENTRY(cursor, &This->event_clients, event_client, entry)
160 TRACE("Notifying %p\n", cursor);
161 IExplorerBrowserEvents_OnNavigationFailed(cursor->pebe, pidl);
165 static void events_ViewCreated(ExplorerBrowserImpl *This, IShellView *psv)
167 event_client *cursor;
169 TRACE("%p\n", This);
171 LIST_FOR_EACH_ENTRY(cursor, &This->event_clients, event_client, entry)
173 TRACE("Notifying %p\n", cursor);
174 IExplorerBrowserEvents_OnViewCreated(cursor->pebe, psv);
178 /**************************************************************************
179 * Travellog functions.
181 static void travellog_remove_entry(ExplorerBrowserImpl *This, travellog_entry *entry)
183 TRACE("Removing %p\n", entry);
185 list_remove(&entry->entry);
186 ILFree(entry->pidl);
187 heap_free(entry);
188 This->travellog_count--;
191 static void travellog_remove_all_entries(ExplorerBrowserImpl *This)
193 travellog_entry *cursor, *cursor2;
194 TRACE("%p\n", This);
196 LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->travellog, travellog_entry, entry)
197 travellog_remove_entry(This, cursor);
199 This->travellog_cursor = NULL;
202 static void travellog_add_entry(ExplorerBrowserImpl *This, LPITEMIDLIST pidl)
204 travellog_entry *new, *cursor, *cursor2;
205 TRACE("%p (old count %d)\n", pidl, This->travellog_count);
207 /* Replace the old tail, if any, with the new entry */
208 if(This->travellog_cursor)
210 LIST_FOR_EACH_ENTRY_SAFE_REV(cursor, cursor2, &This->travellog, travellog_entry, entry)
212 if(cursor == This->travellog_cursor)
213 break;
214 travellog_remove_entry(This, cursor);
218 /* Create and add the new entry */
219 new = heap_alloc(sizeof(*new));
220 new->pidl = ILClone(pidl);
221 list_add_tail(&This->travellog, &new->entry);
222 This->travellog_cursor = new;
223 This->travellog_count++;
225 /* Remove the first few entries if the size limit is reached. */
226 if(This->travellog_count > 200)
228 UINT i = 0;
229 LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->travellog, travellog_entry, entry)
231 if(i++ > 10)
232 break;
233 travellog_remove_entry(This, cursor);
238 static LPCITEMIDLIST travellog_go_back(ExplorerBrowserImpl *This)
240 travellog_entry *prev;
241 TRACE("%p, %p\n", This, This->travellog_cursor);
243 if(!This->travellog_cursor)
244 return NULL;
246 prev = LIST_ENTRY(list_prev(&This->travellog, &This->travellog_cursor->entry),
247 travellog_entry, entry);
248 if(!prev)
249 return NULL;
251 This->travellog_cursor = prev;
252 return prev->pidl;
255 static LPCITEMIDLIST travellog_go_forward(ExplorerBrowserImpl *This)
257 travellog_entry *next;
258 TRACE("%p, %p\n", This, This->travellog_cursor);
260 if(!This->travellog_cursor)
261 return NULL;
263 next = LIST_ENTRY(list_next(&This->travellog, &This->travellog_cursor->entry),
264 travellog_entry, entry);
265 if(!next)
266 return NULL;
268 This->travellog_cursor = next;
269 return next->pidl;
272 /**************************************************************************
273 * Helper functions
275 static void update_layout(ExplorerBrowserImpl *This)
277 RECT rc;
278 INT navpane_width_actual;
279 INT shellview_width_actual;
280 int np_min_width = MulDiv(NP_MIN_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
281 int sv_min_width = MulDiv(SV_MIN_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
282 TRACE("%p (navpane: %d, EBO_SHOWFRAMES: %d)\n",
283 This, This->navpane.show, This->eb_options & EBO_SHOWFRAMES);
285 GetClientRect(This->hwnd_main, &rc);
287 if((This->eb_options & EBO_SHOWFRAMES) && This->navpane.show)
288 navpane_width_actual = This->navpane.width;
289 else
290 navpane_width_actual = 0;
292 shellview_width_actual = rc.right - navpane_width_actual;
293 if(shellview_width_actual < sv_min_width && navpane_width_actual)
295 INT missing_width = sv_min_width - shellview_width_actual;
296 if(missing_width < (navpane_width_actual - np_min_width))
298 /* Shrink the navpane */
299 navpane_width_actual -= missing_width;
300 shellview_width_actual += missing_width;
302 else
304 /* Hide the navpane */
305 shellview_width_actual += navpane_width_actual;
306 navpane_width_actual = 0;
310 /**************************************************************
311 * Calculate rectangles for the panes. All rectangles contain
312 * the position of the panes relative to hwnd_main.
315 if(navpane_width_actual)
317 SetRect(&This->navpane.rc, 0, 0, navpane_width_actual, rc.bottom);
319 if(!This->navpane.hwnd_splitter)
320 initialize_navpane(This, This->hwnd_main, &This->navpane.rc);
322 else
323 ZeroMemory(&This->navpane.rc, sizeof(RECT));
325 SetRect(&This->sv_rc, navpane_width_actual, 0, navpane_width_actual + shellview_width_actual,
326 rc.bottom);
329 static void size_panes(ExplorerBrowserImpl *This)
331 int splitter_width = MulDiv(SPLITTER_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
332 MoveWindow(This->navpane.hwnd_splitter,
333 This->navpane.rc.right - splitter_width, This->navpane.rc.top,
334 splitter_width, This->navpane.rc.bottom - This->navpane.rc.top,
335 TRUE);
337 MoveWindow(This->hwnd_sv,
338 This->sv_rc.left, This->sv_rc.top,
339 This->sv_rc.right - This->sv_rc.left, This->sv_rc.bottom - This->sv_rc.top,
340 TRUE);
343 static HRESULT change_viewmode(ExplorerBrowserImpl *This, UINT viewmode)
345 IFolderView *pfv;
346 HRESULT hr;
348 if(!This->psv)
349 return E_FAIL;
351 hr = IShellView_QueryInterface(This->psv, &IID_IFolderView, (void*)&pfv);
352 if(SUCCEEDED(hr))
354 hr = IFolderView_SetCurrentViewMode(pfv, This->fs.ViewMode);
355 IFolderView_Release(pfv);
358 return hr;
361 static HRESULT create_new_shellview(ExplorerBrowserImpl *This, IShellItem *psi)
363 IShellBrowser *psb = &This->IShellBrowser_iface;
364 IShellFolder *psf;
365 IShellView *psv;
366 HWND hwnd_new;
367 HRESULT hr;
369 TRACE("%p, %p\n", This, psi);
371 hr = IShellItem_BindToHandler(psi, NULL, &BHID_SFObject, &IID_IShellFolder, (void**)&psf);
372 if(SUCCEEDED(hr))
374 hr = IShellFolder_CreateViewObject(psf, This->hwnd_main, &IID_IShellView, (void**)&psv);
375 if(SUCCEEDED(hr))
377 if(This->hwnd_sv)
379 IShellView_DestroyViewWindow(This->psv);
380 This->hwnd_sv = NULL;
383 hr = IShellView_CreateViewWindow(psv, This->psv, &This->fs, psb, &This->sv_rc, &hwnd_new);
384 if(SUCCEEDED(hr))
386 /* Replace the old shellview */
387 if(This->psv) IShellView_Release(This->psv);
389 This->psv = psv;
390 This->hwnd_sv = hwnd_new;
391 events_ViewCreated(This, psv);
393 else
395 ERR("CreateViewWindow failed (0x%x)\n", hr);
396 IShellView_Release(psv);
399 else
400 ERR("CreateViewObject failed (0x%x)\n", hr);
402 IShellFolder_Release(psf);
404 else
405 ERR("SI::BindToHandler failed (0x%x)\n", hr);
407 return hr;
410 static void get_interfaces_from_site(ExplorerBrowserImpl *This)
412 IServiceProvider *psp;
413 HRESULT hr;
415 /* Calling this with This->punk_site set to NULL should properly
416 * release any previously fetched interfaces.
419 if(This->pcdb_site)
421 ICommDlgBrowser_Release(This->pcdb_site);
422 if(This->pcdb2_site) ICommDlgBrowser2_Release(This->pcdb2_site);
423 if(This->pcdb3_site) ICommDlgBrowser3_Release(This->pcdb3_site);
425 This->pcdb_site = NULL;
426 This->pcdb2_site = NULL;
427 This->pcdb3_site = NULL;
430 if(This->pepv_site)
432 IExplorerPaneVisibility_Release(This->pepv_site);
433 This->pepv_site = NULL;
436 if(!This->punk_site)
437 return;
439 hr = IUnknown_QueryInterface(This->punk_site, &IID_IServiceProvider, (void**)&psp);
440 if(FAILED(hr))
442 ERR("Failed to get IServiceProvider from site.\n");
443 return;
446 /* ICommDlgBrowser */
447 IServiceProvider_QueryService(psp, &SID_SExplorerBrowserFrame, &IID_ICommDlgBrowser,
448 (void**)&This->pcdb_site);
449 IServiceProvider_QueryService(psp, &SID_SExplorerBrowserFrame, &IID_ICommDlgBrowser2,
450 (void**)&This->pcdb2_site);
451 IServiceProvider_QueryService(psp, &SID_SExplorerBrowserFrame, &IID_ICommDlgBrowser3,
452 (void**)&This->pcdb3_site);
454 /* IExplorerPaneVisibility */
455 IServiceProvider_QueryService(psp, &SID_ExplorerPaneVisibility, &IID_IExplorerPaneVisibility,
456 (void**)&This->pepv_site);
458 IServiceProvider_Release(psp);
461 /**************************************************************************
462 * General pane functionality.
464 static void update_panestate(ExplorerBrowserImpl *This)
466 EXPLORERPANESTATE eps = EPS_DONTCARE;
467 BOOL show_navpane;
468 TRACE("%p\n", This);
470 if(!This->pepv_site) return;
472 IExplorerPaneVisibility_GetPaneState(This->pepv_site, (REFEXPLORERPANE) &EP_NavPane, &eps);
473 if( !(eps & EPS_DEFAULT_OFF) )
474 show_navpane = TRUE;
475 else
476 show_navpane = FALSE;
478 if(This->navpane.show != show_navpane)
480 update_layout(This);
481 size_panes(This);
484 This->navpane.show = show_navpane;
487 static void splitter_draw(HWND hwnd, RECT *rc)
489 HDC hdc = GetDC(hwnd);
490 InvertRect(hdc, rc);
491 ReleaseDC(hwnd, hdc);
494 /**************************************************************************
495 * The Navigation Pane.
497 static LRESULT navpane_splitter_beginresize(ExplorerBrowserImpl *This, HWND hwnd, LPARAM lParam)
499 int splitter_width = MulDiv(SPLITTER_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
501 TRACE("\n");
503 SetCapture(hwnd);
505 This->splitter_rc = This->navpane.rc;
506 This->splitter_rc.left = This->splitter_rc.right - splitter_width;
508 splitter_draw(GetParent(hwnd), &This->splitter_rc);
510 return TRUE;
513 static LRESULT navpane_splitter_resizing(ExplorerBrowserImpl *This, HWND hwnd, LPARAM lParam)
515 int new_width, dx;
516 RECT rc;
517 int splitter_width = MulDiv(SPLITTER_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
518 int np_min_width = MulDiv(NP_MIN_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
519 int sv_min_width = MulDiv(SV_MIN_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
521 if(GetCapture() != hwnd) return FALSE;
523 dx = (SHORT)LOWORD(lParam);
524 TRACE("%d.\n", dx);
526 rc = This->navpane.rc;
527 new_width = This->navpane.width + dx;
528 if(new_width > np_min_width && This->sv_rc.right - new_width > sv_min_width)
530 rc.right = new_width;
531 rc.left = rc.right - splitter_width;
532 splitter_draw(GetParent(hwnd), &This->splitter_rc);
533 splitter_draw(GetParent(hwnd), &rc);
534 This->splitter_rc = rc;
537 return TRUE;
540 static LRESULT navpane_splitter_endresize(ExplorerBrowserImpl *This, HWND hwnd, LPARAM lParam)
542 int new_width, dx;
543 int np_min_width = MulDiv(NP_MIN_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
544 int sv_min_width = MulDiv(SV_MIN_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
546 if(GetCapture() != hwnd) return FALSE;
548 dx = (SHORT)LOWORD(lParam);
549 TRACE("%d.\n", dx);
551 splitter_draw(GetParent(hwnd), &This->splitter_rc);
553 new_width = This->navpane.width + dx;
554 if(new_width < np_min_width)
555 new_width = np_min_width;
556 else if(This->sv_rc.right - new_width < sv_min_width)
557 new_width = This->sv_rc.right - sv_min_width;
559 This->navpane.width = new_width;
561 update_layout(This);
562 size_panes(This);
564 ReleaseCapture();
566 return TRUE;
569 static LRESULT navpane_on_wm_create(HWND hwnd, CREATESTRUCTW *crs)
571 ExplorerBrowserImpl *This = crs->lpCreateParams;
572 INameSpaceTreeControl2 *pnstc2;
573 DWORD style;
574 HRESULT hr;
576 TRACE("%p\n", This);
577 SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LPARAM)This);
578 This->navpane.hwnd_splitter = hwnd;
580 hr = CoCreateInstance(&CLSID_NamespaceTreeControl, NULL, CLSCTX_INPROC_SERVER,
581 &IID_INameSpaceTreeControl2, (void**)&pnstc2);
583 if(SUCCEEDED(hr))
585 style = NSTCS_HASEXPANDOS | NSTCS_ROOTHASEXPANDO | NSTCS_SHOWSELECTIONALWAYS;
586 hr = INameSpaceTreeControl2_Initialize(pnstc2, GetParent(hwnd), NULL, style);
587 if(SUCCEEDED(hr))
589 INameSpaceTreeControlEvents *pnstce;
590 IShellFolder *psfdesktop;
591 IShellItem *psi;
592 IOleWindow *pow;
593 LPITEMIDLIST pidl;
594 DWORD cookie, style2 = NSTCS2_DISPLAYPADDING;
596 hr = INameSpaceTreeControl2_SetControlStyle2(pnstc2, 0xFF, style2);
597 if(FAILED(hr))
598 ERR("SetControlStyle2 failed (0x%08x)\n", hr);
600 hr = INameSpaceTreeControl2_QueryInterface(pnstc2, &IID_IOleWindow, (void**)&pow);
601 if(SUCCEEDED(hr))
603 IOleWindow_GetWindow(pow, &This->navpane.hwnd_nstc);
604 IOleWindow_Release(pow);
606 else
607 ERR("QueryInterface(IOleWindow) failed (0x%08x)\n", hr);
609 pnstce = &This->INameSpaceTreeControlEvents_iface;
610 hr = INameSpaceTreeControl2_TreeAdvise(pnstc2, (IUnknown*)pnstce, &cookie);
611 if(FAILED(hr))
612 ERR("TreeAdvise failed. (0x%08x).\n", hr);
615 * Add the default roots
618 /* TODO: This should be FOLDERID_Links */
619 hr = SHGetSpecialFolderLocation(NULL, CSIDL_FAVORITES, &pidl);
620 if(SUCCEEDED(hr))
622 hr = SHCreateShellItem(NULL, NULL, pidl, &psi);
623 if(SUCCEEDED(hr))
625 hr = INameSpaceTreeControl2_AppendRoot(pnstc2, psi, SHCONTF_NONFOLDERS, NSTCRS_VISIBLE, NULL);
626 IShellItem_Release(psi);
628 ILFree(pidl);
631 SHGetDesktopFolder(&psfdesktop);
632 hr = SHGetItemFromObject((IUnknown*)psfdesktop, &IID_IShellItem, (void**)&psi);
633 IShellFolder_Release(psfdesktop);
634 if(SUCCEEDED(hr))
636 hr = INameSpaceTreeControl2_AppendRoot(pnstc2, psi, SHCONTF_FOLDERS, NSTCRS_EXPANDED, NULL);
637 IShellItem_Release(psi);
640 /* TODO:
641 * We should advertise IID_INameSpaceTreeControl to the site of the
642 * host through its IProfferService interface, if any.
645 This->navpane.pnstc2 = pnstc2;
646 This->navpane.nstc_cookie = cookie;
648 return TRUE;
652 This->navpane.pnstc2 = NULL;
653 ERR("Failed (0x%08x)\n", hr);
655 return FALSE;
658 static LRESULT navpane_on_wm_size_move(ExplorerBrowserImpl *This)
660 UINT height, width;
661 int splitter_width = MulDiv(SPLITTER_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
663 TRACE("%p\n", This);
665 width = This->navpane.rc.right - This->navpane.rc.left - splitter_width;
666 height = This->navpane.rc.bottom - This->navpane.rc.top;
668 MoveWindow(This->navpane.hwnd_nstc,
669 This->navpane.rc.left, This->navpane.rc.top,
670 width, height,
671 TRUE);
673 return FALSE;
676 static LRESULT navpane_on_wm_destroy(ExplorerBrowserImpl *This)
678 INameSpaceTreeControl2_TreeUnadvise(This->navpane.pnstc2, This->navpane.nstc_cookie);
679 INameSpaceTreeControl2_Release(This->navpane.pnstc2);
680 This->navpane.pnstc2 = NULL;
681 return TRUE;
684 static LRESULT CALLBACK navpane_wndproc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
686 ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
688 switch(uMessage) {
689 case WM_CREATE: return navpane_on_wm_create(hWnd, (CREATESTRUCTW*)lParam);
690 case WM_MOVE: /* Fall through */
691 case WM_SIZE: return navpane_on_wm_size_move(This);
692 case WM_DESTROY: return navpane_on_wm_destroy(This);
693 case WM_LBUTTONDOWN: return navpane_splitter_beginresize(This, hWnd, lParam);
694 case WM_MOUSEMOVE: return navpane_splitter_resizing(This, hWnd, lParam);
695 case WM_LBUTTONUP: return navpane_splitter_endresize(This, hWnd, lParam);
696 default:
697 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
699 return 0;
702 static void initialize_navpane(ExplorerBrowserImpl *This, HWND hwnd_parent, RECT *rc)
704 WNDCLASSW wc;
705 HWND splitter;
706 int splitter_width = MulDiv(SPLITTER_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
707 static const WCHAR navpane_classname[] = {'e','b','_','n','a','v','p','a','n','e',0};
709 if( !GetClassInfoW(shell32_hInstance, navpane_classname, &wc) )
711 wc.style = CS_HREDRAW | CS_VREDRAW;
712 wc.lpfnWndProc = navpane_wndproc;
713 wc.cbClsExtra = 0;
714 wc.cbWndExtra = 0;
715 wc.hInstance = shell32_hInstance;
716 wc.hIcon = 0;
717 wc.hCursor = LoadCursorW(0, (LPWSTR)IDC_SIZEWE);
718 wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
719 wc.lpszMenuName = NULL;
720 wc.lpszClassName = navpane_classname;
722 if (!RegisterClassW(&wc)) return;
725 splitter = CreateWindowExW(0, navpane_classname, NULL,
726 WS_CHILD | WS_TABSTOP | WS_VISIBLE,
727 rc->right - splitter_width, rc->top,
728 splitter_width, rc->bottom - rc->top,
729 hwnd_parent, 0, shell32_hInstance, This);
730 if(!splitter)
731 ERR("Failed to create navpane : %d.\n", GetLastError());
734 /**************************************************************************
735 * Main window related functions.
737 static LRESULT main_on_wm_create(HWND hWnd, CREATESTRUCTW *crs)
739 ExplorerBrowserImpl *This = crs->lpCreateParams;
740 TRACE("%p\n", This);
742 SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LPARAM)This);
743 This->hwnd_main = hWnd;
745 return TRUE;
748 static LRESULT main_on_wm_size(ExplorerBrowserImpl *This)
750 update_layout(This);
751 size_panes(This);
753 return TRUE;
756 static LRESULT main_on_cwm_getishellbrowser(ExplorerBrowserImpl *This)
758 return (LRESULT)&This->IShellBrowser_iface;
761 static LRESULT CALLBACK main_wndproc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
763 ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
765 switch(uMessage)
767 case WM_CREATE: return main_on_wm_create(hWnd, (CREATESTRUCTW*)lParam);
768 case WM_SIZE: return main_on_wm_size(This);
769 case CWM_GETISHELLBROWSER: return main_on_cwm_getishellbrowser(This);
770 default: return DefWindowProcW(hWnd, uMessage, wParam, lParam);
773 return 0;
776 /**************************************************************************
777 * IExplorerBrowser Implementation
780 static inline ExplorerBrowserImpl *impl_from_IExplorerBrowser(IExplorerBrowser *iface)
782 return CONTAINING_RECORD(iface, ExplorerBrowserImpl, IExplorerBrowser_iface);
785 static HRESULT WINAPI IExplorerBrowser_fnQueryInterface(IExplorerBrowser *iface,
786 REFIID riid, void **ppvObject)
788 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
789 TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppvObject);
791 *ppvObject = NULL;
792 if(IsEqualIID(riid, &IID_IExplorerBrowser) ||
793 IsEqualIID(riid, &IID_IUnknown))
795 *ppvObject = &This->IExplorerBrowser_iface;
797 else if(IsEqualIID(riid, &IID_IShellBrowser) ||
798 IsEqualIID(riid, &IID_IOleWindow))
800 *ppvObject = &This->IShellBrowser_iface;
802 else if(IsEqualIID(riid, &IID_ICommDlgBrowser) ||
803 IsEqualIID(riid, &IID_ICommDlgBrowser2) ||
804 IsEqualIID(riid, &IID_ICommDlgBrowser3))
806 *ppvObject = &This->ICommDlgBrowser3_iface;
808 else if(IsEqualIID(riid, &IID_IObjectWithSite))
810 *ppvObject = &This->IObjectWithSite_iface;
812 else if(IsEqualIID(riid, &IID_IInputObject))
814 *ppvObject = &This->IInputObject_iface;
817 if(*ppvObject)
819 IUnknown_AddRef((IUnknown*)*ppvObject);
820 return S_OK;
823 return E_NOINTERFACE;
826 static ULONG WINAPI IExplorerBrowser_fnAddRef(IExplorerBrowser *iface)
828 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
829 LONG ref = InterlockedIncrement(&This->ref);
830 TRACE("%p - ref %d\n", This, ref);
832 return ref;
835 static ULONG WINAPI IExplorerBrowser_fnRelease(IExplorerBrowser *iface)
837 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
838 LONG ref = InterlockedDecrement(&This->ref);
839 TRACE("%p - ref %d\n", This, ref);
841 if(!ref)
843 TRACE("Freeing.\n");
845 if(!This->destroyed)
846 IExplorerBrowser_Destroy(iface);
848 IObjectWithSite_SetSite(&This->IObjectWithSite_iface, NULL);
850 heap_free(This);
853 return ref;
856 static HRESULT WINAPI IExplorerBrowser_fnInitialize(IExplorerBrowser *iface,
857 HWND hwndParent, const RECT *prc,
858 const FOLDERSETTINGS *pfs)
860 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
861 WNDCLASSW wc;
862 LONG style;
863 HDC parent_dc;
864 static const WCHAR EB_CLASS_NAME[] =
865 {'E','x','p','l','o','r','e','r','B','r','o','w','s','e','r','C','o','n','t','r','o','l',0};
867 TRACE("%p (%p, %p, %p)\n", This, hwndParent, prc, pfs);
869 if(This->hwnd_main)
870 return E_UNEXPECTED;
872 if(!hwndParent)
873 return E_INVALIDARG;
875 if( !GetClassInfoW(shell32_hInstance, EB_CLASS_NAME, &wc) )
877 wc.style = CS_HREDRAW | CS_VREDRAW;
878 wc.lpfnWndProc = main_wndproc;
879 wc.cbClsExtra = 0;
880 wc.cbWndExtra = 0;
881 wc.hInstance = shell32_hInstance;
882 wc.hIcon = 0;
883 wc.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW);
884 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
885 wc.lpszMenuName = NULL;
886 wc.lpszClassName = EB_CLASS_NAME;
888 if (!RegisterClassW(&wc)) return E_FAIL;
891 parent_dc = GetDC(hwndParent);
892 This->dpix = GetDeviceCaps(parent_dc, LOGPIXELSX);
893 ReleaseDC(hwndParent, parent_dc);
895 This->navpane.width = MulDiv(NP_DEFAULT_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
897 style = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS;
898 if (!(This->eb_options & EBO_NOBORDER))
899 style |= WS_BORDER;
900 This->hwnd_main = CreateWindowExW(WS_EX_CONTROLPARENT, EB_CLASS_NAME, NULL, style,
901 prc->left, prc->top,
902 prc->right - prc->left, prc->bottom - prc->top,
903 hwndParent, 0, shell32_hInstance, This);
905 if(!This->hwnd_main)
907 ERR("Failed to create the window.\n");
908 return E_FAIL;
911 This->fs.ViewMode = pfs ? pfs->ViewMode : FVM_DETAILS;
912 This->fs.fFlags = pfs ? (pfs->fFlags | FWF_NOCLIENTEDGE) : FWF_NOCLIENTEDGE;
914 return S_OK;
917 static HRESULT WINAPI IExplorerBrowser_fnDestroy(IExplorerBrowser *iface)
919 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
920 TRACE("%p\n", This);
922 if(This->psv)
924 IShellView_DestroyViewWindow(This->psv);
925 IShellView_Release(This->psv);
926 This->psv = NULL;
927 This->hwnd_sv = NULL;
930 events_unadvise_all(This);
931 travellog_remove_all_entries(This);
933 ILFree(This->current_pidl);
934 This->current_pidl = NULL;
936 DestroyWindow(This->hwnd_main);
937 This->destroyed = TRUE;
939 return S_OK;
942 static HRESULT WINAPI IExplorerBrowser_fnSetRect(IExplorerBrowser *iface,
943 HDWP *phdwp, RECT rcBrowser)
945 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
946 TRACE("%p (%p, %s)\n", This, phdwp, wine_dbgstr_rect(&rcBrowser));
948 if(phdwp && *phdwp)
950 *phdwp = DeferWindowPos(*phdwp, This->hwnd_main, NULL, rcBrowser.left, rcBrowser.top,
951 rcBrowser.right - rcBrowser.left, rcBrowser.bottom - rcBrowser.top,
952 SWP_NOZORDER | SWP_NOACTIVATE);
953 if(!*phdwp)
954 return E_FAIL;
956 else
958 MoveWindow(This->hwnd_main, rcBrowser.left, rcBrowser.top,
959 rcBrowser.right - rcBrowser.left, rcBrowser.bottom - rcBrowser.top, TRUE);
962 return S_OK;
965 static HRESULT WINAPI IExplorerBrowser_fnSetPropertyBag(IExplorerBrowser *iface,
966 LPCWSTR pszPropertyBag)
968 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
969 FIXME("stub, %p (%s)\n", This, debugstr_w(pszPropertyBag));
971 if(!pszPropertyBag)
972 return E_INVALIDARG;
974 /* FIXME: This method is currently useless as we don't save any
975 * settings anywhere, but at least one application breaks if we
976 * return E_NOTIMPL.
979 return S_OK;
982 static HRESULT WINAPI IExplorerBrowser_fnSetEmptyText(IExplorerBrowser *iface,
983 LPCWSTR pszEmptyText)
985 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
986 FIXME("stub, %p (%s)\n", This, debugstr_w(pszEmptyText));
988 return E_NOTIMPL;
991 static HRESULT WINAPI IExplorerBrowser_fnSetFolderSettings(IExplorerBrowser *iface,
992 const FOLDERSETTINGS *pfs)
994 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
995 TRACE("%p (%p)\n", This, pfs);
997 if(!pfs)
998 return E_INVALIDARG;
1000 This->fs.ViewMode = pfs->ViewMode;
1001 This->fs.fFlags = pfs->fFlags | FWF_NOCLIENTEDGE;
1003 /* Change the settings of the current view, if any. */
1004 return change_viewmode(This, This->fs.ViewMode);
1007 static HRESULT WINAPI IExplorerBrowser_fnAdvise(IExplorerBrowser *iface,
1008 IExplorerBrowserEvents *psbe,
1009 DWORD *pdwCookie)
1011 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1012 event_client *client;
1013 TRACE("%p (%p, %p)\n", This, psbe, pdwCookie);
1015 client = heap_alloc(sizeof(*client));
1016 client->pebe = psbe;
1017 client->cookie = ++This->events_next_cookie;
1019 IExplorerBrowserEvents_AddRef(psbe);
1020 *pdwCookie = client->cookie;
1022 list_add_tail(&This->event_clients, &client->entry);
1024 return S_OK;
1027 static HRESULT WINAPI IExplorerBrowser_fnUnadvise(IExplorerBrowser *iface,
1028 DWORD dwCookie)
1030 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1031 event_client *client;
1032 TRACE("%p (0x%x)\n", This, dwCookie);
1034 LIST_FOR_EACH_ENTRY(client, &This->event_clients, event_client, entry)
1036 if(client->cookie == dwCookie)
1038 list_remove(&client->entry);
1039 IExplorerBrowserEvents_Release(client->pebe);
1040 heap_free(client);
1041 return S_OK;
1045 return E_INVALIDARG;
1048 static HRESULT WINAPI IExplorerBrowser_fnSetOptions(IExplorerBrowser *iface,
1049 EXPLORER_BROWSER_OPTIONS dwFlag)
1051 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1052 static const EXPLORER_BROWSER_OPTIONS unsupported_options =
1053 EBO_ALWAYSNAVIGATE | EBO_NOWRAPPERWINDOW | EBO_HTMLSHAREPOINTVIEW | EBO_NOPERSISTVIEWSTATE;
1055 TRACE("%p (0x%x)\n", This, dwFlag);
1057 if(dwFlag & unsupported_options)
1058 FIXME("Flags 0x%08x contains unsupported options.\n", dwFlag);
1060 This->eb_options = dwFlag;
1062 return S_OK;
1065 static HRESULT WINAPI IExplorerBrowser_fnGetOptions(IExplorerBrowser *iface,
1066 EXPLORER_BROWSER_OPTIONS *pdwFlag)
1068 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1069 TRACE("%p (%p)\n", This, pdwFlag);
1071 *pdwFlag = This->eb_options;
1073 return S_OK;
1076 static HRESULT WINAPI IExplorerBrowser_fnBrowseToIDList(IExplorerBrowser *iface,
1077 PCUIDLIST_RELATIVE pidl,
1078 UINT uFlags)
1080 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1081 LPITEMIDLIST absolute_pidl = NULL;
1082 HRESULT hr;
1083 static const UINT unsupported_browse_flags =
1084 SBSP_NEWBROWSER | EBF_SELECTFROMDATAOBJECT | EBF_NODROPTARGET;
1085 TRACE("%p (%p, 0x%x)\n", This, pidl, uFlags);
1087 if(!This->hwnd_main)
1088 return E_FAIL;
1090 if(This->destroyed)
1091 return HRESULT_FROM_WIN32(ERROR_BUSY);
1093 if(This->current_pidl && (This->eb_options & EBO_NAVIGATEONCE))
1094 return E_FAIL;
1096 if(uFlags & SBSP_EXPLOREMODE)
1097 return E_INVALIDARG;
1099 if(uFlags & unsupported_browse_flags)
1100 FIXME("Argument 0x%x contains unsupported flags.\n", uFlags);
1102 if(uFlags & SBSP_NAVIGATEBACK)
1104 TRACE("SBSP_NAVIGATEBACK\n");
1105 absolute_pidl = ILClone(travellog_go_back(This));
1106 if(!absolute_pidl && !This->current_pidl)
1107 return E_FAIL;
1108 else if(!absolute_pidl)
1109 return S_OK;
1112 else if(uFlags & SBSP_NAVIGATEFORWARD)
1114 TRACE("SBSP_NAVIGATEFORWARD\n");
1115 absolute_pidl = ILClone(travellog_go_forward(This));
1116 if(!absolute_pidl && !This->current_pidl)
1117 return E_FAIL;
1118 else if(!absolute_pidl)
1119 return S_OK;
1122 else if(uFlags & SBSP_PARENT)
1124 if(This->current_pidl)
1126 if(_ILIsPidlSimple(This->current_pidl))
1128 absolute_pidl = _ILCreateDesktop();
1130 else
1132 absolute_pidl = ILClone(This->current_pidl);
1133 ILRemoveLastID(absolute_pidl);
1136 if(!absolute_pidl)
1138 ERR("Failed to get parent pidl.\n");
1139 return E_FAIL;
1143 else if(uFlags & SBSP_RELATIVE)
1145 /* SBSP_RELATIVE has precedence over SBSP_ABSOLUTE */
1146 TRACE("SBSP_RELATIVE\n");
1147 if(This->current_pidl)
1149 absolute_pidl = ILCombine(This->current_pidl, pidl);
1151 if(!absolute_pidl)
1153 ERR("Failed to get absolute pidl.\n");
1154 return E_FAIL;
1157 else
1159 TRACE("SBSP_ABSOLUTE\n");
1160 absolute_pidl = ILClone(pidl);
1161 if(!absolute_pidl && !This->current_pidl)
1162 return E_INVALIDARG;
1163 else if(!absolute_pidl)
1164 return S_OK;
1167 /* TODO: Asynchronous browsing. Return S_OK here and finish in
1168 * another thread. */
1170 hr = events_NavigationPending(This, absolute_pidl);
1171 if(FAILED(hr))
1173 TRACE("Browsing aborted.\n");
1174 ILFree(absolute_pidl);
1175 return E_FAIL;
1178 get_interfaces_from_site(This);
1179 update_panestate(This);
1181 /* Only browse if the new pidl differs from the old */
1182 if(!ILIsEqual(This->current_pidl, absolute_pidl))
1184 IShellItem *psi;
1185 hr = SHCreateItemFromIDList(absolute_pidl, &IID_IShellItem, (void**)&psi);
1186 if(SUCCEEDED(hr))
1188 hr = create_new_shellview(This, psi);
1189 if(FAILED(hr))
1191 events_NavigationFailed(This, absolute_pidl);
1192 ILFree(absolute_pidl);
1193 IShellItem_Release(psi);
1194 return E_FAIL;
1197 /* Add to travellog */
1198 if( !(This->eb_options & EBO_NOTRAVELLOG) &&
1199 !(uFlags & (SBSP_NAVIGATEFORWARD|SBSP_NAVIGATEBACK)) )
1201 travellog_add_entry(This, absolute_pidl);
1204 IShellItem_Release(psi);
1208 events_NavigationComplete(This, absolute_pidl);
1209 ILFree(This->current_pidl);
1210 This->current_pidl = absolute_pidl;
1212 /* Expand the NameSpaceTree to the current location. */
1213 if(This->navpane.show && This->navpane.pnstc2)
1215 IShellItem *psi;
1216 hr = SHCreateItemFromIDList(This->current_pidl, &IID_IShellItem, (void**)&psi);
1217 if(SUCCEEDED(hr))
1219 INameSpaceTreeControl2_EnsureItemVisible(This->navpane.pnstc2, psi);
1220 IShellItem_Release(psi);
1224 return S_OK;
1227 static HRESULT WINAPI IExplorerBrowser_fnBrowseToObject(IExplorerBrowser *iface,
1228 IUnknown *punk, UINT uFlags)
1230 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1231 LPITEMIDLIST pidl;
1232 HRESULT hr;
1233 TRACE("%p (%p, 0x%x)\n", This, punk, uFlags);
1235 if(!punk)
1236 return IExplorerBrowser_BrowseToIDList(iface, NULL, uFlags);
1238 hr = SHGetIDListFromObject(punk, &pidl);
1239 if(SUCCEEDED(hr))
1241 hr = IExplorerBrowser_BrowseToIDList(iface, pidl, uFlags);
1242 ILFree(pidl);
1245 return hr;
1248 static HRESULT WINAPI IExplorerBrowser_fnFillFromObject(IExplorerBrowser *iface,
1249 IUnknown *punk,
1250 EXPLORER_BROWSER_FILL_FLAGS dwFlags)
1252 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1253 FIXME("stub, %p (%p, 0x%x)\n", This, punk, dwFlags);
1255 return E_NOTIMPL;
1258 static HRESULT WINAPI IExplorerBrowser_fnRemoveAll(IExplorerBrowser *iface)
1260 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1261 FIXME("stub, %p\n", This);
1263 return E_NOTIMPL;
1266 static HRESULT WINAPI IExplorerBrowser_fnGetCurrentView(IExplorerBrowser *iface,
1267 REFIID riid, void **ppv)
1269 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1270 TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppv);
1272 if(!This->psv)
1273 return E_FAIL;
1275 return IShellView_QueryInterface(This->psv, riid, ppv);
1278 static const IExplorerBrowserVtbl vt_IExplorerBrowser =
1280 IExplorerBrowser_fnQueryInterface,
1281 IExplorerBrowser_fnAddRef,
1282 IExplorerBrowser_fnRelease,
1283 IExplorerBrowser_fnInitialize,
1284 IExplorerBrowser_fnDestroy,
1285 IExplorerBrowser_fnSetRect,
1286 IExplorerBrowser_fnSetPropertyBag,
1287 IExplorerBrowser_fnSetEmptyText,
1288 IExplorerBrowser_fnSetFolderSettings,
1289 IExplorerBrowser_fnAdvise,
1290 IExplorerBrowser_fnUnadvise,
1291 IExplorerBrowser_fnSetOptions,
1292 IExplorerBrowser_fnGetOptions,
1293 IExplorerBrowser_fnBrowseToIDList,
1294 IExplorerBrowser_fnBrowseToObject,
1295 IExplorerBrowser_fnFillFromObject,
1296 IExplorerBrowser_fnRemoveAll,
1297 IExplorerBrowser_fnGetCurrentView
1300 /**************************************************************************
1301 * IShellBrowser Implementation
1304 static inline ExplorerBrowserImpl *impl_from_IShellBrowser(IShellBrowser *iface)
1306 return CONTAINING_RECORD(iface, ExplorerBrowserImpl, IShellBrowser_iface);
1309 static HRESULT WINAPI IShellBrowser_fnQueryInterface(IShellBrowser *iface,
1310 REFIID riid, void **ppvObject)
1312 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1313 TRACE("%p\n", This);
1314 return IExplorerBrowser_QueryInterface(&This->IExplorerBrowser_iface, riid, ppvObject);
1317 static ULONG WINAPI IShellBrowser_fnAddRef(IShellBrowser *iface)
1319 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1320 TRACE("%p\n", This);
1321 return IExplorerBrowser_AddRef(&This->IExplorerBrowser_iface);
1324 static ULONG WINAPI IShellBrowser_fnRelease(IShellBrowser *iface)
1326 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1327 TRACE("%p\n", This);
1328 return IExplorerBrowser_Release(&This->IExplorerBrowser_iface);
1331 static HRESULT WINAPI IShellBrowser_fnGetWindow(IShellBrowser *iface, HWND *phwnd)
1333 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1334 TRACE("%p (%p)\n", This, phwnd);
1336 if(!This->hwnd_main)
1337 return E_FAIL;
1339 *phwnd = This->hwnd_main;
1340 return S_OK;
1343 static HRESULT WINAPI IShellBrowser_fnContextSensitiveHelp(IShellBrowser *iface,
1344 BOOL fEnterMode)
1346 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1347 FIXME("stub, %p (%d)\n", This, fEnterMode);
1349 return E_NOTIMPL;
1352 static HRESULT WINAPI IShellBrowser_fnInsertMenusSB(IShellBrowser *iface,
1353 HMENU hmenuShared,
1354 LPOLEMENUGROUPWIDTHS lpMenuWidths)
1356 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1357 TRACE("%p (%p, %p)\n", This, hmenuShared, lpMenuWidths);
1359 /* Not implemented. */
1360 return E_NOTIMPL;
1363 static HRESULT WINAPI IShellBrowser_fnSetMenuSB(IShellBrowser *iface,
1364 HMENU hmenuShared,
1365 HOLEMENU holemenuReserved,
1366 HWND hwndActiveObject)
1368 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1369 TRACE("%p (%p, %p, %p)\n", This, hmenuShared, holemenuReserved, hwndActiveObject);
1371 /* Not implemented. */
1372 return E_NOTIMPL;
1375 static HRESULT WINAPI IShellBrowser_fnRemoveMenusSB(IShellBrowser *iface,
1376 HMENU hmenuShared)
1378 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1379 TRACE("%p (%p)\n", This, hmenuShared);
1381 /* Not implemented. */
1382 return E_NOTIMPL;
1385 static HRESULT WINAPI IShellBrowser_fnSetStatusTextSB(IShellBrowser *iface,
1386 LPCOLESTR pszStatusText)
1388 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1389 FIXME("stub, %p (%s)\n", This, debugstr_w(pszStatusText));
1391 return E_NOTIMPL;
1394 static HRESULT WINAPI IShellBrowser_fnEnableModelessSB(IShellBrowser *iface,
1395 BOOL fEnable)
1397 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1398 FIXME("stub, %p (%d)\n", This, fEnable);
1400 return E_NOTIMPL;
1403 static HRESULT WINAPI IShellBrowser_fnTranslateAcceleratorSB(IShellBrowser *iface,
1404 MSG *pmsg, WORD wID)
1406 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1407 FIXME("stub, %p (%p, 0x%x)\n", This, pmsg, wID);
1409 return E_NOTIMPL;
1412 static HRESULT WINAPI IShellBrowser_fnBrowseObject(IShellBrowser *iface,
1413 LPCITEMIDLIST pidl, UINT wFlags)
1415 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1416 TRACE("%p (%p, %x)\n", This, pidl, wFlags);
1418 return IExplorerBrowser_BrowseToIDList(&This->IExplorerBrowser_iface, pidl, wFlags);
1421 static HRESULT WINAPI IShellBrowser_fnGetViewStateStream(IShellBrowser *iface,
1422 DWORD grfMode,
1423 IStream **ppStrm)
1425 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1426 FIXME("stub, %p (0x%x, %p)\n", This, grfMode, ppStrm);
1428 *ppStrm = NULL;
1429 return E_FAIL;
1432 static HRESULT WINAPI IShellBrowser_fnGetControlWindow(IShellBrowser *iface,
1433 UINT id, HWND *phwnd)
1435 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1436 TRACE("(%p)->(%d, %p)\n", This, id, phwnd);
1437 if (phwnd) *phwnd = NULL;
1438 return E_NOTIMPL;
1441 static HRESULT WINAPI IShellBrowser_fnSendControlMsg(IShellBrowser *iface,
1442 UINT id, UINT uMsg,
1443 WPARAM wParam, LPARAM lParam,
1444 LRESULT *pret)
1446 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1447 FIXME("stub, %p (%d, %d, %lx, %lx, %p)\n", This, id, uMsg, wParam, lParam, pret);
1449 return E_NOTIMPL;
1452 static HRESULT WINAPI IShellBrowser_fnQueryActiveShellView(IShellBrowser *iface,
1453 IShellView **ppshv)
1455 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1456 TRACE("%p (%p)\n", This, ppshv);
1458 if(!This->psv)
1459 return E_FAIL;
1461 *ppshv = This->psv;
1462 IShellView_AddRef(This->psv);
1464 return S_OK;
1467 static HRESULT WINAPI IShellBrowser_fnOnViewWindowActive(IShellBrowser *iface,
1468 IShellView *pshv)
1470 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1471 FIXME("stub, %p (%p)\n", This, pshv);
1473 return E_NOTIMPL;
1476 static HRESULT WINAPI IShellBrowser_fnSetToolbarItems(IShellBrowser *iface,
1477 LPTBBUTTONSB lpButtons,
1478 UINT nButtons, UINT uFlags)
1480 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1481 FIXME("stub, %p (%p, %d, 0x%x)\n", This, lpButtons, nButtons, uFlags);
1483 return E_NOTIMPL;
1486 static const IShellBrowserVtbl vt_IShellBrowser = {
1487 IShellBrowser_fnQueryInterface,
1488 IShellBrowser_fnAddRef,
1489 IShellBrowser_fnRelease,
1490 IShellBrowser_fnGetWindow,
1491 IShellBrowser_fnContextSensitiveHelp,
1492 IShellBrowser_fnInsertMenusSB,
1493 IShellBrowser_fnSetMenuSB,
1494 IShellBrowser_fnRemoveMenusSB,
1495 IShellBrowser_fnSetStatusTextSB,
1496 IShellBrowser_fnEnableModelessSB,
1497 IShellBrowser_fnTranslateAcceleratorSB,
1498 IShellBrowser_fnBrowseObject,
1499 IShellBrowser_fnGetViewStateStream,
1500 IShellBrowser_fnGetControlWindow,
1501 IShellBrowser_fnSendControlMsg,
1502 IShellBrowser_fnQueryActiveShellView,
1503 IShellBrowser_fnOnViewWindowActive,
1504 IShellBrowser_fnSetToolbarItems
1507 /**************************************************************************
1508 * ICommDlgBrowser3 Implementation
1511 static inline ExplorerBrowserImpl *impl_from_ICommDlgBrowser3(ICommDlgBrowser3 *iface)
1513 return CONTAINING_RECORD(iface, ExplorerBrowserImpl, ICommDlgBrowser3_iface);
1516 static HRESULT WINAPI ICommDlgBrowser3_fnQueryInterface(ICommDlgBrowser3 *iface,
1517 REFIID riid,
1518 void **ppvObject)
1520 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1521 TRACE("%p\n", This);
1522 return IExplorerBrowser_QueryInterface(&This->IExplorerBrowser_iface, riid, ppvObject);
1525 static ULONG WINAPI ICommDlgBrowser3_fnAddRef(ICommDlgBrowser3 *iface)
1527 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1528 TRACE("%p\n", This);
1529 return IExplorerBrowser_AddRef(&This->IExplorerBrowser_iface);
1532 static ULONG WINAPI ICommDlgBrowser3_fnRelease(ICommDlgBrowser3 *iface)
1534 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1535 TRACE("%p\n", This);
1536 return IExplorerBrowser_Release(&This->IExplorerBrowser_iface);
1539 static HRESULT WINAPI ICommDlgBrowser3_fnOnDefaultCommand(ICommDlgBrowser3 *iface,
1540 IShellView *shv)
1542 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1543 IDataObject *pdo;
1544 HRESULT hr;
1545 HRESULT ret = S_FALSE;
1547 TRACE("%p (%p)\n", This, shv);
1549 hr = IShellView_GetItemObject(shv, SVGIO_SELECTION, &IID_IDataObject, (void**)&pdo);
1550 if(SUCCEEDED(hr))
1552 FORMATETC fmt;
1553 STGMEDIUM medium;
1555 fmt.cfFormat = RegisterClipboardFormatW(CFSTR_SHELLIDLISTW);
1556 fmt.ptd = NULL;
1557 fmt.dwAspect = DVASPECT_CONTENT;
1558 fmt.lindex = -1;
1559 fmt.tymed = TYMED_HGLOBAL;
1561 hr = IDataObject_GetData(pdo, &fmt ,&medium);
1562 IDataObject_Release(pdo);
1563 if(SUCCEEDED(hr))
1565 LPIDA pida = GlobalLock(medium.u.hGlobal);
1566 LPCITEMIDLIST pidl_child = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[1]);
1568 /* Handle folders by browsing to them. */
1569 if(_ILIsFolder(pidl_child) || _ILIsDrive(pidl_child) || _ILIsSpecialFolder(pidl_child))
1571 IExplorerBrowser_BrowseToIDList(&This->IExplorerBrowser_iface, pidl_child, SBSP_RELATIVE);
1572 ret = S_OK;
1574 GlobalUnlock(medium.u.hGlobal);
1575 GlobalFree(medium.u.hGlobal);
1577 else
1578 ERR("Failed to get data from IDataObject.\n");
1579 } else
1580 ERR("Failed to get IDataObject.\n");
1582 /* If we didn't handle the default command, check if we have a
1583 * client that does */
1584 if(ret == S_FALSE && This->pcdb_site)
1585 return ICommDlgBrowser_OnDefaultCommand(This->pcdb_site, shv);
1587 return ret;
1589 static HRESULT WINAPI ICommDlgBrowser3_fnOnStateChange(ICommDlgBrowser3 *iface,
1590 IShellView *shv, ULONG uChange)
1592 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1593 TRACE("%p (%p, %d)\n", This, shv, uChange);
1595 if(This->pcdb_site)
1596 return ICommDlgBrowser_OnStateChange(This->pcdb_site, shv, uChange);
1598 return E_NOTIMPL;
1600 static HRESULT WINAPI ICommDlgBrowser3_fnIncludeObject(ICommDlgBrowser3 *iface,
1601 IShellView *pshv, LPCITEMIDLIST pidl)
1603 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1604 TRACE("%p (%p, %p)\n", This, pshv, pidl);
1606 if(This->pcdb_site)
1607 return ICommDlgBrowser_IncludeObject(This->pcdb_site, pshv, pidl);
1609 return S_OK;
1612 static HRESULT WINAPI ICommDlgBrowser3_fnNotify(ICommDlgBrowser3 *iface,
1613 IShellView *pshv,
1614 DWORD dwNotifyType)
1616 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1617 TRACE("%p (%p, 0x%x)\n", This, pshv, dwNotifyType);
1619 if(This->pcdb2_site)
1620 return ICommDlgBrowser2_Notify(This->pcdb2_site, pshv, dwNotifyType);
1622 return S_OK;
1625 static HRESULT WINAPI ICommDlgBrowser3_fnGetDefaultMenuText(ICommDlgBrowser3 *iface,
1626 IShellView *pshv,
1627 LPWSTR pszText, int cchMax)
1629 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1630 TRACE("%p (%p, %s, %d)\n", This, pshv, debugstr_w(pszText), cchMax);
1632 if(This->pcdb2_site)
1633 return ICommDlgBrowser2_GetDefaultMenuText(This->pcdb2_site, pshv, pszText, cchMax);
1635 return S_OK;
1638 static HRESULT WINAPI ICommDlgBrowser3_fnGetViewFlags(ICommDlgBrowser3 *iface,
1639 DWORD *pdwFlags)
1641 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1642 TRACE("%p (%p)\n", This, pdwFlags);
1644 if(This->pcdb2_site)
1645 return ICommDlgBrowser2_GetViewFlags(This->pcdb2_site, pdwFlags);
1647 return S_OK;
1650 static HRESULT WINAPI ICommDlgBrowser3_fnOnColumnClicked(ICommDlgBrowser3 *iface,
1651 IShellView *pshv, int iColumn)
1653 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1654 TRACE("%p (%p, %d)\n", This, pshv, iColumn);
1656 if(This->pcdb3_site)
1657 return ICommDlgBrowser3_OnColumnClicked(This->pcdb3_site, pshv, iColumn);
1659 return S_OK;
1662 static HRESULT WINAPI ICommDlgBrowser3_fnGetCurrentFilter(ICommDlgBrowser3 *iface,
1663 LPWSTR pszFileSpec,
1664 int cchFileSpec)
1666 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1667 TRACE("%p (%s, %d)\n", This, debugstr_w(pszFileSpec), cchFileSpec);
1669 if(This->pcdb3_site)
1670 return ICommDlgBrowser3_GetCurrentFilter(This->pcdb3_site, pszFileSpec, cchFileSpec);
1672 return S_OK;
1675 static HRESULT WINAPI ICommDlgBrowser3_fnOnPreViewCreated(ICommDlgBrowser3 *iface,
1676 IShellView *pshv)
1678 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1679 TRACE("%p (%p)\n", This, pshv);
1681 if(This->pcdb3_site)
1682 return ICommDlgBrowser3_OnPreViewCreated(This->pcdb3_site, pshv);
1684 return S_OK;
1687 static const ICommDlgBrowser3Vtbl vt_ICommDlgBrowser3 = {
1688 ICommDlgBrowser3_fnQueryInterface,
1689 ICommDlgBrowser3_fnAddRef,
1690 ICommDlgBrowser3_fnRelease,
1691 ICommDlgBrowser3_fnOnDefaultCommand,
1692 ICommDlgBrowser3_fnOnStateChange,
1693 ICommDlgBrowser3_fnIncludeObject,
1694 ICommDlgBrowser3_fnNotify,
1695 ICommDlgBrowser3_fnGetDefaultMenuText,
1696 ICommDlgBrowser3_fnGetViewFlags,
1697 ICommDlgBrowser3_fnOnColumnClicked,
1698 ICommDlgBrowser3_fnGetCurrentFilter,
1699 ICommDlgBrowser3_fnOnPreViewCreated
1702 /**************************************************************************
1703 * IObjectWithSite Implementation
1706 static inline ExplorerBrowserImpl *impl_from_IObjectWithSite(IObjectWithSite *iface)
1708 return CONTAINING_RECORD(iface, ExplorerBrowserImpl, IObjectWithSite_iface);
1711 static HRESULT WINAPI IObjectWithSite_fnQueryInterface(IObjectWithSite *iface,
1712 REFIID riid, void **ppvObject)
1714 ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
1715 TRACE("%p\n", This);
1716 return IExplorerBrowser_QueryInterface(&This->IExplorerBrowser_iface, riid, ppvObject);
1719 static ULONG WINAPI IObjectWithSite_fnAddRef(IObjectWithSite *iface)
1721 ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
1722 TRACE("%p\n", This);
1723 return IExplorerBrowser_AddRef(&This->IExplorerBrowser_iface);
1726 static ULONG WINAPI IObjectWithSite_fnRelease(IObjectWithSite *iface)
1728 ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
1729 TRACE("%p\n", This);
1730 return IExplorerBrowser_Release(&This->IExplorerBrowser_iface);
1733 static HRESULT WINAPI IObjectWithSite_fnSetSite(IObjectWithSite *iface, IUnknown *punk_site)
1735 ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
1736 TRACE("%p (%p)\n", This, punk_site);
1738 if(This->punk_site)
1740 IUnknown_Release(This->punk_site);
1741 This->punk_site = NULL;
1742 get_interfaces_from_site(This);
1745 This->punk_site = punk_site;
1747 if(This->punk_site)
1748 IUnknown_AddRef(This->punk_site);
1750 return S_OK;
1753 static HRESULT WINAPI IObjectWithSite_fnGetSite(IObjectWithSite *iface, REFIID riid, void **ppvSite)
1755 ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
1756 TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppvSite);
1758 if(!This->punk_site)
1759 return E_FAIL;
1761 return IUnknown_QueryInterface(This->punk_site, riid, ppvSite);
1764 static const IObjectWithSiteVtbl vt_IObjectWithSite = {
1765 IObjectWithSite_fnQueryInterface,
1766 IObjectWithSite_fnAddRef,
1767 IObjectWithSite_fnRelease,
1768 IObjectWithSite_fnSetSite,
1769 IObjectWithSite_fnGetSite
1772 /**************************************************************************
1773 * INameSpaceTreeControlEvents Implementation
1775 static inline ExplorerBrowserImpl *impl_from_INameSpaceTreeControlEvents(INameSpaceTreeControlEvents *iface)
1777 return CONTAINING_RECORD(iface, ExplorerBrowserImpl, INameSpaceTreeControlEvents_iface);
1780 static HRESULT WINAPI NSTCEvents_fnQueryInterface(INameSpaceTreeControlEvents *iface,
1781 REFIID riid, void **ppvObject)
1783 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1784 TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppvObject);
1786 *ppvObject = NULL;
1787 if(IsEqualIID(riid, &IID_INameSpaceTreeControlEvents) ||
1788 IsEqualIID(riid, &IID_IUnknown))
1790 *ppvObject = iface;
1793 if(*ppvObject)
1795 IUnknown_AddRef((IUnknown*)*ppvObject);
1796 return S_OK;
1799 return E_NOINTERFACE;
1802 static ULONG WINAPI NSTCEvents_fnAddRef(INameSpaceTreeControlEvents *iface)
1804 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1805 TRACE("%p\n", This);
1806 return IExplorerBrowser_AddRef(&This->IExplorerBrowser_iface);
1809 static ULONG WINAPI NSTCEvents_fnRelease(INameSpaceTreeControlEvents *iface)
1811 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1812 TRACE("%p\n", This);
1813 return IExplorerBrowser_Release(&This->IExplorerBrowser_iface);
1816 static HRESULT WINAPI NSTCEvents_fnOnItemClick(INameSpaceTreeControlEvents *iface,
1817 IShellItem *psi,
1818 NSTCEHITTEST nstceHitTest,
1819 NSTCECLICKTYPE nstceClickType)
1821 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1822 TRACE("%p (%p, 0x%x, 0x%x)\n", This, psi, nstceHitTest, nstceClickType);
1823 return S_OK;
1826 static HRESULT WINAPI NSTCEvents_fnOnPropertyItemCommit(INameSpaceTreeControlEvents *iface,
1827 IShellItem *psi)
1829 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1830 TRACE("%p (%p)\n", This, psi);
1831 return E_NOTIMPL;
1834 static HRESULT WINAPI NSTCEvents_fnOnItemStateChanging(INameSpaceTreeControlEvents *iface,
1835 IShellItem *psi,
1836 NSTCITEMSTATE nstcisMask,
1837 NSTCITEMSTATE nstcisState)
1839 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1840 TRACE("%p (%p, 0x%x, 0x%x)\n", This, psi, nstcisMask, nstcisState);
1841 return E_NOTIMPL;
1844 static HRESULT WINAPI NSTCEvents_fnOnItemStateChanged(INameSpaceTreeControlEvents *iface,
1845 IShellItem *psi,
1846 NSTCITEMSTATE nstcisMask,
1847 NSTCITEMSTATE nstcisState)
1849 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1850 TRACE("%p (%p, 0x%x, 0x%x)\n", This, psi, nstcisMask, nstcisState);
1851 return E_NOTIMPL;
1854 static HRESULT WINAPI NSTCEvents_fnOnSelectionChanged(INameSpaceTreeControlEvents *iface,
1855 IShellItemArray *psiaSelection)
1857 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1858 IShellItem *psi;
1859 HRESULT hr;
1860 TRACE("%p (%p)\n", This, psiaSelection);
1862 hr = IShellItemArray_GetItemAt(psiaSelection, 0, &psi);
1863 if(SUCCEEDED(hr))
1865 hr = IExplorerBrowser_BrowseToObject(&This->IExplorerBrowser_iface,
1866 (IUnknown*)psi, SBSP_DEFBROWSER);
1867 IShellItem_Release(psi);
1870 return hr;
1873 static HRESULT WINAPI NSTCEvents_fnOnKeyboardInput(INameSpaceTreeControlEvents *iface,
1874 UINT uMsg, WPARAM wParam, LPARAM lParam)
1876 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1877 TRACE("%p (%d, 0x%lx, 0x%lx)\n", This, uMsg, wParam, lParam);
1878 return S_OK;
1881 static HRESULT WINAPI NSTCEvents_fnOnBeforeExpand(INameSpaceTreeControlEvents *iface,
1882 IShellItem *psi)
1884 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1885 TRACE("%p (%p)\n", This, psi);
1886 return E_NOTIMPL;
1889 static HRESULT WINAPI NSTCEvents_fnOnAfterExpand(INameSpaceTreeControlEvents *iface,
1890 IShellItem *psi)
1892 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1893 TRACE("%p (%p)\n", This, psi);
1894 return E_NOTIMPL;
1897 static HRESULT WINAPI NSTCEvents_fnOnBeginLabelEdit(INameSpaceTreeControlEvents *iface,
1898 IShellItem *psi)
1900 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1901 TRACE("%p (%p)\n", This, psi);
1902 return E_NOTIMPL;
1905 static HRESULT WINAPI NSTCEvents_fnOnEndLabelEdit(INameSpaceTreeControlEvents *iface,
1906 IShellItem *psi)
1908 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1909 TRACE("%p (%p)\n", This, psi);
1910 return E_NOTIMPL;
1913 static HRESULT WINAPI NSTCEvents_fnOnGetToolTip(INameSpaceTreeControlEvents *iface,
1914 IShellItem *psi, LPWSTR pszTip, int cchTip)
1916 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1917 TRACE("%p (%p, %p, %d)\n", This, psi, pszTip, cchTip);
1918 return E_NOTIMPL;
1921 static HRESULT WINAPI NSTCEvents_fnOnBeforeItemDelete(INameSpaceTreeControlEvents *iface,
1922 IShellItem *psi)
1924 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1925 TRACE("%p (%p)\n", This, psi);
1926 return E_NOTIMPL;
1929 static HRESULT WINAPI NSTCEvents_fnOnItemAdded(INameSpaceTreeControlEvents *iface,
1930 IShellItem *psi, BOOL fIsRoot)
1932 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1933 TRACE("%p (%p, %d)\n", This, psi, fIsRoot);
1934 return E_NOTIMPL;
1937 static HRESULT WINAPI NSTCEvents_fnOnItemDeleted(INameSpaceTreeControlEvents *iface,
1938 IShellItem *psi, BOOL fIsRoot)
1940 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1941 TRACE("%p (%p, %d)\n", This, psi, fIsRoot);
1942 return E_NOTIMPL;
1945 static HRESULT WINAPI NSTCEvents_fnOnBeforeContextMenu(INameSpaceTreeControlEvents *iface,
1946 IShellItem *psi, REFIID riid, void **ppv)
1948 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1949 TRACE("%p (%p, %s, %p)\n", This, psi, shdebugstr_guid(riid), ppv);
1950 return E_NOTIMPL;
1953 static HRESULT WINAPI NSTCEvents_fnOnAfterContextMenu(INameSpaceTreeControlEvents *iface,
1954 IShellItem *psi, IContextMenu *pcmIn,
1955 REFIID riid, void **ppv)
1957 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1958 TRACE("%p (%p, %p, %s, %p)\n", This, psi, pcmIn, shdebugstr_guid(riid), ppv);
1959 return E_NOTIMPL;
1962 static HRESULT WINAPI NSTCEvents_fnOnBeforeStateImageChange(INameSpaceTreeControlEvents *iface,
1963 IShellItem *psi)
1965 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1966 TRACE("%p (%p)\n", This, psi);
1967 return E_NOTIMPL;
1970 static HRESULT WINAPI NSTCEvents_fnOnGetDefaultIconIndex(INameSpaceTreeControlEvents* iface,
1971 IShellItem *psi,
1972 int *piDefaultIcon, int *piOpenIcon)
1974 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1975 TRACE("%p (%p, %p, %p)\n", This, psi, piDefaultIcon, piOpenIcon);
1976 return E_NOTIMPL;
1980 static const INameSpaceTreeControlEventsVtbl vt_INameSpaceTreeControlEvents = {
1981 NSTCEvents_fnQueryInterface,
1982 NSTCEvents_fnAddRef,
1983 NSTCEvents_fnRelease,
1984 NSTCEvents_fnOnItemClick,
1985 NSTCEvents_fnOnPropertyItemCommit,
1986 NSTCEvents_fnOnItemStateChanging,
1987 NSTCEvents_fnOnItemStateChanged,
1988 NSTCEvents_fnOnSelectionChanged,
1989 NSTCEvents_fnOnKeyboardInput,
1990 NSTCEvents_fnOnBeforeExpand,
1991 NSTCEvents_fnOnAfterExpand,
1992 NSTCEvents_fnOnBeginLabelEdit,
1993 NSTCEvents_fnOnEndLabelEdit,
1994 NSTCEvents_fnOnGetToolTip,
1995 NSTCEvents_fnOnBeforeItemDelete,
1996 NSTCEvents_fnOnItemAdded,
1997 NSTCEvents_fnOnItemDeleted,
1998 NSTCEvents_fnOnBeforeContextMenu,
1999 NSTCEvents_fnOnAfterContextMenu,
2000 NSTCEvents_fnOnBeforeStateImageChange,
2001 NSTCEvents_fnOnGetDefaultIconIndex
2004 /**************************************************************************
2005 * IInputObject Implementation
2008 static inline ExplorerBrowserImpl *impl_from_IInputObject(IInputObject *iface)
2010 return CONTAINING_RECORD(iface, ExplorerBrowserImpl, IInputObject_iface);
2013 static HRESULT WINAPI IInputObject_fnQueryInterface(IInputObject *iface,
2014 REFIID riid, void **ppvObject)
2016 ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
2017 TRACE("%p\n", This);
2018 return IExplorerBrowser_QueryInterface(&This->IExplorerBrowser_iface, riid, ppvObject);
2021 static ULONG WINAPI IInputObject_fnAddRef(IInputObject *iface)
2023 ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
2024 TRACE("%p\n", This);
2025 return IExplorerBrowser_AddRef(&This->IExplorerBrowser_iface);
2028 static ULONG WINAPI IInputObject_fnRelease(IInputObject *iface)
2030 ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
2031 TRACE("%p\n", This);
2032 return IExplorerBrowser_Release(&This->IExplorerBrowser_iface);
2035 static HRESULT WINAPI IInputObject_fnUIActivateIO(IInputObject *iface, BOOL fActivate, MSG *pMsg)
2037 ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
2038 FIXME("stub, %p (%d, %p)\n", This, fActivate, pMsg);
2039 return E_NOTIMPL;
2042 static HRESULT WINAPI IInputObject_fnHasFocusIO(IInputObject *iface)
2044 ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
2045 FIXME("stub, %p\n", This);
2046 return E_NOTIMPL;
2049 static HRESULT WINAPI IInputObject_fnTranslateAcceleratorIO(IInputObject *iface, MSG *pMsg)
2051 ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
2052 FIXME("stub, %p (%p)\n", This, pMsg);
2053 return E_NOTIMPL;
2056 static IInputObjectVtbl vt_IInputObject = {
2057 IInputObject_fnQueryInterface,
2058 IInputObject_fnAddRef,
2059 IInputObject_fnRelease,
2060 IInputObject_fnUIActivateIO,
2061 IInputObject_fnHasFocusIO,
2062 IInputObject_fnTranslateAcceleratorIO
2065 HRESULT WINAPI ExplorerBrowser_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv)
2067 ExplorerBrowserImpl *eb;
2068 HRESULT ret;
2070 TRACE("%p %s %p\n", pUnkOuter, shdebugstr_guid (riid), ppv);
2072 if(!ppv)
2073 return E_POINTER;
2074 if(pUnkOuter)
2075 return CLASS_E_NOAGGREGATION;
2077 eb = heap_alloc_zero(sizeof(*eb));
2078 eb->ref = 1;
2079 eb->IExplorerBrowser_iface.lpVtbl = &vt_IExplorerBrowser;
2080 eb->IShellBrowser_iface.lpVtbl = &vt_IShellBrowser;
2081 eb->ICommDlgBrowser3_iface.lpVtbl = &vt_ICommDlgBrowser3;
2082 eb->IObjectWithSite_iface.lpVtbl = &vt_IObjectWithSite;
2083 eb->INameSpaceTreeControlEvents_iface.lpVtbl = &vt_INameSpaceTreeControlEvents;
2084 eb->IInputObject_iface.lpVtbl = &vt_IInputObject;
2086 /* Default settings */
2087 eb->navpane.show = TRUE;
2089 list_init(&eb->event_clients);
2090 list_init(&eb->travellog);
2092 ret = IExplorerBrowser_QueryInterface(&eb->IExplorerBrowser_iface, riid, ppv);
2093 IExplorerBrowser_Release(&eb->IExplorerBrowser_iface);
2095 TRACE("--(%p)\n", ppv);
2096 return ret;