winejoystick: Fix a crash on accessing a CFArray past its end due to an off-by-one...
[wine/multimedia.git] / dlls / shell32 / ebrowser.c
blobb5cc21fbe9190357c236943d9c4c38f2340555f6
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
25 #define NONAMELESSSTRUCT
27 #include "winerror.h"
28 #include "windef.h"
29 #include "winbase.h"
31 #include "wine/list.h"
32 #include "wine/debug.h"
33 #include "debughlp.h"
35 #include "shell32_main.h"
36 #include "pidl.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(shell);
40 #define SPLITTER_WIDTH 2
41 #define NP_MIN_WIDTH 60
42 #define SV_MIN_WIDTH 150
44 typedef struct _event_client {
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 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 HeapFree(GetProcessHeap(), 0, 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 HeapFree(GetProcessHeap(), 0, 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 = HeapAlloc(GetProcessHeap(), 0, sizeof(travellog_entry));
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 TRACE("%p (navpane: %d, EBO_SHOWFRAMES: %d)\n",
279 This, This->navpane.show, This->eb_options & EBO_SHOWFRAMES);
281 GetClientRect(This->hwnd_main, &rc);
283 if((This->eb_options & EBO_SHOWFRAMES) && This->navpane.show)
284 navpane_width_actual = This->navpane.width;
285 else
286 navpane_width_actual = 0;
288 shellview_width_actual = rc.right - navpane_width_actual;
289 if(shellview_width_actual < SV_MIN_WIDTH && navpane_width_actual)
291 INT missing_width = SV_MIN_WIDTH - shellview_width_actual;
292 if(missing_width < (navpane_width_actual - NP_MIN_WIDTH))
294 /* Shrink the navpane */
295 navpane_width_actual -= missing_width;
296 shellview_width_actual += missing_width;
298 else
300 /* Hide the navpane */
301 shellview_width_actual += navpane_width_actual;
302 navpane_width_actual = 0;
306 /**************************************************************
307 * Calculate rectangles for the panes. All rectangles contain
308 * the position of the panes relative to hwnd_main.
311 if(navpane_width_actual)
313 This->navpane.rc.left = This->navpane.rc.top = 0;
314 This->navpane.rc.right = navpane_width_actual;
315 This->navpane.rc.bottom = 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 This->sv_rc.left = navpane_width_actual;
324 This->sv_rc.top = 0;
325 This->sv_rc.right = This->sv_rc.left + shellview_width_actual;
326 This->sv_rc.bottom = rc.bottom;
329 static void size_panes(ExplorerBrowserImpl *This)
331 MoveWindow(This->navpane.hwnd_splitter,
332 This->navpane.rc.right - SPLITTER_WIDTH, This->navpane.rc.top,
333 SPLITTER_WIDTH, This->navpane.rc.bottom - This->navpane.rc.top,
334 TRUE);
336 MoveWindow(This->hwnd_sv,
337 This->sv_rc.left, This->sv_rc.top,
338 This->sv_rc.right - This->sv_rc.left, This->sv_rc.bottom - This->sv_rc.top,
339 TRUE);
342 static HRESULT change_viewmode(ExplorerBrowserImpl *This, UINT viewmode)
344 IFolderView *pfv;
345 HRESULT hr;
347 if(!This->psv)
348 return E_FAIL;
350 hr = IShellView_QueryInterface(This->psv, &IID_IFolderView, (void*)&pfv);
351 if(SUCCEEDED(hr))
353 hr = IFolderView_SetCurrentViewMode(pfv, This->fs.ViewMode);
354 IFolderView_Release(pfv);
357 return hr;
360 static HRESULT create_new_shellview(ExplorerBrowserImpl *This, IShellItem *psi)
362 IShellBrowser *psb = &This->IShellBrowser_iface;
363 IShellFolder *psf;
364 IShellView *psv;
365 HWND hwnd_new;
366 HRESULT hr;
368 TRACE("%p, %p\n", This, psi);
370 hr = IShellItem_BindToHandler(psi, NULL, &BHID_SFObject, &IID_IShellFolder, (void**)&psf);
371 if(SUCCEEDED(hr))
373 hr = IShellFolder_CreateViewObject(psf, This->hwnd_main, &IID_IShellView, (void**)&psv);
374 if(SUCCEEDED(hr))
376 if(This->hwnd_sv)
378 IShellView_DestroyViewWindow(This->psv);
379 This->hwnd_sv = NULL;
382 hr = IShellView_CreateViewWindow(psv, This->psv, &This->fs, psb, &This->sv_rc, &hwnd_new);
383 if(SUCCEEDED(hr))
385 /* Replace the old shellview */
386 if(This->psv) IShellView_Release(This->psv);
388 This->psv = psv;
389 This->hwnd_sv = hwnd_new;
390 events_ViewCreated(This, psv);
392 else
394 ERR("CreateViewWindow failed (0x%x)\n", hr);
395 IShellView_Release(psv);
398 else
399 ERR("CreateViewObject failed (0x%x)\n", hr);
401 IShellFolder_Release(psf);
403 else
404 ERR("SI::BindToHandler failed (0x%x)\n", hr);
406 return hr;
409 static void get_interfaces_from_site(ExplorerBrowserImpl *This)
411 IServiceProvider *psp;
412 HRESULT hr;
414 /* Calling this with This->punk_site set to NULL should properly
415 * release any previously fetched interfaces.
418 if(This->pcdb_site)
420 ICommDlgBrowser_Release(This->pcdb_site);
421 if(This->pcdb2_site) ICommDlgBrowser2_Release(This->pcdb2_site);
422 if(This->pcdb3_site) ICommDlgBrowser3_Release(This->pcdb3_site);
424 This->pcdb_site = NULL;
425 This->pcdb2_site = NULL;
426 This->pcdb3_site = NULL;
429 if(This->pepv_site)
431 IExplorerPaneVisibility_Release(This->pepv_site);
432 This->pepv_site = NULL;
435 if(!This->punk_site)
436 return;
438 hr = IUnknown_QueryInterface(This->punk_site, &IID_IServiceProvider, (void**)&psp);
439 if(FAILED(hr))
441 ERR("Failed to get IServiceProvider from site.\n");
442 return;
445 /* ICommDlgBrowser */
446 IServiceProvider_QueryService(psp, &SID_SExplorerBrowserFrame, &IID_ICommDlgBrowser,
447 (void**)&This->pcdb_site);
448 IServiceProvider_QueryService(psp, &SID_SExplorerBrowserFrame, &IID_ICommDlgBrowser2,
449 (void**)&This->pcdb2_site);
450 IServiceProvider_QueryService(psp, &SID_SExplorerBrowserFrame, &IID_ICommDlgBrowser3,
451 (void**)&This->pcdb3_site);
453 /* IExplorerPaneVisibility */
454 IServiceProvider_QueryService(psp, &SID_ExplorerPaneVisibility, &IID_IExplorerPaneVisibility,
455 (void**)&This->pepv_site);
457 IServiceProvider_Release(psp);
460 /**************************************************************************
461 * General pane functionality.
463 static void update_panestate(ExplorerBrowserImpl *This)
465 EXPLORERPANESTATE eps = EPS_DONTCARE;
466 BOOL show_navpane;
467 TRACE("%p\n", This);
469 if(!This->pepv_site) return;
471 IExplorerPaneVisibility_GetPaneState(This->pepv_site, (REFEXPLORERPANE) &EP_NavPane, &eps);
472 if( !(eps & EPS_DEFAULT_OFF) )
473 show_navpane = TRUE;
474 else
475 show_navpane = FALSE;
477 if(This->navpane.show != show_navpane)
479 update_layout(This);
480 size_panes(This);
483 This->navpane.show = show_navpane;
486 static void splitter_draw(HWND hwnd, RECT *rc)
488 HDC hdc = GetDC(hwnd);
489 InvertRect(hdc, rc);
490 ReleaseDC(hwnd, hdc);
493 /**************************************************************************
494 * The Navigation Pane.
496 static LRESULT navpane_splitter_beginresize(ExplorerBrowserImpl *This, HWND hwnd, LPARAM lParam)
498 TRACE("\n");
500 SetCapture(hwnd);
502 CopyRect(&This->splitter_rc, &This->navpane.rc);
503 This->splitter_rc.left = This->splitter_rc.right - SPLITTER_WIDTH;
505 splitter_draw(GetParent(hwnd), &This->splitter_rc);
507 return TRUE;
510 static LRESULT navpane_splitter_resizing(ExplorerBrowserImpl *This, HWND hwnd, LPARAM lParam)
512 int new_width, dx;
513 RECT rc;
515 if(GetCapture() != hwnd) return FALSE;
517 dx = (SHORT)LOWORD(lParam);
518 TRACE("%d.\n", dx);
520 CopyRect(&rc, &This->navpane.rc);
522 new_width = This->navpane.width + dx;
523 if(new_width > NP_MIN_WIDTH && This->sv_rc.right - new_width > SV_MIN_WIDTH)
525 rc.right = new_width;
526 rc.left = rc.right - SPLITTER_WIDTH;
527 splitter_draw(GetParent(hwnd), &This->splitter_rc);
528 splitter_draw(GetParent(hwnd), &rc);
529 CopyRect(&This->splitter_rc, &rc);
532 return TRUE;
535 static LRESULT navpane_splitter_endresize(ExplorerBrowserImpl *This, HWND hwnd, LPARAM lParam)
537 int new_width, dx;
539 if(GetCapture() != hwnd) return FALSE;
541 dx = (SHORT)LOWORD(lParam);
542 TRACE("%d.\n", dx);
544 splitter_draw(GetParent(hwnd), &This->splitter_rc);
546 new_width = This->navpane.width + dx;
547 if(new_width < NP_MIN_WIDTH)
548 new_width = NP_MIN_WIDTH;
549 else if(This->sv_rc.right - new_width < SV_MIN_WIDTH)
550 new_width = This->sv_rc.right - SV_MIN_WIDTH;
552 This->navpane.width = new_width;
554 update_layout(This);
555 size_panes(This);
557 ReleaseCapture();
559 return TRUE;
562 static LRESULT navpane_on_wm_create(HWND hwnd, CREATESTRUCTW *crs)
564 ExplorerBrowserImpl *This = crs->lpCreateParams;
565 INameSpaceTreeControl2 *pnstc2;
566 DWORD style;
567 HRESULT hr;
569 TRACE("%p\n", This);
570 SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LPARAM)This);
571 This->navpane.hwnd_splitter = hwnd;
573 hr = CoCreateInstance(&CLSID_NamespaceTreeControl, NULL, CLSCTX_INPROC_SERVER,
574 &IID_INameSpaceTreeControl2, (void**)&pnstc2);
576 if(SUCCEEDED(hr))
578 style = NSTCS_HASEXPANDOS | NSTCS_ROOTHASEXPANDO | NSTCS_SHOWSELECTIONALWAYS;
579 hr = INameSpaceTreeControl2_Initialize(pnstc2, GetParent(hwnd), NULL, style);
580 if(SUCCEEDED(hr))
582 INameSpaceTreeControlEvents *pnstce;
583 IShellFolder *psfdesktop;
584 IShellItem *psi;
585 IOleWindow *pow;
586 LPITEMIDLIST pidl;
587 DWORD cookie, style2 = NSTCS2_DISPLAYPADDING;
589 hr = INameSpaceTreeControl2_SetControlStyle2(pnstc2, 0xFF, style2);
590 if(FAILED(hr))
591 ERR("SetControlStyle2 failed (0x%08x)\n", hr);
593 hr = INameSpaceTreeControl2_QueryInterface(pnstc2, &IID_IOleWindow, (void**)&pow);
594 if(SUCCEEDED(hr))
596 IOleWindow_GetWindow(pow, &This->navpane.hwnd_nstc);
597 IOleWindow_Release(pow);
599 else
600 ERR("QueryInterface(IOleWindow) failed (0x%08x)\n", hr);
602 pnstce = &This->INameSpaceTreeControlEvents_iface;
603 hr = INameSpaceTreeControl2_TreeAdvise(pnstc2, (IUnknown*)pnstce, &cookie);
604 if(FAILED(hr))
605 ERR("TreeAdvise failed. (0x%08x).\n", hr);
608 * Add the default roots
611 /* TODO: This should be FOLDERID_Links */
612 hr = SHGetSpecialFolderLocation(NULL, CSIDL_FAVORITES, &pidl);
613 if(SUCCEEDED(hr))
615 hr = SHCreateShellItem(NULL, NULL, pidl, &psi);
616 if(SUCCEEDED(hr))
618 hr = INameSpaceTreeControl2_AppendRoot(pnstc2, psi, SHCONTF_NONFOLDERS, NSTCRS_VISIBLE, NULL);
619 IShellItem_Release(psi);
621 ILFree(pidl);
624 SHGetDesktopFolder(&psfdesktop);
625 hr = SHGetItemFromObject((IUnknown*)psfdesktop, &IID_IShellItem, (void**)&psi);
626 IShellFolder_Release(psfdesktop);
627 if(SUCCEEDED(hr))
629 hr = INameSpaceTreeControl2_AppendRoot(pnstc2, psi, SHCONTF_FOLDERS, NSTCRS_EXPANDED, NULL);
630 IShellItem_Release(psi);
633 /* TODO:
634 * We should advertise IID_INameSpaceTreeControl to the site of the
635 * host through its IProfferService interface, if any.
638 This->navpane.pnstc2 = pnstc2;
639 This->navpane.nstc_cookie = cookie;
641 return TRUE;
645 This->navpane.pnstc2 = NULL;
646 ERR("Failed (0x%08x)\n", hr);
648 return FALSE;
651 static LRESULT navpane_on_wm_size_move(ExplorerBrowserImpl *This)
653 UINT height, width;
654 TRACE("%p\n", This);
656 width = This->navpane.rc.right - This->navpane.rc.left - SPLITTER_WIDTH;
657 height = This->navpane.rc.bottom - This->navpane.rc.top;
659 MoveWindow(This->navpane.hwnd_nstc,
660 This->navpane.rc.left, This->navpane.rc.top,
661 width, height,
662 TRUE);
664 return FALSE;
667 static LRESULT navpane_on_wm_destroy(ExplorerBrowserImpl *This)
669 INameSpaceTreeControl2_TreeUnadvise(This->navpane.pnstc2, This->navpane.nstc_cookie);
670 INameSpaceTreeControl2_Release(This->navpane.pnstc2);
671 This->navpane.pnstc2 = NULL;
672 return TRUE;
675 static LRESULT CALLBACK navpane_wndproc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
677 ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
679 switch(uMessage) {
680 case WM_CREATE: return navpane_on_wm_create(hWnd, (CREATESTRUCTW*)lParam);
681 case WM_MOVE: /* Fall through */
682 case WM_SIZE: return navpane_on_wm_size_move(This);
683 case WM_DESTROY: return navpane_on_wm_destroy(This);
684 case WM_LBUTTONDOWN: return navpane_splitter_beginresize(This, hWnd, lParam);
685 case WM_MOUSEMOVE: return navpane_splitter_resizing(This, hWnd, lParam);
686 case WM_LBUTTONUP: return navpane_splitter_endresize(This, hWnd, lParam);
687 default:
688 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
690 return 0;
693 static void initialize_navpane(ExplorerBrowserImpl *This, HWND hwnd_parent, RECT *rc)
695 WNDCLASSW wc;
696 HWND splitter;
697 static const WCHAR navpane_classname[] = {'e','b','_','n','a','v','p','a','n','e',0};
699 if( !GetClassInfoW(shell32_hInstance, navpane_classname, &wc) )
701 wc.style = CS_HREDRAW | CS_VREDRAW;
702 wc.lpfnWndProc = navpane_wndproc;
703 wc.cbClsExtra = 0;
704 wc.cbWndExtra = 0;
705 wc.hInstance = shell32_hInstance;
706 wc.hIcon = 0;
707 wc.hCursor = LoadCursorW(0, (LPWSTR)IDC_SIZEWE);
708 wc.hbrBackground = (HBRUSH)(COLOR_HIGHLIGHT + 1);
709 wc.lpszMenuName = NULL;
710 wc.lpszClassName = navpane_classname;
712 if (!RegisterClassW(&wc)) return;
715 splitter = CreateWindowExW(0, navpane_classname, NULL,
716 WS_CHILD | WS_TABSTOP | WS_VISIBLE,
717 rc->right - SPLITTER_WIDTH, rc->top,
718 SPLITTER_WIDTH, rc->bottom - rc->top,
719 hwnd_parent, 0, shell32_hInstance, This);
720 if(!splitter)
721 ERR("Failed to create navpane : %d.\n", GetLastError());
724 /**************************************************************************
725 * Main window related functions.
727 static LRESULT main_on_wm_create(HWND hWnd, CREATESTRUCTW *crs)
729 ExplorerBrowserImpl *This = crs->lpCreateParams;
730 TRACE("%p\n", This);
732 SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LPARAM)This);
733 This->hwnd_main = hWnd;
735 return TRUE;
738 static LRESULT main_on_wm_size(ExplorerBrowserImpl *This)
740 update_layout(This);
741 size_panes(This);
743 return TRUE;
746 static LRESULT main_on_cwm_getishellbrowser(ExplorerBrowserImpl *This)
748 return (LRESULT)&This->IShellBrowser_iface;
751 static LRESULT CALLBACK main_wndproc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
753 ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
755 switch(uMessage)
757 case WM_CREATE: return main_on_wm_create(hWnd, (CREATESTRUCTW*)lParam);
758 case WM_SIZE: return main_on_wm_size(This);
759 case CWM_GETISHELLBROWSER: return main_on_cwm_getishellbrowser(This);
760 default: return DefWindowProcW(hWnd, uMessage, wParam, lParam);
763 return 0;
766 /**************************************************************************
767 * IExplorerBrowser Implementation
770 static inline ExplorerBrowserImpl *impl_from_IExplorerBrowser(IExplorerBrowser *iface)
772 return CONTAINING_RECORD(iface, ExplorerBrowserImpl, IExplorerBrowser_iface);
775 static HRESULT WINAPI IExplorerBrowser_fnQueryInterface(IExplorerBrowser *iface,
776 REFIID riid, void **ppvObject)
778 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
779 TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppvObject);
781 *ppvObject = NULL;
782 if(IsEqualIID(riid, &IID_IExplorerBrowser) ||
783 IsEqualIID(riid, &IID_IUnknown))
785 *ppvObject = &This->IExplorerBrowser_iface;
787 else if(IsEqualIID(riid, &IID_IShellBrowser))
789 *ppvObject = &This->IShellBrowser_iface;
791 else if(IsEqualIID(riid, &IID_ICommDlgBrowser) ||
792 IsEqualIID(riid, &IID_ICommDlgBrowser2) ||
793 IsEqualIID(riid, &IID_ICommDlgBrowser3))
795 *ppvObject = &This->ICommDlgBrowser3_iface;
797 else if(IsEqualIID(riid, &IID_IObjectWithSite))
799 *ppvObject = &This->IObjectWithSite_iface;
801 else if(IsEqualIID(riid, &IID_IInputObject))
803 *ppvObject = &This->IInputObject_iface;
806 if(*ppvObject)
808 IUnknown_AddRef((IUnknown*)*ppvObject);
809 return S_OK;
812 return E_NOINTERFACE;
815 static ULONG WINAPI IExplorerBrowser_fnAddRef(IExplorerBrowser *iface)
817 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
818 LONG ref = InterlockedIncrement(&This->ref);
819 TRACE("%p - ref %d\n", This, ref);
821 return ref;
824 static ULONG WINAPI IExplorerBrowser_fnRelease(IExplorerBrowser *iface)
826 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
827 LONG ref = InterlockedDecrement(&This->ref);
828 TRACE("%p - ref %d\n", This, ref);
830 if(!ref)
832 TRACE("Freeing.\n");
834 if(!This->destroyed)
835 IExplorerBrowser_Destroy(iface);
837 IObjectWithSite_SetSite(&This->IObjectWithSite_iface, NULL);
839 HeapFree(GetProcessHeap(), 0, This);
840 return 0;
843 return ref;
846 static HRESULT WINAPI IExplorerBrowser_fnInitialize(IExplorerBrowser *iface,
847 HWND hwndParent, const RECT *prc,
848 const FOLDERSETTINGS *pfs)
850 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
851 WNDCLASSW wc;
852 LONG style;
853 static const WCHAR EB_CLASS_NAME[] =
854 {'E','x','p','l','o','r','e','r','B','r','o','w','s','e','r','C','o','n','t','r','o','l',0};
856 TRACE("%p (%p, %p, %p)\n", This, hwndParent, prc, pfs);
858 if(This->hwnd_main)
859 return E_UNEXPECTED;
861 if(!hwndParent)
862 return E_INVALIDARG;
864 if( !GetClassInfoW(shell32_hInstance, EB_CLASS_NAME, &wc) )
866 wc.style = CS_HREDRAW | CS_VREDRAW;
867 wc.lpfnWndProc = main_wndproc;
868 wc.cbClsExtra = 0;
869 wc.cbWndExtra = 0;
870 wc.hInstance = shell32_hInstance;
871 wc.hIcon = 0;
872 wc.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW);
873 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
874 wc.lpszMenuName = NULL;
875 wc.lpszClassName = EB_CLASS_NAME;
877 if (!RegisterClassW(&wc)) return E_FAIL;
880 style = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_BORDER;
881 This->hwnd_main = CreateWindowExW(WS_EX_CONTROLPARENT, EB_CLASS_NAME, NULL, style,
882 prc->left, prc->top,
883 prc->right - prc->left, prc->bottom - prc->top,
884 hwndParent, 0, shell32_hInstance, This);
886 if(!This->hwnd_main)
888 ERR("Failed to create the window.\n");
889 return E_FAIL;
892 This->fs.ViewMode = pfs ? pfs->ViewMode : FVM_DETAILS;
893 This->fs.fFlags = pfs ? (pfs->fFlags | FWF_NOCLIENTEDGE) : FWF_NOCLIENTEDGE;
895 return S_OK;
898 static HRESULT WINAPI IExplorerBrowser_fnDestroy(IExplorerBrowser *iface)
900 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
901 TRACE("%p\n", This);
903 if(This->psv)
905 IShellView_DestroyViewWindow(This->psv);
906 IShellView_Release(This->psv);
907 This->psv = NULL;
908 This->hwnd_sv = NULL;
911 events_unadvise_all(This);
912 travellog_remove_all_entries(This);
914 ILFree(This->current_pidl);
915 This->current_pidl = NULL;
917 DestroyWindow(This->hwnd_main);
918 This->destroyed = TRUE;
920 return S_OK;
923 static HRESULT WINAPI IExplorerBrowser_fnSetRect(IExplorerBrowser *iface,
924 HDWP *phdwp, RECT rcBrowser)
926 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
927 TRACE("%p (%p, %s)\n", This, phdwp, wine_dbgstr_rect(&rcBrowser));
929 if(phdwp && *phdwp)
931 *phdwp = DeferWindowPos(*phdwp, This->hwnd_main, NULL, rcBrowser.left, rcBrowser.top,
932 rcBrowser.right - rcBrowser.left, rcBrowser.bottom - rcBrowser.top,
933 SWP_NOZORDER | SWP_NOACTIVATE);
934 if(!*phdwp)
935 return E_FAIL;
937 else
939 MoveWindow(This->hwnd_main, rcBrowser.left, rcBrowser.top,
940 rcBrowser.right - rcBrowser.left, rcBrowser.bottom - rcBrowser.top, TRUE);
943 return S_OK;
946 static HRESULT WINAPI IExplorerBrowser_fnSetPropertyBag(IExplorerBrowser *iface,
947 LPCWSTR pszPropertyBag)
949 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
950 FIXME("stub, %p (%s)\n", This, debugstr_w(pszPropertyBag));
952 if(!pszPropertyBag)
953 return E_INVALIDARG;
955 /* FIXME: This method is currently useless as we don't save any
956 * settings anywhere, but at least one application breaks if we
957 * return E_NOTIMPL.
960 return S_OK;
963 static HRESULT WINAPI IExplorerBrowser_fnSetEmptyText(IExplorerBrowser *iface,
964 LPCWSTR pszEmptyText)
966 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
967 FIXME("stub, %p (%s)\n", This, debugstr_w(pszEmptyText));
969 return E_NOTIMPL;
972 static HRESULT WINAPI IExplorerBrowser_fnSetFolderSettings(IExplorerBrowser *iface,
973 const FOLDERSETTINGS *pfs)
975 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
976 TRACE("%p (%p)\n", This, pfs);
978 if(!pfs)
979 return E_INVALIDARG;
981 This->fs.ViewMode = pfs->ViewMode;
982 This->fs.fFlags = pfs->fFlags | FWF_NOCLIENTEDGE;
984 /* Change the settings of the current view, if any. */
985 return change_viewmode(This, This->fs.ViewMode);
988 static HRESULT WINAPI IExplorerBrowser_fnAdvise(IExplorerBrowser *iface,
989 IExplorerBrowserEvents *psbe,
990 DWORD *pdwCookie)
992 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
993 event_client *client;
994 TRACE("%p (%p, %p)\n", This, psbe, pdwCookie);
996 client = HeapAlloc(GetProcessHeap(), 0, sizeof(event_client));
997 client->pebe = psbe;
998 client->cookie = ++This->events_next_cookie;
1000 IExplorerBrowserEvents_AddRef(psbe);
1001 *pdwCookie = client->cookie;
1003 list_add_tail(&This->event_clients, &client->entry);
1005 return S_OK;
1008 static HRESULT WINAPI IExplorerBrowser_fnUnadvise(IExplorerBrowser *iface,
1009 DWORD dwCookie)
1011 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1012 event_client *client;
1013 TRACE("%p (0x%x)\n", This, dwCookie);
1015 LIST_FOR_EACH_ENTRY(client, &This->event_clients, event_client, entry)
1017 if(client->cookie == dwCookie)
1019 list_remove(&client->entry);
1020 IExplorerBrowserEvents_Release(client->pebe);
1021 HeapFree(GetProcessHeap(), 0, client);
1022 return S_OK;
1026 return E_INVALIDARG;
1029 static HRESULT WINAPI IExplorerBrowser_fnSetOptions(IExplorerBrowser *iface,
1030 EXPLORER_BROWSER_OPTIONS dwFlag)
1032 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1033 static const EXPLORER_BROWSER_OPTIONS unsupported_options =
1034 EBO_ALWAYSNAVIGATE | EBO_NOWRAPPERWINDOW | EBO_HTMLSHAREPOINTVIEW;
1036 TRACE("%p (0x%x)\n", This, dwFlag);
1038 if(dwFlag & unsupported_options)
1039 FIXME("Flags 0x%08x contains unsupported options.\n", dwFlag);
1041 This->eb_options = dwFlag;
1043 return S_OK;
1046 static HRESULT WINAPI IExplorerBrowser_fnGetOptions(IExplorerBrowser *iface,
1047 EXPLORER_BROWSER_OPTIONS *pdwFlag)
1049 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1050 TRACE("%p (%p)\n", This, pdwFlag);
1052 *pdwFlag = This->eb_options;
1054 return S_OK;
1057 static HRESULT WINAPI IExplorerBrowser_fnBrowseToIDList(IExplorerBrowser *iface,
1058 PCUIDLIST_RELATIVE pidl,
1059 UINT uFlags)
1061 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1062 LPITEMIDLIST absolute_pidl = NULL;
1063 HRESULT hr;
1064 static const UINT unsupported_browse_flags =
1065 SBSP_NEWBROWSER | EBF_SELECTFROMDATAOBJECT | EBF_NODROPTARGET;
1066 TRACE("%p (%p, 0x%x)\n", This, pidl, uFlags);
1068 if(!This->hwnd_main)
1069 return E_FAIL;
1071 if(This->destroyed)
1072 return HRESULT_FROM_WIN32(ERROR_BUSY);
1074 if(This->current_pidl && (This->eb_options & EBO_NAVIGATEONCE))
1075 return E_FAIL;
1077 if(uFlags & SBSP_EXPLOREMODE)
1078 return E_INVALIDARG;
1080 if(uFlags & unsupported_browse_flags)
1081 FIXME("Argument 0x%x contains unsupported flags.\n", uFlags);
1083 if(uFlags & SBSP_NAVIGATEBACK)
1085 TRACE("SBSP_NAVIGATEBACK\n");
1086 absolute_pidl = ILClone(travellog_go_back(This));
1087 if(!absolute_pidl && !This->current_pidl)
1088 return E_FAIL;
1089 else if(!absolute_pidl)
1090 return S_OK;
1093 else if(uFlags & SBSP_NAVIGATEFORWARD)
1095 TRACE("SBSP_NAVIGATEFORWARD\n");
1096 absolute_pidl = ILClone(travellog_go_forward(This));
1097 if(!absolute_pidl && !This->current_pidl)
1098 return E_FAIL;
1099 else if(!absolute_pidl)
1100 return S_OK;
1103 else if(uFlags & SBSP_PARENT)
1105 if(This->current_pidl)
1107 if(_ILIsPidlSimple(This->current_pidl))
1109 absolute_pidl = _ILCreateDesktop();
1111 else
1113 absolute_pidl = ILClone(This->current_pidl);
1114 ILRemoveLastID(absolute_pidl);
1117 if(!absolute_pidl)
1119 ERR("Failed to get parent pidl.\n");
1120 return E_FAIL;
1124 else if(uFlags & SBSP_RELATIVE)
1126 /* SBSP_RELATIVE has precedence over SBSP_ABSOLUTE */
1127 TRACE("SBSP_RELATIVE\n");
1128 if(This->current_pidl)
1130 absolute_pidl = ILCombine(This->current_pidl, pidl);
1132 if(!absolute_pidl)
1134 ERR("Failed to get absolute pidl.\n");
1135 return E_FAIL;
1138 else
1140 TRACE("SBSP_ABSOLUTE\n");
1141 absolute_pidl = ILClone(pidl);
1142 if(!absolute_pidl && !This->current_pidl)
1143 return E_INVALIDARG;
1144 else if(!absolute_pidl)
1145 return S_OK;
1148 /* TODO: Asynchronous browsing. Return S_OK here and finish in
1149 * another thread. */
1151 hr = events_NavigationPending(This, absolute_pidl);
1152 if(FAILED(hr))
1154 TRACE("Browsing aborted.\n");
1155 ILFree(absolute_pidl);
1156 return E_FAIL;
1159 get_interfaces_from_site(This);
1160 update_panestate(This);
1162 /* Only browse if the new pidl differs from the old */
1163 if(!ILIsEqual(This->current_pidl, absolute_pidl))
1165 IShellItem *psi;
1166 hr = SHCreateItemFromIDList(absolute_pidl, &IID_IShellItem, (void**)&psi);
1167 if(SUCCEEDED(hr))
1169 hr = create_new_shellview(This, psi);
1170 if(FAILED(hr))
1172 events_NavigationFailed(This, absolute_pidl);
1173 ILFree(absolute_pidl);
1174 IShellItem_Release(psi);
1175 return E_FAIL;
1178 /* Add to travellog */
1179 if( !(This->eb_options & EBO_NOTRAVELLOG) &&
1180 !(uFlags & (SBSP_NAVIGATEFORWARD|SBSP_NAVIGATEBACK)) )
1182 travellog_add_entry(This, absolute_pidl);
1185 IShellItem_Release(psi);
1189 events_NavigationComplete(This, absolute_pidl);
1190 ILFree(This->current_pidl);
1191 This->current_pidl = absolute_pidl;
1193 /* Expand the NameSpaceTree to the current location. */
1194 if(This->navpane.show && This->navpane.pnstc2)
1196 IShellItem *psi;
1197 hr = SHCreateItemFromIDList(This->current_pidl, &IID_IShellItem, (void**)&psi);
1198 if(SUCCEEDED(hr))
1200 INameSpaceTreeControl2_EnsureItemVisible(This->navpane.pnstc2, psi);
1201 IShellItem_Release(psi);
1205 return S_OK;
1208 static HRESULT WINAPI IExplorerBrowser_fnBrowseToObject(IExplorerBrowser *iface,
1209 IUnknown *punk, UINT uFlags)
1211 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1212 LPITEMIDLIST pidl;
1213 HRESULT hr;
1214 TRACE("%p (%p, 0x%x)\n", This, punk, uFlags);
1216 if(!punk)
1217 return IExplorerBrowser_BrowseToIDList(iface, NULL, uFlags);
1219 hr = SHGetIDListFromObject(punk, &pidl);
1220 if(SUCCEEDED(hr))
1222 hr = IExplorerBrowser_BrowseToIDList(iface, pidl, uFlags);
1223 ILFree(pidl);
1226 return hr;
1229 static HRESULT WINAPI IExplorerBrowser_fnFillFromObject(IExplorerBrowser *iface,
1230 IUnknown *punk,
1231 EXPLORER_BROWSER_FILL_FLAGS dwFlags)
1233 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1234 FIXME("stub, %p (%p, 0x%x)\n", This, punk, dwFlags);
1236 return E_NOTIMPL;
1239 static HRESULT WINAPI IExplorerBrowser_fnRemoveAll(IExplorerBrowser *iface)
1241 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1242 FIXME("stub, %p\n", This);
1244 return E_NOTIMPL;
1247 static HRESULT WINAPI IExplorerBrowser_fnGetCurrentView(IExplorerBrowser *iface,
1248 REFIID riid, void **ppv)
1250 ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
1251 TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppv);
1253 if(!This->psv)
1254 return E_FAIL;
1256 return IShellView_QueryInterface(This->psv, riid, ppv);
1259 static const IExplorerBrowserVtbl vt_IExplorerBrowser =
1261 IExplorerBrowser_fnQueryInterface,
1262 IExplorerBrowser_fnAddRef,
1263 IExplorerBrowser_fnRelease,
1264 IExplorerBrowser_fnInitialize,
1265 IExplorerBrowser_fnDestroy,
1266 IExplorerBrowser_fnSetRect,
1267 IExplorerBrowser_fnSetPropertyBag,
1268 IExplorerBrowser_fnSetEmptyText,
1269 IExplorerBrowser_fnSetFolderSettings,
1270 IExplorerBrowser_fnAdvise,
1271 IExplorerBrowser_fnUnadvise,
1272 IExplorerBrowser_fnSetOptions,
1273 IExplorerBrowser_fnGetOptions,
1274 IExplorerBrowser_fnBrowseToIDList,
1275 IExplorerBrowser_fnBrowseToObject,
1276 IExplorerBrowser_fnFillFromObject,
1277 IExplorerBrowser_fnRemoveAll,
1278 IExplorerBrowser_fnGetCurrentView
1281 /**************************************************************************
1282 * IShellBrowser Implementation
1285 static inline ExplorerBrowserImpl *impl_from_IShellBrowser(IShellBrowser *iface)
1287 return CONTAINING_RECORD(iface, ExplorerBrowserImpl, IShellBrowser_iface);
1290 static HRESULT WINAPI IShellBrowser_fnQueryInterface(IShellBrowser *iface,
1291 REFIID riid, void **ppvObject)
1293 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1294 TRACE("%p\n", This);
1295 return IExplorerBrowser_QueryInterface(&This->IExplorerBrowser_iface, riid, ppvObject);
1298 static ULONG WINAPI IShellBrowser_fnAddRef(IShellBrowser *iface)
1300 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1301 TRACE("%p\n", This);
1302 return IExplorerBrowser_AddRef(&This->IExplorerBrowser_iface);
1305 static ULONG WINAPI IShellBrowser_fnRelease(IShellBrowser *iface)
1307 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1308 TRACE("%p\n", This);
1309 return IExplorerBrowser_Release(&This->IExplorerBrowser_iface);
1312 static HRESULT WINAPI IShellBrowser_fnGetWindow(IShellBrowser *iface, HWND *phwnd)
1314 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1315 TRACE("%p (%p)\n", This, phwnd);
1317 if(!This->hwnd_main)
1318 return E_FAIL;
1320 *phwnd = This->hwnd_main;
1321 return S_OK;
1324 static HRESULT WINAPI IShellBrowser_fnContextSensitiveHelp(IShellBrowser *iface,
1325 BOOL fEnterMode)
1327 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1328 FIXME("stub, %p (%d)\n", This, fEnterMode);
1330 return E_NOTIMPL;
1333 static HRESULT WINAPI IShellBrowser_fnInsertMenusSB(IShellBrowser *iface,
1334 HMENU hmenuShared,
1335 LPOLEMENUGROUPWIDTHS lpMenuWidths)
1337 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1338 TRACE("%p (%p, %p)\n", This, hmenuShared, lpMenuWidths);
1340 /* Not implemented. */
1341 return E_NOTIMPL;
1344 static HRESULT WINAPI IShellBrowser_fnSetMenuSB(IShellBrowser *iface,
1345 HMENU hmenuShared,
1346 HOLEMENU holemenuReserved,
1347 HWND hwndActiveObject)
1349 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1350 TRACE("%p (%p, %p, %p)\n", This, hmenuShared, holemenuReserved, hwndActiveObject);
1352 /* Not implemented. */
1353 return E_NOTIMPL;
1356 static HRESULT WINAPI IShellBrowser_fnRemoveMenusSB(IShellBrowser *iface,
1357 HMENU hmenuShared)
1359 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1360 TRACE("%p (%p)\n", This, hmenuShared);
1362 /* Not implemented. */
1363 return E_NOTIMPL;
1366 static HRESULT WINAPI IShellBrowser_fnSetStatusTextSB(IShellBrowser *iface,
1367 LPCOLESTR pszStatusText)
1369 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1370 FIXME("stub, %p (%s)\n", This, debugstr_w(pszStatusText));
1372 return E_NOTIMPL;
1375 static HRESULT WINAPI IShellBrowser_fnEnableModelessSB(IShellBrowser *iface,
1376 BOOL fEnable)
1378 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1379 FIXME("stub, %p (%d)\n", This, fEnable);
1381 return E_NOTIMPL;
1384 static HRESULT WINAPI IShellBrowser_fnTranslateAcceleratorSB(IShellBrowser *iface,
1385 MSG *pmsg, WORD wID)
1387 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1388 FIXME("stub, %p (%p, 0x%x)\n", This, pmsg, wID);
1390 return E_NOTIMPL;
1393 static HRESULT WINAPI IShellBrowser_fnBrowseObject(IShellBrowser *iface,
1394 LPCITEMIDLIST pidl, UINT wFlags)
1396 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1397 TRACE("%p (%p, %x)\n", This, pidl, wFlags);
1399 return IExplorerBrowser_BrowseToIDList(&This->IExplorerBrowser_iface, pidl, wFlags);
1402 static HRESULT WINAPI IShellBrowser_fnGetViewStateStream(IShellBrowser *iface,
1403 DWORD grfMode,
1404 IStream **ppStrm)
1406 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1407 FIXME("stub, %p (0x%x, %p)\n", This, grfMode, ppStrm);
1409 *ppStrm = NULL;
1410 return E_FAIL;
1413 static HRESULT WINAPI IShellBrowser_fnGetControlWindow(IShellBrowser *iface,
1414 UINT id, HWND *phwnd)
1416 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1417 TRACE("(%p)->(%d, %p)\n", This, id, phwnd);
1418 if (phwnd) *phwnd = NULL;
1419 return E_NOTIMPL;
1422 static HRESULT WINAPI IShellBrowser_fnSendControlMsg(IShellBrowser *iface,
1423 UINT id, UINT uMsg,
1424 WPARAM wParam, LPARAM lParam,
1425 LRESULT *pret)
1427 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1428 FIXME("stub, %p (%d, %d, %lx, %lx, %p)\n", This, id, uMsg, wParam, lParam, pret);
1430 return E_NOTIMPL;
1433 static HRESULT WINAPI IShellBrowser_fnQueryActiveShellView(IShellBrowser *iface,
1434 IShellView **ppshv)
1436 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1437 TRACE("%p (%p)\n", This, ppshv);
1439 if(!This->psv)
1440 return E_FAIL;
1442 *ppshv = This->psv;
1443 IShellView_AddRef(This->psv);
1445 return S_OK;
1448 static HRESULT WINAPI IShellBrowser_fnOnViewWindowActive(IShellBrowser *iface,
1449 IShellView *pshv)
1451 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1452 FIXME("stub, %p (%p)\n", This, pshv);
1454 return E_NOTIMPL;
1457 static HRESULT WINAPI IShellBrowser_fnSetToolbarItems(IShellBrowser *iface,
1458 LPTBBUTTONSB lpButtons,
1459 UINT nButtons, UINT uFlags)
1461 ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1462 FIXME("stub, %p (%p, %d, 0x%x)\n", This, lpButtons, nButtons, uFlags);
1464 return E_NOTIMPL;
1467 static const IShellBrowserVtbl vt_IShellBrowser = {
1468 IShellBrowser_fnQueryInterface,
1469 IShellBrowser_fnAddRef,
1470 IShellBrowser_fnRelease,
1471 IShellBrowser_fnGetWindow,
1472 IShellBrowser_fnContextSensitiveHelp,
1473 IShellBrowser_fnInsertMenusSB,
1474 IShellBrowser_fnSetMenuSB,
1475 IShellBrowser_fnRemoveMenusSB,
1476 IShellBrowser_fnSetStatusTextSB,
1477 IShellBrowser_fnEnableModelessSB,
1478 IShellBrowser_fnTranslateAcceleratorSB,
1479 IShellBrowser_fnBrowseObject,
1480 IShellBrowser_fnGetViewStateStream,
1481 IShellBrowser_fnGetControlWindow,
1482 IShellBrowser_fnSendControlMsg,
1483 IShellBrowser_fnQueryActiveShellView,
1484 IShellBrowser_fnOnViewWindowActive,
1485 IShellBrowser_fnSetToolbarItems
1488 /**************************************************************************
1489 * ICommDlgBrowser3 Implementation
1492 static inline ExplorerBrowserImpl *impl_from_ICommDlgBrowser3(ICommDlgBrowser3 *iface)
1494 return CONTAINING_RECORD(iface, ExplorerBrowserImpl, ICommDlgBrowser3_iface);
1497 static HRESULT WINAPI ICommDlgBrowser3_fnQueryInterface(ICommDlgBrowser3 *iface,
1498 REFIID riid,
1499 void **ppvObject)
1501 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1502 TRACE("%p\n", This);
1503 return IExplorerBrowser_QueryInterface(&This->IExplorerBrowser_iface, riid, ppvObject);
1506 static ULONG WINAPI ICommDlgBrowser3_fnAddRef(ICommDlgBrowser3 *iface)
1508 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1509 TRACE("%p\n", This);
1510 return IExplorerBrowser_AddRef(&This->IExplorerBrowser_iface);
1513 static ULONG WINAPI ICommDlgBrowser3_fnRelease(ICommDlgBrowser3 *iface)
1515 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1516 TRACE("%p\n", This);
1517 return IExplorerBrowser_Release(&This->IExplorerBrowser_iface);
1520 static HRESULT WINAPI ICommDlgBrowser3_fnOnDefaultCommand(ICommDlgBrowser3 *iface,
1521 IShellView *shv)
1523 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1524 IDataObject *pdo;
1525 HRESULT hr;
1526 HRESULT ret = S_FALSE;
1528 TRACE("%p (%p)\n", This, shv);
1530 hr = IShellView_GetItemObject(shv, SVGIO_SELECTION, &IID_IDataObject, (void**)&pdo);
1531 if(SUCCEEDED(hr))
1533 FORMATETC fmt;
1534 STGMEDIUM medium;
1536 fmt.cfFormat = RegisterClipboardFormatW(CFSTR_SHELLIDLISTW);
1537 fmt.ptd = NULL;
1538 fmt.dwAspect = DVASPECT_CONTENT;
1539 fmt.lindex = -1;
1540 fmt.tymed = TYMED_HGLOBAL;
1542 hr = IDataObject_GetData(pdo, &fmt ,&medium);
1543 IDataObject_Release(pdo);
1544 if(SUCCEEDED(hr))
1546 LPIDA pida = GlobalLock(medium.u.hGlobal);
1547 LPCITEMIDLIST pidl_child = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[1]);
1549 /* Handle folders by browsing to them. */
1550 if(_ILIsFolder(pidl_child) || _ILIsDrive(pidl_child) || _ILIsSpecialFolder(pidl_child))
1552 IExplorerBrowser_BrowseToIDList(&This->IExplorerBrowser_iface, pidl_child, SBSP_RELATIVE);
1553 ret = S_OK;
1555 GlobalUnlock(medium.u.hGlobal);
1556 GlobalFree(medium.u.hGlobal);
1558 else
1559 ERR("Failed to get data from IDataObject.\n");
1560 } else
1561 ERR("Failed to get IDataObject.\n");
1563 /* If we didn't handle the default command, check if we have a
1564 * client that does */
1565 if(ret == S_FALSE && This->pcdb_site)
1566 return ICommDlgBrowser_OnDefaultCommand(This->pcdb_site, shv);
1568 return ret;
1570 static HRESULT WINAPI ICommDlgBrowser3_fnOnStateChange(ICommDlgBrowser3 *iface,
1571 IShellView *shv, ULONG uChange)
1573 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1574 TRACE("%p (%p, %d)\n", This, shv, uChange);
1576 if(This->pcdb_site)
1577 return ICommDlgBrowser_OnStateChange(This->pcdb_site, shv, uChange);
1579 return E_NOTIMPL;
1581 static HRESULT WINAPI ICommDlgBrowser3_fnIncludeObject(ICommDlgBrowser3 *iface,
1582 IShellView *pshv, LPCITEMIDLIST pidl)
1584 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1585 TRACE("%p (%p, %p)\n", This, pshv, pidl);
1587 if(This->pcdb_site)
1588 return ICommDlgBrowser_IncludeObject(This->pcdb_site, pshv, pidl);
1590 return S_OK;
1593 static HRESULT WINAPI ICommDlgBrowser3_fnNotify(ICommDlgBrowser3 *iface,
1594 IShellView *pshv,
1595 DWORD dwNotifyType)
1597 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1598 TRACE("%p (%p, 0x%x)\n", This, pshv, dwNotifyType);
1600 if(This->pcdb2_site)
1601 return ICommDlgBrowser2_Notify(This->pcdb2_site, pshv, dwNotifyType);
1603 return S_OK;
1606 static HRESULT WINAPI ICommDlgBrowser3_fnGetDefaultMenuText(ICommDlgBrowser3 *iface,
1607 IShellView *pshv,
1608 LPWSTR pszText, int cchMax)
1610 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1611 TRACE("%p (%p, %s, %d)\n", This, pshv, debugstr_w(pszText), cchMax);
1613 if(This->pcdb2_site)
1614 return ICommDlgBrowser2_GetDefaultMenuText(This->pcdb2_site, pshv, pszText, cchMax);
1616 return S_OK;
1619 static HRESULT WINAPI ICommDlgBrowser3_fnGetViewFlags(ICommDlgBrowser3 *iface,
1620 DWORD *pdwFlags)
1622 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1623 TRACE("%p (%p)\n", This, pdwFlags);
1625 if(This->pcdb2_site)
1626 return ICommDlgBrowser2_GetViewFlags(This->pcdb2_site, pdwFlags);
1628 return S_OK;
1631 static HRESULT WINAPI ICommDlgBrowser3_fnOnColumnClicked(ICommDlgBrowser3 *iface,
1632 IShellView *pshv, int iColumn)
1634 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1635 TRACE("%p (%p, %d)\n", This, pshv, iColumn);
1637 if(This->pcdb3_site)
1638 return ICommDlgBrowser3_OnColumnClicked(This->pcdb3_site, pshv, iColumn);
1640 return S_OK;
1643 static HRESULT WINAPI ICommDlgBrowser3_fnGetCurrentFilter(ICommDlgBrowser3 *iface,
1644 LPWSTR pszFileSpec,
1645 int cchFileSpec)
1647 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1648 TRACE("%p (%s, %d)\n", This, debugstr_w(pszFileSpec), cchFileSpec);
1650 if(This->pcdb3_site)
1651 return ICommDlgBrowser3_GetCurrentFilter(This->pcdb3_site, pszFileSpec, cchFileSpec);
1653 return S_OK;
1656 static HRESULT WINAPI ICommDlgBrowser3_fnOnPreviewCreated(ICommDlgBrowser3 *iface,
1657 IShellView *pshv)
1659 ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1660 TRACE("%p (%p)\n", This, pshv);
1662 if(This->pcdb3_site)
1663 return ICommDlgBrowser3_OnPreviewCreated(This->pcdb3_site, pshv);
1665 return S_OK;
1668 static const ICommDlgBrowser3Vtbl vt_ICommDlgBrowser3 = {
1669 ICommDlgBrowser3_fnQueryInterface,
1670 ICommDlgBrowser3_fnAddRef,
1671 ICommDlgBrowser3_fnRelease,
1672 ICommDlgBrowser3_fnOnDefaultCommand,
1673 ICommDlgBrowser3_fnOnStateChange,
1674 ICommDlgBrowser3_fnIncludeObject,
1675 ICommDlgBrowser3_fnNotify,
1676 ICommDlgBrowser3_fnGetDefaultMenuText,
1677 ICommDlgBrowser3_fnGetViewFlags,
1678 ICommDlgBrowser3_fnOnColumnClicked,
1679 ICommDlgBrowser3_fnGetCurrentFilter,
1680 ICommDlgBrowser3_fnOnPreviewCreated
1683 /**************************************************************************
1684 * IObjectWithSite Implementation
1687 static inline ExplorerBrowserImpl *impl_from_IObjectWithSite(IObjectWithSite *iface)
1689 return CONTAINING_RECORD(iface, ExplorerBrowserImpl, IObjectWithSite_iface);
1692 static HRESULT WINAPI IObjectWithSite_fnQueryInterface(IObjectWithSite *iface,
1693 REFIID riid, void **ppvObject)
1695 ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
1696 TRACE("%p\n", This);
1697 return IExplorerBrowser_QueryInterface(&This->IExplorerBrowser_iface, riid, ppvObject);
1700 static ULONG WINAPI IObjectWithSite_fnAddRef(IObjectWithSite *iface)
1702 ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
1703 TRACE("%p\n", This);
1704 return IExplorerBrowser_AddRef(&This->IExplorerBrowser_iface);
1707 static ULONG WINAPI IObjectWithSite_fnRelease(IObjectWithSite *iface)
1709 ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
1710 TRACE("%p\n", This);
1711 return IExplorerBrowser_Release(&This->IExplorerBrowser_iface);
1714 static HRESULT WINAPI IObjectWithSite_fnSetSite(IObjectWithSite *iface, IUnknown *punk_site)
1716 ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
1717 TRACE("%p (%p)\n", This, punk_site);
1719 if(This->punk_site)
1721 IUnknown_Release(This->punk_site);
1722 This->punk_site = NULL;
1723 get_interfaces_from_site(This);
1726 This->punk_site = punk_site;
1728 if(This->punk_site)
1729 IUnknown_AddRef(This->punk_site);
1731 return S_OK;
1734 static HRESULT WINAPI IObjectWithSite_fnGetSite(IObjectWithSite *iface, REFIID riid, void **ppvSite)
1736 ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
1737 TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppvSite);
1739 if(!This->punk_site)
1740 return E_FAIL;
1742 return IUnknown_QueryInterface(This->punk_site, riid, ppvSite);
1745 static const IObjectWithSiteVtbl vt_IObjectWithSite = {
1746 IObjectWithSite_fnQueryInterface,
1747 IObjectWithSite_fnAddRef,
1748 IObjectWithSite_fnRelease,
1749 IObjectWithSite_fnSetSite,
1750 IObjectWithSite_fnGetSite
1753 /**************************************************************************
1754 * INameSpaceTreeControlEvents Implementation
1756 static inline ExplorerBrowserImpl *impl_from_INameSpaceTreeControlEvents(INameSpaceTreeControlEvents *iface)
1758 return CONTAINING_RECORD(iface, ExplorerBrowserImpl, INameSpaceTreeControlEvents_iface);
1761 static HRESULT WINAPI NSTCEvents_fnQueryInterface(INameSpaceTreeControlEvents *iface,
1762 REFIID riid, void **ppvObject)
1764 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1765 TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppvObject);
1767 *ppvObject = NULL;
1768 if(IsEqualIID(riid, &IID_INameSpaceTreeControlEvents) ||
1769 IsEqualIID(riid, &IID_IUnknown))
1771 *ppvObject = iface;
1774 if(*ppvObject)
1776 IUnknown_AddRef((IUnknown*)*ppvObject);
1777 return S_OK;
1780 return E_NOINTERFACE;
1783 static ULONG WINAPI NSTCEvents_fnAddRef(INameSpaceTreeControlEvents *iface)
1785 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1786 TRACE("%p\n", This);
1787 return IExplorerBrowser_AddRef(&This->IExplorerBrowser_iface);
1790 static ULONG WINAPI NSTCEvents_fnRelease(INameSpaceTreeControlEvents *iface)
1792 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1793 TRACE("%p\n", This);
1794 return IExplorerBrowser_Release(&This->IExplorerBrowser_iface);
1797 static HRESULT WINAPI NSTCEvents_fnOnItemClick(INameSpaceTreeControlEvents *iface,
1798 IShellItem *psi,
1799 NSTCEHITTEST nstceHitTest,
1800 NSTCECLICKTYPE nstceClickType)
1802 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1803 TRACE("%p (%p, 0x%x, 0x%x)\n", This, psi, nstceHitTest, nstceClickType);
1804 return S_OK;
1807 static HRESULT WINAPI NSTCEvents_fnOnPropertyItemCommit(INameSpaceTreeControlEvents *iface,
1808 IShellItem *psi)
1810 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1811 TRACE("%p (%p)\n", This, psi);
1812 return E_NOTIMPL;
1815 static HRESULT WINAPI NSTCEvents_fnOnItemStateChanging(INameSpaceTreeControlEvents *iface,
1816 IShellItem *psi,
1817 NSTCITEMSTATE nstcisMask,
1818 NSTCITEMSTATE nstcisState)
1820 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1821 TRACE("%p (%p, 0x%x, 0x%x)\n", This, psi, nstcisMask, nstcisState);
1822 return E_NOTIMPL;
1825 static HRESULT WINAPI NSTCEvents_fnOnItemStateChanged(INameSpaceTreeControlEvents *iface,
1826 IShellItem *psi,
1827 NSTCITEMSTATE nstcisMask,
1828 NSTCITEMSTATE nstcisState)
1830 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1831 TRACE("%p (%p, 0x%x, 0x%x)\n", This, psi, nstcisMask, nstcisState);
1832 return E_NOTIMPL;
1835 static HRESULT WINAPI NSTCEvents_fnOnSelectionChanged(INameSpaceTreeControlEvents *iface,
1836 IShellItemArray *psiaSelection)
1838 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1839 IShellItem *psi;
1840 HRESULT hr;
1841 TRACE("%p (%p)\n", This, psiaSelection);
1843 hr = IShellItemArray_GetItemAt(psiaSelection, 0, &psi);
1844 if(SUCCEEDED(hr))
1846 hr = IExplorerBrowser_BrowseToObject(&This->IExplorerBrowser_iface,
1847 (IUnknown*)psi, SBSP_DEFBROWSER);
1848 IShellItem_Release(psi);
1851 return hr;
1854 static HRESULT WINAPI NSTCEvents_fnOnKeyboardInput(INameSpaceTreeControlEvents *iface,
1855 UINT uMsg, WPARAM wParam, LPARAM lParam)
1857 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1858 TRACE("%p (%d, 0x%lx, 0x%lx)\n", This, uMsg, wParam, lParam);
1859 return S_OK;
1862 static HRESULT WINAPI NSTCEvents_fnOnBeforeExpand(INameSpaceTreeControlEvents *iface,
1863 IShellItem *psi)
1865 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1866 TRACE("%p (%p)\n", This, psi);
1867 return E_NOTIMPL;
1870 static HRESULT WINAPI NSTCEvents_fnOnAfterExpand(INameSpaceTreeControlEvents *iface,
1871 IShellItem *psi)
1873 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1874 TRACE("%p (%p)\n", This, psi);
1875 return E_NOTIMPL;
1878 static HRESULT WINAPI NSTCEvents_fnOnBeginLabelEdit(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_fnOnEndLabelEdit(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_fnOnGetToolTip(INameSpaceTreeControlEvents *iface,
1895 IShellItem *psi, LPWSTR pszTip, int cchTip)
1897 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1898 TRACE("%p (%p, %p, %d)\n", This, psi, pszTip, cchTip);
1899 return E_NOTIMPL;
1902 static HRESULT WINAPI NSTCEvents_fnOnBeforeItemDelete(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_fnOnItemAdded(INameSpaceTreeControlEvents *iface,
1911 IShellItem *psi, BOOL fIsRoot)
1913 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1914 TRACE("%p (%p, %d)\n", This, psi, fIsRoot);
1915 return E_NOTIMPL;
1918 static HRESULT WINAPI NSTCEvents_fnOnItemDeleted(INameSpaceTreeControlEvents *iface,
1919 IShellItem *psi, BOOL fIsRoot)
1921 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1922 TRACE("%p (%p, %d)\n", This, psi, fIsRoot);
1923 return E_NOTIMPL;
1926 static HRESULT WINAPI NSTCEvents_fnOnBeforeContextMenu(INameSpaceTreeControlEvents *iface,
1927 IShellItem *psi, REFIID riid, void **ppv)
1929 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1930 TRACE("%p (%p, %s, %p)\n", This, psi, shdebugstr_guid(riid), ppv);
1931 return E_NOTIMPL;
1934 static HRESULT WINAPI NSTCEvents_fnOnAfterContextMenu(INameSpaceTreeControlEvents *iface,
1935 IShellItem *psi, IContextMenu *pcmIn,
1936 REFIID riid, void **ppv)
1938 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1939 TRACE("%p (%p, %p, %s, %p)\n", This, psi, pcmIn, shdebugstr_guid(riid), ppv);
1940 return E_NOTIMPL;
1943 static HRESULT WINAPI NSTCEvents_fnOnBeforeStateImageChange(INameSpaceTreeControlEvents *iface,
1944 IShellItem *psi)
1946 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1947 TRACE("%p (%p)\n", This, psi);
1948 return E_NOTIMPL;
1951 static HRESULT WINAPI NSTCEvents_fnOnGetDefaultIconIndex(INameSpaceTreeControlEvents* iface,
1952 IShellItem *psi,
1953 int *piDefaultIcon, int *piOpenIcon)
1955 ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1956 TRACE("%p (%p, %p, %p)\n", This, psi, piDefaultIcon, piOpenIcon);
1957 return E_NOTIMPL;
1961 static const INameSpaceTreeControlEventsVtbl vt_INameSpaceTreeControlEvents = {
1962 NSTCEvents_fnQueryInterface,
1963 NSTCEvents_fnAddRef,
1964 NSTCEvents_fnRelease,
1965 NSTCEvents_fnOnItemClick,
1966 NSTCEvents_fnOnPropertyItemCommit,
1967 NSTCEvents_fnOnItemStateChanging,
1968 NSTCEvents_fnOnItemStateChanged,
1969 NSTCEvents_fnOnSelectionChanged,
1970 NSTCEvents_fnOnKeyboardInput,
1971 NSTCEvents_fnOnBeforeExpand,
1972 NSTCEvents_fnOnAfterExpand,
1973 NSTCEvents_fnOnBeginLabelEdit,
1974 NSTCEvents_fnOnEndLabelEdit,
1975 NSTCEvents_fnOnGetToolTip,
1976 NSTCEvents_fnOnBeforeItemDelete,
1977 NSTCEvents_fnOnItemAdded,
1978 NSTCEvents_fnOnItemDeleted,
1979 NSTCEvents_fnOnBeforeContextMenu,
1980 NSTCEvents_fnOnAfterContextMenu,
1981 NSTCEvents_fnOnBeforeStateImageChange,
1982 NSTCEvents_fnOnGetDefaultIconIndex
1985 /**************************************************************************
1986 * IInputObject Implementation
1989 static inline ExplorerBrowserImpl *impl_from_IInputObject(IInputObject *iface)
1991 return CONTAINING_RECORD(iface, ExplorerBrowserImpl, IInputObject_iface);
1994 static HRESULT WINAPI IInputObject_fnQueryInterface(IInputObject *iface,
1995 REFIID riid, void **ppvObject)
1997 ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
1998 TRACE("%p\n", This);
1999 return IExplorerBrowser_QueryInterface(&This->IExplorerBrowser_iface, riid, ppvObject);
2002 static ULONG WINAPI IInputObject_fnAddRef(IInputObject *iface)
2004 ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
2005 TRACE("%p\n", This);
2006 return IExplorerBrowser_AddRef(&This->IExplorerBrowser_iface);
2009 static ULONG WINAPI IInputObject_fnRelease(IInputObject *iface)
2011 ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
2012 TRACE("%p\n", This);
2013 return IExplorerBrowser_Release(&This->IExplorerBrowser_iface);
2016 static HRESULT WINAPI IInputObject_fnUIActivateIO(IInputObject *iface, BOOL fActivate, MSG *pMsg)
2018 ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
2019 FIXME("stub, %p (%d, %p)\n", This, fActivate, pMsg);
2020 return E_NOTIMPL;
2023 static HRESULT WINAPI IInputObject_fnHasFocusIO(IInputObject *iface)
2025 ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
2026 FIXME("stub, %p\n", This);
2027 return E_NOTIMPL;
2030 static HRESULT WINAPI IInputObject_fnTranslateAcceleratorIO(IInputObject *iface, MSG *pMsg)
2032 ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
2033 FIXME("stub, %p (%p)\n", This, pMsg);
2034 return E_NOTIMPL;
2037 static IInputObjectVtbl vt_IInputObject = {
2038 IInputObject_fnQueryInterface,
2039 IInputObject_fnAddRef,
2040 IInputObject_fnRelease,
2041 IInputObject_fnUIActivateIO,
2042 IInputObject_fnHasFocusIO,
2043 IInputObject_fnTranslateAcceleratorIO
2046 HRESULT WINAPI ExplorerBrowser_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv)
2048 ExplorerBrowserImpl *eb;
2049 HRESULT ret;
2051 TRACE("%p %s %p\n", pUnkOuter, shdebugstr_guid (riid), ppv);
2053 if(!ppv)
2054 return E_POINTER;
2055 if(pUnkOuter)
2056 return CLASS_E_NOAGGREGATION;
2058 eb = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ExplorerBrowserImpl));
2059 eb->ref = 1;
2060 eb->IExplorerBrowser_iface.lpVtbl = &vt_IExplorerBrowser;
2061 eb->IShellBrowser_iface.lpVtbl = &vt_IShellBrowser;
2062 eb->ICommDlgBrowser3_iface.lpVtbl = &vt_ICommDlgBrowser3;
2063 eb->IObjectWithSite_iface.lpVtbl = &vt_IObjectWithSite;
2064 eb->INameSpaceTreeControlEvents_iface.lpVtbl = &vt_INameSpaceTreeControlEvents;
2065 eb->IInputObject_iface.lpVtbl = &vt_IInputObject;
2067 /* Default settings */
2068 eb->navpane.width = 150;
2069 eb->navpane.show = TRUE;
2071 list_init(&eb->event_clients);
2072 list_init(&eb->travellog);
2074 ret = IExplorerBrowser_QueryInterface(&eb->IExplorerBrowser_iface, riid, ppv);
2075 IExplorerBrowser_Release(&eb->IExplorerBrowser_iface);
2077 TRACE("--(%p)\n", ppv);
2078 return ret;