comctl32: Fix a typo in comment.
[wine.git] / dlls / shell32 / ebrowser.c
blob45c62c85b33f4026b7078e9686cd8c40b5b88baa
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 HeapFree(GetProcessHeap(), 0, 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 HeapFree(GetProcessHeap(), 0, 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 = HeapAlloc(GetProcessHeap(), 0, sizeof(travellog_entry));
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 This->navpane.rc.left = This->navpane.rc.top = 0;
318 This->navpane.rc.right = navpane_width_actual;
319 This->navpane.rc.bottom = rc.bottom;
321 if(!This->navpane.hwnd_splitter)
322 initialize_navpane(This, This->hwnd_main, &This->navpane.rc);
324 else
325 ZeroMemory(&This->navpane.rc, sizeof(RECT));
327 This->sv_rc.left = navpane_width_actual;
328 This->sv_rc.top = 0;
329 This->sv_rc.right = This->sv_rc.left + shellview_width_actual;
330 This->sv_rc.bottom = rc.bottom;
333 static void size_panes(ExplorerBrowserImpl *This)
335 int splitter_width = MulDiv(SPLITTER_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
336 MoveWindow(This->navpane.hwnd_splitter,
337 This->navpane.rc.right - splitter_width, This->navpane.rc.top,
338 splitter_width, This->navpane.rc.bottom - This->navpane.rc.top,
339 TRUE);
341 MoveWindow(This->hwnd_sv,
342 This->sv_rc.left, This->sv_rc.top,
343 This->sv_rc.right - This->sv_rc.left, This->sv_rc.bottom - This->sv_rc.top,
344 TRUE);
347 static HRESULT change_viewmode(ExplorerBrowserImpl *This, UINT viewmode)
349 IFolderView *pfv;
350 HRESULT hr;
352 if(!This->psv)
353 return E_FAIL;
355 hr = IShellView_QueryInterface(This->psv, &IID_IFolderView, (void*)&pfv);
356 if(SUCCEEDED(hr))
358 hr = IFolderView_SetCurrentViewMode(pfv, This->fs.ViewMode);
359 IFolderView_Release(pfv);
362 return hr;
365 static HRESULT create_new_shellview(ExplorerBrowserImpl *This, IShellItem *psi)
367 IShellBrowser *psb = &This->IShellBrowser_iface;
368 IShellFolder *psf;
369 IShellView *psv;
370 HWND hwnd_new;
371 HRESULT hr;
373 TRACE("%p, %p\n", This, psi);
375 hr = IShellItem_BindToHandler(psi, NULL, &BHID_SFObject, &IID_IShellFolder, (void**)&psf);
376 if(SUCCEEDED(hr))
378 hr = IShellFolder_CreateViewObject(psf, This->hwnd_main, &IID_IShellView, (void**)&psv);
379 if(SUCCEEDED(hr))
381 if(This->hwnd_sv)
383 IShellView_DestroyViewWindow(This->psv);
384 This->hwnd_sv = NULL;
387 hr = IShellView_CreateViewWindow(psv, This->psv, &This->fs, psb, &This->sv_rc, &hwnd_new);
388 if(SUCCEEDED(hr))
390 /* Replace the old shellview */
391 if(This->psv) IShellView_Release(This->psv);
393 This->psv = psv;
394 This->hwnd_sv = hwnd_new;
395 events_ViewCreated(This, psv);
397 else
399 ERR("CreateViewWindow failed (0x%x)\n", hr);
400 IShellView_Release(psv);
403 else
404 ERR("CreateViewObject failed (0x%x)\n", hr);
406 IShellFolder_Release(psf);
408 else
409 ERR("SI::BindToHandler failed (0x%x)\n", hr);
411 return hr;
414 static void get_interfaces_from_site(ExplorerBrowserImpl *This)
416 IServiceProvider *psp;
417 HRESULT hr;
419 /* Calling this with This->punk_site set to NULL should properly
420 * release any previously fetched interfaces.
423 if(This->pcdb_site)
425 ICommDlgBrowser_Release(This->pcdb_site);
426 if(This->pcdb2_site) ICommDlgBrowser2_Release(This->pcdb2_site);
427 if(This->pcdb3_site) ICommDlgBrowser3_Release(This->pcdb3_site);
429 This->pcdb_site = NULL;
430 This->pcdb2_site = NULL;
431 This->pcdb3_site = NULL;
434 if(This->pepv_site)
436 IExplorerPaneVisibility_Release(This->pepv_site);
437 This->pepv_site = NULL;
440 if(!This->punk_site)
441 return;
443 hr = IUnknown_QueryInterface(This->punk_site, &IID_IServiceProvider, (void**)&psp);
444 if(FAILED(hr))
446 ERR("Failed to get IServiceProvider from site.\n");
447 return;
450 /* ICommDlgBrowser */
451 IServiceProvider_QueryService(psp, &SID_SExplorerBrowserFrame, &IID_ICommDlgBrowser,
452 (void**)&This->pcdb_site);
453 IServiceProvider_QueryService(psp, &SID_SExplorerBrowserFrame, &IID_ICommDlgBrowser2,
454 (void**)&This->pcdb2_site);
455 IServiceProvider_QueryService(psp, &SID_SExplorerBrowserFrame, &IID_ICommDlgBrowser3,
456 (void**)&This->pcdb3_site);
458 /* IExplorerPaneVisibility */
459 IServiceProvider_QueryService(psp, &SID_ExplorerPaneVisibility, &IID_IExplorerPaneVisibility,
460 (void**)&This->pepv_site);
462 IServiceProvider_Release(psp);
465 /**************************************************************************
466 * General pane functionality.
468 static void update_panestate(ExplorerBrowserImpl *This)
470 EXPLORERPANESTATE eps = EPS_DONTCARE;
471 BOOL show_navpane;
472 TRACE("%p\n", This);
474 if(!This->pepv_site) return;
476 IExplorerPaneVisibility_GetPaneState(This->pepv_site, (REFEXPLORERPANE) &EP_NavPane, &eps);
477 if( !(eps & EPS_DEFAULT_OFF) )
478 show_navpane = TRUE;
479 else
480 show_navpane = FALSE;
482 if(This->navpane.show != show_navpane)
484 update_layout(This);
485 size_panes(This);
488 This->navpane.show = show_navpane;
491 static void splitter_draw(HWND hwnd, RECT *rc)
493 HDC hdc = GetDC(hwnd);
494 InvertRect(hdc, rc);
495 ReleaseDC(hwnd, hdc);
498 /**************************************************************************
499 * The Navigation Pane.
501 static LRESULT navpane_splitter_beginresize(ExplorerBrowserImpl *This, HWND hwnd, LPARAM lParam)
503 int splitter_width = MulDiv(SPLITTER_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
505 TRACE("\n");
507 SetCapture(hwnd);
509 This->splitter_rc = This->navpane.rc;
510 This->splitter_rc.left = This->splitter_rc.right - splitter_width;
512 splitter_draw(GetParent(hwnd), &This->splitter_rc);
514 return TRUE;
517 static LRESULT navpane_splitter_resizing(ExplorerBrowserImpl *This, HWND hwnd, LPARAM lParam)
519 int new_width, dx;
520 RECT rc;
521 int splitter_width = MulDiv(SPLITTER_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
522 int np_min_width = MulDiv(NP_MIN_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
523 int sv_min_width = MulDiv(SV_MIN_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
525 if(GetCapture() != hwnd) return FALSE;
527 dx = (SHORT)LOWORD(lParam);
528 TRACE("%d.\n", dx);
530 rc = This->navpane.rc;
531 new_width = This->navpane.width + dx;
532 if(new_width > np_min_width && This->sv_rc.right - new_width > sv_min_width)
534 rc.right = new_width;
535 rc.left = rc.right - splitter_width;
536 splitter_draw(GetParent(hwnd), &This->splitter_rc);
537 splitter_draw(GetParent(hwnd), &rc);
538 This->splitter_rc = rc;
541 return TRUE;
544 static LRESULT navpane_splitter_endresize(ExplorerBrowserImpl *This, HWND hwnd, LPARAM lParam)
546 int new_width, dx;
547 int np_min_width = MulDiv(NP_MIN_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
548 int sv_min_width = MulDiv(SV_MIN_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
550 if(GetCapture() != hwnd) return FALSE;
552 dx = (SHORT)LOWORD(lParam);
553 TRACE("%d.\n", dx);
555 splitter_draw(GetParent(hwnd), &This->splitter_rc);
557 new_width = This->navpane.width + dx;
558 if(new_width < np_min_width)
559 new_width = np_min_width;
560 else if(This->sv_rc.right - new_width < sv_min_width)
561 new_width = This->sv_rc.right - sv_min_width;
563 This->navpane.width = new_width;
565 update_layout(This);
566 size_panes(This);
568 ReleaseCapture();
570 return TRUE;
573 static LRESULT navpane_on_wm_create(HWND hwnd, CREATESTRUCTW *crs)
575 ExplorerBrowserImpl *This = crs->lpCreateParams;
576 INameSpaceTreeControl2 *pnstc2;
577 DWORD style;
578 HRESULT hr;
580 TRACE("%p\n", This);
581 SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LPARAM)This);
582 This->navpane.hwnd_splitter = hwnd;
584 hr = CoCreateInstance(&CLSID_NamespaceTreeControl, NULL, CLSCTX_INPROC_SERVER,
585 &IID_INameSpaceTreeControl2, (void**)&pnstc2);
587 if(SUCCEEDED(hr))
589 style = NSTCS_HASEXPANDOS | NSTCS_ROOTHASEXPANDO | NSTCS_SHOWSELECTIONALWAYS;
590 hr = INameSpaceTreeControl2_Initialize(pnstc2, GetParent(hwnd), NULL, style);
591 if(SUCCEEDED(hr))
593 INameSpaceTreeControlEvents *pnstce;
594 IShellFolder *psfdesktop;
595 IShellItem *psi;
596 IOleWindow *pow;
597 LPITEMIDLIST pidl;
598 DWORD cookie, style2 = NSTCS2_DISPLAYPADDING;
600 hr = INameSpaceTreeControl2_SetControlStyle2(pnstc2, 0xFF, style2);
601 if(FAILED(hr))
602 ERR("SetControlStyle2 failed (0x%08x)\n", hr);
604 hr = INameSpaceTreeControl2_QueryInterface(pnstc2, &IID_IOleWindow, (void**)&pow);
605 if(SUCCEEDED(hr))
607 IOleWindow_GetWindow(pow, &This->navpane.hwnd_nstc);
608 IOleWindow_Release(pow);
610 else
611 ERR("QueryInterface(IOleWindow) failed (0x%08x)\n", hr);
613 pnstce = &This->INameSpaceTreeControlEvents_iface;
614 hr = INameSpaceTreeControl2_TreeAdvise(pnstc2, (IUnknown*)pnstce, &cookie);
615 if(FAILED(hr))
616 ERR("TreeAdvise failed. (0x%08x).\n", hr);
619 * Add the default roots
622 /* TODO: This should be FOLDERID_Links */
623 hr = SHGetSpecialFolderLocation(NULL, CSIDL_FAVORITES, &pidl);
624 if(SUCCEEDED(hr))
626 hr = SHCreateShellItem(NULL, NULL, pidl, &psi);
627 if(SUCCEEDED(hr))
629 hr = INameSpaceTreeControl2_AppendRoot(pnstc2, psi, SHCONTF_NONFOLDERS, NSTCRS_VISIBLE, NULL);
630 IShellItem_Release(psi);
632 ILFree(pidl);
635 SHGetDesktopFolder(&psfdesktop);
636 hr = SHGetItemFromObject((IUnknown*)psfdesktop, &IID_IShellItem, (void**)&psi);
637 IShellFolder_Release(psfdesktop);
638 if(SUCCEEDED(hr))
640 hr = INameSpaceTreeControl2_AppendRoot(pnstc2, psi, SHCONTF_FOLDERS, NSTCRS_EXPANDED, NULL);
641 IShellItem_Release(psi);
644 /* TODO:
645 * We should advertise IID_INameSpaceTreeControl to the site of the
646 * host through its IProfferService interface, if any.
649 This->navpane.pnstc2 = pnstc2;
650 This->navpane.nstc_cookie = cookie;
652 return TRUE;
656 This->navpane.pnstc2 = NULL;
657 ERR("Failed (0x%08x)\n", hr);
659 return FALSE;
662 static LRESULT navpane_on_wm_size_move(ExplorerBrowserImpl *This)
664 UINT height, width;
665 int splitter_width = MulDiv(SPLITTER_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
667 TRACE("%p\n", This);
669 width = This->navpane.rc.right - This->navpane.rc.left - splitter_width;
670 height = This->navpane.rc.bottom - This->navpane.rc.top;
672 MoveWindow(This->navpane.hwnd_nstc,
673 This->navpane.rc.left, This->navpane.rc.top,
674 width, height,
675 TRUE);
677 return FALSE;
680 static LRESULT navpane_on_wm_destroy(ExplorerBrowserImpl *This)
682 INameSpaceTreeControl2_TreeUnadvise(This->navpane.pnstc2, This->navpane.nstc_cookie);
683 INameSpaceTreeControl2_Release(This->navpane.pnstc2);
684 This->navpane.pnstc2 = NULL;
685 return TRUE;
688 static LRESULT CALLBACK navpane_wndproc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
690 ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
692 switch(uMessage) {
693 case WM_CREATE: return navpane_on_wm_create(hWnd, (CREATESTRUCTW*)lParam);
694 case WM_MOVE: /* Fall through */
695 case WM_SIZE: return navpane_on_wm_size_move(This);
696 case WM_DESTROY: return navpane_on_wm_destroy(This);
697 case WM_LBUTTONDOWN: return navpane_splitter_beginresize(This, hWnd, lParam);
698 case WM_MOUSEMOVE: return navpane_splitter_resizing(This, hWnd, lParam);
699 case WM_LBUTTONUP: return navpane_splitter_endresize(This, hWnd, lParam);
700 default:
701 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
703 return 0;
706 static void initialize_navpane(ExplorerBrowserImpl *This, HWND hwnd_parent, RECT *rc)
708 WNDCLASSW wc;
709 HWND splitter;
710 int splitter_width = MulDiv(SPLITTER_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
711 static const WCHAR navpane_classname[] = {'e','b','_','n','a','v','p','a','n','e',0};
713 if( !GetClassInfoW(shell32_hInstance, navpane_classname, &wc) )
715 wc.style = CS_HREDRAW | CS_VREDRAW;
716 wc.lpfnWndProc = navpane_wndproc;
717 wc.cbClsExtra = 0;
718 wc.cbWndExtra = 0;
719 wc.hInstance = shell32_hInstance;
720 wc.hIcon = 0;
721 wc.hCursor = LoadCursorW(0, (LPWSTR)IDC_SIZEWE);
722 wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
723 wc.lpszMenuName = NULL;
724 wc.lpszClassName = navpane_classname;
726 if (!RegisterClassW(&wc)) return;
729 splitter = CreateWindowExW(0, navpane_classname, NULL,
730 WS_CHILD | WS_TABSTOP | WS_VISIBLE,
731 rc->right - splitter_width, rc->top,
732 splitter_width, rc->bottom - rc->top,
733 hwnd_parent, 0, shell32_hInstance, This);
734 if(!splitter)
735 ERR("Failed to create navpane : %d.\n", GetLastError());
738 /**************************************************************************
739 * Main window related functions.
741 static LRESULT main_on_wm_create(HWND hWnd, CREATESTRUCTW *crs)
743 ExplorerBrowserImpl *This = crs->lpCreateParams;
744 TRACE("%p\n", This);
746 SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LPARAM)This);
747 This->hwnd_main = hWnd;
749 return TRUE;
752 static LRESULT main_on_wm_size(ExplorerBrowserImpl *This)
754 update_layout(This);
755 size_panes(This);
757 return TRUE;
760 static LRESULT main_on_cwm_getishellbrowser(ExplorerBrowserImpl *This)
762 return (LRESULT)&This->IShellBrowser_iface;
765 static LRESULT CALLBACK main_wndproc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
767 ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
769 switch(uMessage)
771 case WM_CREATE: return main_on_wm_create(hWnd, (CREATESTRUCTW*)lParam);
772 case WM_SIZE: return main_on_wm_size(This);
773 case CWM_GETISHELLBROWSER: return main_on_cwm_getishellbrowser(This);
774 default: return DefWindowProcW(hWnd, uMessage, wParam, lParam);
777 return 0;
780 /**************************************************************************
781 * IExplorerBrowser Implementation
784 static inline ExplorerBrowserImpl *impl_from_IExplorerBrowser(IExplorerBrowser *iface)
786 return CONTAINING_RECORD(iface, ExplorerBrowserImpl, IExplorerBrowser_iface);
789 static HRESULT WINAPI IExplorerBrowser_fnQueryInterface(IExplorerBrowser *iface,
790 REFIID riid, void **ppvObject)
792 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
793 TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppvObject);
795 *ppvObject = NULL;
796 if(IsEqualIID(riid, &IID_IExplorerBrowser) ||
797 IsEqualIID(riid, &IID_IUnknown))
799 *ppvObject = &This->IExplorerBrowser_iface;
801 else if(IsEqualIID(riid, &IID_IShellBrowser) ||
802 IsEqualIID(riid, &IID_IOleWindow))
804 *ppvObject = &This->IShellBrowser_iface;
806 else if(IsEqualIID(riid, &IID_ICommDlgBrowser) ||
807 IsEqualIID(riid, &IID_ICommDlgBrowser2) ||
808 IsEqualIID(riid, &IID_ICommDlgBrowser3))
810 *ppvObject = &This->ICommDlgBrowser3_iface;
812 else if(IsEqualIID(riid, &IID_IObjectWithSite))
814 *ppvObject = &This->IObjectWithSite_iface;
816 else if(IsEqualIID(riid, &IID_IInputObject))
818 *ppvObject = &This->IInputObject_iface;
821 if(*ppvObject)
823 IUnknown_AddRef((IUnknown*)*ppvObject);
824 return S_OK;
827 return E_NOINTERFACE;
830 static ULONG WINAPI IExplorerBrowser_fnAddRef(IExplorerBrowser *iface)
832 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
833 LONG ref = InterlockedIncrement(&This->ref);
834 TRACE("%p - ref %d\n", This, ref);
836 return ref;
839 static ULONG WINAPI IExplorerBrowser_fnRelease(IExplorerBrowser *iface)
841 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
842 LONG ref = InterlockedDecrement(&This->ref);
843 TRACE("%p - ref %d\n", This, ref);
845 if(!ref)
847 TRACE("Freeing.\n");
849 if(!This->destroyed)
850 IExplorerBrowser_Destroy(iface);
852 IObjectWithSite_SetSite(&This->IObjectWithSite_iface, NULL);
854 HeapFree(GetProcessHeap(), 0, This);
855 return 0;
858 return ref;
861 static HRESULT WINAPI IExplorerBrowser_fnInitialize(IExplorerBrowser *iface,
862 HWND hwndParent, const RECT *prc,
863 const FOLDERSETTINGS *pfs)
865 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
866 WNDCLASSW wc;
867 LONG style;
868 HDC parent_dc;
869 static const WCHAR EB_CLASS_NAME[] =
870 {'E','x','p','l','o','r','e','r','B','r','o','w','s','e','r','C','o','n','t','r','o','l',0};
872 TRACE("%p (%p, %p, %p)\n", This, hwndParent, prc, pfs);
874 if(This->hwnd_main)
875 return E_UNEXPECTED;
877 if(!hwndParent)
878 return E_INVALIDARG;
880 if( !GetClassInfoW(shell32_hInstance, EB_CLASS_NAME, &wc) )
882 wc.style = CS_HREDRAW | CS_VREDRAW;
883 wc.lpfnWndProc = main_wndproc;
884 wc.cbClsExtra = 0;
885 wc.cbWndExtra = 0;
886 wc.hInstance = shell32_hInstance;
887 wc.hIcon = 0;
888 wc.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW);
889 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
890 wc.lpszMenuName = NULL;
891 wc.lpszClassName = EB_CLASS_NAME;
893 if (!RegisterClassW(&wc)) return E_FAIL;
896 parent_dc = GetDC(hwndParent);
897 This->dpix = GetDeviceCaps(parent_dc, LOGPIXELSX);
898 ReleaseDC(hwndParent, parent_dc);
900 This->navpane.width = MulDiv(NP_DEFAULT_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
902 style = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS;
903 if (!(This->eb_options & EBO_NOBORDER))
904 style |= WS_BORDER;
905 This->hwnd_main = CreateWindowExW(WS_EX_CONTROLPARENT, EB_CLASS_NAME, NULL, style,
906 prc->left, prc->top,
907 prc->right - prc->left, prc->bottom - prc->top,
908 hwndParent, 0, shell32_hInstance, This);
910 if(!This->hwnd_main)
912 ERR("Failed to create the window.\n");
913 return E_FAIL;
916 This->fs.ViewMode = pfs ? pfs->ViewMode : FVM_DETAILS;
917 This->fs.fFlags = pfs ? (pfs->fFlags | FWF_NOCLIENTEDGE) : FWF_NOCLIENTEDGE;
919 return S_OK;
922 static HRESULT WINAPI IExplorerBrowser_fnDestroy(IExplorerBrowser *iface)
924 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
925 TRACE("%p\n", This);
927 if(This->psv)
929 IShellView_DestroyViewWindow(This->psv);
930 IShellView_Release(This->psv);
931 This->psv = NULL;
932 This->hwnd_sv = NULL;
935 events_unadvise_all(This);
936 travellog_remove_all_entries(This);
938 ILFree(This->current_pidl);
939 This->current_pidl = NULL;
941 DestroyWindow(This->hwnd_main);
942 This->destroyed = TRUE;
944 return S_OK;
947 static HRESULT WINAPI IExplorerBrowser_fnSetRect(IExplorerBrowser *iface,
948 HDWP *phdwp, RECT rcBrowser)
950 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
951 TRACE("%p (%p, %s)\n", This, phdwp, wine_dbgstr_rect(&rcBrowser));
953 if(phdwp && *phdwp)
955 *phdwp = DeferWindowPos(*phdwp, This->hwnd_main, NULL, rcBrowser.left, rcBrowser.top,
956 rcBrowser.right - rcBrowser.left, rcBrowser.bottom - rcBrowser.top,
957 SWP_NOZORDER | SWP_NOACTIVATE);
958 if(!*phdwp)
959 return E_FAIL;
961 else
963 MoveWindow(This->hwnd_main, rcBrowser.left, rcBrowser.top,
964 rcBrowser.right - rcBrowser.left, rcBrowser.bottom - rcBrowser.top, TRUE);
967 return S_OK;
970 static HRESULT WINAPI IExplorerBrowser_fnSetPropertyBag(IExplorerBrowser *iface,
971 LPCWSTR pszPropertyBag)
973 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
974 FIXME("stub, %p (%s)\n", This, debugstr_w(pszPropertyBag));
976 if(!pszPropertyBag)
977 return E_INVALIDARG;
979 /* FIXME: This method is currently useless as we don't save any
980 * settings anywhere, but at least one application breaks if we
981 * return E_NOTIMPL.
984 return S_OK;
987 static HRESULT WINAPI IExplorerBrowser_fnSetEmptyText(IExplorerBrowser *iface,
988 LPCWSTR pszEmptyText)
990 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
991 FIXME("stub, %p (%s)\n", This, debugstr_w(pszEmptyText));
993 return E_NOTIMPL;
996 static HRESULT WINAPI IExplorerBrowser_fnSetFolderSettings(IExplorerBrowser *iface,
997 const FOLDERSETTINGS *pfs)
999 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1000 TRACE("%p (%p)\n", This, pfs);
1002 if(!pfs)
1003 return E_INVALIDARG;
1005 This->fs.ViewMode = pfs->ViewMode;
1006 This->fs.fFlags = pfs->fFlags | FWF_NOCLIENTEDGE;
1008 /* Change the settings of the current view, if any. */
1009 return change_viewmode(This, This->fs.ViewMode);
1012 static HRESULT WINAPI IExplorerBrowser_fnAdvise(IExplorerBrowser *iface,
1013 IExplorerBrowserEvents *psbe,
1014 DWORD *pdwCookie)
1016 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1017 event_client *client;
1018 TRACE("%p (%p, %p)\n", This, psbe, pdwCookie);
1020 client = HeapAlloc(GetProcessHeap(), 0, sizeof(event_client));
1021 client->pebe = psbe;
1022 client->cookie = ++This->events_next_cookie;
1024 IExplorerBrowserEvents_AddRef(psbe);
1025 *pdwCookie = client->cookie;
1027 list_add_tail(&This->event_clients, &client->entry);
1029 return S_OK;
1032 static HRESULT WINAPI IExplorerBrowser_fnUnadvise(IExplorerBrowser *iface,
1033 DWORD dwCookie)
1035 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1036 event_client *client;
1037 TRACE("%p (0x%x)\n", This, dwCookie);
1039 LIST_FOR_EACH_ENTRY(client, &This->event_clients, event_client, entry)
1041 if(client->cookie == dwCookie)
1043 list_remove(&client->entry);
1044 IExplorerBrowserEvents_Release(client->pebe);
1045 HeapFree(GetProcessHeap(), 0, client);
1046 return S_OK;
1050 return E_INVALIDARG;
1053 static HRESULT WINAPI IExplorerBrowser_fnSetOptions(IExplorerBrowser *iface,
1054 EXPLORER_BROWSER_OPTIONS dwFlag)
1056 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1057 static const EXPLORER_BROWSER_OPTIONS unsupported_options =
1058 EBO_ALWAYSNAVIGATE | EBO_NOWRAPPERWINDOW | EBO_HTMLSHAREPOINTVIEW | EBO_NOPERSISTVIEWSTATE;
1060 TRACE("%p (0x%x)\n", This, dwFlag);
1062 if(dwFlag & unsupported_options)
1063 FIXME("Flags 0x%08x contains unsupported options.\n", dwFlag);
1065 This->eb_options = dwFlag;
1067 return S_OK;
1070 static HRESULT WINAPI IExplorerBrowser_fnGetOptions(IExplorerBrowser *iface,
1071 EXPLORER_BROWSER_OPTIONS *pdwFlag)
1073 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1074 TRACE("%p (%p)\n", This, pdwFlag);
1076 *pdwFlag = This->eb_options;
1078 return S_OK;
1081 static HRESULT WINAPI IExplorerBrowser_fnBrowseToIDList(IExplorerBrowser *iface,
1082 PCUIDLIST_RELATIVE pidl,
1083 UINT uFlags)
1085 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1086 LPITEMIDLIST absolute_pidl = NULL;
1087 HRESULT hr;
1088 static const UINT unsupported_browse_flags =
1089 SBSP_NEWBROWSER | EBF_SELECTFROMDATAOBJECT | EBF_NODROPTARGET;
1090 TRACE("%p (%p, 0x%x)\n", This, pidl, uFlags);
1092 if(!This->hwnd_main)
1093 return E_FAIL;
1095 if(This->destroyed)
1096 return HRESULT_FROM_WIN32(ERROR_BUSY);
1098 if(This->current_pidl && (This->eb_options & EBO_NAVIGATEONCE))
1099 return E_FAIL;
1101 if(uFlags & SBSP_EXPLOREMODE)
1102 return E_INVALIDARG;
1104 if(uFlags & unsupported_browse_flags)
1105 FIXME("Argument 0x%x contains unsupported flags.\n", uFlags);
1107 if(uFlags & SBSP_NAVIGATEBACK)
1109 TRACE("SBSP_NAVIGATEBACK\n");
1110 absolute_pidl = ILClone(travellog_go_back(This));
1111 if(!absolute_pidl && !This->current_pidl)
1112 return E_FAIL;
1113 else if(!absolute_pidl)
1114 return S_OK;
1117 else if(uFlags & SBSP_NAVIGATEFORWARD)
1119 TRACE("SBSP_NAVIGATEFORWARD\n");
1120 absolute_pidl = ILClone(travellog_go_forward(This));
1121 if(!absolute_pidl && !This->current_pidl)
1122 return E_FAIL;
1123 else if(!absolute_pidl)
1124 return S_OK;
1127 else if(uFlags & SBSP_PARENT)
1129 if(This->current_pidl)
1131 if(_ILIsPidlSimple(This->current_pidl))
1133 absolute_pidl = _ILCreateDesktop();
1135 else
1137 absolute_pidl = ILClone(This->current_pidl);
1138 ILRemoveLastID(absolute_pidl);
1141 if(!absolute_pidl)
1143 ERR("Failed to get parent pidl.\n");
1144 return E_FAIL;
1148 else if(uFlags & SBSP_RELATIVE)
1150 /* SBSP_RELATIVE has precedence over SBSP_ABSOLUTE */
1151 TRACE("SBSP_RELATIVE\n");
1152 if(This->current_pidl)
1154 absolute_pidl = ILCombine(This->current_pidl, pidl);
1156 if(!absolute_pidl)
1158 ERR("Failed to get absolute pidl.\n");
1159 return E_FAIL;
1162 else
1164 TRACE("SBSP_ABSOLUTE\n");
1165 absolute_pidl = ILClone(pidl);
1166 if(!absolute_pidl && !This->current_pidl)
1167 return E_INVALIDARG;
1168 else if(!absolute_pidl)
1169 return S_OK;
1172 /* TODO: Asynchronous browsing. Return S_OK here and finish in
1173 * another thread. */
1175 hr = events_NavigationPending(This, absolute_pidl);
1176 if(FAILED(hr))
1178 TRACE("Browsing aborted.\n");
1179 ILFree(absolute_pidl);
1180 return E_FAIL;
1183 get_interfaces_from_site(This);
1184 update_panestate(This);
1186 /* Only browse if the new pidl differs from the old */
1187 if(!ILIsEqual(This->current_pidl, absolute_pidl))
1189 IShellItem *psi;
1190 hr = SHCreateItemFromIDList(absolute_pidl, &IID_IShellItem, (void**)&psi);
1191 if(SUCCEEDED(hr))
1193 hr = create_new_shellview(This, psi);
1194 if(FAILED(hr))
1196 events_NavigationFailed(This, absolute_pidl);
1197 ILFree(absolute_pidl);
1198 IShellItem_Release(psi);
1199 return E_FAIL;
1202 /* Add to travellog */
1203 if( !(This->eb_options & EBO_NOTRAVELLOG) &&
1204 !(uFlags & (SBSP_NAVIGATEFORWARD|SBSP_NAVIGATEBACK)) )
1206 travellog_add_entry(This, absolute_pidl);
1209 IShellItem_Release(psi);
1213 events_NavigationComplete(This, absolute_pidl);
1214 ILFree(This->current_pidl);
1215 This->current_pidl = absolute_pidl;
1217 /* Expand the NameSpaceTree to the current location. */
1218 if(This->navpane.show && This->navpane.pnstc2)
1220 IShellItem *psi;
1221 hr = SHCreateItemFromIDList(This->current_pidl, &IID_IShellItem, (void**)&psi);
1222 if(SUCCEEDED(hr))
1224 INameSpaceTreeControl2_EnsureItemVisible(This->navpane.pnstc2, psi);
1225 IShellItem_Release(psi);
1229 return S_OK;
1232 static HRESULT WINAPI IExplorerBrowser_fnBrowseToObject(IExplorerBrowser *iface,
1233 IUnknown *punk, UINT uFlags)
1235 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1236 LPITEMIDLIST pidl;
1237 HRESULT hr;
1238 TRACE("%p (%p, 0x%x)\n", This, punk, uFlags);
1240 if(!punk)
1241 return IExplorerBrowser_BrowseToIDList(iface, NULL, uFlags);
1243 hr = SHGetIDListFromObject(punk, &pidl);
1244 if(SUCCEEDED(hr))
1246 hr = IExplorerBrowser_BrowseToIDList(iface, pidl, uFlags);
1247 ILFree(pidl);
1250 return hr;
1253 static HRESULT WINAPI IExplorerBrowser_fnFillFromObject(IExplorerBrowser *iface,
1254 IUnknown *punk,
1255 EXPLORER_BROWSER_FILL_FLAGS dwFlags)
1257 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1258 FIXME("stub, %p (%p, 0x%x)\n", This, punk, dwFlags);
1260 return E_NOTIMPL;
1263 static HRESULT WINAPI IExplorerBrowser_fnRemoveAll(IExplorerBrowser *iface)
1265 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1266 FIXME("stub, %p\n", This);
1268 return E_NOTIMPL;
1271 static HRESULT WINAPI IExplorerBrowser_fnGetCurrentView(IExplorerBrowser *iface,
1272 REFIID riid, void **ppv)
1274 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1275 TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppv);
1277 if(!This->psv)
1278 return E_FAIL;
1280 return IShellView_QueryInterface(This->psv, riid, ppv);
1283 static const IExplorerBrowserVtbl vt_IExplorerBrowser =
1285 IExplorerBrowser_fnQueryInterface,
1286 IExplorerBrowser_fnAddRef,
1287 IExplorerBrowser_fnRelease,
1288 IExplorerBrowser_fnInitialize,
1289 IExplorerBrowser_fnDestroy,
1290 IExplorerBrowser_fnSetRect,
1291 IExplorerBrowser_fnSetPropertyBag,
1292 IExplorerBrowser_fnSetEmptyText,
1293 IExplorerBrowser_fnSetFolderSettings,
1294 IExplorerBrowser_fnAdvise,
1295 IExplorerBrowser_fnUnadvise,
1296 IExplorerBrowser_fnSetOptions,
1297 IExplorerBrowser_fnGetOptions,
1298 IExplorerBrowser_fnBrowseToIDList,
1299 IExplorerBrowser_fnBrowseToObject,
1300 IExplorerBrowser_fnFillFromObject,
1301 IExplorerBrowser_fnRemoveAll,
1302 IExplorerBrowser_fnGetCurrentView
1305 /**************************************************************************
1306 * IShellBrowser Implementation
1309 static inline ExplorerBrowserImpl *impl_from_IShellBrowser(IShellBrowser *iface)
1311 return CONTAINING_RECORD(iface, ExplorerBrowserImpl, IShellBrowser_iface);
1314 static HRESULT WINAPI IShellBrowser_fnQueryInterface(IShellBrowser *iface,
1315 REFIID riid, void **ppvObject)
1317 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1318 TRACE("%p\n", This);
1319 return IExplorerBrowser_QueryInterface(&This->IExplorerBrowser_iface, riid, ppvObject);
1322 static ULONG WINAPI IShellBrowser_fnAddRef(IShellBrowser *iface)
1324 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1325 TRACE("%p\n", This);
1326 return IExplorerBrowser_AddRef(&This->IExplorerBrowser_iface);
1329 static ULONG WINAPI IShellBrowser_fnRelease(IShellBrowser *iface)
1331 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1332 TRACE("%p\n", This);
1333 return IExplorerBrowser_Release(&This->IExplorerBrowser_iface);
1336 static HRESULT WINAPI IShellBrowser_fnGetWindow(IShellBrowser *iface, HWND *phwnd)
1338 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1339 TRACE("%p (%p)\n", This, phwnd);
1341 if(!This->hwnd_main)
1342 return E_FAIL;
1344 *phwnd = This->hwnd_main;
1345 return S_OK;
1348 static HRESULT WINAPI IShellBrowser_fnContextSensitiveHelp(IShellBrowser *iface,
1349 BOOL fEnterMode)
1351 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1352 FIXME("stub, %p (%d)\n", This, fEnterMode);
1354 return E_NOTIMPL;
1357 static HRESULT WINAPI IShellBrowser_fnInsertMenusSB(IShellBrowser *iface,
1358 HMENU hmenuShared,
1359 LPOLEMENUGROUPWIDTHS lpMenuWidths)
1361 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1362 TRACE("%p (%p, %p)\n", This, hmenuShared, lpMenuWidths);
1364 /* Not implemented. */
1365 return E_NOTIMPL;
1368 static HRESULT WINAPI IShellBrowser_fnSetMenuSB(IShellBrowser *iface,
1369 HMENU hmenuShared,
1370 HOLEMENU holemenuReserved,
1371 HWND hwndActiveObject)
1373 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1374 TRACE("%p (%p, %p, %p)\n", This, hmenuShared, holemenuReserved, hwndActiveObject);
1376 /* Not implemented. */
1377 return E_NOTIMPL;
1380 static HRESULT WINAPI IShellBrowser_fnRemoveMenusSB(IShellBrowser *iface,
1381 HMENU hmenuShared)
1383 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1384 TRACE("%p (%p)\n", This, hmenuShared);
1386 /* Not implemented. */
1387 return E_NOTIMPL;
1390 static HRESULT WINAPI IShellBrowser_fnSetStatusTextSB(IShellBrowser *iface,
1391 LPCOLESTR pszStatusText)
1393 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1394 FIXME("stub, %p (%s)\n", This, debugstr_w(pszStatusText));
1396 return E_NOTIMPL;
1399 static HRESULT WINAPI IShellBrowser_fnEnableModelessSB(IShellBrowser *iface,
1400 BOOL fEnable)
1402 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1403 FIXME("stub, %p (%d)\n", This, fEnable);
1405 return E_NOTIMPL;
1408 static HRESULT WINAPI IShellBrowser_fnTranslateAcceleratorSB(IShellBrowser *iface,
1409 MSG *pmsg, WORD wID)
1411 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1412 FIXME("stub, %p (%p, 0x%x)\n", This, pmsg, wID);
1414 return E_NOTIMPL;
1417 static HRESULT WINAPI IShellBrowser_fnBrowseObject(IShellBrowser *iface,
1418 LPCITEMIDLIST pidl, UINT wFlags)
1420 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1421 TRACE("%p (%p, %x)\n", This, pidl, wFlags);
1423 return IExplorerBrowser_BrowseToIDList(&This->IExplorerBrowser_iface, pidl, wFlags);
1426 static HRESULT WINAPI IShellBrowser_fnGetViewStateStream(IShellBrowser *iface,
1427 DWORD grfMode,
1428 IStream **ppStrm)
1430 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1431 FIXME("stub, %p (0x%x, %p)\n", This, grfMode, ppStrm);
1433 *ppStrm = NULL;
1434 return E_FAIL;
1437 static HRESULT WINAPI IShellBrowser_fnGetControlWindow(IShellBrowser *iface,
1438 UINT id, HWND *phwnd)
1440 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1441 TRACE("(%p)->(%d, %p)\n", This, id, phwnd);
1442 if (phwnd) *phwnd = NULL;
1443 return E_NOTIMPL;
1446 static HRESULT WINAPI IShellBrowser_fnSendControlMsg(IShellBrowser *iface,
1447 UINT id, UINT uMsg,
1448 WPARAM wParam, LPARAM lParam,
1449 LRESULT *pret)
1451 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1452 FIXME("stub, %p (%d, %d, %lx, %lx, %p)\n", This, id, uMsg, wParam, lParam, pret);
1454 return E_NOTIMPL;
1457 static HRESULT WINAPI IShellBrowser_fnQueryActiveShellView(IShellBrowser *iface,
1458 IShellView **ppshv)
1460 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1461 TRACE("%p (%p)\n", This, ppshv);
1463 if(!This->psv)
1464 return E_FAIL;
1466 *ppshv = This->psv;
1467 IShellView_AddRef(This->psv);
1469 return S_OK;
1472 static HRESULT WINAPI IShellBrowser_fnOnViewWindowActive(IShellBrowser *iface,
1473 IShellView *pshv)
1475 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1476 FIXME("stub, %p (%p)\n", This, pshv);
1478 return E_NOTIMPL;
1481 static HRESULT WINAPI IShellBrowser_fnSetToolbarItems(IShellBrowser *iface,
1482 LPTBBUTTONSB lpButtons,
1483 UINT nButtons, UINT uFlags)
1485 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1486 FIXME("stub, %p (%p, %d, 0x%x)\n", This, lpButtons, nButtons, uFlags);
1488 return E_NOTIMPL;
1491 static const IShellBrowserVtbl vt_IShellBrowser = {
1492 IShellBrowser_fnQueryInterface,
1493 IShellBrowser_fnAddRef,
1494 IShellBrowser_fnRelease,
1495 IShellBrowser_fnGetWindow,
1496 IShellBrowser_fnContextSensitiveHelp,
1497 IShellBrowser_fnInsertMenusSB,
1498 IShellBrowser_fnSetMenuSB,
1499 IShellBrowser_fnRemoveMenusSB,
1500 IShellBrowser_fnSetStatusTextSB,
1501 IShellBrowser_fnEnableModelessSB,
1502 IShellBrowser_fnTranslateAcceleratorSB,
1503 IShellBrowser_fnBrowseObject,
1504 IShellBrowser_fnGetViewStateStream,
1505 IShellBrowser_fnGetControlWindow,
1506 IShellBrowser_fnSendControlMsg,
1507 IShellBrowser_fnQueryActiveShellView,
1508 IShellBrowser_fnOnViewWindowActive,
1509 IShellBrowser_fnSetToolbarItems
1512 /**************************************************************************
1513 * ICommDlgBrowser3 Implementation
1516 static inline ExplorerBrowserImpl *impl_from_ICommDlgBrowser3(ICommDlgBrowser3 *iface)
1518 return CONTAINING_RECORD(iface, ExplorerBrowserImpl, ICommDlgBrowser3_iface);
1521 static HRESULT WINAPI ICommDlgBrowser3_fnQueryInterface(ICommDlgBrowser3 *iface,
1522 REFIID riid,
1523 void **ppvObject)
1525 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1526 TRACE("%p\n", This);
1527 return IExplorerBrowser_QueryInterface(&This->IExplorerBrowser_iface, riid, ppvObject);
1530 static ULONG WINAPI ICommDlgBrowser3_fnAddRef(ICommDlgBrowser3 *iface)
1532 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1533 TRACE("%p\n", This);
1534 return IExplorerBrowser_AddRef(&This->IExplorerBrowser_iface);
1537 static ULONG WINAPI ICommDlgBrowser3_fnRelease(ICommDlgBrowser3 *iface)
1539 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1540 TRACE("%p\n", This);
1541 return IExplorerBrowser_Release(&This->IExplorerBrowser_iface);
1544 static HRESULT WINAPI ICommDlgBrowser3_fnOnDefaultCommand(ICommDlgBrowser3 *iface,
1545 IShellView *shv)
1547 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1548 IDataObject *pdo;
1549 HRESULT hr;
1550 HRESULT ret = S_FALSE;
1552 TRACE("%p (%p)\n", This, shv);
1554 hr = IShellView_GetItemObject(shv, SVGIO_SELECTION, &IID_IDataObject, (void**)&pdo);
1555 if(SUCCEEDED(hr))
1557 FORMATETC fmt;
1558 STGMEDIUM medium;
1560 fmt.cfFormat = RegisterClipboardFormatW(CFSTR_SHELLIDLISTW);
1561 fmt.ptd = NULL;
1562 fmt.dwAspect = DVASPECT_CONTENT;
1563 fmt.lindex = -1;
1564 fmt.tymed = TYMED_HGLOBAL;
1566 hr = IDataObject_GetData(pdo, &fmt ,&medium);
1567 IDataObject_Release(pdo);
1568 if(SUCCEEDED(hr))
1570 LPIDA pida = GlobalLock(medium.u.hGlobal);
1571 LPCITEMIDLIST pidl_child = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[1]);
1573 /* Handle folders by browsing to them. */
1574 if(_ILIsFolder(pidl_child) || _ILIsDrive(pidl_child) || _ILIsSpecialFolder(pidl_child))
1576 IExplorerBrowser_BrowseToIDList(&This->IExplorerBrowser_iface, pidl_child, SBSP_RELATIVE);
1577 ret = S_OK;
1579 GlobalUnlock(medium.u.hGlobal);
1580 GlobalFree(medium.u.hGlobal);
1582 else
1583 ERR("Failed to get data from IDataObject.\n");
1584 } else
1585 ERR("Failed to get IDataObject.\n");
1587 /* If we didn't handle the default command, check if we have a
1588 * client that does */
1589 if(ret == S_FALSE && This->pcdb_site)
1590 return ICommDlgBrowser_OnDefaultCommand(This->pcdb_site, shv);
1592 return ret;
1594 static HRESULT WINAPI ICommDlgBrowser3_fnOnStateChange(ICommDlgBrowser3 *iface,
1595 IShellView *shv, ULONG uChange)
1597 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1598 TRACE("%p (%p, %d)\n", This, shv, uChange);
1600 if(This->pcdb_site)
1601 return ICommDlgBrowser_OnStateChange(This->pcdb_site, shv, uChange);
1603 return E_NOTIMPL;
1605 static HRESULT WINAPI ICommDlgBrowser3_fnIncludeObject(ICommDlgBrowser3 *iface,
1606 IShellView *pshv, LPCITEMIDLIST pidl)
1608 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1609 TRACE("%p (%p, %p)\n", This, pshv, pidl);
1611 if(This->pcdb_site)
1612 return ICommDlgBrowser_IncludeObject(This->pcdb_site, pshv, pidl);
1614 return S_OK;
1617 static HRESULT WINAPI ICommDlgBrowser3_fnNotify(ICommDlgBrowser3 *iface,
1618 IShellView *pshv,
1619 DWORD dwNotifyType)
1621 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1622 TRACE("%p (%p, 0x%x)\n", This, pshv, dwNotifyType);
1624 if(This->pcdb2_site)
1625 return ICommDlgBrowser2_Notify(This->pcdb2_site, pshv, dwNotifyType);
1627 return S_OK;
1630 static HRESULT WINAPI ICommDlgBrowser3_fnGetDefaultMenuText(ICommDlgBrowser3 *iface,
1631 IShellView *pshv,
1632 LPWSTR pszText, int cchMax)
1634 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1635 TRACE("%p (%p, %s, %d)\n", This, pshv, debugstr_w(pszText), cchMax);
1637 if(This->pcdb2_site)
1638 return ICommDlgBrowser2_GetDefaultMenuText(This->pcdb2_site, pshv, pszText, cchMax);
1640 return S_OK;
1643 static HRESULT WINAPI ICommDlgBrowser3_fnGetViewFlags(ICommDlgBrowser3 *iface,
1644 DWORD *pdwFlags)
1646 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1647 TRACE("%p (%p)\n", This, pdwFlags);
1649 if(This->pcdb2_site)
1650 return ICommDlgBrowser2_GetViewFlags(This->pcdb2_site, pdwFlags);
1652 return S_OK;
1655 static HRESULT WINAPI ICommDlgBrowser3_fnOnColumnClicked(ICommDlgBrowser3 *iface,
1656 IShellView *pshv, int iColumn)
1658 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1659 TRACE("%p (%p, %d)\n", This, pshv, iColumn);
1661 if(This->pcdb3_site)
1662 return ICommDlgBrowser3_OnColumnClicked(This->pcdb3_site, pshv, iColumn);
1664 return S_OK;
1667 static HRESULT WINAPI ICommDlgBrowser3_fnGetCurrentFilter(ICommDlgBrowser3 *iface,
1668 LPWSTR pszFileSpec,
1669 int cchFileSpec)
1671 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1672 TRACE("%p (%s, %d)\n", This, debugstr_w(pszFileSpec), cchFileSpec);
1674 if(This->pcdb3_site)
1675 return ICommDlgBrowser3_GetCurrentFilter(This->pcdb3_site, pszFileSpec, cchFileSpec);
1677 return S_OK;
1680 static HRESULT WINAPI ICommDlgBrowser3_fnOnPreviewCreated(ICommDlgBrowser3 *iface,
1681 IShellView *pshv)
1683 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1684 TRACE("%p (%p)\n", This, pshv);
1686 if(This->pcdb3_site)
1687 return ICommDlgBrowser3_OnPreviewCreated(This->pcdb3_site, pshv);
1689 return S_OK;
1692 static const ICommDlgBrowser3Vtbl vt_ICommDlgBrowser3 = {
1693 ICommDlgBrowser3_fnQueryInterface,
1694 ICommDlgBrowser3_fnAddRef,
1695 ICommDlgBrowser3_fnRelease,
1696 ICommDlgBrowser3_fnOnDefaultCommand,
1697 ICommDlgBrowser3_fnOnStateChange,
1698 ICommDlgBrowser3_fnIncludeObject,
1699 ICommDlgBrowser3_fnNotify,
1700 ICommDlgBrowser3_fnGetDefaultMenuText,
1701 ICommDlgBrowser3_fnGetViewFlags,
1702 ICommDlgBrowser3_fnOnColumnClicked,
1703 ICommDlgBrowser3_fnGetCurrentFilter,
1704 ICommDlgBrowser3_fnOnPreviewCreated
1707 /**************************************************************************
1708 * IObjectWithSite Implementation
1711 static inline ExplorerBrowserImpl *impl_from_IObjectWithSite(IObjectWithSite *iface)
1713 return CONTAINING_RECORD(iface, ExplorerBrowserImpl, IObjectWithSite_iface);
1716 static HRESULT WINAPI IObjectWithSite_fnQueryInterface(IObjectWithSite *iface,
1717 REFIID riid, void **ppvObject)
1719 ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
1720 TRACE("%p\n", This);
1721 return IExplorerBrowser_QueryInterface(&This->IExplorerBrowser_iface, riid, ppvObject);
1724 static ULONG WINAPI IObjectWithSite_fnAddRef(IObjectWithSite *iface)
1726 ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
1727 TRACE("%p\n", This);
1728 return IExplorerBrowser_AddRef(&This->IExplorerBrowser_iface);
1731 static ULONG WINAPI IObjectWithSite_fnRelease(IObjectWithSite *iface)
1733 ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
1734 TRACE("%p\n", This);
1735 return IExplorerBrowser_Release(&This->IExplorerBrowser_iface);
1738 static HRESULT WINAPI IObjectWithSite_fnSetSite(IObjectWithSite *iface, IUnknown *punk_site)
1740 ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
1741 TRACE("%p (%p)\n", This, punk_site);
1743 if(This->punk_site)
1745 IUnknown_Release(This->punk_site);
1746 This->punk_site = NULL;
1747 get_interfaces_from_site(This);
1750 This->punk_site = punk_site;
1752 if(This->punk_site)
1753 IUnknown_AddRef(This->punk_site);
1755 return S_OK;
1758 static HRESULT WINAPI IObjectWithSite_fnGetSite(IObjectWithSite *iface, REFIID riid, void **ppvSite)
1760 ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
1761 TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppvSite);
1763 if(!This->punk_site)
1764 return E_FAIL;
1766 return IUnknown_QueryInterface(This->punk_site, riid, ppvSite);
1769 static const IObjectWithSiteVtbl vt_IObjectWithSite = {
1770 IObjectWithSite_fnQueryInterface,
1771 IObjectWithSite_fnAddRef,
1772 IObjectWithSite_fnRelease,
1773 IObjectWithSite_fnSetSite,
1774 IObjectWithSite_fnGetSite
1777 /**************************************************************************
1778 * INameSpaceTreeControlEvents Implementation
1780 static inline ExplorerBrowserImpl *impl_from_INameSpaceTreeControlEvents(INameSpaceTreeControlEvents *iface)
1782 return CONTAINING_RECORD(iface, ExplorerBrowserImpl, INameSpaceTreeControlEvents_iface);
1785 static HRESULT WINAPI NSTCEvents_fnQueryInterface(INameSpaceTreeControlEvents *iface,
1786 REFIID riid, void **ppvObject)
1788 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1789 TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppvObject);
1791 *ppvObject = NULL;
1792 if(IsEqualIID(riid, &IID_INameSpaceTreeControlEvents) ||
1793 IsEqualIID(riid, &IID_IUnknown))
1795 *ppvObject = iface;
1798 if(*ppvObject)
1800 IUnknown_AddRef((IUnknown*)*ppvObject);
1801 return S_OK;
1804 return E_NOINTERFACE;
1807 static ULONG WINAPI NSTCEvents_fnAddRef(INameSpaceTreeControlEvents *iface)
1809 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1810 TRACE("%p\n", This);
1811 return IExplorerBrowser_AddRef(&This->IExplorerBrowser_iface);
1814 static ULONG WINAPI NSTCEvents_fnRelease(INameSpaceTreeControlEvents *iface)
1816 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1817 TRACE("%p\n", This);
1818 return IExplorerBrowser_Release(&This->IExplorerBrowser_iface);
1821 static HRESULT WINAPI NSTCEvents_fnOnItemClick(INameSpaceTreeControlEvents *iface,
1822 IShellItem *psi,
1823 NSTCEHITTEST nstceHitTest,
1824 NSTCECLICKTYPE nstceClickType)
1826 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1827 TRACE("%p (%p, 0x%x, 0x%x)\n", This, psi, nstceHitTest, nstceClickType);
1828 return S_OK;
1831 static HRESULT WINAPI NSTCEvents_fnOnPropertyItemCommit(INameSpaceTreeControlEvents *iface,
1832 IShellItem *psi)
1834 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1835 TRACE("%p (%p)\n", This, psi);
1836 return E_NOTIMPL;
1839 static HRESULT WINAPI NSTCEvents_fnOnItemStateChanging(INameSpaceTreeControlEvents *iface,
1840 IShellItem *psi,
1841 NSTCITEMSTATE nstcisMask,
1842 NSTCITEMSTATE nstcisState)
1844 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1845 TRACE("%p (%p, 0x%x, 0x%x)\n", This, psi, nstcisMask, nstcisState);
1846 return E_NOTIMPL;
1849 static HRESULT WINAPI NSTCEvents_fnOnItemStateChanged(INameSpaceTreeControlEvents *iface,
1850 IShellItem *psi,
1851 NSTCITEMSTATE nstcisMask,
1852 NSTCITEMSTATE nstcisState)
1854 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1855 TRACE("%p (%p, 0x%x, 0x%x)\n", This, psi, nstcisMask, nstcisState);
1856 return E_NOTIMPL;
1859 static HRESULT WINAPI NSTCEvents_fnOnSelectionChanged(INameSpaceTreeControlEvents *iface,
1860 IShellItemArray *psiaSelection)
1862 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1863 IShellItem *psi;
1864 HRESULT hr;
1865 TRACE("%p (%p)\n", This, psiaSelection);
1867 hr = IShellItemArray_GetItemAt(psiaSelection, 0, &psi);
1868 if(SUCCEEDED(hr))
1870 hr = IExplorerBrowser_BrowseToObject(&This->IExplorerBrowser_iface,
1871 (IUnknown*)psi, SBSP_DEFBROWSER);
1872 IShellItem_Release(psi);
1875 return hr;
1878 static HRESULT WINAPI NSTCEvents_fnOnKeyboardInput(INameSpaceTreeControlEvents *iface,
1879 UINT uMsg, WPARAM wParam, LPARAM lParam)
1881 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1882 TRACE("%p (%d, 0x%lx, 0x%lx)\n", This, uMsg, wParam, lParam);
1883 return S_OK;
1886 static HRESULT WINAPI NSTCEvents_fnOnBeforeExpand(INameSpaceTreeControlEvents *iface,
1887 IShellItem *psi)
1889 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1890 TRACE("%p (%p)\n", This, psi);
1891 return E_NOTIMPL;
1894 static HRESULT WINAPI NSTCEvents_fnOnAfterExpand(INameSpaceTreeControlEvents *iface,
1895 IShellItem *psi)
1897 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1898 TRACE("%p (%p)\n", This, psi);
1899 return E_NOTIMPL;
1902 static HRESULT WINAPI NSTCEvents_fnOnBeginLabelEdit(INameSpaceTreeControlEvents *iface,
1903 IShellItem *psi)
1905 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1906 TRACE("%p (%p)\n", This, psi);
1907 return E_NOTIMPL;
1910 static HRESULT WINAPI NSTCEvents_fnOnEndLabelEdit(INameSpaceTreeControlEvents *iface,
1911 IShellItem *psi)
1913 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1914 TRACE("%p (%p)\n", This, psi);
1915 return E_NOTIMPL;
1918 static HRESULT WINAPI NSTCEvents_fnOnGetToolTip(INameSpaceTreeControlEvents *iface,
1919 IShellItem *psi, LPWSTR pszTip, int cchTip)
1921 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1922 TRACE("%p (%p, %p, %d)\n", This, psi, pszTip, cchTip);
1923 return E_NOTIMPL;
1926 static HRESULT WINAPI NSTCEvents_fnOnBeforeItemDelete(INameSpaceTreeControlEvents *iface,
1927 IShellItem *psi)
1929 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1930 TRACE("%p (%p)\n", This, psi);
1931 return E_NOTIMPL;
1934 static HRESULT WINAPI NSTCEvents_fnOnItemAdded(INameSpaceTreeControlEvents *iface,
1935 IShellItem *psi, BOOL fIsRoot)
1937 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1938 TRACE("%p (%p, %d)\n", This, psi, fIsRoot);
1939 return E_NOTIMPL;
1942 static HRESULT WINAPI NSTCEvents_fnOnItemDeleted(INameSpaceTreeControlEvents *iface,
1943 IShellItem *psi, BOOL fIsRoot)
1945 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1946 TRACE("%p (%p, %d)\n", This, psi, fIsRoot);
1947 return E_NOTIMPL;
1950 static HRESULT WINAPI NSTCEvents_fnOnBeforeContextMenu(INameSpaceTreeControlEvents *iface,
1951 IShellItem *psi, REFIID riid, void **ppv)
1953 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1954 TRACE("%p (%p, %s, %p)\n", This, psi, shdebugstr_guid(riid), ppv);
1955 return E_NOTIMPL;
1958 static HRESULT WINAPI NSTCEvents_fnOnAfterContextMenu(INameSpaceTreeControlEvents *iface,
1959 IShellItem *psi, IContextMenu *pcmIn,
1960 REFIID riid, void **ppv)
1962 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1963 TRACE("%p (%p, %p, %s, %p)\n", This, psi, pcmIn, shdebugstr_guid(riid), ppv);
1964 return E_NOTIMPL;
1967 static HRESULT WINAPI NSTCEvents_fnOnBeforeStateImageChange(INameSpaceTreeControlEvents *iface,
1968 IShellItem *psi)
1970 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1971 TRACE("%p (%p)\n", This, psi);
1972 return E_NOTIMPL;
1975 static HRESULT WINAPI NSTCEvents_fnOnGetDefaultIconIndex(INameSpaceTreeControlEvents* iface,
1976 IShellItem *psi,
1977 int *piDefaultIcon, int *piOpenIcon)
1979 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1980 TRACE("%p (%p, %p, %p)\n", This, psi, piDefaultIcon, piOpenIcon);
1981 return E_NOTIMPL;
1985 static const INameSpaceTreeControlEventsVtbl vt_INameSpaceTreeControlEvents = {
1986 NSTCEvents_fnQueryInterface,
1987 NSTCEvents_fnAddRef,
1988 NSTCEvents_fnRelease,
1989 NSTCEvents_fnOnItemClick,
1990 NSTCEvents_fnOnPropertyItemCommit,
1991 NSTCEvents_fnOnItemStateChanging,
1992 NSTCEvents_fnOnItemStateChanged,
1993 NSTCEvents_fnOnSelectionChanged,
1994 NSTCEvents_fnOnKeyboardInput,
1995 NSTCEvents_fnOnBeforeExpand,
1996 NSTCEvents_fnOnAfterExpand,
1997 NSTCEvents_fnOnBeginLabelEdit,
1998 NSTCEvents_fnOnEndLabelEdit,
1999 NSTCEvents_fnOnGetToolTip,
2000 NSTCEvents_fnOnBeforeItemDelete,
2001 NSTCEvents_fnOnItemAdded,
2002 NSTCEvents_fnOnItemDeleted,
2003 NSTCEvents_fnOnBeforeContextMenu,
2004 NSTCEvents_fnOnAfterContextMenu,
2005 NSTCEvents_fnOnBeforeStateImageChange,
2006 NSTCEvents_fnOnGetDefaultIconIndex
2009 /**************************************************************************
2010 * IInputObject Implementation
2013 static inline ExplorerBrowserImpl *impl_from_IInputObject(IInputObject *iface)
2015 return CONTAINING_RECORD(iface, ExplorerBrowserImpl, IInputObject_iface);
2018 static HRESULT WINAPI IInputObject_fnQueryInterface(IInputObject *iface,
2019 REFIID riid, void **ppvObject)
2021 ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
2022 TRACE("%p\n", This);
2023 return IExplorerBrowser_QueryInterface(&This->IExplorerBrowser_iface, riid, ppvObject);
2026 static ULONG WINAPI IInputObject_fnAddRef(IInputObject *iface)
2028 ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
2029 TRACE("%p\n", This);
2030 return IExplorerBrowser_AddRef(&This->IExplorerBrowser_iface);
2033 static ULONG WINAPI IInputObject_fnRelease(IInputObject *iface)
2035 ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
2036 TRACE("%p\n", This);
2037 return IExplorerBrowser_Release(&This->IExplorerBrowser_iface);
2040 static HRESULT WINAPI IInputObject_fnUIActivateIO(IInputObject *iface, BOOL fActivate, MSG *pMsg)
2042 ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
2043 FIXME("stub, %p (%d, %p)\n", This, fActivate, pMsg);
2044 return E_NOTIMPL;
2047 static HRESULT WINAPI IInputObject_fnHasFocusIO(IInputObject *iface)
2049 ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
2050 FIXME("stub, %p\n", This);
2051 return E_NOTIMPL;
2054 static HRESULT WINAPI IInputObject_fnTranslateAcceleratorIO(IInputObject *iface, MSG *pMsg)
2056 ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
2057 FIXME("stub, %p (%p)\n", This, pMsg);
2058 return E_NOTIMPL;
2061 static IInputObjectVtbl vt_IInputObject = {
2062 IInputObject_fnQueryInterface,
2063 IInputObject_fnAddRef,
2064 IInputObject_fnRelease,
2065 IInputObject_fnUIActivateIO,
2066 IInputObject_fnHasFocusIO,
2067 IInputObject_fnTranslateAcceleratorIO
2070 HRESULT WINAPI ExplorerBrowser_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv)
2072 ExplorerBrowserImpl *eb;
2073 HRESULT ret;
2075 TRACE("%p %s %p\n", pUnkOuter, shdebugstr_guid (riid), ppv);
2077 if(!ppv)
2078 return E_POINTER;
2079 if(pUnkOuter)
2080 return CLASS_E_NOAGGREGATION;
2082 eb = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ExplorerBrowserImpl));
2083 eb->ref = 1;
2084 eb->IExplorerBrowser_iface.lpVtbl = &vt_IExplorerBrowser;
2085 eb->IShellBrowser_iface.lpVtbl = &vt_IShellBrowser;
2086 eb->ICommDlgBrowser3_iface.lpVtbl = &vt_ICommDlgBrowser3;
2087 eb->IObjectWithSite_iface.lpVtbl = &vt_IObjectWithSite;
2088 eb->INameSpaceTreeControlEvents_iface.lpVtbl = &vt_INameSpaceTreeControlEvents;
2089 eb->IInputObject_iface.lpVtbl = &vt_IInputObject;
2091 /* Default settings */
2092 eb->navpane.show = TRUE;
2094 list_init(&eb->event_clients);
2095 list_init(&eb->travellog);
2097 ret = IExplorerBrowser_QueryInterface(&eb->IExplorerBrowser_iface, riid, ppv);
2098 IExplorerBrowser_Release(&eb->IExplorerBrowser_iface);
2100 TRACE("--(%p)\n", ppv);
2101 return ret;