po: Update Finnish translation.
[wine.git] / dlls / shell32 / ebrowser.c
blob9704228d42666b7ef279ece358e86194ae01e2ec
1 /*
2 * ExplorerBrowser Control implementation.
4 * Copyright 2010 David Hedberg
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdarg.h>
23 #define COBJMACROS
24 #define NONAMELESSUNION
26 #include "winerror.h"
27 #include "windef.h"
28 #include "winbase.h"
30 #include "wine/list.h"
31 #include "wine/debug.h"
32 #include "debughlp.h"
34 #include "shell32_main.h"
35 #include "pidl.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(shell);
39 #define SPLITTER_WIDTH 2
40 #define NP_MIN_WIDTH 60
41 #define NP_DEFAULT_WIDTH 150
42 #define SV_MIN_WIDTH 150
44 typedef struct _event_client {
45 struct list entry;
46 IExplorerBrowserEvents *pebe;
47 DWORD cookie;
48 } event_client;
50 typedef struct _travellog_entry {
51 struct list entry;
52 LPITEMIDLIST pidl;
53 } travellog_entry;
55 typedef struct _ExplorerBrowserImpl {
56 IExplorerBrowser IExplorerBrowser_iface;
57 IShellBrowser IShellBrowser_iface;
58 ICommDlgBrowser3 ICommDlgBrowser3_iface;
59 IObjectWithSite IObjectWithSite_iface;
60 INameSpaceTreeControlEvents INameSpaceTreeControlEvents_iface;
61 IInputObject IInputObject_iface;
62 LONG ref;
63 BOOL destroyed;
65 HWND hwnd_main;
66 HWND hwnd_sv;
68 RECT splitter_rc;
69 struct {
70 INameSpaceTreeControl2 *pnstc2;
71 HWND hwnd_splitter, hwnd_nstc;
72 DWORD nstc_cookie;
73 UINT width;
74 BOOL show;
75 RECT rc;
76 } navpane;
78 EXPLORER_BROWSER_OPTIONS eb_options;
79 FOLDERSETTINGS fs;
81 struct list event_clients;
82 DWORD events_next_cookie;
83 struct list travellog;
84 travellog_entry *travellog_cursor;
85 int travellog_count;
87 int dpix;
89 IShellView *psv;
90 RECT sv_rc;
91 LPITEMIDLIST current_pidl;
93 IUnknown *punk_site;
94 ICommDlgBrowser *pcdb_site;
95 ICommDlgBrowser2 *pcdb2_site;
96 ICommDlgBrowser3 *pcdb3_site;
97 IExplorerPaneVisibility *pepv_site;
98 } ExplorerBrowserImpl;
100 static void initialize_navpane(ExplorerBrowserImpl *This, HWND hwnd_parent, RECT *rc);
102 /**************************************************************************
103 * Event functions.
105 static void events_unadvise_all(ExplorerBrowserImpl *This)
107 event_client *client, *curs;
108 TRACE("%p\n", This);
110 LIST_FOR_EACH_ENTRY_SAFE(client, curs, &This->event_clients, event_client, entry)
112 TRACE("Removing %p\n", client);
113 list_remove(&client->entry);
114 IExplorerBrowserEvents_Release(client->pebe);
115 heap_free(client);
119 static HRESULT events_NavigationPending(ExplorerBrowserImpl *This, PCIDLIST_ABSOLUTE pidl)
121 event_client *cursor;
122 HRESULT hres = S_OK;
124 TRACE("%p\n", This);
126 LIST_FOR_EACH_ENTRY(cursor, &This->event_clients, event_client, entry)
128 TRACE("Notifying %p\n", cursor);
129 hres = IExplorerBrowserEvents_OnNavigationPending(cursor->pebe, pidl);
131 /* If this failed for any reason, the browsing is supposed to be aborted. */
132 if(FAILED(hres))
133 break;
136 return hres;
139 static void events_NavigationComplete(ExplorerBrowserImpl *This, PCIDLIST_ABSOLUTE pidl)
141 event_client *cursor;
143 TRACE("%p\n", This);
145 LIST_FOR_EACH_ENTRY(cursor, &This->event_clients, event_client, entry)
147 TRACE("Notifying %p\n", cursor);
148 IExplorerBrowserEvents_OnNavigationComplete(cursor->pebe, pidl);
152 static void events_NavigationFailed(ExplorerBrowserImpl *This, PCIDLIST_ABSOLUTE pidl)
154 event_client *cursor;
156 TRACE("%p\n", This);
158 LIST_FOR_EACH_ENTRY(cursor, &This->event_clients, event_client, entry)
160 TRACE("Notifying %p\n", cursor);
161 IExplorerBrowserEvents_OnNavigationFailed(cursor->pebe, pidl);
165 static void events_ViewCreated(ExplorerBrowserImpl *This, IShellView *psv)
167 event_client *cursor;
169 TRACE("%p\n", This);
171 LIST_FOR_EACH_ENTRY(cursor, &This->event_clients, event_client, entry)
173 TRACE("Notifying %p\n", cursor);
174 IExplorerBrowserEvents_OnViewCreated(cursor->pebe, psv);
178 /**************************************************************************
179 * Travellog functions.
181 static void travellog_remove_entry(ExplorerBrowserImpl *This, travellog_entry *entry)
183 TRACE("Removing %p\n", entry);
185 list_remove(&entry->entry);
186 ILFree(entry->pidl);
187 heap_free(entry);
188 This->travellog_count--;
191 static void travellog_remove_all_entries(ExplorerBrowserImpl *This)
193 travellog_entry *cursor, *cursor2;
194 TRACE("%p\n", This);
196 LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->travellog, travellog_entry, entry)
197 travellog_remove_entry(This, cursor);
199 This->travellog_cursor = NULL;
202 static void travellog_add_entry(ExplorerBrowserImpl *This, LPITEMIDLIST pidl)
204 travellog_entry *new, *cursor, *cursor2;
205 TRACE("%p (old count %d)\n", pidl, This->travellog_count);
207 /* Replace the old tail, if any, with the new entry */
208 if(This->travellog_cursor)
210 LIST_FOR_EACH_ENTRY_SAFE_REV(cursor, cursor2, &This->travellog, travellog_entry, entry)
212 if(cursor == This->travellog_cursor)
213 break;
214 travellog_remove_entry(This, cursor);
218 /* Create and add the new entry */
219 new = heap_alloc(sizeof(*new));
220 new->pidl = ILClone(pidl);
221 list_add_tail(&This->travellog, &new->entry);
222 This->travellog_cursor = new;
223 This->travellog_count++;
225 /* Remove the first few entries if the size limit is reached. */
226 if(This->travellog_count > 200)
228 UINT i = 0;
229 LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->travellog, travellog_entry, entry)
231 if(i++ > 10)
232 break;
233 travellog_remove_entry(This, cursor);
238 static LPCITEMIDLIST travellog_go_back(ExplorerBrowserImpl *This)
240 travellog_entry *prev;
241 TRACE("%p, %p\n", This, This->travellog_cursor);
243 if(!This->travellog_cursor)
244 return NULL;
246 prev = LIST_ENTRY(list_prev(&This->travellog, &This->travellog_cursor->entry),
247 travellog_entry, entry);
248 if(!prev)
249 return NULL;
251 This->travellog_cursor = prev;
252 return prev->pidl;
255 static LPCITEMIDLIST travellog_go_forward(ExplorerBrowserImpl *This)
257 travellog_entry *next;
258 TRACE("%p, %p\n", This, This->travellog_cursor);
260 if(!This->travellog_cursor)
261 return NULL;
263 next = LIST_ENTRY(list_next(&This->travellog, &This->travellog_cursor->entry),
264 travellog_entry, entry);
265 if(!next)
266 return NULL;
268 This->travellog_cursor = next;
269 return next->pidl;
272 /**************************************************************************
273 * Helper functions
275 static void update_layout(ExplorerBrowserImpl *This)
277 RECT rc;
278 INT navpane_width_actual;
279 INT shellview_width_actual;
280 int np_min_width = MulDiv(NP_MIN_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
281 int sv_min_width = MulDiv(SV_MIN_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
282 TRACE("%p (navpane: %d, EBO_SHOWFRAMES: %d)\n",
283 This, This->navpane.show, This->eb_options & EBO_SHOWFRAMES);
285 GetClientRect(This->hwnd_main, &rc);
287 if((This->eb_options & EBO_SHOWFRAMES) && This->navpane.show)
288 navpane_width_actual = This->navpane.width;
289 else
290 navpane_width_actual = 0;
292 shellview_width_actual = rc.right - navpane_width_actual;
293 if(shellview_width_actual < sv_min_width && navpane_width_actual)
295 INT missing_width = sv_min_width - shellview_width_actual;
296 if(missing_width < (navpane_width_actual - np_min_width))
298 /* Shrink the navpane */
299 navpane_width_actual -= missing_width;
300 shellview_width_actual += missing_width;
302 else
304 /* Hide the navpane */
305 shellview_width_actual += navpane_width_actual;
306 navpane_width_actual = 0;
310 /**************************************************************
311 * Calculate rectangles for the panes. All rectangles contain
312 * the position of the panes relative to hwnd_main.
315 if(navpane_width_actual)
317 SetRect(&This->navpane.rc, 0, 0, navpane_width_actual, rc.bottom);
319 if(!This->navpane.hwnd_splitter)
320 initialize_navpane(This, This->hwnd_main, &This->navpane.rc);
322 else
323 ZeroMemory(&This->navpane.rc, sizeof(RECT));
325 SetRect(&This->sv_rc, navpane_width_actual, 0, navpane_width_actual + shellview_width_actual,
326 rc.bottom);
329 static void size_panes(ExplorerBrowserImpl *This)
331 int splitter_width = MulDiv(SPLITTER_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
332 MoveWindow(This->navpane.hwnd_splitter,
333 This->navpane.rc.right - splitter_width, This->navpane.rc.top,
334 splitter_width, This->navpane.rc.bottom - This->navpane.rc.top,
335 TRUE);
337 MoveWindow(This->hwnd_sv,
338 This->sv_rc.left, This->sv_rc.top,
339 This->sv_rc.right - This->sv_rc.left, This->sv_rc.bottom - This->sv_rc.top,
340 TRUE);
343 static HRESULT change_viewmode(ExplorerBrowserImpl *This, UINT viewmode)
345 IFolderView *pfv;
346 HRESULT hr;
348 if(!This->psv)
349 return E_FAIL;
351 hr = IShellView_QueryInterface(This->psv, &IID_IFolderView, (void*)&pfv);
352 if(SUCCEEDED(hr))
354 hr = IFolderView_SetCurrentViewMode(pfv, This->fs.ViewMode);
355 IFolderView_Release(pfv);
358 return hr;
361 static HRESULT create_new_shellview(ExplorerBrowserImpl *This, IShellItem *psi)
363 IShellBrowser *psb = &This->IShellBrowser_iface;
364 IShellFolder *psf;
365 IShellView *psv;
366 HWND hwnd_new;
367 HRESULT hr;
369 TRACE("%p, %p\n", This, psi);
371 hr = IShellItem_BindToHandler(psi, NULL, &BHID_SFObject, &IID_IShellFolder, (void**)&psf);
372 if(SUCCEEDED(hr))
374 hr = IShellFolder_CreateViewObject(psf, This->hwnd_main, &IID_IShellView, (void**)&psv);
375 if(SUCCEEDED(hr))
377 if(This->hwnd_sv)
379 IShellView_DestroyViewWindow(This->psv);
380 This->hwnd_sv = NULL;
383 hr = IShellView_CreateViewWindow(psv, This->psv, &This->fs, psb, &This->sv_rc, &hwnd_new);
384 if(SUCCEEDED(hr))
386 /* Replace the old shellview */
387 if(This->psv) IShellView_Release(This->psv);
389 This->psv = psv;
390 This->hwnd_sv = hwnd_new;
391 events_ViewCreated(This, psv);
393 else
395 ERR("CreateViewWindow failed (0x%lx)\n", hr);
396 IShellView_Release(psv);
399 else
400 ERR("CreateViewObject failed (0x%lx)\n", hr);
402 IShellFolder_Release(psf);
404 else
405 ERR("SI::BindToHandler failed (0x%lx)\n", hr);
407 return hr;
410 static void get_interfaces_from_site(ExplorerBrowserImpl *This)
412 IServiceProvider *psp;
413 HRESULT hr;
415 /* Calling this with This->punk_site set to NULL should properly
416 * release any previously fetched interfaces.
419 if(This->pcdb_site)
421 ICommDlgBrowser_Release(This->pcdb_site);
422 if(This->pcdb2_site) ICommDlgBrowser2_Release(This->pcdb2_site);
423 if(This->pcdb3_site) ICommDlgBrowser3_Release(This->pcdb3_site);
425 This->pcdb_site = NULL;
426 This->pcdb2_site = NULL;
427 This->pcdb3_site = NULL;
430 if(This->pepv_site)
432 IExplorerPaneVisibility_Release(This->pepv_site);
433 This->pepv_site = NULL;
436 if(!This->punk_site)
437 return;
439 hr = IUnknown_QueryInterface(This->punk_site, &IID_IServiceProvider, (void**)&psp);
440 if(FAILED(hr))
442 ERR("Failed to get IServiceProvider from site.\n");
443 return;
446 /* ICommDlgBrowser */
447 IServiceProvider_QueryService(psp, &SID_SExplorerBrowserFrame, &IID_ICommDlgBrowser,
448 (void**)&This->pcdb_site);
449 IServiceProvider_QueryService(psp, &SID_SExplorerBrowserFrame, &IID_ICommDlgBrowser2,
450 (void**)&This->pcdb2_site);
451 IServiceProvider_QueryService(psp, &SID_SExplorerBrowserFrame, &IID_ICommDlgBrowser3,
452 (void**)&This->pcdb3_site);
454 /* IExplorerPaneVisibility */
455 IServiceProvider_QueryService(psp, &SID_ExplorerPaneVisibility, &IID_IExplorerPaneVisibility,
456 (void**)&This->pepv_site);
458 IServiceProvider_Release(psp);
461 /**************************************************************************
462 * General pane functionality.
464 static void update_panestate(ExplorerBrowserImpl *This)
466 EXPLORERPANESTATE eps = EPS_DONTCARE;
467 BOOL show_navpane;
468 TRACE("%p\n", This);
470 if(!This->pepv_site) return;
472 IExplorerPaneVisibility_GetPaneState(This->pepv_site, (REFEXPLORERPANE) &EP_NavPane, &eps);
473 if( !(eps & EPS_DEFAULT_OFF) )
474 show_navpane = TRUE;
475 else
476 show_navpane = FALSE;
478 if(This->navpane.show != show_navpane)
480 update_layout(This);
481 size_panes(This);
484 This->navpane.show = show_navpane;
487 static void splitter_draw(HWND hwnd, RECT *rc)
489 HDC hdc = GetDC(hwnd);
490 InvertRect(hdc, rc);
491 ReleaseDC(hwnd, hdc);
494 /**************************************************************************
495 * The Navigation Pane.
497 static LRESULT navpane_splitter_beginresize(ExplorerBrowserImpl *This, HWND hwnd, LPARAM lParam)
499 int splitter_width = MulDiv(SPLITTER_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
501 TRACE("\n");
503 SetCapture(hwnd);
505 This->splitter_rc = This->navpane.rc;
506 This->splitter_rc.left = This->splitter_rc.right - splitter_width;
508 splitter_draw(GetParent(hwnd), &This->splitter_rc);
510 return TRUE;
513 static LRESULT navpane_splitter_resizing(ExplorerBrowserImpl *This, HWND hwnd, LPARAM lParam)
515 int new_width, dx;
516 RECT rc;
517 int splitter_width = MulDiv(SPLITTER_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
518 int np_min_width = MulDiv(NP_MIN_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
519 int sv_min_width = MulDiv(SV_MIN_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
521 if(GetCapture() != hwnd) return FALSE;
523 dx = (SHORT)LOWORD(lParam);
524 TRACE("%d.\n", dx);
526 rc = This->navpane.rc;
527 new_width = This->navpane.width + dx;
528 if(new_width > np_min_width && This->sv_rc.right - new_width > sv_min_width)
530 rc.right = new_width;
531 rc.left = rc.right - splitter_width;
532 splitter_draw(GetParent(hwnd), &This->splitter_rc);
533 splitter_draw(GetParent(hwnd), &rc);
534 This->splitter_rc = rc;
537 return TRUE;
540 static LRESULT navpane_splitter_endresize(ExplorerBrowserImpl *This, HWND hwnd, LPARAM lParam)
542 int new_width, dx;
543 int np_min_width = MulDiv(NP_MIN_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
544 int sv_min_width = MulDiv(SV_MIN_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
546 if(GetCapture() != hwnd) return FALSE;
548 dx = (SHORT)LOWORD(lParam);
549 TRACE("%d.\n", dx);
551 splitter_draw(GetParent(hwnd), &This->splitter_rc);
553 new_width = This->navpane.width + dx;
554 if(new_width < np_min_width)
555 new_width = np_min_width;
556 else if(This->sv_rc.right - new_width < sv_min_width)
557 new_width = This->sv_rc.right - sv_min_width;
559 This->navpane.width = new_width;
561 update_layout(This);
562 size_panes(This);
564 ReleaseCapture();
566 return TRUE;
569 static LRESULT navpane_on_wm_create(HWND hwnd, CREATESTRUCTW *crs)
571 ExplorerBrowserImpl *This = crs->lpCreateParams;
572 INameSpaceTreeControl2 *pnstc2;
573 DWORD style;
574 HRESULT hr;
576 TRACE("%p\n", This);
577 SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LPARAM)This);
578 This->navpane.hwnd_splitter = hwnd;
580 hr = CoCreateInstance(&CLSID_NamespaceTreeControl, NULL, CLSCTX_INPROC_SERVER,
581 &IID_INameSpaceTreeControl2, (void**)&pnstc2);
583 if(SUCCEEDED(hr))
585 style = NSTCS_HASEXPANDOS | NSTCS_ROOTHASEXPANDO | NSTCS_SHOWSELECTIONALWAYS;
586 hr = INameSpaceTreeControl2_Initialize(pnstc2, GetParent(hwnd), NULL, style);
587 if(SUCCEEDED(hr))
589 INameSpaceTreeControlEvents *pnstce;
590 IShellFolder *psfdesktop;
591 IShellItem *psi;
592 IOleWindow *pow;
593 LPITEMIDLIST pidl;
594 DWORD cookie, style2 = NSTCS2_DISPLAYPADDING;
596 hr = INameSpaceTreeControl2_SetControlStyle2(pnstc2, 0xFF, style2);
597 if(FAILED(hr))
598 ERR("SetControlStyle2 failed (0x%08lx)\n", hr);
600 hr = INameSpaceTreeControl2_QueryInterface(pnstc2, &IID_IOleWindow, (void**)&pow);
601 if(SUCCEEDED(hr))
603 IOleWindow_GetWindow(pow, &This->navpane.hwnd_nstc);
604 IOleWindow_Release(pow);
606 else
607 ERR("QueryInterface(IOleWindow) failed (0x%08lx)\n", hr);
609 pnstce = &This->INameSpaceTreeControlEvents_iface;
610 hr = INameSpaceTreeControl2_TreeAdvise(pnstc2, (IUnknown*)pnstce, &cookie);
611 if(FAILED(hr))
612 ERR("TreeAdvise failed. (0x%08lx).\n", hr);
615 * Add the default roots
618 /* TODO: This should be FOLDERID_Links */
619 hr = SHGetSpecialFolderLocation(NULL, CSIDL_FAVORITES, &pidl);
620 if(SUCCEEDED(hr))
622 hr = SHCreateShellItem(NULL, NULL, pidl, &psi);
623 if(SUCCEEDED(hr))
625 hr = INameSpaceTreeControl2_AppendRoot(pnstc2, psi, SHCONTF_NONFOLDERS, NSTCRS_VISIBLE, NULL);
626 IShellItem_Release(psi);
628 ILFree(pidl);
631 SHGetDesktopFolder(&psfdesktop);
632 hr = SHGetItemFromObject((IUnknown*)psfdesktop, &IID_IShellItem, (void**)&psi);
633 IShellFolder_Release(psfdesktop);
634 if(SUCCEEDED(hr))
636 hr = INameSpaceTreeControl2_AppendRoot(pnstc2, psi, SHCONTF_FOLDERS, NSTCRS_EXPANDED, NULL);
637 IShellItem_Release(psi);
640 /* TODO:
641 * We should advertise IID_INameSpaceTreeControl to the site of the
642 * host through its IProfferService interface, if any.
645 This->navpane.pnstc2 = pnstc2;
646 This->navpane.nstc_cookie = cookie;
648 return TRUE;
652 This->navpane.pnstc2 = NULL;
653 ERR("Failed (0x%08lx)\n", hr);
655 return FALSE;
658 static LRESULT navpane_on_wm_size_move(ExplorerBrowserImpl *This)
660 UINT height, width;
661 int splitter_width = MulDiv(SPLITTER_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
663 TRACE("%p\n", This);
665 width = This->navpane.rc.right - This->navpane.rc.left - splitter_width;
666 height = This->navpane.rc.bottom - This->navpane.rc.top;
668 MoveWindow(This->navpane.hwnd_nstc,
669 This->navpane.rc.left, This->navpane.rc.top,
670 width, height,
671 TRUE);
673 return FALSE;
676 static LRESULT navpane_on_wm_destroy(ExplorerBrowserImpl *This)
678 INameSpaceTreeControl2_TreeUnadvise(This->navpane.pnstc2, This->navpane.nstc_cookie);
679 INameSpaceTreeControl2_Release(This->navpane.pnstc2);
680 This->navpane.pnstc2 = NULL;
681 return TRUE;
684 static LRESULT CALLBACK navpane_wndproc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
686 ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
688 switch(uMessage) {
689 case WM_CREATE: return navpane_on_wm_create(hWnd, (CREATESTRUCTW*)lParam);
690 case WM_MOVE: /* Fall through */
691 case WM_SIZE: return navpane_on_wm_size_move(This);
692 case WM_DESTROY: return navpane_on_wm_destroy(This);
693 case WM_LBUTTONDOWN: return navpane_splitter_beginresize(This, hWnd, lParam);
694 case WM_MOUSEMOVE: return navpane_splitter_resizing(This, hWnd, lParam);
695 case WM_LBUTTONUP: return navpane_splitter_endresize(This, hWnd, lParam);
696 default:
697 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
699 return 0;
702 static void initialize_navpane(ExplorerBrowserImpl *This, HWND hwnd_parent, RECT *rc)
704 WNDCLASSW wc;
705 HWND splitter;
706 int splitter_width = MulDiv(SPLITTER_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
708 if( !GetClassInfoW(shell32_hInstance, L"eb_navpane", &wc) )
710 wc.style = CS_HREDRAW | CS_VREDRAW;
711 wc.lpfnWndProc = navpane_wndproc;
712 wc.cbClsExtra = 0;
713 wc.cbWndExtra = 0;
714 wc.hInstance = shell32_hInstance;
715 wc.hIcon = 0;
716 wc.hCursor = LoadCursorW(0, (LPWSTR)IDC_SIZEWE);
717 wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
718 wc.lpszMenuName = NULL;
719 wc.lpszClassName = L"eb_navpane";
721 if (!RegisterClassW(&wc)) return;
724 splitter = CreateWindowExW(0, L"eb_navpane", NULL,
725 WS_CHILD | WS_TABSTOP | WS_VISIBLE,
726 rc->right - splitter_width, rc->top,
727 splitter_width, rc->bottom - rc->top,
728 hwnd_parent, 0, shell32_hInstance, This);
729 if(!splitter)
730 ERR("Failed to create navpane : %ld.\n", GetLastError());
733 /**************************************************************************
734 * Main window related functions.
736 static LRESULT main_on_wm_create(HWND hWnd, CREATESTRUCTW *crs)
738 ExplorerBrowserImpl *This = crs->lpCreateParams;
739 TRACE("%p\n", This);
741 SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LPARAM)This);
742 This->hwnd_main = hWnd;
744 return TRUE;
747 static LRESULT main_on_wm_size(ExplorerBrowserImpl *This)
749 update_layout(This);
750 size_panes(This);
752 return TRUE;
755 static LRESULT main_on_cwm_getishellbrowser(ExplorerBrowserImpl *This)
757 return (LRESULT)&This->IShellBrowser_iface;
760 static LRESULT CALLBACK main_wndproc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
762 ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
764 switch(uMessage)
766 case WM_CREATE: return main_on_wm_create(hWnd, (CREATESTRUCTW*)lParam);
767 case WM_SIZE: return main_on_wm_size(This);
768 case CWM_GETISHELLBROWSER: return main_on_cwm_getishellbrowser(This);
769 default: return DefWindowProcW(hWnd, uMessage, wParam, lParam);
772 return 0;
775 /**************************************************************************
776 * IExplorerBrowser Implementation
779 static inline ExplorerBrowserImpl *impl_from_IExplorerBrowser(IExplorerBrowser *iface)
781 return CONTAINING_RECORD(iface, ExplorerBrowserImpl, IExplorerBrowser_iface);
784 static HRESULT WINAPI IExplorerBrowser_fnQueryInterface(IExplorerBrowser *iface,
785 REFIID riid, void **ppvObject)
787 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
788 TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppvObject);
790 *ppvObject = NULL;
791 if(IsEqualIID(riid, &IID_IExplorerBrowser) ||
792 IsEqualIID(riid, &IID_IUnknown))
794 *ppvObject = &This->IExplorerBrowser_iface;
796 else if(IsEqualIID(riid, &IID_IShellBrowser) ||
797 IsEqualIID(riid, &IID_IOleWindow))
799 *ppvObject = &This->IShellBrowser_iface;
801 else if(IsEqualIID(riid, &IID_ICommDlgBrowser) ||
802 IsEqualIID(riid, &IID_ICommDlgBrowser2) ||
803 IsEqualIID(riid, &IID_ICommDlgBrowser3))
805 *ppvObject = &This->ICommDlgBrowser3_iface;
807 else if(IsEqualIID(riid, &IID_IObjectWithSite))
809 *ppvObject = &This->IObjectWithSite_iface;
811 else if(IsEqualIID(riid, &IID_IInputObject))
813 *ppvObject = &This->IInputObject_iface;
816 if(*ppvObject)
818 IUnknown_AddRef((IUnknown*)*ppvObject);
819 return S_OK;
822 return E_NOINTERFACE;
825 static ULONG WINAPI IExplorerBrowser_fnAddRef(IExplorerBrowser *iface)
827 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
828 LONG ref = InterlockedIncrement(&This->ref);
829 TRACE("%p - ref %ld\n", This, ref);
831 return ref;
834 static ULONG WINAPI IExplorerBrowser_fnRelease(IExplorerBrowser *iface)
836 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
837 LONG ref = InterlockedDecrement(&This->ref);
838 TRACE("%p - ref %ld\n", This, ref);
840 if(!ref)
842 TRACE("Freeing.\n");
844 if(!This->destroyed)
845 IExplorerBrowser_Destroy(iface);
847 IObjectWithSite_SetSite(&This->IObjectWithSite_iface, NULL);
849 heap_free(This);
852 return ref;
855 static HRESULT WINAPI IExplorerBrowser_fnInitialize(IExplorerBrowser *iface,
856 HWND hwndParent, const RECT *prc,
857 const FOLDERSETTINGS *pfs)
859 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
860 WNDCLASSW wc;
861 LONG style;
862 HDC parent_dc;
864 TRACE("%p (%p, %p, %p)\n", This, hwndParent, prc, pfs);
866 if(This->hwnd_main)
867 return E_UNEXPECTED;
869 if(!hwndParent)
870 return E_INVALIDARG;
872 if( !GetClassInfoW(shell32_hInstance, L"ExplorerBrowserControl", &wc) )
874 wc.style = CS_HREDRAW | CS_VREDRAW;
875 wc.lpfnWndProc = main_wndproc;
876 wc.cbClsExtra = 0;
877 wc.cbWndExtra = 0;
878 wc.hInstance = shell32_hInstance;
879 wc.hIcon = 0;
880 wc.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW);
881 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
882 wc.lpszMenuName = NULL;
883 wc.lpszClassName = L"ExplorerBrowserControl";
885 if (!RegisterClassW(&wc)) return E_FAIL;
888 parent_dc = GetDC(hwndParent);
889 This->dpix = GetDeviceCaps(parent_dc, LOGPIXELSX);
890 ReleaseDC(hwndParent, parent_dc);
892 This->navpane.width = MulDiv(NP_DEFAULT_WIDTH, This->dpix, USER_DEFAULT_SCREEN_DPI);
894 style = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS;
895 if (!(This->eb_options & EBO_NOBORDER))
896 style |= WS_BORDER;
897 This->hwnd_main = CreateWindowExW(WS_EX_CONTROLPARENT, L"ExplorerBrowserControl", NULL, style,
898 prc->left, prc->top,
899 prc->right - prc->left, prc->bottom - prc->top,
900 hwndParent, 0, shell32_hInstance, This);
902 if(!This->hwnd_main)
904 ERR("Failed to create the window.\n");
905 return E_FAIL;
908 This->fs.ViewMode = pfs ? pfs->ViewMode : FVM_DETAILS;
909 This->fs.fFlags = pfs ? (pfs->fFlags | FWF_NOCLIENTEDGE) : FWF_NOCLIENTEDGE;
911 return S_OK;
914 static HRESULT WINAPI IExplorerBrowser_fnDestroy(IExplorerBrowser *iface)
916 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
917 TRACE("%p\n", This);
919 if(This->psv)
921 IShellView_DestroyViewWindow(This->psv);
922 IShellView_Release(This->psv);
923 This->psv = NULL;
924 This->hwnd_sv = NULL;
927 events_unadvise_all(This);
928 travellog_remove_all_entries(This);
930 ILFree(This->current_pidl);
931 This->current_pidl = NULL;
933 DestroyWindow(This->hwnd_main);
934 This->destroyed = TRUE;
936 return S_OK;
939 static HRESULT WINAPI IExplorerBrowser_fnSetRect(IExplorerBrowser *iface,
940 HDWP *phdwp, RECT rcBrowser)
942 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
943 TRACE("%p (%p, %s)\n", This, phdwp, wine_dbgstr_rect(&rcBrowser));
945 if(phdwp && *phdwp)
947 *phdwp = DeferWindowPos(*phdwp, This->hwnd_main, NULL, rcBrowser.left, rcBrowser.top,
948 rcBrowser.right - rcBrowser.left, rcBrowser.bottom - rcBrowser.top,
949 SWP_NOZORDER | SWP_NOACTIVATE);
950 if(!*phdwp)
951 return E_FAIL;
953 else
955 MoveWindow(This->hwnd_main, rcBrowser.left, rcBrowser.top,
956 rcBrowser.right - rcBrowser.left, rcBrowser.bottom - rcBrowser.top, TRUE);
959 return S_OK;
962 static HRESULT WINAPI IExplorerBrowser_fnSetPropertyBag(IExplorerBrowser *iface,
963 LPCWSTR pszPropertyBag)
965 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
966 FIXME("stub, %p (%s)\n", This, debugstr_w(pszPropertyBag));
968 if(!pszPropertyBag)
969 return E_INVALIDARG;
971 /* FIXME: This method is currently useless as we don't save any
972 * settings anywhere, but at least one application breaks if we
973 * return E_NOTIMPL.
976 return S_OK;
979 static HRESULT WINAPI IExplorerBrowser_fnSetEmptyText(IExplorerBrowser *iface,
980 LPCWSTR pszEmptyText)
982 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
983 FIXME("stub, %p (%s)\n", This, debugstr_w(pszEmptyText));
985 return E_NOTIMPL;
988 static HRESULT WINAPI IExplorerBrowser_fnSetFolderSettings(IExplorerBrowser *iface,
989 const FOLDERSETTINGS *pfs)
991 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
992 TRACE("%p (%p)\n", This, pfs);
994 if(!pfs)
995 return E_INVALIDARG;
997 This->fs.ViewMode = pfs->ViewMode;
998 This->fs.fFlags = pfs->fFlags | FWF_NOCLIENTEDGE;
1000 /* Change the settings of the current view, if any. */
1001 return change_viewmode(This, This->fs.ViewMode);
1004 static HRESULT WINAPI IExplorerBrowser_fnAdvise(IExplorerBrowser *iface,
1005 IExplorerBrowserEvents *psbe,
1006 DWORD *pdwCookie)
1008 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1009 event_client *client;
1010 TRACE("%p (%p, %p)\n", This, psbe, pdwCookie);
1012 client = heap_alloc(sizeof(*client));
1013 client->pebe = psbe;
1014 client->cookie = ++This->events_next_cookie;
1016 IExplorerBrowserEvents_AddRef(psbe);
1017 *pdwCookie = client->cookie;
1019 list_add_tail(&This->event_clients, &client->entry);
1021 return S_OK;
1024 static HRESULT WINAPI IExplorerBrowser_fnUnadvise(IExplorerBrowser *iface,
1025 DWORD dwCookie)
1027 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1028 event_client *client;
1029 TRACE("%p (0x%lx)\n", This, dwCookie);
1031 LIST_FOR_EACH_ENTRY(client, &This->event_clients, event_client, entry)
1033 if(client->cookie == dwCookie)
1035 list_remove(&client->entry);
1036 IExplorerBrowserEvents_Release(client->pebe);
1037 heap_free(client);
1038 return S_OK;
1042 return E_INVALIDARG;
1045 static HRESULT WINAPI IExplorerBrowser_fnSetOptions(IExplorerBrowser *iface,
1046 EXPLORER_BROWSER_OPTIONS dwFlag)
1048 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1049 static const EXPLORER_BROWSER_OPTIONS unsupported_options =
1050 EBO_ALWAYSNAVIGATE | EBO_NOWRAPPERWINDOW | EBO_HTMLSHAREPOINTVIEW | EBO_NOPERSISTVIEWSTATE;
1052 TRACE("%p (0x%x)\n", This, dwFlag);
1054 if(dwFlag & unsupported_options)
1055 FIXME("Flags 0x%08x contains unsupported options.\n", dwFlag);
1057 This->eb_options = dwFlag;
1059 return S_OK;
1062 static HRESULT WINAPI IExplorerBrowser_fnGetOptions(IExplorerBrowser *iface,
1063 EXPLORER_BROWSER_OPTIONS *pdwFlag)
1065 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1066 TRACE("%p (%p)\n", This, pdwFlag);
1068 *pdwFlag = This->eb_options;
1070 return S_OK;
1073 static HRESULT WINAPI IExplorerBrowser_fnBrowseToIDList(IExplorerBrowser *iface,
1074 PCUIDLIST_RELATIVE pidl,
1075 UINT uFlags)
1077 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1078 LPITEMIDLIST absolute_pidl = NULL;
1079 HRESULT hr;
1080 static const UINT unsupported_browse_flags =
1081 SBSP_NEWBROWSER | EBF_SELECTFROMDATAOBJECT | EBF_NODROPTARGET;
1082 TRACE("%p (%p, 0x%x)\n", This, pidl, uFlags);
1084 if(!This->hwnd_main)
1085 return E_FAIL;
1087 if(This->destroyed)
1088 return HRESULT_FROM_WIN32(ERROR_BUSY);
1090 if(This->current_pidl && (This->eb_options & EBO_NAVIGATEONCE))
1091 return E_FAIL;
1093 if(uFlags & SBSP_EXPLOREMODE)
1094 return E_INVALIDARG;
1096 if(uFlags & unsupported_browse_flags)
1097 FIXME("Argument 0x%x contains unsupported flags.\n", uFlags);
1099 if(uFlags & SBSP_NAVIGATEBACK)
1101 TRACE("SBSP_NAVIGATEBACK\n");
1102 absolute_pidl = ILClone(travellog_go_back(This));
1103 if(!absolute_pidl && !This->current_pidl)
1104 return E_FAIL;
1105 else if(!absolute_pidl)
1106 return S_OK;
1109 else if(uFlags & SBSP_NAVIGATEFORWARD)
1111 TRACE("SBSP_NAVIGATEFORWARD\n");
1112 absolute_pidl = ILClone(travellog_go_forward(This));
1113 if(!absolute_pidl && !This->current_pidl)
1114 return E_FAIL;
1115 else if(!absolute_pidl)
1116 return S_OK;
1119 else if(uFlags & SBSP_PARENT)
1121 if(This->current_pidl)
1123 if(_ILIsPidlSimple(This->current_pidl))
1125 absolute_pidl = _ILCreateDesktop();
1127 else
1129 absolute_pidl = ILClone(This->current_pidl);
1130 ILRemoveLastID(absolute_pidl);
1133 if(!absolute_pidl)
1135 ERR("Failed to get parent pidl.\n");
1136 return E_FAIL;
1140 else if(uFlags & SBSP_RELATIVE)
1142 /* SBSP_RELATIVE has precedence over SBSP_ABSOLUTE */
1143 TRACE("SBSP_RELATIVE\n");
1144 if(This->current_pidl)
1146 absolute_pidl = ILCombine(This->current_pidl, pidl);
1148 if(!absolute_pidl)
1150 ERR("Failed to get absolute pidl.\n");
1151 return E_FAIL;
1154 else
1156 TRACE("SBSP_ABSOLUTE\n");
1157 absolute_pidl = ILClone(pidl);
1158 if(!absolute_pidl && !This->current_pidl)
1159 return E_INVALIDARG;
1160 else if(!absolute_pidl)
1161 return S_OK;
1164 /* TODO: Asynchronous browsing. Return S_OK here and finish in
1165 * another thread. */
1167 hr = events_NavigationPending(This, absolute_pidl);
1168 if(FAILED(hr))
1170 TRACE("Browsing aborted.\n");
1171 ILFree(absolute_pidl);
1172 return E_FAIL;
1175 get_interfaces_from_site(This);
1176 update_panestate(This);
1178 /* Only browse if the new pidl differs from the old */
1179 if(!ILIsEqual(This->current_pidl, absolute_pidl))
1181 IShellItem *psi;
1182 hr = SHCreateItemFromIDList(absolute_pidl, &IID_IShellItem, (void**)&psi);
1183 if(SUCCEEDED(hr))
1185 hr = create_new_shellview(This, psi);
1186 if(FAILED(hr))
1188 events_NavigationFailed(This, absolute_pidl);
1189 ILFree(absolute_pidl);
1190 IShellItem_Release(psi);
1191 return E_FAIL;
1194 /* Add to travellog */
1195 if( !(This->eb_options & EBO_NOTRAVELLOG) &&
1196 !(uFlags & (SBSP_NAVIGATEFORWARD|SBSP_NAVIGATEBACK)) )
1198 travellog_add_entry(This, absolute_pidl);
1201 IShellItem_Release(psi);
1205 events_NavigationComplete(This, absolute_pidl);
1206 ILFree(This->current_pidl);
1207 This->current_pidl = absolute_pidl;
1209 /* Expand the NameSpaceTree to the current location. */
1210 if(This->navpane.show && This->navpane.pnstc2)
1212 IShellItem *psi;
1213 hr = SHCreateItemFromIDList(This->current_pidl, &IID_IShellItem, (void**)&psi);
1214 if(SUCCEEDED(hr))
1216 INameSpaceTreeControl2_EnsureItemVisible(This->navpane.pnstc2, psi);
1217 IShellItem_Release(psi);
1221 return S_OK;
1224 static HRESULT WINAPI IExplorerBrowser_fnBrowseToObject(IExplorerBrowser *iface,
1225 IUnknown *punk, UINT uFlags)
1227 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1228 LPITEMIDLIST pidl;
1229 HRESULT hr;
1230 TRACE("%p (%p, 0x%x)\n", This, punk, uFlags);
1232 if(!punk)
1233 return IExplorerBrowser_BrowseToIDList(iface, NULL, uFlags);
1235 hr = SHGetIDListFromObject(punk, &pidl);
1236 if(SUCCEEDED(hr))
1238 hr = IExplorerBrowser_BrowseToIDList(iface, pidl, uFlags);
1239 ILFree(pidl);
1242 return hr;
1245 static HRESULT WINAPI IExplorerBrowser_fnFillFromObject(IExplorerBrowser *iface,
1246 IUnknown *punk,
1247 EXPLORER_BROWSER_FILL_FLAGS dwFlags)
1249 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1250 FIXME("stub, %p (%p, 0x%x)\n", This, punk, dwFlags);
1252 return E_NOTIMPL;
1255 static HRESULT WINAPI IExplorerBrowser_fnRemoveAll(IExplorerBrowser *iface)
1257 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1258 FIXME("stub, %p\n", This);
1260 return E_NOTIMPL;
1263 static HRESULT WINAPI IExplorerBrowser_fnGetCurrentView(IExplorerBrowser *iface,
1264 REFIID riid, void **ppv)
1266 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1267 TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppv);
1269 if(!This->psv)
1270 return E_FAIL;
1272 return IShellView_QueryInterface(This->psv, riid, ppv);
1275 static const IExplorerBrowserVtbl vt_IExplorerBrowser =
1277 IExplorerBrowser_fnQueryInterface,
1278 IExplorerBrowser_fnAddRef,
1279 IExplorerBrowser_fnRelease,
1280 IExplorerBrowser_fnInitialize,
1281 IExplorerBrowser_fnDestroy,
1282 IExplorerBrowser_fnSetRect,
1283 IExplorerBrowser_fnSetPropertyBag,
1284 IExplorerBrowser_fnSetEmptyText,
1285 IExplorerBrowser_fnSetFolderSettings,
1286 IExplorerBrowser_fnAdvise,
1287 IExplorerBrowser_fnUnadvise,
1288 IExplorerBrowser_fnSetOptions,
1289 IExplorerBrowser_fnGetOptions,
1290 IExplorerBrowser_fnBrowseToIDList,
1291 IExplorerBrowser_fnBrowseToObject,
1292 IExplorerBrowser_fnFillFromObject,
1293 IExplorerBrowser_fnRemoveAll,
1294 IExplorerBrowser_fnGetCurrentView
1297 /**************************************************************************
1298 * IShellBrowser Implementation
1301 static inline ExplorerBrowserImpl *impl_from_IShellBrowser(IShellBrowser *iface)
1303 return CONTAINING_RECORD(iface, ExplorerBrowserImpl, IShellBrowser_iface);
1306 static HRESULT WINAPI IShellBrowser_fnQueryInterface(IShellBrowser *iface,
1307 REFIID riid, void **ppvObject)
1309 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1310 TRACE("%p\n", This);
1311 return IExplorerBrowser_QueryInterface(&This->IExplorerBrowser_iface, riid, ppvObject);
1314 static ULONG WINAPI IShellBrowser_fnAddRef(IShellBrowser *iface)
1316 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1317 TRACE("%p\n", This);
1318 return IExplorerBrowser_AddRef(&This->IExplorerBrowser_iface);
1321 static ULONG WINAPI IShellBrowser_fnRelease(IShellBrowser *iface)
1323 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1324 TRACE("%p\n", This);
1325 return IExplorerBrowser_Release(&This->IExplorerBrowser_iface);
1328 static HRESULT WINAPI IShellBrowser_fnGetWindow(IShellBrowser *iface, HWND *phwnd)
1330 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1331 TRACE("%p (%p)\n", This, phwnd);
1333 if(!This->hwnd_main)
1334 return E_FAIL;
1336 *phwnd = This->hwnd_main;
1337 return S_OK;
1340 static HRESULT WINAPI IShellBrowser_fnContextSensitiveHelp(IShellBrowser *iface,
1341 BOOL fEnterMode)
1343 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1344 FIXME("stub, %p (%d)\n", This, fEnterMode);
1346 return E_NOTIMPL;
1349 static HRESULT WINAPI IShellBrowser_fnInsertMenusSB(IShellBrowser *iface,
1350 HMENU hmenuShared,
1351 LPOLEMENUGROUPWIDTHS lpMenuWidths)
1353 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1354 TRACE("%p (%p, %p)\n", This, hmenuShared, lpMenuWidths);
1356 /* Not implemented. */
1357 return E_NOTIMPL;
1360 static HRESULT WINAPI IShellBrowser_fnSetMenuSB(IShellBrowser *iface,
1361 HMENU hmenuShared,
1362 HOLEMENU holemenuReserved,
1363 HWND hwndActiveObject)
1365 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1366 TRACE("%p (%p, %p, %p)\n", This, hmenuShared, holemenuReserved, hwndActiveObject);
1368 /* Not implemented. */
1369 return E_NOTIMPL;
1372 static HRESULT WINAPI IShellBrowser_fnRemoveMenusSB(IShellBrowser *iface,
1373 HMENU hmenuShared)
1375 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1376 TRACE("%p (%p)\n", This, hmenuShared);
1378 /* Not implemented. */
1379 return E_NOTIMPL;
1382 static HRESULT WINAPI IShellBrowser_fnSetStatusTextSB(IShellBrowser *iface,
1383 LPCOLESTR pszStatusText)
1385 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1386 FIXME("stub, %p (%s)\n", This, debugstr_w(pszStatusText));
1388 return E_NOTIMPL;
1391 static HRESULT WINAPI IShellBrowser_fnEnableModelessSB(IShellBrowser *iface,
1392 BOOL fEnable)
1394 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1395 FIXME("stub, %p (%d)\n", This, fEnable);
1397 return E_NOTIMPL;
1400 static HRESULT WINAPI IShellBrowser_fnTranslateAcceleratorSB(IShellBrowser *iface,
1401 MSG *pmsg, WORD wID)
1403 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1404 FIXME("stub, %p (%p, 0x%x)\n", This, pmsg, wID);
1406 return E_NOTIMPL;
1409 static HRESULT WINAPI IShellBrowser_fnBrowseObject(IShellBrowser *iface,
1410 LPCITEMIDLIST pidl, UINT wFlags)
1412 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1413 TRACE("%p (%p, %x)\n", This, pidl, wFlags);
1415 return IExplorerBrowser_BrowseToIDList(&This->IExplorerBrowser_iface, pidl, wFlags);
1418 static HRESULT WINAPI IShellBrowser_fnGetViewStateStream(IShellBrowser *iface,
1419 DWORD grfMode,
1420 IStream **ppStrm)
1422 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1423 FIXME("stub, %p (0x%lx, %p)\n", This, grfMode, ppStrm);
1425 *ppStrm = NULL;
1426 return E_FAIL;
1429 static HRESULT WINAPI IShellBrowser_fnGetControlWindow(IShellBrowser *iface,
1430 UINT id, HWND *phwnd)
1432 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1433 TRACE("(%p)->(%d, %p)\n", This, id, phwnd);
1434 if (phwnd) *phwnd = NULL;
1435 return E_NOTIMPL;
1438 static HRESULT WINAPI IShellBrowser_fnSendControlMsg(IShellBrowser *iface,
1439 UINT id, UINT uMsg,
1440 WPARAM wParam, LPARAM lParam,
1441 LRESULT *pret)
1443 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1444 FIXME("stub, %p (%d, %d, %Ix, %Ix, %p)\n", This, id, uMsg, wParam, lParam, pret);
1446 return E_NOTIMPL;
1449 static HRESULT WINAPI IShellBrowser_fnQueryActiveShellView(IShellBrowser *iface,
1450 IShellView **ppshv)
1452 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1453 TRACE("%p (%p)\n", This, ppshv);
1455 if(!This->psv)
1456 return E_FAIL;
1458 *ppshv = This->psv;
1459 IShellView_AddRef(This->psv);
1461 return S_OK;
1464 static HRESULT WINAPI IShellBrowser_fnOnViewWindowActive(IShellBrowser *iface,
1465 IShellView *pshv)
1467 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1468 FIXME("stub, %p (%p)\n", This, pshv);
1470 return E_NOTIMPL;
1473 static HRESULT WINAPI IShellBrowser_fnSetToolbarItems(IShellBrowser *iface,
1474 LPTBBUTTONSB lpButtons,
1475 UINT nButtons, UINT uFlags)
1477 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1478 FIXME("stub, %p (%p, %d, 0x%x)\n", This, lpButtons, nButtons, uFlags);
1480 return E_NOTIMPL;
1483 static const IShellBrowserVtbl vt_IShellBrowser = {
1484 IShellBrowser_fnQueryInterface,
1485 IShellBrowser_fnAddRef,
1486 IShellBrowser_fnRelease,
1487 IShellBrowser_fnGetWindow,
1488 IShellBrowser_fnContextSensitiveHelp,
1489 IShellBrowser_fnInsertMenusSB,
1490 IShellBrowser_fnSetMenuSB,
1491 IShellBrowser_fnRemoveMenusSB,
1492 IShellBrowser_fnSetStatusTextSB,
1493 IShellBrowser_fnEnableModelessSB,
1494 IShellBrowser_fnTranslateAcceleratorSB,
1495 IShellBrowser_fnBrowseObject,
1496 IShellBrowser_fnGetViewStateStream,
1497 IShellBrowser_fnGetControlWindow,
1498 IShellBrowser_fnSendControlMsg,
1499 IShellBrowser_fnQueryActiveShellView,
1500 IShellBrowser_fnOnViewWindowActive,
1501 IShellBrowser_fnSetToolbarItems
1504 /**************************************************************************
1505 * ICommDlgBrowser3 Implementation
1508 static inline ExplorerBrowserImpl *impl_from_ICommDlgBrowser3(ICommDlgBrowser3 *iface)
1510 return CONTAINING_RECORD(iface, ExplorerBrowserImpl, ICommDlgBrowser3_iface);
1513 static HRESULT WINAPI ICommDlgBrowser3_fnQueryInterface(ICommDlgBrowser3 *iface,
1514 REFIID riid,
1515 void **ppvObject)
1517 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1518 TRACE("%p\n", This);
1519 return IExplorerBrowser_QueryInterface(&This->IExplorerBrowser_iface, riid, ppvObject);
1522 static ULONG WINAPI ICommDlgBrowser3_fnAddRef(ICommDlgBrowser3 *iface)
1524 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1525 TRACE("%p\n", This);
1526 return IExplorerBrowser_AddRef(&This->IExplorerBrowser_iface);
1529 static ULONG WINAPI ICommDlgBrowser3_fnRelease(ICommDlgBrowser3 *iface)
1531 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1532 TRACE("%p\n", This);
1533 return IExplorerBrowser_Release(&This->IExplorerBrowser_iface);
1536 static HRESULT WINAPI ICommDlgBrowser3_fnOnDefaultCommand(ICommDlgBrowser3 *iface,
1537 IShellView *shv)
1539 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1540 IDataObject *pdo;
1541 HRESULT hr;
1542 HRESULT ret = S_FALSE;
1544 TRACE("%p (%p)\n", This, shv);
1546 hr = IShellView_GetItemObject(shv, SVGIO_SELECTION, &IID_IDataObject, (void**)&pdo);
1547 if(SUCCEEDED(hr))
1549 FORMATETC fmt;
1550 STGMEDIUM medium;
1552 fmt.cfFormat = RegisterClipboardFormatW(CFSTR_SHELLIDLISTW);
1553 fmt.ptd = NULL;
1554 fmt.dwAspect = DVASPECT_CONTENT;
1555 fmt.lindex = -1;
1556 fmt.tymed = TYMED_HGLOBAL;
1558 hr = IDataObject_GetData(pdo, &fmt ,&medium);
1559 IDataObject_Release(pdo);
1560 if(SUCCEEDED(hr))
1562 LPIDA pida = GlobalLock(medium.u.hGlobal);
1563 LPCITEMIDLIST pidl_child = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[1]);
1565 /* Handle folders by browsing to them. */
1566 if(_ILIsFolder(pidl_child) || _ILIsDrive(pidl_child) || _ILIsSpecialFolder(pidl_child))
1568 IExplorerBrowser_BrowseToIDList(&This->IExplorerBrowser_iface, pidl_child, SBSP_RELATIVE);
1569 ret = S_OK;
1571 GlobalUnlock(medium.u.hGlobal);
1572 GlobalFree(medium.u.hGlobal);
1574 else
1575 ERR("Failed to get data from IDataObject.\n");
1576 } else
1577 ERR("Failed to get IDataObject.\n");
1579 /* If we didn't handle the default command, check if we have a
1580 * client that does */
1581 if(ret == S_FALSE && This->pcdb_site)
1582 return ICommDlgBrowser_OnDefaultCommand(This->pcdb_site, shv);
1584 return ret;
1586 static HRESULT WINAPI ICommDlgBrowser3_fnOnStateChange(ICommDlgBrowser3 *iface,
1587 IShellView *shv, ULONG uChange)
1589 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1590 TRACE("%p (%p, %ld)\n", This, shv, uChange);
1592 if(This->pcdb_site)
1593 return ICommDlgBrowser_OnStateChange(This->pcdb_site, shv, uChange);
1595 return E_NOTIMPL;
1597 static HRESULT WINAPI ICommDlgBrowser3_fnIncludeObject(ICommDlgBrowser3 *iface,
1598 IShellView *pshv, LPCITEMIDLIST pidl)
1600 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1601 TRACE("%p (%p, %p)\n", This, pshv, pidl);
1603 if(This->pcdb_site)
1604 return ICommDlgBrowser_IncludeObject(This->pcdb_site, pshv, pidl);
1606 return S_OK;
1609 static HRESULT WINAPI ICommDlgBrowser3_fnNotify(ICommDlgBrowser3 *iface,
1610 IShellView *pshv,
1611 DWORD dwNotifyType)
1613 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1614 TRACE("%p (%p, 0x%lx)\n", This, pshv, dwNotifyType);
1616 if(This->pcdb2_site)
1617 return ICommDlgBrowser2_Notify(This->pcdb2_site, pshv, dwNotifyType);
1619 return S_OK;
1622 static HRESULT WINAPI ICommDlgBrowser3_fnGetDefaultMenuText(ICommDlgBrowser3 *iface,
1623 IShellView *pshv,
1624 LPWSTR pszText, int cchMax)
1626 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1627 TRACE("%p (%p, %s, %d)\n", This, pshv, debugstr_w(pszText), cchMax);
1629 if(This->pcdb2_site)
1630 return ICommDlgBrowser2_GetDefaultMenuText(This->pcdb2_site, pshv, pszText, cchMax);
1632 return S_OK;
1635 static HRESULT WINAPI ICommDlgBrowser3_fnGetViewFlags(ICommDlgBrowser3 *iface,
1636 DWORD *pdwFlags)
1638 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1639 TRACE("%p (%p)\n", This, pdwFlags);
1641 if(This->pcdb2_site)
1642 return ICommDlgBrowser2_GetViewFlags(This->pcdb2_site, pdwFlags);
1644 return S_OK;
1647 static HRESULT WINAPI ICommDlgBrowser3_fnOnColumnClicked(ICommDlgBrowser3 *iface,
1648 IShellView *pshv, int iColumn)
1650 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1651 TRACE("%p (%p, %d)\n", This, pshv, iColumn);
1653 if(This->pcdb3_site)
1654 return ICommDlgBrowser3_OnColumnClicked(This->pcdb3_site, pshv, iColumn);
1656 return S_OK;
1659 static HRESULT WINAPI ICommDlgBrowser3_fnGetCurrentFilter(ICommDlgBrowser3 *iface,
1660 LPWSTR pszFileSpec,
1661 int cchFileSpec)
1663 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1664 TRACE("%p (%s, %d)\n", This, debugstr_w(pszFileSpec), cchFileSpec);
1666 if(This->pcdb3_site)
1667 return ICommDlgBrowser3_GetCurrentFilter(This->pcdb3_site, pszFileSpec, cchFileSpec);
1669 return S_OK;
1672 static HRESULT WINAPI ICommDlgBrowser3_fnOnPreViewCreated(ICommDlgBrowser3 *iface,
1673 IShellView *pshv)
1675 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1676 TRACE("%p (%p)\n", This, pshv);
1678 if(This->pcdb3_site)
1679 return ICommDlgBrowser3_OnPreViewCreated(This->pcdb3_site, pshv);
1681 return S_OK;
1684 static const ICommDlgBrowser3Vtbl vt_ICommDlgBrowser3 = {
1685 ICommDlgBrowser3_fnQueryInterface,
1686 ICommDlgBrowser3_fnAddRef,
1687 ICommDlgBrowser3_fnRelease,
1688 ICommDlgBrowser3_fnOnDefaultCommand,
1689 ICommDlgBrowser3_fnOnStateChange,
1690 ICommDlgBrowser3_fnIncludeObject,
1691 ICommDlgBrowser3_fnNotify,
1692 ICommDlgBrowser3_fnGetDefaultMenuText,
1693 ICommDlgBrowser3_fnGetViewFlags,
1694 ICommDlgBrowser3_fnOnColumnClicked,
1695 ICommDlgBrowser3_fnGetCurrentFilter,
1696 ICommDlgBrowser3_fnOnPreViewCreated
1699 /**************************************************************************
1700 * IObjectWithSite Implementation
1703 static inline ExplorerBrowserImpl *impl_from_IObjectWithSite(IObjectWithSite *iface)
1705 return CONTAINING_RECORD(iface, ExplorerBrowserImpl, IObjectWithSite_iface);
1708 static HRESULT WINAPI IObjectWithSite_fnQueryInterface(IObjectWithSite *iface,
1709 REFIID riid, void **ppvObject)
1711 ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
1712 TRACE("%p\n", This);
1713 return IExplorerBrowser_QueryInterface(&This->IExplorerBrowser_iface, riid, ppvObject);
1716 static ULONG WINAPI IObjectWithSite_fnAddRef(IObjectWithSite *iface)
1718 ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
1719 TRACE("%p\n", This);
1720 return IExplorerBrowser_AddRef(&This->IExplorerBrowser_iface);
1723 static ULONG WINAPI IObjectWithSite_fnRelease(IObjectWithSite *iface)
1725 ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
1726 TRACE("%p\n", This);
1727 return IExplorerBrowser_Release(&This->IExplorerBrowser_iface);
1730 static HRESULT WINAPI IObjectWithSite_fnSetSite(IObjectWithSite *iface, IUnknown *punk_site)
1732 ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
1733 TRACE("%p (%p)\n", This, punk_site);
1735 if(This->punk_site)
1737 IUnknown_Release(This->punk_site);
1738 This->punk_site = NULL;
1739 get_interfaces_from_site(This);
1742 This->punk_site = punk_site;
1744 if(This->punk_site)
1745 IUnknown_AddRef(This->punk_site);
1747 return S_OK;
1750 static HRESULT WINAPI IObjectWithSite_fnGetSite(IObjectWithSite *iface, REFIID riid, void **ppvSite)
1752 ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
1753 TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppvSite);
1755 if(!This->punk_site)
1756 return E_FAIL;
1758 return IUnknown_QueryInterface(This->punk_site, riid, ppvSite);
1761 static const IObjectWithSiteVtbl vt_IObjectWithSite = {
1762 IObjectWithSite_fnQueryInterface,
1763 IObjectWithSite_fnAddRef,
1764 IObjectWithSite_fnRelease,
1765 IObjectWithSite_fnSetSite,
1766 IObjectWithSite_fnGetSite
1769 /**************************************************************************
1770 * INameSpaceTreeControlEvents Implementation
1772 static inline ExplorerBrowserImpl *impl_from_INameSpaceTreeControlEvents(INameSpaceTreeControlEvents *iface)
1774 return CONTAINING_RECORD(iface, ExplorerBrowserImpl, INameSpaceTreeControlEvents_iface);
1777 static HRESULT WINAPI NSTCEvents_fnQueryInterface(INameSpaceTreeControlEvents *iface,
1778 REFIID riid, void **ppvObject)
1780 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1781 TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppvObject);
1783 *ppvObject = NULL;
1784 if(IsEqualIID(riid, &IID_INameSpaceTreeControlEvents) ||
1785 IsEqualIID(riid, &IID_IUnknown))
1787 *ppvObject = iface;
1790 if(*ppvObject)
1792 IUnknown_AddRef((IUnknown*)*ppvObject);
1793 return S_OK;
1796 return E_NOINTERFACE;
1799 static ULONG WINAPI NSTCEvents_fnAddRef(INameSpaceTreeControlEvents *iface)
1801 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1802 TRACE("%p\n", This);
1803 return IExplorerBrowser_AddRef(&This->IExplorerBrowser_iface);
1806 static ULONG WINAPI NSTCEvents_fnRelease(INameSpaceTreeControlEvents *iface)
1808 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1809 TRACE("%p\n", This);
1810 return IExplorerBrowser_Release(&This->IExplorerBrowser_iface);
1813 static HRESULT WINAPI NSTCEvents_fnOnItemClick(INameSpaceTreeControlEvents *iface,
1814 IShellItem *psi,
1815 NSTCEHITTEST nstceHitTest,
1816 NSTCECLICKTYPE nstceClickType)
1818 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1819 TRACE("%p (%p, 0x%lx, 0x%lx)\n", This, psi, nstceHitTest, nstceClickType);
1820 return S_OK;
1823 static HRESULT WINAPI NSTCEvents_fnOnPropertyItemCommit(INameSpaceTreeControlEvents *iface,
1824 IShellItem *psi)
1826 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1827 TRACE("%p (%p)\n", This, psi);
1828 return E_NOTIMPL;
1831 static HRESULT WINAPI NSTCEvents_fnOnItemStateChanging(INameSpaceTreeControlEvents *iface,
1832 IShellItem *psi,
1833 NSTCITEMSTATE nstcisMask,
1834 NSTCITEMSTATE nstcisState)
1836 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1837 TRACE("%p (%p, 0x%lx, 0x%lx)\n", This, psi, nstcisMask, nstcisState);
1838 return E_NOTIMPL;
1841 static HRESULT WINAPI NSTCEvents_fnOnItemStateChanged(INameSpaceTreeControlEvents *iface,
1842 IShellItem *psi,
1843 NSTCITEMSTATE nstcisMask,
1844 NSTCITEMSTATE nstcisState)
1846 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1847 TRACE("%p (%p, 0x%lx, 0x%lx)\n", This, psi, nstcisMask, nstcisState);
1848 return E_NOTIMPL;
1851 static HRESULT WINAPI NSTCEvents_fnOnSelectionChanged(INameSpaceTreeControlEvents *iface,
1852 IShellItemArray *psiaSelection)
1854 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1855 IShellItem *psi;
1856 HRESULT hr;
1857 TRACE("%p (%p)\n", This, psiaSelection);
1859 hr = IShellItemArray_GetItemAt(psiaSelection, 0, &psi);
1860 if(SUCCEEDED(hr))
1862 hr = IExplorerBrowser_BrowseToObject(&This->IExplorerBrowser_iface,
1863 (IUnknown*)psi, SBSP_DEFBROWSER);
1864 IShellItem_Release(psi);
1867 return hr;
1870 static HRESULT WINAPI NSTCEvents_fnOnKeyboardInput(INameSpaceTreeControlEvents *iface,
1871 UINT uMsg, WPARAM wParam, LPARAM lParam)
1873 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1874 TRACE("%p (%d, 0x%Ix, 0x%Ix)\n", This, uMsg, wParam, lParam);
1875 return S_OK;
1878 static HRESULT WINAPI NSTCEvents_fnOnBeforeExpand(INameSpaceTreeControlEvents *iface,
1879 IShellItem *psi)
1881 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1882 TRACE("%p (%p)\n", This, psi);
1883 return E_NOTIMPL;
1886 static HRESULT WINAPI NSTCEvents_fnOnAfterExpand(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_fnOnBeginLabelEdit(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_fnOnEndLabelEdit(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_fnOnGetToolTip(INameSpaceTreeControlEvents *iface,
1911 IShellItem *psi, LPWSTR pszTip, int cchTip)
1913 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1914 TRACE("%p (%p, %p, %d)\n", This, psi, pszTip, cchTip);
1915 return E_NOTIMPL;
1918 static HRESULT WINAPI NSTCEvents_fnOnBeforeItemDelete(INameSpaceTreeControlEvents *iface,
1919 IShellItem *psi)
1921 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1922 TRACE("%p (%p)\n", This, psi);
1923 return E_NOTIMPL;
1926 static HRESULT WINAPI NSTCEvents_fnOnItemAdded(INameSpaceTreeControlEvents *iface,
1927 IShellItem *psi, BOOL fIsRoot)
1929 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1930 TRACE("%p (%p, %d)\n", This, psi, fIsRoot);
1931 return E_NOTIMPL;
1934 static HRESULT WINAPI NSTCEvents_fnOnItemDeleted(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_fnOnBeforeContextMenu(INameSpaceTreeControlEvents *iface,
1943 IShellItem *psi, REFIID riid, void **ppv)
1945 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1946 TRACE("%p (%p, %s, %p)\n", This, psi, shdebugstr_guid(riid), ppv);
1947 return E_NOTIMPL;
1950 static HRESULT WINAPI NSTCEvents_fnOnAfterContextMenu(INameSpaceTreeControlEvents *iface,
1951 IShellItem *psi, IContextMenu *pcmIn,
1952 REFIID riid, void **ppv)
1954 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1955 TRACE("%p (%p, %p, %s, %p)\n", This, psi, pcmIn, shdebugstr_guid(riid), ppv);
1956 return E_NOTIMPL;
1959 static HRESULT WINAPI NSTCEvents_fnOnBeforeStateImageChange(INameSpaceTreeControlEvents *iface,
1960 IShellItem *psi)
1962 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1963 TRACE("%p (%p)\n", This, psi);
1964 return E_NOTIMPL;
1967 static HRESULT WINAPI NSTCEvents_fnOnGetDefaultIconIndex(INameSpaceTreeControlEvents* iface,
1968 IShellItem *psi,
1969 int *piDefaultIcon, int *piOpenIcon)
1971 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1972 TRACE("%p (%p, %p, %p)\n", This, psi, piDefaultIcon, piOpenIcon);
1973 return E_NOTIMPL;
1977 static const INameSpaceTreeControlEventsVtbl vt_INameSpaceTreeControlEvents = {
1978 NSTCEvents_fnQueryInterface,
1979 NSTCEvents_fnAddRef,
1980 NSTCEvents_fnRelease,
1981 NSTCEvents_fnOnItemClick,
1982 NSTCEvents_fnOnPropertyItemCommit,
1983 NSTCEvents_fnOnItemStateChanging,
1984 NSTCEvents_fnOnItemStateChanged,
1985 NSTCEvents_fnOnSelectionChanged,
1986 NSTCEvents_fnOnKeyboardInput,
1987 NSTCEvents_fnOnBeforeExpand,
1988 NSTCEvents_fnOnAfterExpand,
1989 NSTCEvents_fnOnBeginLabelEdit,
1990 NSTCEvents_fnOnEndLabelEdit,
1991 NSTCEvents_fnOnGetToolTip,
1992 NSTCEvents_fnOnBeforeItemDelete,
1993 NSTCEvents_fnOnItemAdded,
1994 NSTCEvents_fnOnItemDeleted,
1995 NSTCEvents_fnOnBeforeContextMenu,
1996 NSTCEvents_fnOnAfterContextMenu,
1997 NSTCEvents_fnOnBeforeStateImageChange,
1998 NSTCEvents_fnOnGetDefaultIconIndex
2001 /**************************************************************************
2002 * IInputObject Implementation
2005 static inline ExplorerBrowserImpl *impl_from_IInputObject(IInputObject *iface)
2007 return CONTAINING_RECORD(iface, ExplorerBrowserImpl, IInputObject_iface);
2010 static HRESULT WINAPI IInputObject_fnQueryInterface(IInputObject *iface,
2011 REFIID riid, void **ppvObject)
2013 ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
2014 TRACE("%p\n", This);
2015 return IExplorerBrowser_QueryInterface(&This->IExplorerBrowser_iface, riid, ppvObject);
2018 static ULONG WINAPI IInputObject_fnAddRef(IInputObject *iface)
2020 ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
2021 TRACE("%p\n", This);
2022 return IExplorerBrowser_AddRef(&This->IExplorerBrowser_iface);
2025 static ULONG WINAPI IInputObject_fnRelease(IInputObject *iface)
2027 ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
2028 TRACE("%p\n", This);
2029 return IExplorerBrowser_Release(&This->IExplorerBrowser_iface);
2032 static HRESULT WINAPI IInputObject_fnUIActivateIO(IInputObject *iface, BOOL fActivate, MSG *pMsg)
2034 ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
2035 FIXME("stub, %p (%d, %p)\n", This, fActivate, pMsg);
2036 return E_NOTIMPL;
2039 static HRESULT WINAPI IInputObject_fnHasFocusIO(IInputObject *iface)
2041 ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
2042 FIXME("stub, %p\n", This);
2043 return E_NOTIMPL;
2046 static HRESULT WINAPI IInputObject_fnTranslateAcceleratorIO(IInputObject *iface, MSG *pMsg)
2048 ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
2049 FIXME("stub, %p (%p)\n", This, pMsg);
2050 return E_NOTIMPL;
2053 static IInputObjectVtbl vt_IInputObject = {
2054 IInputObject_fnQueryInterface,
2055 IInputObject_fnAddRef,
2056 IInputObject_fnRelease,
2057 IInputObject_fnUIActivateIO,
2058 IInputObject_fnHasFocusIO,
2059 IInputObject_fnTranslateAcceleratorIO
2062 HRESULT WINAPI ExplorerBrowser_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv)
2064 ExplorerBrowserImpl *eb;
2065 HRESULT ret;
2067 TRACE("%p %s %p\n", pUnkOuter, shdebugstr_guid (riid), ppv);
2069 if(!ppv)
2070 return E_POINTER;
2071 if(pUnkOuter)
2072 return CLASS_E_NOAGGREGATION;
2074 eb = heap_alloc_zero(sizeof(*eb));
2075 eb->ref = 1;
2076 eb->IExplorerBrowser_iface.lpVtbl = &vt_IExplorerBrowser;
2077 eb->IShellBrowser_iface.lpVtbl = &vt_IShellBrowser;
2078 eb->ICommDlgBrowser3_iface.lpVtbl = &vt_ICommDlgBrowser3;
2079 eb->IObjectWithSite_iface.lpVtbl = &vt_IObjectWithSite;
2080 eb->INameSpaceTreeControlEvents_iface.lpVtbl = &vt_INameSpaceTreeControlEvents;
2081 eb->IInputObject_iface.lpVtbl = &vt_IInputObject;
2083 /* Default settings */
2084 eb->navpane.show = TRUE;
2086 list_init(&eb->event_clients);
2087 list_init(&eb->travellog);
2089 ret = IExplorerBrowser_QueryInterface(&eb->IExplorerBrowser_iface, riid, ppv);
2090 IExplorerBrowser_Release(&eb->IExplorerBrowser_iface);
2092 TRACE("--(%p)\n", ppv);
2093 return ret;