dmusic: Avoid swallowing collection Load failures.
[wine.git] / dlls / shell32 / ebrowser.c
blob8ae09d441bbc75b94f19b171799d481641a36c51
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 #include "winerror.h"
25 #include "windef.h"
26 #include "winbase.h"
28 #include "wine/list.h"
29 #include "wine/debug.h"
30 #include "debughlp.h"
32 #include "shell32_main.h"
33 #include "pidl.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(shell);
37 #define SPLITTER_WIDTH 2
38 #define NP_MIN_WIDTH 60
39 #define NP_DEFAULT_WIDTH 150
40 #define SV_MIN_WIDTH 150
42 typedef struct _event_client {
43 struct list entry;
44 IExplorerBrowserEvents *pebe;
45 DWORD cookie;
46 } event_client;
48 typedef struct _travellog_entry {
49 struct list entry;
50 LPITEMIDLIST pidl;
51 } travellog_entry;
53 typedef struct _ExplorerBrowserImpl {
54 IExplorerBrowser IExplorerBrowser_iface;
55 IShellBrowser IShellBrowser_iface;
56 ICommDlgBrowser3 ICommDlgBrowser3_iface;
57 IObjectWithSite IObjectWithSite_iface;
58 INameSpaceTreeControlEvents INameSpaceTreeControlEvents_iface;
59 IInputObject IInputObject_iface;
60 LONG ref;
61 BOOL destroyed;
63 HWND hwnd_main;
64 HWND hwnd_sv;
66 RECT splitter_rc;
67 struct {
68 INameSpaceTreeControl2 *pnstc2;
69 HWND hwnd_splitter, hwnd_nstc;
70 DWORD nstc_cookie;
71 UINT width;
72 BOOL show;
73 RECT rc;
74 } navpane;
76 EXPLORER_BROWSER_OPTIONS eb_options;
77 FOLDERSETTINGS fs;
79 struct list event_clients;
80 DWORD events_next_cookie;
81 struct list travellog;
82 travellog_entry *travellog_cursor;
83 int travellog_count;
85 int dpix;
87 IShellView *psv;
88 RECT sv_rc;
89 LPITEMIDLIST current_pidl;
91 IUnknown *punk_site;
92 ICommDlgBrowser *pcdb_site;
93 ICommDlgBrowser2 *pcdb2_site;
94 ICommDlgBrowser3 *pcdb3_site;
95 IExplorerPaneVisibility *pepv_site;
96 } ExplorerBrowserImpl;
98 static void initialize_navpane(ExplorerBrowserImpl *This, HWND hwnd_parent, RECT *rc);
100 /**************************************************************************
101 * Event functions.
103 static void events_unadvise_all(ExplorerBrowserImpl *This)
105 event_client *client, *curs;
106 TRACE("%p\n", This);
108 LIST_FOR_EACH_ENTRY_SAFE(client, curs, &This->event_clients, event_client, entry)
110 TRACE("Removing %p\n", client);
111 list_remove(&client->entry);
112 IExplorerBrowserEvents_Release(client->pebe);
113 free(client);
117 static HRESULT events_NavigationPending(ExplorerBrowserImpl *This, PCIDLIST_ABSOLUTE pidl)
119 event_client *cursor;
120 HRESULT hres = S_OK;
122 TRACE("%p\n", This);
124 LIST_FOR_EACH_ENTRY(cursor, &This->event_clients, event_client, entry)
126 TRACE("Notifying %p\n", cursor);
127 hres = IExplorerBrowserEvents_OnNavigationPending(cursor->pebe, pidl);
129 /* If this failed for any reason, the browsing is supposed to be aborted. */
130 if(FAILED(hres))
131 break;
134 return hres;
137 static void events_NavigationComplete(ExplorerBrowserImpl *This, PCIDLIST_ABSOLUTE pidl)
139 event_client *cursor;
141 TRACE("%p\n", This);
143 LIST_FOR_EACH_ENTRY(cursor, &This->event_clients, event_client, entry)
145 TRACE("Notifying %p\n", cursor);
146 IExplorerBrowserEvents_OnNavigationComplete(cursor->pebe, pidl);
150 static void events_NavigationFailed(ExplorerBrowserImpl *This, PCIDLIST_ABSOLUTE pidl)
152 event_client *cursor;
154 TRACE("%p\n", This);
156 LIST_FOR_EACH_ENTRY(cursor, &This->event_clients, event_client, entry)
158 TRACE("Notifying %p\n", cursor);
159 IExplorerBrowserEvents_OnNavigationFailed(cursor->pebe, pidl);
163 static void events_ViewCreated(ExplorerBrowserImpl *This, IShellView *psv)
165 event_client *cursor;
167 TRACE("%p\n", This);
169 LIST_FOR_EACH_ENTRY(cursor, &This->event_clients, event_client, entry)
171 TRACE("Notifying %p\n", cursor);
172 IExplorerBrowserEvents_OnViewCreated(cursor->pebe, psv);
176 /**************************************************************************
177 * Travellog functions.
179 static void travellog_remove_entry(ExplorerBrowserImpl *This, travellog_entry *entry)
181 TRACE("Removing %p\n", entry);
183 list_remove(&entry->entry);
184 ILFree(entry->pidl);
185 free(entry);
186 This->travellog_count--;
189 static void travellog_remove_all_entries(ExplorerBrowserImpl *This)
191 travellog_entry *cursor, *cursor2;
192 TRACE("%p\n", This);
194 LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->travellog, travellog_entry, entry)
195 travellog_remove_entry(This, cursor);
197 This->travellog_cursor = NULL;
200 static void travellog_add_entry(ExplorerBrowserImpl *This, LPITEMIDLIST pidl)
202 travellog_entry *new, *cursor, *cursor2;
203 TRACE("%p (old count %d)\n", pidl, This->travellog_count);
205 /* Replace the old tail, if any, with the new entry */
206 if(This->travellog_cursor)
208 LIST_FOR_EACH_ENTRY_SAFE_REV(cursor, cursor2, &This->travellog, travellog_entry, entry)
210 if(cursor == This->travellog_cursor)
211 break;
212 travellog_remove_entry(This, cursor);
216 /* Create and add the new entry */
217 new = malloc(sizeof(*new));
218 new->pidl = ILClone(pidl);
219 list_add_tail(&This->travellog, &new->entry);
220 This->travellog_cursor = new;
221 This->travellog_count++;
223 /* Remove the first few entries if the size limit is reached. */
224 if(This->travellog_count > 200)
226 UINT i = 0;
227 LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->travellog, travellog_entry, entry)
229 if(i++ > 10)
230 break;
231 travellog_remove_entry(This, cursor);
236 static LPCITEMIDLIST travellog_go_back(ExplorerBrowserImpl *This)
238 travellog_entry *prev;
239 TRACE("%p, %p\n", This, This->travellog_cursor);
241 if(!This->travellog_cursor)
242 return NULL;
244 prev = LIST_ENTRY(list_prev(&This->travellog, &This->travellog_cursor->entry),
245 travellog_entry, entry);
246 if(!prev)
247 return NULL;
249 This->travellog_cursor = prev;
250 return prev->pidl;
253 static LPCITEMIDLIST travellog_go_forward(ExplorerBrowserImpl *This)
255 travellog_entry *next;
256 TRACE("%p, %p\n", This, This->travellog_cursor);
258 if(!This->travellog_cursor)
259 return NULL;
261 next = LIST_ENTRY(list_next(&This->travellog, &This->travellog_cursor->entry),
262 travellog_entry, entry);
263 if(!next)
264 return NULL;
266 This->travellog_cursor = next;
267 return next->pidl;
270 /**************************************************************************
271 * Helper functions
273 static void update_layout(ExplorerBrowserImpl *This)
275 RECT rc;
276 INT navpane_width_actual;
277 INT shellview_width_actual;
278 int np_min_width = MulDiv(NP_MIN_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
279 int sv_min_width = MulDiv(SV_MIN_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
280 TRACE("%p (navpane: %d, EBO_SHOWFRAMES: %d)\n",
281 This, This->navpane.show, This->eb_options & EBO_SHOWFRAMES);
283 GetClientRect(This->hwnd_main, &rc);
285 if((This->eb_options & EBO_SHOWFRAMES) && This->navpane.show)
286 navpane_width_actual = This->navpane.width;
287 else
288 navpane_width_actual = 0;
290 shellview_width_actual = rc.right - navpane_width_actual;
291 if(shellview_width_actual < sv_min_width && navpane_width_actual)
293 INT missing_width = sv_min_width - shellview_width_actual;
294 if(missing_width < (navpane_width_actual - np_min_width))
296 /* Shrink the navpane */
297 navpane_width_actual -= missing_width;
298 shellview_width_actual += missing_width;
300 else
302 /* Hide the navpane */
303 shellview_width_actual += navpane_width_actual;
304 navpane_width_actual = 0;
308 /**************************************************************
309 * Calculate rectangles for the panes. All rectangles contain
310 * the position of the panes relative to hwnd_main.
313 if(navpane_width_actual)
315 SetRect(&This->navpane.rc, 0, 0, navpane_width_actual, rc.bottom);
317 if(!This->navpane.hwnd_splitter)
318 initialize_navpane(This, This->hwnd_main, &This->navpane.rc);
320 else
321 ZeroMemory(&This->navpane.rc, sizeof(RECT));
323 SetRect(&This->sv_rc, navpane_width_actual, 0, navpane_width_actual + shellview_width_actual,
324 rc.bottom);
327 static void size_panes(ExplorerBrowserImpl *This)
329 int splitter_width = MulDiv(SPLITTER_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
330 MoveWindow(This->navpane.hwnd_splitter,
331 This->navpane.rc.right - splitter_width, This->navpane.rc.top,
332 splitter_width, This->navpane.rc.bottom - This->navpane.rc.top,
333 TRUE);
335 MoveWindow(This->hwnd_sv,
336 This->sv_rc.left, This->sv_rc.top,
337 This->sv_rc.right - This->sv_rc.left, This->sv_rc.bottom - This->sv_rc.top,
338 TRUE);
341 static HRESULT create_new_shellview(ExplorerBrowserImpl *This, IShellItem *psi)
343 IShellBrowser *psb = &This->IShellBrowser_iface;
344 IShellFolder *psf;
345 IShellView *psv;
346 HWND hwnd_new;
347 HRESULT hr;
349 TRACE("%p, %p\n", This, psi);
351 hr = IShellItem_BindToHandler(psi, NULL, &BHID_SFObject, &IID_IShellFolder, (void**)&psf);
352 if(SUCCEEDED(hr))
354 hr = IShellFolder_CreateViewObject(psf, This->hwnd_main, &IID_IShellView, (void**)&psv);
355 if(SUCCEEDED(hr))
357 if(This->hwnd_sv)
359 IShellView_DestroyViewWindow(This->psv);
360 This->hwnd_sv = NULL;
363 This->fs.fFlags |= FWF_USESEARCHFOLDER | FWF_FULLROWSELECT | FWF_NOCLIENTEDGE;
364 hr = IShellView_CreateViewWindow(psv, This->psv, &This->fs, psb, &This->sv_rc, &hwnd_new);
365 if(SUCCEEDED(hr))
367 /* Replace the old shellview */
368 if(This->psv) IShellView_Release(This->psv);
370 This->psv = psv;
371 This->hwnd_sv = hwnd_new;
372 events_ViewCreated(This, psv);
374 else
376 ERR("CreateViewWindow failed (0x%lx)\n", hr);
377 IShellView_Release(psv);
380 else
381 ERR("CreateViewObject failed (0x%lx)\n", hr);
383 IShellFolder_Release(psf);
385 else
386 ERR("SI::BindToHandler failed (0x%lx)\n", hr);
388 return hr;
391 static void get_interfaces_from_site(ExplorerBrowserImpl *This)
393 IServiceProvider *psp;
394 HRESULT hr;
396 /* Calling this with This->punk_site set to NULL should properly
397 * release any previously fetched interfaces.
400 if(This->pcdb_site)
402 ICommDlgBrowser_Release(This->pcdb_site);
403 if(This->pcdb2_site) ICommDlgBrowser2_Release(This->pcdb2_site);
404 if(This->pcdb3_site) ICommDlgBrowser3_Release(This->pcdb3_site);
406 This->pcdb_site = NULL;
407 This->pcdb2_site = NULL;
408 This->pcdb3_site = NULL;
411 if(This->pepv_site)
413 IExplorerPaneVisibility_Release(This->pepv_site);
414 This->pepv_site = NULL;
417 if(!This->punk_site)
418 return;
420 hr = IUnknown_QueryInterface(This->punk_site, &IID_IServiceProvider, (void**)&psp);
421 if(FAILED(hr))
423 ERR("Failed to get IServiceProvider from site.\n");
424 return;
427 /* ICommDlgBrowser */
428 IServiceProvider_QueryService(psp, &SID_SExplorerBrowserFrame, &IID_ICommDlgBrowser,
429 (void**)&This->pcdb_site);
430 IServiceProvider_QueryService(psp, &SID_SExplorerBrowserFrame, &IID_ICommDlgBrowser2,
431 (void**)&This->pcdb2_site);
432 IServiceProvider_QueryService(psp, &SID_SExplorerBrowserFrame, &IID_ICommDlgBrowser3,
433 (void**)&This->pcdb3_site);
435 /* IExplorerPaneVisibility */
436 IServiceProvider_QueryService(psp, &SID_ExplorerPaneVisibility, &IID_IExplorerPaneVisibility,
437 (void**)&This->pepv_site);
439 IServiceProvider_Release(psp);
442 /**************************************************************************
443 * General pane functionality.
445 static void update_panestate(ExplorerBrowserImpl *This)
447 EXPLORERPANESTATE eps = EPS_DONTCARE;
448 BOOL show_navpane;
449 TRACE("%p\n", This);
451 if(!This->pepv_site) return;
453 IExplorerPaneVisibility_GetPaneState(This->pepv_site, (REFEXPLORERPANE) &EP_NavPane, &eps);
454 if( !(eps & EPS_DEFAULT_OFF) )
455 show_navpane = TRUE;
456 else
457 show_navpane = FALSE;
459 if(This->navpane.show != show_navpane)
461 update_layout(This);
462 size_panes(This);
465 This->navpane.show = show_navpane;
468 static void splitter_draw(HWND hwnd, RECT *rc)
470 HDC hdc = GetDC(hwnd);
471 InvertRect(hdc, rc);
472 ReleaseDC(hwnd, hdc);
475 /**************************************************************************
476 * The Navigation Pane.
478 static LRESULT navpane_splitter_beginresize(ExplorerBrowserImpl *This, HWND hwnd, LPARAM lParam)
480 int splitter_width = MulDiv(SPLITTER_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
482 TRACE("\n");
484 SetCapture(hwnd);
486 This->splitter_rc = This->navpane.rc;
487 This->splitter_rc.left = This->splitter_rc.right - splitter_width;
489 splitter_draw(GetParent(hwnd), &This->splitter_rc);
491 return TRUE;
494 static LRESULT navpane_splitter_resizing(ExplorerBrowserImpl *This, HWND hwnd, LPARAM lParam)
496 int new_width, dx;
497 RECT rc;
498 int splitter_width = MulDiv(SPLITTER_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
499 int np_min_width = MulDiv(NP_MIN_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
500 int sv_min_width = MulDiv(SV_MIN_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
502 if(GetCapture() != hwnd) return FALSE;
504 dx = (SHORT)LOWORD(lParam);
505 TRACE("%d.\n", dx);
507 rc = This->navpane.rc;
508 new_width = This->navpane.width + dx;
509 if(new_width > np_min_width && This->sv_rc.right - new_width > sv_min_width)
511 rc.right = new_width;
512 rc.left = rc.right - splitter_width;
513 splitter_draw(GetParent(hwnd), &This->splitter_rc);
514 splitter_draw(GetParent(hwnd), &rc);
515 This->splitter_rc = rc;
518 return TRUE;
521 static LRESULT navpane_splitter_endresize(ExplorerBrowserImpl *This, HWND hwnd, LPARAM lParam)
523 int new_width, dx;
524 int np_min_width = MulDiv(NP_MIN_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
525 int sv_min_width = MulDiv(SV_MIN_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
527 if(GetCapture() != hwnd) return FALSE;
529 dx = (SHORT)LOWORD(lParam);
530 TRACE("%d.\n", dx);
532 splitter_draw(GetParent(hwnd), &This->splitter_rc);
534 new_width = This->navpane.width + dx;
535 if(new_width < np_min_width)
536 new_width = np_min_width;
537 else if(This->sv_rc.right - new_width < sv_min_width)
538 new_width = This->sv_rc.right - sv_min_width;
540 This->navpane.width = new_width;
542 update_layout(This);
543 size_panes(This);
545 ReleaseCapture();
547 return TRUE;
550 static LRESULT navpane_on_wm_create(HWND hwnd, CREATESTRUCTW *crs)
552 ExplorerBrowserImpl *This = crs->lpCreateParams;
553 INameSpaceTreeControl2 *pnstc2;
554 DWORD style;
555 HRESULT hr;
557 TRACE("%p\n", This);
558 SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LPARAM)This);
559 This->navpane.hwnd_splitter = hwnd;
561 hr = CoCreateInstance(&CLSID_NamespaceTreeControl, NULL, CLSCTX_INPROC_SERVER,
562 &IID_INameSpaceTreeControl2, (void**)&pnstc2);
564 if(SUCCEEDED(hr))
566 style = NSTCS_HASEXPANDOS | NSTCS_ROOTHASEXPANDO | NSTCS_SHOWSELECTIONALWAYS;
567 hr = INameSpaceTreeControl2_Initialize(pnstc2, GetParent(hwnd), NULL, style);
568 if(SUCCEEDED(hr))
570 INameSpaceTreeControlEvents *pnstce;
571 IShellFolder *psfdesktop;
572 IShellItem *psi;
573 IOleWindow *pow;
574 LPITEMIDLIST pidl;
575 DWORD cookie, style2 = NSTCS2_DISPLAYPADDING;
577 hr = INameSpaceTreeControl2_SetControlStyle2(pnstc2, 0xFF, style2);
578 if(FAILED(hr))
579 ERR("SetControlStyle2 failed (0x%08lx)\n", hr);
581 hr = INameSpaceTreeControl2_QueryInterface(pnstc2, &IID_IOleWindow, (void**)&pow);
582 if(SUCCEEDED(hr))
584 IOleWindow_GetWindow(pow, &This->navpane.hwnd_nstc);
585 IOleWindow_Release(pow);
587 else
588 ERR("QueryInterface(IOleWindow) failed (0x%08lx)\n", hr);
590 pnstce = &This->INameSpaceTreeControlEvents_iface;
591 hr = INameSpaceTreeControl2_TreeAdvise(pnstc2, (IUnknown*)pnstce, &cookie);
592 if(FAILED(hr))
593 ERR("TreeAdvise failed. (0x%08lx).\n", hr);
596 * Add the default roots
599 /* TODO: This should be FOLDERID_Links */
600 hr = SHGetSpecialFolderLocation(NULL, CSIDL_FAVORITES, &pidl);
601 if(SUCCEEDED(hr))
603 hr = SHCreateShellItem(NULL, NULL, pidl, &psi);
604 if(SUCCEEDED(hr))
606 hr = INameSpaceTreeControl2_AppendRoot(pnstc2, psi, SHCONTF_NONFOLDERS, NSTCRS_VISIBLE, NULL);
607 IShellItem_Release(psi);
609 ILFree(pidl);
612 SHGetDesktopFolder(&psfdesktop);
613 hr = SHGetItemFromObject((IUnknown*)psfdesktop, &IID_IShellItem, (void**)&psi);
614 IShellFolder_Release(psfdesktop);
615 if(SUCCEEDED(hr))
617 hr = INameSpaceTreeControl2_AppendRoot(pnstc2, psi, SHCONTF_FOLDERS, NSTCRS_EXPANDED, NULL);
618 IShellItem_Release(psi);
621 /* TODO:
622 * We should advertise IID_INameSpaceTreeControl to the site of the
623 * host through its IProfferService interface, if any.
626 This->navpane.pnstc2 = pnstc2;
627 This->navpane.nstc_cookie = cookie;
629 return TRUE;
633 This->navpane.pnstc2 = NULL;
634 ERR("Failed (0x%08lx)\n", hr);
636 return FALSE;
639 static LRESULT navpane_on_wm_size_move(ExplorerBrowserImpl *This)
641 UINT height, width;
642 int splitter_width = MulDiv(SPLITTER_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
644 TRACE("%p\n", This);
646 width = This->navpane.rc.right - This->navpane.rc.left - splitter_width;
647 height = This->navpane.rc.bottom - This->navpane.rc.top;
649 MoveWindow(This->navpane.hwnd_nstc,
650 This->navpane.rc.left, This->navpane.rc.top,
651 width, height,
652 TRUE);
654 return FALSE;
657 static LRESULT navpane_on_wm_destroy(ExplorerBrowserImpl *This)
659 INameSpaceTreeControl2_TreeUnadvise(This->navpane.pnstc2, This->navpane.nstc_cookie);
660 INameSpaceTreeControl2_Release(This->navpane.pnstc2);
661 This->navpane.pnstc2 = NULL;
662 return TRUE;
665 static LRESULT CALLBACK navpane_wndproc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
667 ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
669 switch(uMessage) {
670 case WM_CREATE: return navpane_on_wm_create(hWnd, (CREATESTRUCTW*)lParam);
671 case WM_MOVE: /* Fall through */
672 case WM_SIZE: return navpane_on_wm_size_move(This);
673 case WM_DESTROY: return navpane_on_wm_destroy(This);
674 case WM_LBUTTONDOWN: return navpane_splitter_beginresize(This, hWnd, lParam);
675 case WM_MOUSEMOVE: return navpane_splitter_resizing(This, hWnd, lParam);
676 case WM_LBUTTONUP: return navpane_splitter_endresize(This, hWnd, lParam);
677 default:
678 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
680 return 0;
683 static void initialize_navpane(ExplorerBrowserImpl *This, HWND hwnd_parent, RECT *rc)
685 WNDCLASSW wc;
686 HWND splitter;
687 int splitter_width = MulDiv(SPLITTER_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
689 if( !GetClassInfoW(shell32_hInstance, L"eb_navpane", &wc) )
691 wc.style = CS_HREDRAW | CS_VREDRAW;
692 wc.lpfnWndProc = navpane_wndproc;
693 wc.cbClsExtra = 0;
694 wc.cbWndExtra = 0;
695 wc.hInstance = shell32_hInstance;
696 wc.hIcon = 0;
697 wc.hCursor = LoadCursorW(0, (LPWSTR)IDC_SIZEWE);
698 wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
699 wc.lpszMenuName = NULL;
700 wc.lpszClassName = L"eb_navpane";
702 if (!RegisterClassW(&wc)) return;
705 splitter = CreateWindowExW(0, L"eb_navpane", NULL,
706 WS_CHILD | WS_TABSTOP | WS_VISIBLE,
707 rc->right - splitter_width, rc->top,
708 splitter_width, rc->bottom - rc->top,
709 hwnd_parent, 0, shell32_hInstance, This);
710 if(!splitter)
711 ERR("Failed to create navpane : %ld.\n", GetLastError());
714 /**************************************************************************
715 * Main window related functions.
717 static LRESULT main_on_wm_create(HWND hWnd, CREATESTRUCTW *crs)
719 ExplorerBrowserImpl *This = crs->lpCreateParams;
720 TRACE("%p\n", This);
722 SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LPARAM)This);
723 This->hwnd_main = hWnd;
725 return TRUE;
728 static LRESULT main_on_wm_size(ExplorerBrowserImpl *This)
730 update_layout(This);
731 size_panes(This);
733 return TRUE;
736 static LRESULT main_on_cwm_getishellbrowser(ExplorerBrowserImpl *This)
738 return (LRESULT)&This->IShellBrowser_iface;
741 static LRESULT CALLBACK main_wndproc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
743 ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
745 switch(uMessage)
747 case WM_CREATE: return main_on_wm_create(hWnd, (CREATESTRUCTW*)lParam);
748 case WM_SIZE: return main_on_wm_size(This);
749 case CWM_GETISHELLBROWSER: return main_on_cwm_getishellbrowser(This);
750 default: return DefWindowProcW(hWnd, uMessage, wParam, lParam);
753 return 0;
756 /**************************************************************************
757 * IExplorerBrowser Implementation
760 static inline ExplorerBrowserImpl *impl_from_IExplorerBrowser(IExplorerBrowser *iface)
762 return CONTAINING_RECORD(iface, ExplorerBrowserImpl, IExplorerBrowser_iface);
765 static HRESULT WINAPI IExplorerBrowser_fnQueryInterface(IExplorerBrowser *iface,
766 REFIID riid, void **ppvObject)
768 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
769 TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppvObject);
771 *ppvObject = NULL;
772 if(IsEqualIID(riid, &IID_IExplorerBrowser) ||
773 IsEqualIID(riid, &IID_IUnknown))
775 *ppvObject = &This->IExplorerBrowser_iface;
777 else if(IsEqualIID(riid, &IID_IShellBrowser) ||
778 IsEqualIID(riid, &IID_IOleWindow))
780 *ppvObject = &This->IShellBrowser_iface;
782 else if(IsEqualIID(riid, &IID_ICommDlgBrowser) ||
783 IsEqualIID(riid, &IID_ICommDlgBrowser2) ||
784 IsEqualIID(riid, &IID_ICommDlgBrowser3))
786 *ppvObject = &This->ICommDlgBrowser3_iface;
788 else if(IsEqualIID(riid, &IID_IObjectWithSite))
790 *ppvObject = &This->IObjectWithSite_iface;
792 else if(IsEqualIID(riid, &IID_IInputObject))
794 *ppvObject = &This->IInputObject_iface;
797 if(*ppvObject)
799 IUnknown_AddRef((IUnknown*)*ppvObject);
800 return S_OK;
803 return E_NOINTERFACE;
806 static ULONG WINAPI IExplorerBrowser_fnAddRef(IExplorerBrowser *iface)
808 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
809 LONG ref = InterlockedIncrement(&This->ref);
810 TRACE("%p - ref %ld\n", This, ref);
812 return ref;
815 static ULONG WINAPI IExplorerBrowser_fnRelease(IExplorerBrowser *iface)
817 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
818 LONG ref = InterlockedDecrement(&This->ref);
819 TRACE("%p - ref %ld\n", This, ref);
821 if(!ref)
823 TRACE("Freeing.\n");
825 if(!This->destroyed)
826 IExplorerBrowser_Destroy(iface);
828 IObjectWithSite_SetSite(&This->IObjectWithSite_iface, NULL);
830 free(This);
833 return ref;
836 static HRESULT WINAPI IExplorerBrowser_fnInitialize(IExplorerBrowser *iface,
837 HWND hwndParent, const RECT *prc,
838 const FOLDERSETTINGS *pfs)
840 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
841 WNDCLASSW wc;
842 LONG style;
843 HDC parent_dc;
845 TRACE("%p (%p, %p, %p)\n", This, hwndParent, prc, pfs);
847 if(This->hwnd_main)
848 return E_UNEXPECTED;
850 if(!hwndParent)
851 return E_INVALIDARG;
853 if( !GetClassInfoW(shell32_hInstance, L"ExplorerBrowserControl", &wc) )
855 wc.style = CS_HREDRAW | CS_VREDRAW;
856 wc.lpfnWndProc = main_wndproc;
857 wc.cbClsExtra = 0;
858 wc.cbWndExtra = 0;
859 wc.hInstance = shell32_hInstance;
860 wc.hIcon = 0;
861 wc.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW);
862 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
863 wc.lpszMenuName = NULL;
864 wc.lpszClassName = L"ExplorerBrowserControl";
866 if (!RegisterClassW(&wc)) return E_FAIL;
869 parent_dc = GetDC(hwndParent);
870 This->dpix = GetDeviceCaps(parent_dc, LOGPIXELSX);
871 ReleaseDC(hwndParent, parent_dc);
873 This->navpane.width = MulDiv(NP_DEFAULT_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
875 style = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS;
876 if (!(This->eb_options & EBO_NOBORDER))
877 style |= WS_BORDER;
878 This->hwnd_main = CreateWindowExW(WS_EX_CONTROLPARENT, L"ExplorerBrowserControl", NULL, style,
879 prc->left, prc->top,
880 prc->right - prc->left, prc->bottom - prc->top,
881 hwndParent, 0, shell32_hInstance, This);
883 if(!This->hwnd_main)
885 ERR("Failed to create the window.\n");
886 return E_FAIL;
889 This->fs.ViewMode = pfs ? pfs->ViewMode : FVM_DETAILS;
890 This->fs.fFlags = pfs ? (pfs->fFlags | FWF_NOCLIENTEDGE) : FWF_NOCLIENTEDGE;
892 return S_OK;
895 static HRESULT WINAPI IExplorerBrowser_fnDestroy(IExplorerBrowser *iface)
897 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
898 TRACE("%p\n", This);
900 if(This->psv)
902 IShellView_DestroyViewWindow(This->psv);
903 IShellView_Release(This->psv);
904 This->psv = NULL;
905 This->hwnd_sv = NULL;
908 events_unadvise_all(This);
909 travellog_remove_all_entries(This);
911 ILFree(This->current_pidl);
912 This->current_pidl = NULL;
914 DestroyWindow(This->hwnd_main);
915 This->destroyed = TRUE;
917 return S_OK;
920 static HRESULT WINAPI IExplorerBrowser_fnSetRect(IExplorerBrowser *iface,
921 HDWP *phdwp, RECT rcBrowser)
923 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
924 TRACE("%p (%p, %s)\n", This, phdwp, wine_dbgstr_rect(&rcBrowser));
926 if(phdwp && *phdwp)
928 *phdwp = DeferWindowPos(*phdwp, This->hwnd_main, NULL, rcBrowser.left, rcBrowser.top,
929 rcBrowser.right - rcBrowser.left, rcBrowser.bottom - rcBrowser.top,
930 SWP_NOZORDER | SWP_NOACTIVATE);
931 if(!*phdwp)
932 return E_FAIL;
934 else
936 MoveWindow(This->hwnd_main, rcBrowser.left, rcBrowser.top,
937 rcBrowser.right - rcBrowser.left, rcBrowser.bottom - rcBrowser.top, TRUE);
940 return S_OK;
943 static HRESULT WINAPI IExplorerBrowser_fnSetPropertyBag(IExplorerBrowser *iface,
944 LPCWSTR pszPropertyBag)
946 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
947 FIXME("stub, %p (%s)\n", This, debugstr_w(pszPropertyBag));
949 if(!pszPropertyBag)
950 return E_INVALIDARG;
952 /* FIXME: This method is currently useless as we don't save any
953 * settings anywhere, but at least one application breaks if we
954 * return E_NOTIMPL.
957 return S_OK;
960 static HRESULT WINAPI IExplorerBrowser_fnSetEmptyText(IExplorerBrowser *iface,
961 LPCWSTR pszEmptyText)
963 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
964 FIXME("stub, %p (%s)\n", This, debugstr_w(pszEmptyText));
966 return E_NOTIMPL;
969 static HRESULT WINAPI IExplorerBrowser_fnSetFolderSettings(IExplorerBrowser *iface,
970 const FOLDERSETTINGS *pfs)
972 ExplorerBrowserImpl *browser = impl_from_IExplorerBrowser(iface);
973 IFolderView2 *view;
974 HRESULT hr;
976 TRACE("explorer browser %p, settings %p.\n", iface, pfs);
978 if (!pfs)
979 return E_INVALIDARG;
981 if (pfs->ViewMode)
982 browser->fs.ViewMode = pfs->ViewMode;
983 browser->fs.fFlags = pfs->fFlags;
985 if (!browser->psv)
986 return E_INVALIDARG;
988 hr = IShellView_QueryInterface(browser->psv, &IID_IFolderView2, (void **)&view);
989 if (SUCCEEDED(hr))
991 hr = IFolderView2_SetCurrentViewMode(view, browser->fs.ViewMode);
992 if (SUCCEEDED(hr))
993 if (SUCCEEDED(hr))
994 hr = IFolderView2_SetCurrentFolderFlags(view, ~FWF_NONE, browser->fs.fFlags);
995 IFolderView2_Release(view);
997 return hr;
1000 static HRESULT WINAPI IExplorerBrowser_fnAdvise(IExplorerBrowser *iface,
1001 IExplorerBrowserEvents *psbe,
1002 DWORD *pdwCookie)
1004 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1005 event_client *client;
1006 TRACE("%p (%p, %p)\n", This, psbe, pdwCookie);
1008 client = malloc(sizeof(*client));
1009 client->pebe = psbe;
1010 client->cookie = ++This->events_next_cookie;
1012 IExplorerBrowserEvents_AddRef(psbe);
1013 *pdwCookie = client->cookie;
1015 list_add_tail(&This->event_clients, &client->entry);
1017 return S_OK;
1020 static HRESULT WINAPI IExplorerBrowser_fnUnadvise(IExplorerBrowser *iface,
1021 DWORD dwCookie)
1023 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1024 event_client *client;
1025 TRACE("%p (0x%lx)\n", This, dwCookie);
1027 LIST_FOR_EACH_ENTRY(client, &This->event_clients, event_client, entry)
1029 if(client->cookie == dwCookie)
1031 list_remove(&client->entry);
1032 IExplorerBrowserEvents_Release(client->pebe);
1033 free(client);
1034 return S_OK;
1038 return E_INVALIDARG;
1041 static HRESULT WINAPI IExplorerBrowser_fnSetOptions(IExplorerBrowser *iface,
1042 EXPLORER_BROWSER_OPTIONS dwFlag)
1044 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1045 static const EXPLORER_BROWSER_OPTIONS unsupported_options =
1046 EBO_ALWAYSNAVIGATE | EBO_NOWRAPPERWINDOW | EBO_HTMLSHAREPOINTVIEW | EBO_NOPERSISTVIEWSTATE;
1048 TRACE("%p (0x%x)\n", This, dwFlag);
1050 if(dwFlag & unsupported_options)
1051 FIXME("Flags 0x%08x contains unsupported options.\n", dwFlag);
1053 This->eb_options = dwFlag;
1055 return S_OK;
1058 static HRESULT WINAPI IExplorerBrowser_fnGetOptions(IExplorerBrowser *iface,
1059 EXPLORER_BROWSER_OPTIONS *pdwFlag)
1061 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1062 TRACE("%p (%p)\n", This, pdwFlag);
1064 *pdwFlag = This->eb_options;
1066 return S_OK;
1069 static HRESULT WINAPI IExplorerBrowser_fnBrowseToIDList(IExplorerBrowser *iface,
1070 PCUIDLIST_RELATIVE pidl,
1071 UINT uFlags)
1073 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1074 LPITEMIDLIST absolute_pidl = NULL;
1075 HRESULT hr;
1076 static const UINT unsupported_browse_flags =
1077 SBSP_NEWBROWSER | EBF_SELECTFROMDATAOBJECT | EBF_NODROPTARGET;
1078 TRACE("%p (%p, 0x%x)\n", This, pidl, uFlags);
1080 if(!This->hwnd_main)
1081 return E_FAIL;
1083 if(This->destroyed)
1084 return HRESULT_FROM_WIN32(ERROR_BUSY);
1086 if(This->current_pidl && (This->eb_options & EBO_NAVIGATEONCE))
1087 return E_FAIL;
1089 if(uFlags & SBSP_EXPLOREMODE)
1090 return E_INVALIDARG;
1092 if(uFlags & unsupported_browse_flags)
1093 FIXME("Argument 0x%x contains unsupported flags.\n", uFlags);
1095 if(uFlags & SBSP_NAVIGATEBACK)
1097 TRACE("SBSP_NAVIGATEBACK\n");
1098 absolute_pidl = ILClone(travellog_go_back(This));
1099 if(!absolute_pidl && !This->current_pidl)
1100 return E_FAIL;
1101 else if(!absolute_pidl)
1102 return S_OK;
1105 else if(uFlags & SBSP_NAVIGATEFORWARD)
1107 TRACE("SBSP_NAVIGATEFORWARD\n");
1108 absolute_pidl = ILClone(travellog_go_forward(This));
1109 if(!absolute_pidl && !This->current_pidl)
1110 return E_FAIL;
1111 else if(!absolute_pidl)
1112 return S_OK;
1115 else if(uFlags & SBSP_PARENT)
1117 if(This->current_pidl)
1119 if(_ILIsPidlSimple(This->current_pidl))
1121 absolute_pidl = _ILCreateDesktop();
1123 else
1125 absolute_pidl = ILClone(This->current_pidl);
1126 ILRemoveLastID(absolute_pidl);
1129 if(!absolute_pidl)
1131 ERR("Failed to get parent pidl.\n");
1132 return E_FAIL;
1136 else if(uFlags & SBSP_RELATIVE)
1138 /* SBSP_RELATIVE has precedence over SBSP_ABSOLUTE */
1139 TRACE("SBSP_RELATIVE\n");
1140 if(This->current_pidl)
1142 absolute_pidl = ILCombine(This->current_pidl, pidl);
1144 if(!absolute_pidl)
1146 ERR("Failed to get absolute pidl.\n");
1147 return E_FAIL;
1150 else
1152 TRACE("SBSP_ABSOLUTE\n");
1153 absolute_pidl = ILClone(pidl);
1154 if(!absolute_pidl && !This->current_pidl)
1155 return E_INVALIDARG;
1156 else if(!absolute_pidl)
1157 return S_OK;
1160 /* TODO: Asynchronous browsing. Return S_OK here and finish in
1161 * another thread. */
1163 hr = events_NavigationPending(This, absolute_pidl);
1164 if(FAILED(hr))
1166 TRACE("Browsing aborted.\n");
1167 ILFree(absolute_pidl);
1168 return E_FAIL;
1171 get_interfaces_from_site(This);
1172 update_panestate(This);
1174 /* Only browse if the new pidl differs from the old */
1175 if(!ILIsEqual(This->current_pidl, absolute_pidl))
1177 IShellItem *psi;
1178 hr = SHCreateItemFromIDList(absolute_pidl, &IID_IShellItem, (void**)&psi);
1179 if(SUCCEEDED(hr))
1181 hr = create_new_shellview(This, psi);
1182 if(FAILED(hr))
1184 events_NavigationFailed(This, absolute_pidl);
1185 ILFree(absolute_pidl);
1186 IShellItem_Release(psi);
1187 return E_FAIL;
1190 /* Add to travellog */
1191 if( !(This->eb_options & EBO_NOTRAVELLOG) &&
1192 !(uFlags & (SBSP_NAVIGATEFORWARD|SBSP_NAVIGATEBACK)) )
1194 travellog_add_entry(This, absolute_pidl);
1197 IShellItem_Release(psi);
1201 events_NavigationComplete(This, absolute_pidl);
1202 ILFree(This->current_pidl);
1203 This->current_pidl = absolute_pidl;
1205 /* Expand the NameSpaceTree to the current location. */
1206 if(This->navpane.show && This->navpane.pnstc2)
1208 IShellItem *psi;
1209 hr = SHCreateItemFromIDList(This->current_pidl, &IID_IShellItem, (void**)&psi);
1210 if(SUCCEEDED(hr))
1212 INameSpaceTreeControl2_EnsureItemVisible(This->navpane.pnstc2, psi);
1213 IShellItem_Release(psi);
1217 return S_OK;
1220 static HRESULT WINAPI IExplorerBrowser_fnBrowseToObject(IExplorerBrowser *iface,
1221 IUnknown *punk, UINT uFlags)
1223 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1224 LPITEMIDLIST pidl;
1225 HRESULT hr;
1226 TRACE("%p (%p, 0x%x)\n", This, punk, uFlags);
1228 if(!punk)
1229 return IExplorerBrowser_BrowseToIDList(iface, NULL, uFlags);
1231 hr = SHGetIDListFromObject(punk, &pidl);
1232 if(SUCCEEDED(hr))
1234 hr = IExplorerBrowser_BrowseToIDList(iface, pidl, uFlags);
1235 ILFree(pidl);
1238 return hr;
1241 static HRESULT WINAPI IExplorerBrowser_fnFillFromObject(IExplorerBrowser *iface,
1242 IUnknown *punk,
1243 EXPLORER_BROWSER_FILL_FLAGS dwFlags)
1245 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1246 FIXME("stub, %p (%p, 0x%x)\n", This, punk, dwFlags);
1248 return E_NOTIMPL;
1251 static HRESULT WINAPI IExplorerBrowser_fnRemoveAll(IExplorerBrowser *iface)
1253 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1254 FIXME("stub, %p\n", This);
1256 return E_NOTIMPL;
1259 static HRESULT WINAPI IExplorerBrowser_fnGetCurrentView(IExplorerBrowser *iface,
1260 REFIID riid, void **ppv)
1262 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1263 TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppv);
1265 if(!This->psv)
1266 return E_FAIL;
1268 return IShellView_QueryInterface(This->psv, riid, ppv);
1271 static const IExplorerBrowserVtbl vt_IExplorerBrowser =
1273 IExplorerBrowser_fnQueryInterface,
1274 IExplorerBrowser_fnAddRef,
1275 IExplorerBrowser_fnRelease,
1276 IExplorerBrowser_fnInitialize,
1277 IExplorerBrowser_fnDestroy,
1278 IExplorerBrowser_fnSetRect,
1279 IExplorerBrowser_fnSetPropertyBag,
1280 IExplorerBrowser_fnSetEmptyText,
1281 IExplorerBrowser_fnSetFolderSettings,
1282 IExplorerBrowser_fnAdvise,
1283 IExplorerBrowser_fnUnadvise,
1284 IExplorerBrowser_fnSetOptions,
1285 IExplorerBrowser_fnGetOptions,
1286 IExplorerBrowser_fnBrowseToIDList,
1287 IExplorerBrowser_fnBrowseToObject,
1288 IExplorerBrowser_fnFillFromObject,
1289 IExplorerBrowser_fnRemoveAll,
1290 IExplorerBrowser_fnGetCurrentView
1293 /**************************************************************************
1294 * IShellBrowser Implementation
1297 static inline ExplorerBrowserImpl *impl_from_IShellBrowser(IShellBrowser *iface)
1299 return CONTAINING_RECORD(iface, ExplorerBrowserImpl, IShellBrowser_iface);
1302 static HRESULT WINAPI IShellBrowser_fnQueryInterface(IShellBrowser *iface,
1303 REFIID riid, void **ppvObject)
1305 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1306 TRACE("%p\n", This);
1307 return IExplorerBrowser_QueryInterface(&This->IExplorerBrowser_iface, riid, ppvObject);
1310 static ULONG WINAPI IShellBrowser_fnAddRef(IShellBrowser *iface)
1312 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1313 TRACE("%p\n", This);
1314 return IExplorerBrowser_AddRef(&This->IExplorerBrowser_iface);
1317 static ULONG WINAPI IShellBrowser_fnRelease(IShellBrowser *iface)
1319 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1320 TRACE("%p\n", This);
1321 return IExplorerBrowser_Release(&This->IExplorerBrowser_iface);
1324 static HRESULT WINAPI IShellBrowser_fnGetWindow(IShellBrowser *iface, HWND *phwnd)
1326 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1327 TRACE("%p (%p)\n", This, phwnd);
1329 if(!This->hwnd_main)
1330 return E_FAIL;
1332 *phwnd = This->hwnd_main;
1333 return S_OK;
1336 static HRESULT WINAPI IShellBrowser_fnContextSensitiveHelp(IShellBrowser *iface,
1337 BOOL fEnterMode)
1339 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1340 FIXME("stub, %p (%d)\n", This, fEnterMode);
1342 return E_NOTIMPL;
1345 static HRESULT WINAPI IShellBrowser_fnInsertMenusSB(IShellBrowser *iface,
1346 HMENU hmenuShared,
1347 LPOLEMENUGROUPWIDTHS lpMenuWidths)
1349 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1350 TRACE("%p (%p, %p)\n", This, hmenuShared, lpMenuWidths);
1352 /* Not implemented. */
1353 return E_NOTIMPL;
1356 static HRESULT WINAPI IShellBrowser_fnSetMenuSB(IShellBrowser *iface,
1357 HMENU hmenuShared,
1358 HOLEMENU holemenuReserved,
1359 HWND hwndActiveObject)
1361 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1362 TRACE("%p (%p, %p, %p)\n", This, hmenuShared, holemenuReserved, hwndActiveObject);
1364 /* Not implemented. */
1365 return E_NOTIMPL;
1368 static HRESULT WINAPI IShellBrowser_fnRemoveMenusSB(IShellBrowser *iface,
1369 HMENU hmenuShared)
1371 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1372 TRACE("%p (%p)\n", This, hmenuShared);
1374 /* Not implemented. */
1375 return E_NOTIMPL;
1378 static HRESULT WINAPI IShellBrowser_fnSetStatusTextSB(IShellBrowser *iface,
1379 LPCOLESTR pszStatusText)
1381 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1382 FIXME("stub, %p (%s)\n", This, debugstr_w(pszStatusText));
1384 return E_NOTIMPL;
1387 static HRESULT WINAPI IShellBrowser_fnEnableModelessSB(IShellBrowser *iface,
1388 BOOL fEnable)
1390 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1391 FIXME("stub, %p (%d)\n", This, fEnable);
1393 return E_NOTIMPL;
1396 static HRESULT WINAPI IShellBrowser_fnTranslateAcceleratorSB(IShellBrowser *iface,
1397 MSG *pmsg, WORD wID)
1399 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1400 FIXME("stub, %p (%p, 0x%x)\n", This, pmsg, wID);
1402 return E_NOTIMPL;
1405 static HRESULT WINAPI IShellBrowser_fnBrowseObject(IShellBrowser *iface,
1406 LPCITEMIDLIST pidl, UINT wFlags)
1408 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1409 TRACE("%p (%p, %x)\n", This, pidl, wFlags);
1411 return IExplorerBrowser_BrowseToIDList(&This->IExplorerBrowser_iface, pidl, wFlags);
1414 static HRESULT WINAPI IShellBrowser_fnGetViewStateStream(IShellBrowser *iface,
1415 DWORD grfMode,
1416 IStream **ppStrm)
1418 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1419 FIXME("stub, %p (0x%lx, %p)\n", This, grfMode, ppStrm);
1421 *ppStrm = NULL;
1422 return E_FAIL;
1425 static HRESULT WINAPI IShellBrowser_fnGetControlWindow(IShellBrowser *iface,
1426 UINT id, HWND *phwnd)
1428 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1429 TRACE("(%p)->(%d, %p)\n", This, id, phwnd);
1430 if (phwnd) *phwnd = NULL;
1431 return E_NOTIMPL;
1434 static HRESULT WINAPI IShellBrowser_fnSendControlMsg(IShellBrowser *iface,
1435 UINT id, UINT uMsg,
1436 WPARAM wParam, LPARAM lParam,
1437 LRESULT *pret)
1439 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1440 FIXME("stub, %p (%d, %d, %Ix, %Ix, %p)\n", This, id, uMsg, wParam, lParam, pret);
1442 return E_NOTIMPL;
1445 static HRESULT WINAPI IShellBrowser_fnQueryActiveShellView(IShellBrowser *iface,
1446 IShellView **ppshv)
1448 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1449 TRACE("%p (%p)\n", This, ppshv);
1451 if(!This->psv)
1452 return E_FAIL;
1454 *ppshv = This->psv;
1455 IShellView_AddRef(This->psv);
1457 return S_OK;
1460 static HRESULT WINAPI IShellBrowser_fnOnViewWindowActive(IShellBrowser *iface,
1461 IShellView *pshv)
1463 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1464 FIXME("stub, %p (%p)\n", This, pshv);
1466 return E_NOTIMPL;
1469 static HRESULT WINAPI IShellBrowser_fnSetToolbarItems(IShellBrowser *iface,
1470 LPTBBUTTONSB lpButtons,
1471 UINT nButtons, UINT uFlags)
1473 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1474 FIXME("stub, %p (%p, %d, 0x%x)\n", This, lpButtons, nButtons, uFlags);
1476 return E_NOTIMPL;
1479 static const IShellBrowserVtbl vt_IShellBrowser = {
1480 IShellBrowser_fnQueryInterface,
1481 IShellBrowser_fnAddRef,
1482 IShellBrowser_fnRelease,
1483 IShellBrowser_fnGetWindow,
1484 IShellBrowser_fnContextSensitiveHelp,
1485 IShellBrowser_fnInsertMenusSB,
1486 IShellBrowser_fnSetMenuSB,
1487 IShellBrowser_fnRemoveMenusSB,
1488 IShellBrowser_fnSetStatusTextSB,
1489 IShellBrowser_fnEnableModelessSB,
1490 IShellBrowser_fnTranslateAcceleratorSB,
1491 IShellBrowser_fnBrowseObject,
1492 IShellBrowser_fnGetViewStateStream,
1493 IShellBrowser_fnGetControlWindow,
1494 IShellBrowser_fnSendControlMsg,
1495 IShellBrowser_fnQueryActiveShellView,
1496 IShellBrowser_fnOnViewWindowActive,
1497 IShellBrowser_fnSetToolbarItems
1500 /**************************************************************************
1501 * ICommDlgBrowser3 Implementation
1504 static inline ExplorerBrowserImpl *impl_from_ICommDlgBrowser3(ICommDlgBrowser3 *iface)
1506 return CONTAINING_RECORD(iface, ExplorerBrowserImpl, ICommDlgBrowser3_iface);
1509 static HRESULT WINAPI ICommDlgBrowser3_fnQueryInterface(ICommDlgBrowser3 *iface,
1510 REFIID riid,
1511 void **ppvObject)
1513 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1514 TRACE("%p\n", This);
1515 return IExplorerBrowser_QueryInterface(&This->IExplorerBrowser_iface, riid, ppvObject);
1518 static ULONG WINAPI ICommDlgBrowser3_fnAddRef(ICommDlgBrowser3 *iface)
1520 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1521 TRACE("%p\n", This);
1522 return IExplorerBrowser_AddRef(&This->IExplorerBrowser_iface);
1525 static ULONG WINAPI ICommDlgBrowser3_fnRelease(ICommDlgBrowser3 *iface)
1527 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1528 TRACE("%p\n", This);
1529 return IExplorerBrowser_Release(&This->IExplorerBrowser_iface);
1532 static HRESULT WINAPI ICommDlgBrowser3_fnOnDefaultCommand(ICommDlgBrowser3 *iface,
1533 IShellView *shv)
1535 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1536 IDataObject *pdo;
1537 HRESULT hr;
1538 HRESULT ret = S_FALSE;
1540 TRACE("%p (%p)\n", This, shv);
1542 hr = IShellView_GetItemObject(shv, SVGIO_SELECTION, &IID_IDataObject, (void**)&pdo);
1543 if(SUCCEEDED(hr))
1545 FORMATETC fmt;
1546 STGMEDIUM medium;
1548 fmt.cfFormat = RegisterClipboardFormatW(CFSTR_SHELLIDLISTW);
1549 fmt.ptd = NULL;
1550 fmt.dwAspect = DVASPECT_CONTENT;
1551 fmt.lindex = -1;
1552 fmt.tymed = TYMED_HGLOBAL;
1554 hr = IDataObject_GetData(pdo, &fmt ,&medium);
1555 IDataObject_Release(pdo);
1556 if(SUCCEEDED(hr))
1558 LPIDA pida = GlobalLock(medium.hGlobal);
1559 LPCITEMIDLIST pidl_child = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[1]);
1561 /* Handle folders by browsing to them. */
1562 if(_ILIsFolder(pidl_child) || _ILIsDrive(pidl_child) || _ILIsSpecialFolder(pidl_child))
1564 IExplorerBrowser_BrowseToIDList(&This->IExplorerBrowser_iface, pidl_child, SBSP_RELATIVE);
1565 ret = S_OK;
1567 GlobalUnlock(medium.hGlobal);
1568 GlobalFree(medium.hGlobal);
1570 else
1571 ERR("Failed to get data from IDataObject.\n");
1572 } else
1573 ERR("Failed to get IDataObject.\n");
1575 /* If we didn't handle the default command, check if we have a
1576 * client that does */
1577 if(ret == S_FALSE && This->pcdb_site)
1578 return ICommDlgBrowser_OnDefaultCommand(This->pcdb_site, shv);
1580 return ret;
1582 static HRESULT WINAPI ICommDlgBrowser3_fnOnStateChange(ICommDlgBrowser3 *iface,
1583 IShellView *shv, ULONG uChange)
1585 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1586 TRACE("%p (%p, %ld)\n", This, shv, uChange);
1588 if(This->pcdb_site)
1589 return ICommDlgBrowser_OnStateChange(This->pcdb_site, shv, uChange);
1591 return E_NOTIMPL;
1593 static HRESULT WINAPI ICommDlgBrowser3_fnIncludeObject(ICommDlgBrowser3 *iface,
1594 IShellView *pshv, LPCITEMIDLIST pidl)
1596 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1597 TRACE("%p (%p, %p)\n", This, pshv, pidl);
1599 if(This->pcdb_site)
1600 return ICommDlgBrowser_IncludeObject(This->pcdb_site, pshv, pidl);
1602 return S_OK;
1605 static HRESULT WINAPI ICommDlgBrowser3_fnNotify(ICommDlgBrowser3 *iface,
1606 IShellView *pshv,
1607 DWORD dwNotifyType)
1609 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1610 TRACE("%p (%p, 0x%lx)\n", This, pshv, dwNotifyType);
1612 if(This->pcdb2_site)
1613 return ICommDlgBrowser2_Notify(This->pcdb2_site, pshv, dwNotifyType);
1615 return S_OK;
1618 static HRESULT WINAPI ICommDlgBrowser3_fnGetDefaultMenuText(ICommDlgBrowser3 *iface,
1619 IShellView *pshv,
1620 LPWSTR pszText, int cchMax)
1622 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1623 TRACE("%p (%p, %s, %d)\n", This, pshv, debugstr_w(pszText), cchMax);
1625 if(This->pcdb2_site)
1626 return ICommDlgBrowser2_GetDefaultMenuText(This->pcdb2_site, pshv, pszText, cchMax);
1628 return S_OK;
1631 static HRESULT WINAPI ICommDlgBrowser3_fnGetViewFlags(ICommDlgBrowser3 *iface,
1632 DWORD *pdwFlags)
1634 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1635 TRACE("%p (%p)\n", This, pdwFlags);
1637 if(This->pcdb2_site)
1638 return ICommDlgBrowser2_GetViewFlags(This->pcdb2_site, pdwFlags);
1640 return S_OK;
1643 static HRESULT WINAPI ICommDlgBrowser3_fnOnColumnClicked(ICommDlgBrowser3 *iface,
1644 IShellView *pshv, int iColumn)
1646 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1647 TRACE("%p (%p, %d)\n", This, pshv, iColumn);
1649 if(This->pcdb3_site)
1650 return ICommDlgBrowser3_OnColumnClicked(This->pcdb3_site, pshv, iColumn);
1652 return S_OK;
1655 static HRESULT WINAPI ICommDlgBrowser3_fnGetCurrentFilter(ICommDlgBrowser3 *iface,
1656 LPWSTR pszFileSpec,
1657 int cchFileSpec)
1659 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1660 TRACE("%p (%s, %d)\n", This, debugstr_w(pszFileSpec), cchFileSpec);
1662 if(This->pcdb3_site)
1663 return ICommDlgBrowser3_GetCurrentFilter(This->pcdb3_site, pszFileSpec, cchFileSpec);
1665 return S_OK;
1668 static HRESULT WINAPI ICommDlgBrowser3_fnOnPreViewCreated(ICommDlgBrowser3 *iface,
1669 IShellView *pshv)
1671 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1672 TRACE("%p (%p)\n", This, pshv);
1674 if(This->pcdb3_site)
1675 return ICommDlgBrowser3_OnPreViewCreated(This->pcdb3_site, pshv);
1677 return S_OK;
1680 static const ICommDlgBrowser3Vtbl vt_ICommDlgBrowser3 = {
1681 ICommDlgBrowser3_fnQueryInterface,
1682 ICommDlgBrowser3_fnAddRef,
1683 ICommDlgBrowser3_fnRelease,
1684 ICommDlgBrowser3_fnOnDefaultCommand,
1685 ICommDlgBrowser3_fnOnStateChange,
1686 ICommDlgBrowser3_fnIncludeObject,
1687 ICommDlgBrowser3_fnNotify,
1688 ICommDlgBrowser3_fnGetDefaultMenuText,
1689 ICommDlgBrowser3_fnGetViewFlags,
1690 ICommDlgBrowser3_fnOnColumnClicked,
1691 ICommDlgBrowser3_fnGetCurrentFilter,
1692 ICommDlgBrowser3_fnOnPreViewCreated
1695 /**************************************************************************
1696 * IObjectWithSite Implementation
1699 static inline ExplorerBrowserImpl *impl_from_IObjectWithSite(IObjectWithSite *iface)
1701 return CONTAINING_RECORD(iface, ExplorerBrowserImpl, IObjectWithSite_iface);
1704 static HRESULT WINAPI IObjectWithSite_fnQueryInterface(IObjectWithSite *iface,
1705 REFIID riid, void **ppvObject)
1707 ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
1708 TRACE("%p\n", This);
1709 return IExplorerBrowser_QueryInterface(&This->IExplorerBrowser_iface, riid, ppvObject);
1712 static ULONG WINAPI IObjectWithSite_fnAddRef(IObjectWithSite *iface)
1714 ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
1715 TRACE("%p\n", This);
1716 return IExplorerBrowser_AddRef(&This->IExplorerBrowser_iface);
1719 static ULONG WINAPI IObjectWithSite_fnRelease(IObjectWithSite *iface)
1721 ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
1722 TRACE("%p\n", This);
1723 return IExplorerBrowser_Release(&This->IExplorerBrowser_iface);
1726 static HRESULT WINAPI IObjectWithSite_fnSetSite(IObjectWithSite *iface, IUnknown *punk_site)
1728 ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
1729 TRACE("%p (%p)\n", This, punk_site);
1731 if(This->punk_site)
1733 IUnknown_Release(This->punk_site);
1734 This->punk_site = NULL;
1735 get_interfaces_from_site(This);
1738 This->punk_site = punk_site;
1740 if(This->punk_site)
1741 IUnknown_AddRef(This->punk_site);
1743 return S_OK;
1746 static HRESULT WINAPI IObjectWithSite_fnGetSite(IObjectWithSite *iface, REFIID riid, void **ppvSite)
1748 ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
1749 TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppvSite);
1751 if(!This->punk_site)
1752 return E_FAIL;
1754 return IUnknown_QueryInterface(This->punk_site, riid, ppvSite);
1757 static const IObjectWithSiteVtbl vt_IObjectWithSite = {
1758 IObjectWithSite_fnQueryInterface,
1759 IObjectWithSite_fnAddRef,
1760 IObjectWithSite_fnRelease,
1761 IObjectWithSite_fnSetSite,
1762 IObjectWithSite_fnGetSite
1765 /**************************************************************************
1766 * INameSpaceTreeControlEvents Implementation
1768 static inline ExplorerBrowserImpl *impl_from_INameSpaceTreeControlEvents(INameSpaceTreeControlEvents *iface)
1770 return CONTAINING_RECORD(iface, ExplorerBrowserImpl, INameSpaceTreeControlEvents_iface);
1773 static HRESULT WINAPI NSTCEvents_fnQueryInterface(INameSpaceTreeControlEvents *iface,
1774 REFIID riid, void **ppvObject)
1776 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1777 TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppvObject);
1779 *ppvObject = NULL;
1780 if(IsEqualIID(riid, &IID_INameSpaceTreeControlEvents) ||
1781 IsEqualIID(riid, &IID_IUnknown))
1783 *ppvObject = iface;
1786 if(*ppvObject)
1788 IUnknown_AddRef((IUnknown*)*ppvObject);
1789 return S_OK;
1792 return E_NOINTERFACE;
1795 static ULONG WINAPI NSTCEvents_fnAddRef(INameSpaceTreeControlEvents *iface)
1797 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1798 TRACE("%p\n", This);
1799 return IExplorerBrowser_AddRef(&This->IExplorerBrowser_iface);
1802 static ULONG WINAPI NSTCEvents_fnRelease(INameSpaceTreeControlEvents *iface)
1804 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1805 TRACE("%p\n", This);
1806 return IExplorerBrowser_Release(&This->IExplorerBrowser_iface);
1809 static HRESULT WINAPI NSTCEvents_fnOnItemClick(INameSpaceTreeControlEvents *iface,
1810 IShellItem *psi,
1811 NSTCEHITTEST nstceHitTest,
1812 NSTCECLICKTYPE nstceClickType)
1814 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1815 TRACE("%p (%p, 0x%lx, 0x%lx)\n", This, psi, nstceHitTest, nstceClickType);
1816 return S_OK;
1819 static HRESULT WINAPI NSTCEvents_fnOnPropertyItemCommit(INameSpaceTreeControlEvents *iface,
1820 IShellItem *psi)
1822 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1823 TRACE("%p (%p)\n", This, psi);
1824 return E_NOTIMPL;
1827 static HRESULT WINAPI NSTCEvents_fnOnItemStateChanging(INameSpaceTreeControlEvents *iface,
1828 IShellItem *psi,
1829 NSTCITEMSTATE nstcisMask,
1830 NSTCITEMSTATE nstcisState)
1832 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1833 TRACE("%p (%p, 0x%lx, 0x%lx)\n", This, psi, nstcisMask, nstcisState);
1834 return E_NOTIMPL;
1837 static HRESULT WINAPI NSTCEvents_fnOnItemStateChanged(INameSpaceTreeControlEvents *iface,
1838 IShellItem *psi,
1839 NSTCITEMSTATE nstcisMask,
1840 NSTCITEMSTATE nstcisState)
1842 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1843 TRACE("%p (%p, 0x%lx, 0x%lx)\n", This, psi, nstcisMask, nstcisState);
1844 return E_NOTIMPL;
1847 static HRESULT WINAPI NSTCEvents_fnOnSelectionChanged(INameSpaceTreeControlEvents *iface,
1848 IShellItemArray *psiaSelection)
1850 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1851 IShellItem *psi;
1852 HRESULT hr;
1853 TRACE("%p (%p)\n", This, psiaSelection);
1855 hr = IShellItemArray_GetItemAt(psiaSelection, 0, &psi);
1856 if(SUCCEEDED(hr))
1858 hr = IExplorerBrowser_BrowseToObject(&This->IExplorerBrowser_iface,
1859 (IUnknown*)psi, SBSP_DEFBROWSER);
1860 IShellItem_Release(psi);
1863 return hr;
1866 static HRESULT WINAPI NSTCEvents_fnOnKeyboardInput(INameSpaceTreeControlEvents *iface,
1867 UINT uMsg, WPARAM wParam, LPARAM lParam)
1869 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1870 TRACE("%p (%d, 0x%Ix, 0x%Ix)\n", This, uMsg, wParam, lParam);
1871 return S_OK;
1874 static HRESULT WINAPI NSTCEvents_fnOnBeforeExpand(INameSpaceTreeControlEvents *iface,
1875 IShellItem *psi)
1877 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1878 TRACE("%p (%p)\n", This, psi);
1879 return E_NOTIMPL;
1882 static HRESULT WINAPI NSTCEvents_fnOnAfterExpand(INameSpaceTreeControlEvents *iface,
1883 IShellItem *psi)
1885 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1886 TRACE("%p (%p)\n", This, psi);
1887 return E_NOTIMPL;
1890 static HRESULT WINAPI NSTCEvents_fnOnBeginLabelEdit(INameSpaceTreeControlEvents *iface,
1891 IShellItem *psi)
1893 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1894 TRACE("%p (%p)\n", This, psi);
1895 return E_NOTIMPL;
1898 static HRESULT WINAPI NSTCEvents_fnOnEndLabelEdit(INameSpaceTreeControlEvents *iface,
1899 IShellItem *psi)
1901 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1902 TRACE("%p (%p)\n", This, psi);
1903 return E_NOTIMPL;
1906 static HRESULT WINAPI NSTCEvents_fnOnGetToolTip(INameSpaceTreeControlEvents *iface,
1907 IShellItem *psi, LPWSTR pszTip, int cchTip)
1909 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1910 TRACE("%p (%p, %p, %d)\n", This, psi, pszTip, cchTip);
1911 return E_NOTIMPL;
1914 static HRESULT WINAPI NSTCEvents_fnOnBeforeItemDelete(INameSpaceTreeControlEvents *iface,
1915 IShellItem *psi)
1917 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1918 TRACE("%p (%p)\n", This, psi);
1919 return E_NOTIMPL;
1922 static HRESULT WINAPI NSTCEvents_fnOnItemAdded(INameSpaceTreeControlEvents *iface,
1923 IShellItem *psi, BOOL fIsRoot)
1925 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1926 TRACE("%p (%p, %d)\n", This, psi, fIsRoot);
1927 return E_NOTIMPL;
1930 static HRESULT WINAPI NSTCEvents_fnOnItemDeleted(INameSpaceTreeControlEvents *iface,
1931 IShellItem *psi, BOOL fIsRoot)
1933 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1934 TRACE("%p (%p, %d)\n", This, psi, fIsRoot);
1935 return E_NOTIMPL;
1938 static HRESULT WINAPI NSTCEvents_fnOnBeforeContextMenu(INameSpaceTreeControlEvents *iface,
1939 IShellItem *psi, REFIID riid, void **ppv)
1941 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1942 TRACE("%p (%p, %s, %p)\n", This, psi, shdebugstr_guid(riid), ppv);
1943 return E_NOTIMPL;
1946 static HRESULT WINAPI NSTCEvents_fnOnAfterContextMenu(INameSpaceTreeControlEvents *iface,
1947 IShellItem *psi, IContextMenu *pcmIn,
1948 REFIID riid, void **ppv)
1950 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1951 TRACE("%p (%p, %p, %s, %p)\n", This, psi, pcmIn, shdebugstr_guid(riid), ppv);
1952 return E_NOTIMPL;
1955 static HRESULT WINAPI NSTCEvents_fnOnBeforeStateImageChange(INameSpaceTreeControlEvents *iface,
1956 IShellItem *psi)
1958 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1959 TRACE("%p (%p)\n", This, psi);
1960 return E_NOTIMPL;
1963 static HRESULT WINAPI NSTCEvents_fnOnGetDefaultIconIndex(INameSpaceTreeControlEvents* iface,
1964 IShellItem *psi,
1965 int *piDefaultIcon, int *piOpenIcon)
1967 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1968 TRACE("%p (%p, %p, %p)\n", This, psi, piDefaultIcon, piOpenIcon);
1969 return E_NOTIMPL;
1973 static const INameSpaceTreeControlEventsVtbl vt_INameSpaceTreeControlEvents = {
1974 NSTCEvents_fnQueryInterface,
1975 NSTCEvents_fnAddRef,
1976 NSTCEvents_fnRelease,
1977 NSTCEvents_fnOnItemClick,
1978 NSTCEvents_fnOnPropertyItemCommit,
1979 NSTCEvents_fnOnItemStateChanging,
1980 NSTCEvents_fnOnItemStateChanged,
1981 NSTCEvents_fnOnSelectionChanged,
1982 NSTCEvents_fnOnKeyboardInput,
1983 NSTCEvents_fnOnBeforeExpand,
1984 NSTCEvents_fnOnAfterExpand,
1985 NSTCEvents_fnOnBeginLabelEdit,
1986 NSTCEvents_fnOnEndLabelEdit,
1987 NSTCEvents_fnOnGetToolTip,
1988 NSTCEvents_fnOnBeforeItemDelete,
1989 NSTCEvents_fnOnItemAdded,
1990 NSTCEvents_fnOnItemDeleted,
1991 NSTCEvents_fnOnBeforeContextMenu,
1992 NSTCEvents_fnOnAfterContextMenu,
1993 NSTCEvents_fnOnBeforeStateImageChange,
1994 NSTCEvents_fnOnGetDefaultIconIndex
1997 /**************************************************************************
1998 * IInputObject Implementation
2001 static inline ExplorerBrowserImpl *impl_from_IInputObject(IInputObject *iface)
2003 return CONTAINING_RECORD(iface, ExplorerBrowserImpl, IInputObject_iface);
2006 static HRESULT WINAPI IInputObject_fnQueryInterface(IInputObject *iface,
2007 REFIID riid, void **ppvObject)
2009 ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
2010 TRACE("%p\n", This);
2011 return IExplorerBrowser_QueryInterface(&This->IExplorerBrowser_iface, riid, ppvObject);
2014 static ULONG WINAPI IInputObject_fnAddRef(IInputObject *iface)
2016 ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
2017 TRACE("%p\n", This);
2018 return IExplorerBrowser_AddRef(&This->IExplorerBrowser_iface);
2021 static ULONG WINAPI IInputObject_fnRelease(IInputObject *iface)
2023 ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
2024 TRACE("%p\n", This);
2025 return IExplorerBrowser_Release(&This->IExplorerBrowser_iface);
2028 static HRESULT WINAPI IInputObject_fnUIActivateIO(IInputObject *iface, BOOL fActivate, MSG *pMsg)
2030 ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
2031 FIXME("stub, %p (%d, %p)\n", This, fActivate, pMsg);
2032 return E_NOTIMPL;
2035 static HRESULT WINAPI IInputObject_fnHasFocusIO(IInputObject *iface)
2037 ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
2038 FIXME("stub, %p\n", This);
2039 return E_NOTIMPL;
2042 static HRESULT WINAPI IInputObject_fnTranslateAcceleratorIO(IInputObject *iface, MSG *pMsg)
2044 ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
2045 FIXME("stub, %p (%p)\n", This, pMsg);
2046 return E_NOTIMPL;
2049 static IInputObjectVtbl vt_IInputObject = {
2050 IInputObject_fnQueryInterface,
2051 IInputObject_fnAddRef,
2052 IInputObject_fnRelease,
2053 IInputObject_fnUIActivateIO,
2054 IInputObject_fnHasFocusIO,
2055 IInputObject_fnTranslateAcceleratorIO
2058 HRESULT WINAPI ExplorerBrowser_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv)
2060 ExplorerBrowserImpl *eb;
2061 HRESULT ret;
2063 TRACE("%p %s %p\n", pUnkOuter, shdebugstr_guid (riid), ppv);
2065 if(!ppv)
2066 return E_POINTER;
2067 if(pUnkOuter)
2068 return CLASS_E_NOAGGREGATION;
2070 eb = calloc(1, sizeof(*eb));
2071 eb->ref = 1;
2072 eb->IExplorerBrowser_iface.lpVtbl = &vt_IExplorerBrowser;
2073 eb->IShellBrowser_iface.lpVtbl = &vt_IShellBrowser;
2074 eb->ICommDlgBrowser3_iface.lpVtbl = &vt_ICommDlgBrowser3;
2075 eb->IObjectWithSite_iface.lpVtbl = &vt_IObjectWithSite;
2076 eb->INameSpaceTreeControlEvents_iface.lpVtbl = &vt_INameSpaceTreeControlEvents;
2077 eb->IInputObject_iface.lpVtbl = &vt_IInputObject;
2079 /* Default settings */
2080 eb->navpane.show = TRUE;
2082 list_init(&eb->event_clients);
2083 list_init(&eb->travellog);
2085 ret = IExplorerBrowser_QueryInterface(&eb->IExplorerBrowser_iface, riid, ppv);
2086 IExplorerBrowser_Release(&eb->IExplorerBrowser_iface);
2088 TRACE("--(%p)\n", ppv);
2089 return ret;