mscoree/tests: Remove spaces before '\n's in traces.
[wine] / dlls / shell32 / ebrowser.c
1 /*
2  * ExplorerBrowser Control implementation.
3  *
4  * Copyright 2010 David Hedberg
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include <stdarg.h>
22
23 #define COBJMACROS
24 #define NONAMELESSUNION
25 #define NONAMELESSSTRUCT
26
27 #include "winerror.h"
28 #include "windef.h"
29 #include "winbase.h"
30
31 #include "wine/list.h"
32 #include "wine/debug.h"
33 #include "debughlp.h"
34
35 #include "shell32_main.h"
36 #include "pidl.h"
37
38 WINE_DEFAULT_DEBUG_CHANNEL(shell);
39
40 #define SPLITTER_WIDTH 2
41 #define NP_MIN_WIDTH 60
42 #define SV_MIN_WIDTH 150
43
44 typedef struct _event_client {
45     struct list entry;
46     IExplorerBrowserEvents *pebe;
47     DWORD cookie;
48 } event_client;
49
50 typedef struct _travellog_entry {
51     struct list entry;
52     LPITEMIDLIST pidl;
53 } travellog_entry;
54
55 typedef struct _ExplorerBrowserImpl {
56     const IExplorerBrowserVtbl *lpVtbl;
57     const IShellBrowserVtbl *lpsbVtbl;
58     const ICommDlgBrowser3Vtbl *lpcdb3Vtbl;
59     const IObjectWithSiteVtbl *lpowsVtbl;
60     const INameSpaceTreeControlEventsVtbl *lpnstceVtbl;
61     LONG ref;
62     BOOL destroyed;
63
64     HWND hwnd_main;
65     HWND hwnd_sv;
66
67     RECT splitter_rc;
68     struct {
69         INameSpaceTreeControl2 *pnstc2;
70         HWND hwnd_splitter, hwnd_nstc;
71         DWORD nstc_cookie;
72         UINT width;
73         BOOL show;
74         RECT rc;
75     } navpane;
76
77     EXPLORER_BROWSER_OPTIONS eb_options;
78     FOLDERSETTINGS fs;
79
80     struct list event_clients;
81     DWORD events_next_cookie;
82     struct list travellog;
83     travellog_entry *travellog_cursor;
84     int travellog_count;
85
86     IShellView *psv;
87     RECT sv_rc;
88     LPITEMIDLIST current_pidl;
89
90     IUnknown *punk_site;
91     ICommDlgBrowser *pcdb_site;
92     ICommDlgBrowser2 *pcdb2_site;
93     ICommDlgBrowser3 *pcdb3_site;
94     IExplorerPaneVisibility *pepv_site;
95 } ExplorerBrowserImpl;
96
97 static void initialize_navpane(ExplorerBrowserImpl *This, HWND hwnd_parent, RECT *rc);
98
99 /**************************************************************************
100  * Event functions.
101  */
102 static void events_unadvise_all(ExplorerBrowserImpl *This)
103 {
104     event_client *client, *curs;
105     TRACE("%p\n", This);
106
107     LIST_FOR_EACH_ENTRY_SAFE(client, curs, &This->event_clients, event_client, entry)
108     {
109         TRACE("Removing %p\n", client);
110         list_remove(&client->entry);
111         IExplorerBrowserEvents_Release(client->pebe);
112         HeapFree(GetProcessHeap(), 0, client);
113     }
114 }
115
116 static HRESULT events_NavigationPending(ExplorerBrowserImpl *This, PCIDLIST_ABSOLUTE pidl)
117 {
118     event_client *cursor;
119     HRESULT hres = S_OK;
120
121     TRACE("%p\n", This);
122
123     LIST_FOR_EACH_ENTRY(cursor, &This->event_clients, event_client, entry)
124     {
125         TRACE("Notifying %p\n", cursor);
126         hres = IExplorerBrowserEvents_OnNavigationPending(cursor->pebe, pidl);
127
128         /* If this failed for any reason, the browsing is supposed to be aborted. */
129         if(FAILED(hres))
130             break;
131     }
132
133     return hres;
134 }
135
136 static void events_NavigationComplete(ExplorerBrowserImpl *This, PCIDLIST_ABSOLUTE pidl)
137 {
138     event_client *cursor;
139
140     TRACE("%p\n", This);
141
142     LIST_FOR_EACH_ENTRY(cursor, &This->event_clients, event_client, entry)
143     {
144         TRACE("Notifying %p\n", cursor);
145         IExplorerBrowserEvents_OnNavigationComplete(cursor->pebe, pidl);
146     }
147 }
148
149 static void events_NavigationFailed(ExplorerBrowserImpl *This, PCIDLIST_ABSOLUTE pidl)
150 {
151     event_client *cursor;
152
153     TRACE("%p\n", This);
154
155     LIST_FOR_EACH_ENTRY(cursor, &This->event_clients, event_client, entry)
156     {
157         TRACE("Notifying %p\n", cursor);
158         IExplorerBrowserEvents_OnNavigationFailed(cursor->pebe, pidl);
159     }
160 }
161
162 static void events_ViewCreated(ExplorerBrowserImpl *This, IShellView *psv)
163 {
164     event_client *cursor;
165
166     TRACE("%p\n", This);
167
168     LIST_FOR_EACH_ENTRY(cursor, &This->event_clients, event_client, entry)
169     {
170         TRACE("Notifying %p\n", cursor);
171         IExplorerBrowserEvents_OnViewCreated(cursor->pebe, psv);
172     }
173 }
174
175 /**************************************************************************
176  * Travellog functions.
177  */
178 static void travellog_remove_entry(ExplorerBrowserImpl *This, travellog_entry *entry)
179 {
180     TRACE("Removing %p\n", entry);
181
182     list_remove(&entry->entry);
183     HeapFree(GetProcessHeap(), 0, entry);
184     This->travellog_count--;
185 }
186
187 static void travellog_remove_all_entries(ExplorerBrowserImpl *This)
188 {
189     travellog_entry *cursor, *cursor2;
190     TRACE("%p\n", This);
191
192     LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->travellog, travellog_entry, entry)
193         travellog_remove_entry(This, cursor);
194
195     This->travellog_cursor = NULL;
196 }
197
198 static void travellog_add_entry(ExplorerBrowserImpl *This, LPITEMIDLIST pidl)
199 {
200     travellog_entry *new, *cursor, *cursor2;
201     TRACE("%p (old count %d)\n", pidl, This->travellog_count);
202
203     /* Replace the old tail, if any, with the new entry */
204     if(This->travellog_cursor)
205     {
206         LIST_FOR_EACH_ENTRY_SAFE_REV(cursor, cursor2, &This->travellog, travellog_entry, entry)
207         {
208             if(cursor == This->travellog_cursor)
209                 break;
210             travellog_remove_entry(This, cursor);
211         }
212     }
213
214     /* Create and add the new entry */
215     new = HeapAlloc(GetProcessHeap(), 0, sizeof(travellog_entry));
216     new->pidl = ILClone(pidl);
217     list_add_tail(&This->travellog, &new->entry);
218     This->travellog_cursor = new;
219     This->travellog_count++;
220
221     /* Remove the first few entries if the size limit is reached. */
222     if(This->travellog_count > 200)
223     {
224         UINT i = 0;
225         LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->travellog, travellog_entry, entry)
226         {
227             if(i++ > 10)
228                 break;
229             travellog_remove_entry(This, cursor);
230         }
231     }
232 }
233
234 static LPCITEMIDLIST travellog_go_back(ExplorerBrowserImpl *This)
235 {
236     travellog_entry *prev;
237     TRACE("%p, %p\n", This, This->travellog_cursor);
238
239     if(!This->travellog_cursor)
240         return NULL;
241
242     prev = LIST_ENTRY(list_prev(&This->travellog, &This->travellog_cursor->entry),
243                       travellog_entry, entry);
244     if(!prev)
245         return NULL;
246
247     This->travellog_cursor = prev;
248     return prev->pidl;
249 }
250
251 static LPCITEMIDLIST travellog_go_forward(ExplorerBrowserImpl *This)
252 {
253     travellog_entry *next;
254     TRACE("%p, %p\n", This, This->travellog_cursor);
255
256     if(!This->travellog_cursor)
257         return NULL;
258
259     next = LIST_ENTRY(list_next(&This->travellog, &This->travellog_cursor->entry),
260                       travellog_entry, entry);
261     if(!next)
262         return NULL;
263
264     This->travellog_cursor = next;
265     return next->pidl;
266 }
267
268 /**************************************************************************
269  * Helper functions
270  */
271 static void update_layout(ExplorerBrowserImpl *This)
272 {
273     RECT rc;
274     INT navpane_width_actual;
275     INT shellview_width_actual;
276     TRACE("%p (navpane: %d, EBO_SHOWFRAMES: %d)\n",
277           This, This->navpane.show, This->eb_options & EBO_SHOWFRAMES);
278
279     GetClientRect(This->hwnd_main, &rc);
280
281     if((This->eb_options & EBO_SHOWFRAMES) && This->navpane.show)
282         navpane_width_actual = This->navpane.width;
283     else
284         navpane_width_actual = 0;
285
286     shellview_width_actual = rc.right - navpane_width_actual;
287     if(shellview_width_actual < SV_MIN_WIDTH && navpane_width_actual)
288     {
289         INT missing_width = SV_MIN_WIDTH - shellview_width_actual;
290         if(missing_width < (navpane_width_actual - NP_MIN_WIDTH))
291         {
292             /* Shrink the navpane */
293             navpane_width_actual -= missing_width;
294             shellview_width_actual += missing_width;
295         }
296         else
297         {
298             /* Hide the navpane */
299             shellview_width_actual += navpane_width_actual;
300             navpane_width_actual = 0;
301         }
302     }
303
304     /**************************************************************
305      *  Calculate rectangles for the panes. All rectangles contain
306      *  the position of the panes relative to hwnd_main.
307      */
308
309     if(navpane_width_actual)
310     {
311         This->navpane.rc.left = This->navpane.rc.top = 0;
312         This->navpane.rc.right = navpane_width_actual;
313         This->navpane.rc.bottom = rc.bottom;
314
315         if(!This->navpane.hwnd_splitter)
316             initialize_navpane(This, This->hwnd_main, &This->navpane.rc);
317     }
318     else
319         ZeroMemory(&This->navpane.rc, sizeof(RECT));
320
321     This->sv_rc.left   = navpane_width_actual;
322     This->sv_rc.top    = 0;
323     This->sv_rc.right  = This->sv_rc.left + shellview_width_actual;
324     This->sv_rc.bottom = rc.bottom;
325 }
326
327 static void size_panes(ExplorerBrowserImpl *This)
328 {
329     MoveWindow(This->navpane.hwnd_splitter,
330                This->navpane.rc.right - SPLITTER_WIDTH, This->navpane.rc.top,
331                SPLITTER_WIDTH, This->navpane.rc.bottom - This->navpane.rc.top,
332                TRUE);
333
334     MoveWindow(This->hwnd_sv,
335                This->sv_rc.left, This->sv_rc.top,
336                This->sv_rc.right - This->sv_rc.left, This->sv_rc.bottom - This->sv_rc.top,
337                TRUE);
338 }
339
340 static HRESULT change_viewmode(ExplorerBrowserImpl *This, UINT viewmode)
341 {
342     IFolderView *pfv;
343     HRESULT hr;
344
345     if(!This->psv)
346         return E_FAIL;
347
348     hr = IShellView_QueryInterface(This->psv, &IID_IFolderView, (void*)&pfv);
349     if(SUCCEEDED(hr))
350     {
351         hr = IFolderView_SetCurrentViewMode(pfv, This->fs.ViewMode);
352         IFolderView_Release(pfv);
353     }
354
355     return hr;
356 }
357
358 static HRESULT create_new_shellview(ExplorerBrowserImpl *This, IShellItem *psi)
359 {
360     IShellBrowser *psb = (IShellBrowser*)&This->lpsbVtbl;
361     IShellFolder *psf;
362     IShellView *psv;
363     HWND hwnd_new;
364     HRESULT hr;
365
366     TRACE("%p, %p\n", This, psi);
367
368     hr = IShellItem_BindToHandler(psi, NULL, &BHID_SFObject, &IID_IShellFolder, (void**)&psf);
369     if(SUCCEEDED(hr))
370     {
371         hr = IShellFolder_CreateViewObject(psf, This->hwnd_main, &IID_IShellView, (void**)&psv);
372         if(SUCCEEDED(hr))
373         {
374             if(This->hwnd_sv)
375             {
376                 IShellView_DestroyViewWindow(This->psv);
377                 This->hwnd_sv = NULL;
378             }
379
380             hr = IShellView_CreateViewWindow(psv, This->psv, &This->fs, psb, &This->sv_rc, &hwnd_new);
381             if(SUCCEEDED(hr))
382             {
383                 /* Replace the old shellview */
384                 if(This->psv) IShellView_Release(This->psv);
385
386                 This->psv = psv;
387                 This->hwnd_sv = hwnd_new;
388                 events_ViewCreated(This, psv);
389             }
390             else
391             {
392                 ERR("CreateViewWindow failed (0x%x)\n", hr);
393                 IShellView_Release(psv);
394             }
395         }
396         else
397             ERR("CreateViewObject failed (0x%x)\n", hr);
398
399         IShellFolder_Release(psf);
400     }
401     else
402         ERR("SI::BindToHandler failed (0x%x)\n", hr);
403
404     return hr;
405 }
406
407 static void get_interfaces_from_site(ExplorerBrowserImpl *This)
408 {
409     IServiceProvider *psp;
410     HRESULT hr;
411
412     /* Calling this with This->punk_site set to NULL should properly
413      * release any previously fetched interfaces.
414      */
415
416     if(This->pcdb_site)
417     {
418         IUnknown_Release(This->pcdb_site);
419         if(This->pcdb2_site) IUnknown_Release(This->pcdb2_site);
420         if(This->pcdb3_site) IUnknown_Release(This->pcdb3_site);
421
422         This->pcdb_site = NULL;
423         This->pcdb2_site = NULL;
424         This->pcdb3_site = NULL;
425     }
426
427     if(This->pepv_site)
428     {
429         IExplorerPaneVisibility_Release(This->pepv_site);
430         This->pepv_site = NULL;
431     }
432
433     if(!This->punk_site)
434         return;
435
436     hr = IUnknown_QueryInterface(This->punk_site, &IID_IServiceProvider, (void**)&psp);
437     if(FAILED(hr))
438     {
439         ERR("Failed to get IServiceProvider from site.\n");
440         return;
441     }
442
443     /* ICommDlgBrowser */
444     IServiceProvider_QueryService(psp, &SID_SExplorerBrowserFrame, &IID_ICommDlgBrowser,
445                                   (void**)&This->pcdb_site);
446     IServiceProvider_QueryService(psp, &SID_SExplorerBrowserFrame, &IID_ICommDlgBrowser2,
447                                   (void**)&This->pcdb2_site);
448     IServiceProvider_QueryService(psp, &SID_SExplorerBrowserFrame, &IID_ICommDlgBrowser3,
449                                   (void**)&This->pcdb3_site);
450
451     /* IExplorerPaneVisibility */
452     IServiceProvider_QueryService(psp, &SID_ExplorerPaneVisibility, &IID_IExplorerPaneVisibility,
453                                   (void**)&This->pepv_site);
454
455     IServiceProvider_Release(psp);
456 }
457
458 /**************************************************************************
459  * General pane functionality.
460  */
461 static void update_panestate(ExplorerBrowserImpl *This)
462 {
463     EXPLORERPANESTATE eps = EPS_DONTCARE;
464     BOOL show_navpane;
465     TRACE("%p\n", This);
466
467     if(!This->pepv_site) return;
468
469     IExplorerPaneVisibility_GetPaneState(This->pepv_site, (REFEXPLORERPANE) &EP_NavPane, &eps);
470     if( !(eps & EPS_DEFAULT_OFF) )
471         show_navpane = TRUE;
472     else
473         show_navpane = FALSE;
474
475     if(This->navpane.show ^ show_navpane)
476     {
477         update_layout(This);
478         size_panes(This);
479     }
480
481     This->navpane.show = show_navpane;
482 }
483
484 static void splitter_draw(HWND hwnd, RECT *rc)
485 {
486     HDC hdc = GetDC(hwnd);
487     InvertRect(hdc, rc);
488     ReleaseDC(hwnd, hdc);
489 }
490
491 /**************************************************************************
492  * The Navigation Pane.
493  */
494 static LRESULT navpane_splitter_beginresize(ExplorerBrowserImpl *This, HWND hwnd, LPARAM lParam)
495 {
496     TRACE("\n");
497
498     SetCapture(hwnd);
499
500     CopyRect(&This->splitter_rc, &This->navpane.rc);
501     This->splitter_rc.left = This->splitter_rc.right - SPLITTER_WIDTH;
502
503     splitter_draw(GetParent(hwnd), &This->splitter_rc);
504
505     return TRUE;
506 }
507
508 static LRESULT navpane_splitter_resizing(ExplorerBrowserImpl *This, HWND hwnd, LPARAM lParam)
509 {
510     int new_width, dx;
511     RECT rc;
512
513     if(GetCapture() != hwnd) return FALSE;
514
515     dx = (SHORT)LOWORD(lParam);
516     TRACE("%d.\n", dx);
517
518     CopyRect(&rc, &This->navpane.rc);
519
520     new_width = This->navpane.width + dx;
521     if(new_width > NP_MIN_WIDTH && This->sv_rc.right - new_width > SV_MIN_WIDTH)
522     {
523         rc.right = new_width;
524         rc.left = rc.right - SPLITTER_WIDTH;
525         splitter_draw(GetParent(hwnd), &This->splitter_rc);
526         splitter_draw(GetParent(hwnd), &rc);
527         CopyRect(&This->splitter_rc, &rc);
528     }
529
530     return TRUE;
531 }
532
533 static LRESULT navpane_splitter_endresize(ExplorerBrowserImpl *This, HWND hwnd, LPARAM lParam)
534 {
535     int new_width, dx;
536
537     if(GetCapture() != hwnd) return FALSE;
538
539     dx = (SHORT)LOWORD(lParam);
540     TRACE("%d.\n", dx);
541
542     splitter_draw(GetParent(hwnd), &This->splitter_rc);
543
544     new_width = This->navpane.width + dx;
545     if(new_width < NP_MIN_WIDTH)
546         new_width = NP_MIN_WIDTH;
547     else if(This->sv_rc.right - new_width < SV_MIN_WIDTH)
548         new_width = This->sv_rc.right - SV_MIN_WIDTH;
549
550     This->navpane.width = new_width;
551
552     update_layout(This);
553     size_panes(This);
554
555     ReleaseCapture();
556
557     return TRUE;
558 }
559
560 static LRESULT navpane_on_wm_create(HWND hwnd, CREATESTRUCTW *crs)
561 {
562     ExplorerBrowserImpl *This = crs->lpCreateParams;
563     INameSpaceTreeControl2 *pnstc2;
564     DWORD style;
565     HRESULT hr;
566
567     TRACE("%p\n", This);
568     SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LPARAM)This);
569     This->navpane.hwnd_splitter = hwnd;
570
571     hr = CoCreateInstance(&CLSID_NamespaceTreeControl, NULL, CLSCTX_INPROC_SERVER,
572                           &IID_INameSpaceTreeControl2, (void**)&pnstc2);
573
574     if(SUCCEEDED(hr))
575     {
576         style = NSTCS_HASEXPANDOS | NSTCS_ROOTHASEXPANDO | NSTCS_SHOWSELECTIONALWAYS;
577         hr = INameSpaceTreeControl2_Initialize(pnstc2, GetParent(hwnd), NULL, style);
578         if(SUCCEEDED(hr))
579         {
580             INameSpaceTreeControlEvents *pnstce;
581             IShellFolder *psfdesktop;
582             IShellItem *psi;
583             IOleWindow *pow;
584             LPITEMIDLIST pidl;
585             DWORD cookie, style2 = NSTCS2_DISPLAYPADDING;
586
587             hr = INameSpaceTreeControl2_SetControlStyle2(pnstc2, 0xFF, style2);
588             if(FAILED(hr))
589                 ERR("SetControlStyle2 failed (0x%08x)\n", hr);
590
591             hr = INameSpaceTreeControl2_QueryInterface(pnstc2, &IID_IOleWindow, (void**)&pow);
592             if(SUCCEEDED(hr))
593             {
594                 IOleWindow_GetWindow(pow, &This->navpane.hwnd_nstc);
595                 IOleWindow_Release(pow);
596             }
597             else
598                 ERR("QueryInterface(IOleWindow) failed (0x%08x)\n", hr);
599
600             pnstce = (INameSpaceTreeControlEvents *)&This->lpnstceVtbl;
601             hr = INameSpaceTreeControl2_TreeAdvise(pnstc2, (IUnknown*)pnstce, &cookie);
602             if(FAILED(hr))
603                 ERR("TreeAdvise failed. (0x%08x).\n", hr);
604
605             /*
606              * Add the default roots
607              */
608
609             /* TODO: This should be FOLDERID_Links */
610             hr = SHGetSpecialFolderLocation(NULL, CSIDL_FAVORITES, &pidl);
611             if(SUCCEEDED(hr))
612             {
613                 hr = SHCreateShellItem(NULL, NULL, pidl, &psi);
614                 if(SUCCEEDED(hr))
615                 {
616                     hr = INameSpaceTreeControl2_AppendRoot(pnstc2, psi, SHCONTF_NONFOLDERS, NSTCRS_VISIBLE, NULL);
617                     IShellItem_Release(psi);
618                 }
619                 ILFree(pidl);
620             }
621
622             SHGetDesktopFolder(&psfdesktop);
623             hr = SHGetItemFromObject((IUnknown*)psfdesktop, &IID_IShellItem, (void**)&psi);
624             IShellFolder_Release(psfdesktop);
625             if(SUCCEEDED(hr))
626             {
627                 hr = INameSpaceTreeControl2_AppendRoot(pnstc2, psi, SHCONTF_FOLDERS, NSTCRS_EXPANDED, NULL);
628                 IShellItem_Release(psi);
629             }
630
631             /* TODO:
632              * We should advertise IID_INameSpaceTreeControl to the site of the
633              * host through its IProfferService interface, if any.
634              */
635
636             This->navpane.pnstc2 = pnstc2;
637             This->navpane.nstc_cookie = cookie;
638
639             return TRUE;
640         }
641     }
642
643     This->navpane.pnstc2 = NULL;
644     ERR("Failed (0x%08x)\n", hr);
645
646     return FALSE;
647 }
648
649 static LRESULT navpane_on_wm_size_move(ExplorerBrowserImpl *This)
650 {
651     UINT height, width;
652     TRACE("%p\n", This);
653
654     width = This->navpane.rc.right - This->navpane.rc.left - SPLITTER_WIDTH;
655     height = This->navpane.rc.bottom - This->navpane.rc.top;
656
657     MoveWindow(This->navpane.hwnd_nstc,
658                This->navpane.rc.left, This->navpane.rc.top,
659                width, height,
660                TRUE);
661
662     return FALSE;
663 }
664
665 static LRESULT navpane_on_wm_destroy(ExplorerBrowserImpl *This)
666 {
667     INameSpaceTreeControl_TreeUnadvise(This->navpane.pnstc2, This->navpane.nstc_cookie);
668     INameSpaceTreeControl_Release(This->navpane.pnstc2);
669     This->navpane.pnstc2 = NULL;
670     return TRUE;
671 }
672
673 static LRESULT CALLBACK navpane_wndproc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
674 {
675     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
676
677     switch(uMessage) {
678     case WM_CREATE:           return navpane_on_wm_create(hWnd, (CREATESTRUCTW*)lParam);
679     case WM_MOVE:             /* Fall through */
680     case WM_SIZE:             return navpane_on_wm_size_move(This);
681     case WM_DESTROY:          return navpane_on_wm_destroy(This);
682     case WM_LBUTTONDOWN:      return navpane_splitter_beginresize(This, hWnd, lParam);
683     case WM_MOUSEMOVE:        return navpane_splitter_resizing(This, hWnd, lParam);
684     case WM_LBUTTONUP:        return navpane_splitter_endresize(This, hWnd, lParam);
685     default:
686         return DefWindowProcW(hWnd, uMessage, wParam, lParam);
687     }
688     return 0;
689 }
690
691 static void initialize_navpane(ExplorerBrowserImpl *This, HWND hwnd_parent, RECT *rc)
692 {
693     WNDCLASSW wc;
694     HWND splitter;
695     static const WCHAR navpane_classname[] = {'e','b','_','n','a','v','p','a','n','e',0};
696
697     if( !GetClassInfoW(shell32_hInstance, navpane_classname, &wc) )
698     {
699         wc.style            = CS_HREDRAW | CS_VREDRAW;
700         wc.lpfnWndProc      = navpane_wndproc;
701         wc.cbClsExtra       = 0;
702         wc.cbWndExtra       = 0;
703         wc.hInstance        = shell32_hInstance;
704         wc.hIcon            = 0;
705         wc.hCursor          = LoadCursorW(0, (LPWSTR)IDC_SIZEWE);
706         wc.hbrBackground    = (HBRUSH)(COLOR_HIGHLIGHT + 1);
707         wc.lpszMenuName     = NULL;
708         wc.lpszClassName    = navpane_classname;
709
710         if (!RegisterClassW(&wc)) return;
711     }
712
713     splitter = CreateWindowExW(0, navpane_classname, NULL,
714                                WS_CHILD | WS_TABSTOP | WS_VISIBLE,
715                                rc->right - SPLITTER_WIDTH, rc->top,
716                                SPLITTER_WIDTH, rc->bottom - rc->top,
717                                hwnd_parent, 0, shell32_hInstance, This);
718     if(!splitter)
719         ERR("Failed to create navpane : %d.\n", GetLastError());
720 }
721
722 /**************************************************************************
723  * Main window related functions.
724  */
725 static LRESULT main_on_wm_create(HWND hWnd, CREATESTRUCTW *crs)
726 {
727     ExplorerBrowserImpl *This = crs->lpCreateParams;
728     TRACE("%p\n", This);
729
730     SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LPARAM)This);
731     This->hwnd_main = hWnd;
732
733     return TRUE;
734 }
735
736 static LRESULT main_on_wm_size(ExplorerBrowserImpl *This)
737 {
738     update_layout(This);
739     size_panes(This);
740
741     return TRUE;
742 }
743
744 static LRESULT CALLBACK main_wndproc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
745 {
746     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
747
748     switch(uMessage)
749     {
750     case WM_CREATE:           return main_on_wm_create(hWnd, (CREATESTRUCTW*)lParam);
751     case WM_SIZE:             return main_on_wm_size(This);
752     default:                  return DefWindowProcW(hWnd, uMessage, wParam, lParam);
753     }
754
755     return 0;
756 }
757
758 /**************************************************************************
759  * IExplorerBrowser Implementation
760  */
761 static HRESULT WINAPI IExplorerBrowser_fnQueryInterface(IExplorerBrowser *iface,
762                                                         REFIID riid, void **ppvObject)
763 {
764     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
765     TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppvObject);
766
767     *ppvObject = NULL;
768     if(IsEqualIID(riid, &IID_IExplorerBrowser) ||
769        IsEqualIID(riid, &IID_IUnknown))
770     {
771         *ppvObject = This;
772     }
773     else if(IsEqualIID(riid, &IID_IShellBrowser))
774     {
775         *ppvObject = &This->lpsbVtbl;
776     }
777     else if(IsEqualIID(riid, &IID_ICommDlgBrowser) ||
778             IsEqualIID(riid, &IID_ICommDlgBrowser2) ||
779             IsEqualIID(riid, &IID_ICommDlgBrowser3))
780     {
781         *ppvObject = &This->lpcdb3Vtbl;
782     }
783     else if(IsEqualIID(riid, &IID_IObjectWithSite))
784     {
785         *ppvObject = &This->lpowsVtbl;
786     }
787
788     if(*ppvObject)
789     {
790         IUnknown_AddRef((IUnknown*)*ppvObject);
791         return S_OK;
792     }
793
794     return E_NOINTERFACE;
795 }
796
797 static ULONG WINAPI IExplorerBrowser_fnAddRef(IExplorerBrowser *iface)
798 {
799     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
800     LONG ref = InterlockedIncrement(&This->ref);
801     TRACE("%p - ref %d\n", This, ref);
802
803     return ref;
804 }
805
806 static ULONG WINAPI IExplorerBrowser_fnRelease(IExplorerBrowser *iface)
807 {
808     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
809     LONG ref = InterlockedDecrement(&This->ref);
810     TRACE("%p - ref %d\n", This, ref);
811
812     if(!ref)
813     {
814         TRACE("Freeing.\n");
815
816         if(!This->destroyed)
817             IExplorerBrowser_Destroy(iface);
818
819         IObjectWithSite_SetSite((IObjectWithSite*)&This->lpowsVtbl, NULL);
820
821         HeapFree(GetProcessHeap(), 0, This);
822         return 0;
823     }
824
825     return ref;
826 }
827
828 static HRESULT WINAPI IExplorerBrowser_fnInitialize(IExplorerBrowser *iface,
829                                                     HWND hwndParent, const RECT *prc,
830                                                     const FOLDERSETTINGS *pfs)
831 {
832     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
833     WNDCLASSW wc;
834     LONG style;
835     static const WCHAR EB_CLASS_NAME[] =
836         {'E','x','p','l','o','r','e','r','B','r','o','w','s','e','r','C','o','n','t','r','o','l',0};
837
838     TRACE("%p (%p, %p, %p)\n", This, hwndParent, prc, pfs);
839
840     if(This->hwnd_main)
841         return E_UNEXPECTED;
842
843     if(!hwndParent)
844         return E_INVALIDARG;
845
846     if( !GetClassInfoW(shell32_hInstance, EB_CLASS_NAME, &wc) )
847     {
848         wc.style            = CS_HREDRAW | CS_VREDRAW;
849         wc.lpfnWndProc      = main_wndproc;
850         wc.cbClsExtra       = 0;
851         wc.cbWndExtra       = 0;
852         wc.hInstance        = shell32_hInstance;
853         wc.hIcon            = 0;
854         wc.hCursor          = LoadCursorW(0, (LPWSTR)IDC_ARROW);
855         wc.hbrBackground    = (HBRUSH)(COLOR_WINDOW + 1);
856         wc.lpszMenuName     = NULL;
857         wc.lpszClassName    = EB_CLASS_NAME;
858
859         if (!RegisterClassW(&wc)) return E_FAIL;
860     }
861
862     style = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_BORDER;
863     This->hwnd_main = CreateWindowExW(WS_EX_CONTROLPARENT, EB_CLASS_NAME, NULL, style,
864                                       prc->left, prc->top,
865                                       prc->right - prc->left, prc->bottom - prc->top,
866                                       hwndParent, 0, shell32_hInstance, This);
867
868     if(!This->hwnd_main)
869     {
870         ERR("Failed to create the window.\n");
871         return E_FAIL;
872     }
873
874     This->fs.ViewMode = pfs ? pfs->ViewMode : FVM_DETAILS;
875     This->fs.fFlags = pfs ? (pfs->fFlags | FWF_NOCLIENTEDGE) : FWF_NOCLIENTEDGE;
876
877     return S_OK;
878 }
879
880 static HRESULT WINAPI IExplorerBrowser_fnDestroy(IExplorerBrowser *iface)
881 {
882     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
883     TRACE("%p\n", This);
884
885     if(This->psv)
886     {
887         IShellView_DestroyViewWindow(This->psv);
888         IShellView_Release(This->psv);
889         This->psv = NULL;
890         This->hwnd_sv = NULL;
891     }
892
893     events_unadvise_all(This);
894     travellog_remove_all_entries(This);
895
896     ILFree(This->current_pidl);
897     This->current_pidl = NULL;
898
899     DestroyWindow(This->hwnd_main);
900     This->destroyed = TRUE;
901
902     return S_OK;
903 }
904
905 static HRESULT WINAPI IExplorerBrowser_fnSetRect(IExplorerBrowser *iface,
906                                                  HDWP *phdwp, RECT rcBrowser)
907 {
908     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
909     TRACE("%p (%p, %s)\n", This, phdwp, wine_dbgstr_rect(&rcBrowser));
910
911     if(phdwp)
912     {
913         *phdwp = DeferWindowPos(*phdwp, This->hwnd_main, NULL, rcBrowser.left, rcBrowser.top,
914                                 rcBrowser.right - rcBrowser.left, rcBrowser.bottom - rcBrowser.top,
915                                 SWP_NOZORDER | SWP_NOACTIVATE);
916     }
917     else
918     {
919         MoveWindow(This->hwnd_main, rcBrowser.left, rcBrowser.top,
920                    rcBrowser.right - rcBrowser.left, rcBrowser.bottom - rcBrowser.top, TRUE);
921     }
922
923     return S_OK;
924 }
925
926 static HRESULT WINAPI IExplorerBrowser_fnSetPropertyBag(IExplorerBrowser *iface,
927                                                         LPCWSTR pszPropertyBag)
928 {
929     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
930     FIXME("stub, %p (%s)\n", This, debugstr_w(pszPropertyBag));
931
932     return E_NOTIMPL;
933 }
934
935 static HRESULT WINAPI IExplorerBrowser_fnSetEmptyText(IExplorerBrowser *iface,
936                                                       LPCWSTR pszEmptyText)
937 {
938     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
939     FIXME("stub, %p (%s)\n", This, debugstr_w(pszEmptyText));
940
941     return E_NOTIMPL;
942 }
943
944 static HRESULT WINAPI IExplorerBrowser_fnSetFolderSettings(IExplorerBrowser *iface,
945                                                            const FOLDERSETTINGS *pfs)
946 {
947     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
948     TRACE("%p (%p)\n", This, pfs);
949
950     if(!pfs)
951         return E_INVALIDARG;
952
953     This->fs.ViewMode = pfs->ViewMode;
954     This->fs.fFlags = pfs->fFlags | FWF_NOCLIENTEDGE;
955
956     /* Change the settings of the current view, if any. */
957     return change_viewmode(This, This->fs.ViewMode);
958 }
959
960 static HRESULT WINAPI IExplorerBrowser_fnAdvise(IExplorerBrowser *iface,
961                                                 IExplorerBrowserEvents *psbe,
962                                                 DWORD *pdwCookie)
963 {
964     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
965     event_client *client;
966     TRACE("%p (%p, %p)\n", This, psbe, pdwCookie);
967
968     client = HeapAlloc(GetProcessHeap(), 0, sizeof(event_client));
969     client->pebe = psbe;
970     client->cookie = ++This->events_next_cookie;
971
972     IExplorerBrowserEvents_AddRef(psbe);
973     *pdwCookie = client->cookie;
974
975     list_add_tail(&This->event_clients, &client->entry);
976
977     return S_OK;
978 }
979
980 static HRESULT WINAPI IExplorerBrowser_fnUnadvise(IExplorerBrowser *iface,
981                                                   DWORD dwCookie)
982 {
983     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
984     event_client *client;
985     TRACE("%p (0x%x)\n", This, dwCookie);
986
987     LIST_FOR_EACH_ENTRY(client, &This->event_clients, event_client, entry)
988     {
989         if(client->cookie == dwCookie)
990         {
991             list_remove(&client->entry);
992             IExplorerBrowserEvents_Release(client->pebe);
993             HeapFree(GetProcessHeap(), 0, client);
994             return S_OK;
995         }
996     }
997
998     return E_INVALIDARG;
999 }
1000
1001 static HRESULT WINAPI IExplorerBrowser_fnSetOptions(IExplorerBrowser *iface,
1002                                                     EXPLORER_BROWSER_OPTIONS dwFlag)
1003 {
1004     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
1005     static const EXPLORER_BROWSER_OPTIONS unsupported_options =
1006         EBO_ALWAYSNAVIGATE | EBO_NOWRAPPERWINDOW | EBO_HTMLSHAREPOINTVIEW;
1007
1008     TRACE("%p (0x%x)\n", This, dwFlag);
1009
1010     if(dwFlag & unsupported_options)
1011         FIXME("Flags 0x%08x contains unsupported options.\n", dwFlag);
1012
1013     This->eb_options = dwFlag;
1014
1015     return S_OK;
1016 }
1017
1018 static HRESULT WINAPI IExplorerBrowser_fnGetOptions(IExplorerBrowser *iface,
1019                                                     EXPLORER_BROWSER_OPTIONS *pdwFlag)
1020 {
1021     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
1022     TRACE("%p (%p)\n", This, pdwFlag);
1023
1024     *pdwFlag = This->eb_options;
1025
1026     return S_OK;
1027 }
1028
1029 static HRESULT WINAPI IExplorerBrowser_fnBrowseToIDList(IExplorerBrowser *iface,
1030                                                         PCUIDLIST_RELATIVE pidl,
1031                                                         UINT uFlags)
1032 {
1033     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
1034     LPITEMIDLIST absolute_pidl = NULL;
1035     HRESULT hr;
1036     static const UINT unsupported_browse_flags =
1037         SBSP_NEWBROWSER | EBF_SELECTFROMDATAOBJECT | EBF_NODROPTARGET;
1038     TRACE("%p (%p, 0x%x)\n", This, pidl, uFlags);
1039
1040     if(!This->hwnd_main)
1041         return E_FAIL;
1042
1043     if(This->destroyed)
1044         return HRESULT_FROM_WIN32(ERROR_BUSY);
1045
1046     if(This->current_pidl && (This->eb_options & EBO_NAVIGATEONCE))
1047         return E_FAIL;
1048
1049     if(uFlags & SBSP_EXPLOREMODE)
1050         return E_INVALIDARG;
1051
1052     if(uFlags & unsupported_browse_flags)
1053         FIXME("Argument 0x%x contains unsupported flags.\n", uFlags);
1054
1055     if(uFlags & SBSP_NAVIGATEBACK)
1056     {
1057         TRACE("SBSP_NAVIGATEBACK\n");
1058         absolute_pidl = ILClone(travellog_go_back(This));
1059         if(!absolute_pidl && !This->current_pidl)
1060             return E_FAIL;
1061         else if(!absolute_pidl)
1062             return S_OK;
1063
1064     }
1065     else if(uFlags & SBSP_NAVIGATEFORWARD)
1066     {
1067         TRACE("SBSP_NAVIGATEFORWARD\n");
1068         absolute_pidl = ILClone(travellog_go_forward(This));
1069         if(!absolute_pidl && !This->current_pidl)
1070             return E_FAIL;
1071         else if(!absolute_pidl)
1072             return S_OK;
1073
1074     }
1075     else if(uFlags & SBSP_PARENT)
1076     {
1077         if(This->current_pidl)
1078         {
1079             if(_ILIsPidlSimple(This->current_pidl))
1080             {
1081                 absolute_pidl = _ILCreateDesktop();
1082             }
1083             else
1084             {
1085                 absolute_pidl = ILClone(This->current_pidl);
1086                 ILRemoveLastID(absolute_pidl);
1087             }
1088         }
1089         if(!absolute_pidl)
1090         {
1091             ERR("Failed to get parent pidl.\n");
1092             return E_FAIL;
1093         }
1094
1095     }
1096     else if(uFlags & SBSP_RELATIVE)
1097     {
1098         /* SBSP_RELATIVE has precedence over SBSP_ABSOLUTE */
1099         TRACE("SBSP_RELATIVE\n");
1100         if(This->current_pidl)
1101         {
1102             absolute_pidl = ILCombine(This->current_pidl, pidl);
1103         }
1104         if(!absolute_pidl)
1105         {
1106             ERR("Failed to get absolute pidl.\n");
1107             return E_FAIL;
1108         }
1109     }
1110     else
1111     {
1112         TRACE("SBSP_ABSOLUTE\n");
1113         absolute_pidl = ILClone(pidl);
1114         if(!absolute_pidl && !This->current_pidl)
1115             return E_INVALIDARG;
1116         else if(!absolute_pidl)
1117             return S_OK;
1118     }
1119
1120     /* TODO: Asynchronous browsing. Return S_OK here and finish in
1121      * another thread. */
1122
1123     hr = events_NavigationPending(This, absolute_pidl);
1124     if(FAILED(hr))
1125     {
1126         TRACE("Browsing aborted.\n");
1127         ILFree(absolute_pidl);
1128         return E_FAIL;
1129     }
1130
1131     get_interfaces_from_site(This);
1132     update_panestate(This);
1133
1134     /* Only browse if the new pidl differs from the old */
1135     if(!ILIsEqual(This->current_pidl, absolute_pidl))
1136     {
1137         IShellItem *psi;
1138         hr = SHCreateItemFromIDList(absolute_pidl, &IID_IShellItem, (void**)&psi);
1139         if(SUCCEEDED(hr))
1140         {
1141             hr = create_new_shellview(This, psi);
1142             if(FAILED(hr))
1143             {
1144                 events_NavigationFailed(This, absolute_pidl);
1145                 ILFree(absolute_pidl);
1146                 IShellItem_Release(psi);
1147                 return E_FAIL;
1148             }
1149
1150             /* Add to travellog */
1151             if( !(This->eb_options & EBO_NOTRAVELLOG) &&
1152                 !(uFlags & (SBSP_NAVIGATEFORWARD|SBSP_NAVIGATEBACK)) )
1153             {
1154                 travellog_add_entry(This, absolute_pidl);
1155             }
1156
1157             IShellItem_Release(psi);
1158         }
1159     }
1160
1161     events_NavigationComplete(This, absolute_pidl);
1162     ILFree(This->current_pidl);
1163     This->current_pidl = absolute_pidl;
1164
1165     /* Expand the NameSpaceTree to the current location. */
1166     if(This->navpane.show && This->navpane.pnstc2)
1167     {
1168         IShellItem *psi;
1169         hr = SHCreateItemFromIDList(This->current_pidl, &IID_IShellItem, (void**)&psi);
1170         if(SUCCEEDED(hr))
1171         {
1172             INameSpaceTreeControl_EnsureItemVisible(This->navpane.pnstc2, psi);
1173             IShellItem_Release(psi);
1174         }
1175     }
1176
1177     return S_OK;
1178 }
1179
1180 static HRESULT WINAPI IExplorerBrowser_fnBrowseToObject(IExplorerBrowser *iface,
1181                                                         IUnknown *punk, UINT uFlags)
1182 {
1183     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
1184     LPITEMIDLIST pidl;
1185     HRESULT hr;
1186     TRACE("%p (%p, 0x%x)\n", This, punk, uFlags);
1187
1188     if(!punk)
1189         return IExplorerBrowser_fnBrowseToIDList(iface, NULL, uFlags);
1190
1191     hr = SHGetIDListFromObject(punk, &pidl);
1192     if(SUCCEEDED(hr))
1193     {
1194         hr = IExplorerBrowser_BrowseToIDList(iface, pidl, uFlags);
1195         ILFree(pidl);
1196     }
1197
1198     return hr;
1199 }
1200
1201 static HRESULT WINAPI IExplorerBrowser_fnFillFromObject(IExplorerBrowser *iface,
1202                                                         IUnknown *punk,
1203                                                         EXPLORER_BROWSER_FILL_FLAGS dwFlags)
1204 {
1205     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
1206     FIXME("stub, %p (%p, 0x%x)\n", This, punk, dwFlags);
1207
1208     return E_NOTIMPL;
1209 }
1210
1211 static HRESULT WINAPI IExplorerBrowser_fnRemoveAll(IExplorerBrowser *iface)
1212 {
1213     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
1214     FIXME("stub, %p\n", This);
1215
1216     return E_NOTIMPL;
1217 }
1218
1219 static HRESULT WINAPI IExplorerBrowser_fnGetCurrentView(IExplorerBrowser *iface,
1220                                                         REFIID riid, void **ppv)
1221 {
1222     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
1223     TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppv);
1224
1225     if(!This->psv)
1226         return E_FAIL;
1227
1228     return IShellView_QueryInterface(This->psv, riid, ppv);
1229 }
1230
1231 static const IExplorerBrowserVtbl vt_IExplorerBrowser =
1232 {
1233     IExplorerBrowser_fnQueryInterface,
1234     IExplorerBrowser_fnAddRef,
1235     IExplorerBrowser_fnRelease,
1236     IExplorerBrowser_fnInitialize,
1237     IExplorerBrowser_fnDestroy,
1238     IExplorerBrowser_fnSetRect,
1239     IExplorerBrowser_fnSetPropertyBag,
1240     IExplorerBrowser_fnSetEmptyText,
1241     IExplorerBrowser_fnSetFolderSettings,
1242     IExplorerBrowser_fnAdvise,
1243     IExplorerBrowser_fnUnadvise,
1244     IExplorerBrowser_fnSetOptions,
1245     IExplorerBrowser_fnGetOptions,
1246     IExplorerBrowser_fnBrowseToIDList,
1247     IExplorerBrowser_fnBrowseToObject,
1248     IExplorerBrowser_fnFillFromObject,
1249     IExplorerBrowser_fnRemoveAll,
1250     IExplorerBrowser_fnGetCurrentView
1251 };
1252
1253 /**************************************************************************
1254  * IShellBrowser Implementation
1255  */
1256
1257 static inline ExplorerBrowserImpl *impl_from_IShellBrowser(IShellBrowser *iface)
1258 {
1259     return (ExplorerBrowserImpl *)((char*)iface - FIELD_OFFSET(ExplorerBrowserImpl, lpsbVtbl));
1260 }
1261
1262 static HRESULT WINAPI IShellBrowser_fnQueryInterface(IShellBrowser *iface,
1263                                                      REFIID riid, void **ppvObject)
1264 {
1265     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1266     TRACE("%p\n", This);
1267     return IUnknown_QueryInterface((IUnknown*) This, riid, ppvObject);
1268 }
1269
1270 static ULONG WINAPI IShellBrowser_fnAddRef(IShellBrowser *iface)
1271 {
1272     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1273     TRACE("%p\n", This);
1274     return IUnknown_AddRef((IUnknown*) This);
1275 }
1276
1277 static ULONG WINAPI IShellBrowser_fnRelease(IShellBrowser *iface)
1278 {
1279     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1280     TRACE("%p\n", This);
1281     return IUnknown_Release((IUnknown*) This);
1282 }
1283
1284 static HRESULT WINAPI IShellBrowser_fnGetWindow(IShellBrowser *iface, HWND *phwnd)
1285 {
1286     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1287     TRACE("%p (%p)\n", This, phwnd);
1288
1289     if(!This->hwnd_main)
1290         return E_FAIL;
1291
1292     *phwnd = This->hwnd_main;
1293     return S_OK;
1294 }
1295
1296 static HRESULT WINAPI IShellBrowser_fnContextSensitiveHelp(IShellBrowser *iface,
1297                                                            BOOL fEnterMode)
1298 {
1299     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1300     FIXME("stub, %p (%d)\n", This, fEnterMode);
1301
1302     return E_NOTIMPL;
1303 }
1304
1305 static HRESULT WINAPI IShellBrowser_fnInsertMenusSB(IShellBrowser *iface,
1306                                                     HMENU hmenuShared,
1307                                                     LPOLEMENUGROUPWIDTHS lpMenuWidths)
1308 {
1309     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1310     TRACE("%p (%p, %p)\n", This, hmenuShared, lpMenuWidths);
1311
1312     /* Not implemented. */
1313     return E_NOTIMPL;
1314 }
1315
1316 static HRESULT WINAPI IShellBrowser_fnSetMenuSB(IShellBrowser *iface,
1317                                                 HMENU hmenuShared,
1318                                                 HOLEMENU holemenuReserved,
1319                                                 HWND hwndActiveObject)
1320 {
1321     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1322     TRACE("%p (%p, %p, %p)\n", This, hmenuShared, holemenuReserved, hwndActiveObject);
1323
1324     /* Not implemented. */
1325     return E_NOTIMPL;
1326 }
1327
1328 static HRESULT WINAPI IShellBrowser_fnRemoveMenusSB(IShellBrowser *iface,
1329                                                     HMENU hmenuShared)
1330 {
1331     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1332     TRACE("%p (%p)\n", This, hmenuShared);
1333
1334     /* Not implemented. */
1335     return E_NOTIMPL;
1336 }
1337
1338 static HRESULT WINAPI IShellBrowser_fnSetStatusTextSB(IShellBrowser *iface,
1339                                                       LPCOLESTR pszStatusText)
1340 {
1341     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1342     FIXME("stub, %p (%s)\n", This, debugstr_w(pszStatusText));
1343
1344     return E_NOTIMPL;
1345 }
1346
1347 static HRESULT WINAPI IShellBrowser_fnEnableModelessSB(IShellBrowser *iface,
1348                                                        BOOL fEnable)
1349 {
1350     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1351     FIXME("stub, %p (%d)\n", This, fEnable);
1352
1353     return E_NOTIMPL;
1354 }
1355
1356 static HRESULT WINAPI IShellBrowser_fnTranslateAcceleratorSB(IShellBrowser *iface,
1357                                                              MSG *pmsg, WORD wID)
1358 {
1359     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1360     FIXME("stub, %p (%p, 0x%x)\n", This, pmsg, wID);
1361
1362     return E_NOTIMPL;
1363 }
1364
1365 static HRESULT WINAPI IShellBrowser_fnBrowseObject(IShellBrowser *iface,
1366                                                    LPCITEMIDLIST pidl, UINT wFlags)
1367 {
1368     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1369     TRACE("%p (%p, %x)\n", This, pidl, wFlags);
1370
1371     return IExplorerBrowser_fnBrowseToIDList((IExplorerBrowser*)This, pidl, wFlags);
1372 }
1373
1374 static HRESULT WINAPI IShellBrowser_fnGetViewStateStream(IShellBrowser *iface,
1375                                                          DWORD grfMode,
1376                                                          IStream **ppStrm)
1377 {
1378     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1379     FIXME("stub, %p (0x%x, %p)\n", This, grfMode, ppStrm);
1380
1381     *ppStrm = NULL;
1382     return E_FAIL;
1383 }
1384
1385 static HRESULT WINAPI IShellBrowser_fnGetControlWindow(IShellBrowser *iface,
1386                                                        UINT id, HWND *phwnd)
1387 {
1388     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1389     TRACE("%p (%d, %p)\n", This, id, phwnd);
1390
1391     /* Not implemented. */
1392     return E_NOTIMPL;
1393 }
1394
1395 static HRESULT WINAPI IShellBrowser_fnSendControlMsg(IShellBrowser *iface,
1396                                                      UINT id, UINT uMsg,
1397                                                      WPARAM wParam, LPARAM lParam,
1398                                                      LRESULT *pret)
1399 {
1400     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1401     FIXME("stub, %p (%d, %d, %lx, %lx, %p)\n", This, id, uMsg, wParam, lParam, pret);
1402
1403     return E_NOTIMPL;
1404 }
1405
1406 static HRESULT WINAPI IShellBrowser_fnQueryActiveShellView(IShellBrowser *iface,
1407                                                            IShellView **ppshv)
1408 {
1409     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1410     TRACE("%p (%p)\n", This, ppshv);
1411
1412     if(!This->psv)
1413         return E_FAIL;
1414
1415     *ppshv = This->psv;
1416     IShellView_AddRef(This->psv);
1417
1418     return S_OK;
1419 }
1420
1421 static HRESULT WINAPI IShellBrowser_fnOnViewWindowActive(IShellBrowser *iface,
1422                                                          IShellView *pshv)
1423 {
1424     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1425     FIXME("stub, %p (%p)\n", This, pshv);
1426
1427     return E_NOTIMPL;
1428 }
1429
1430 static HRESULT WINAPI IShellBrowser_fnSetToolbarItems(IShellBrowser *iface,
1431                                                       LPTBBUTTONSB lpButtons,
1432                                                       UINT nButtons, UINT uFlags)
1433 {
1434     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
1435     FIXME("stub, %p (%p, %d, 0x%x)\n", This, lpButtons, nButtons, uFlags);
1436
1437     return E_NOTIMPL;
1438 }
1439
1440 static const IShellBrowserVtbl vt_IShellBrowser = {
1441     IShellBrowser_fnQueryInterface,
1442     IShellBrowser_fnAddRef,
1443     IShellBrowser_fnRelease,
1444     IShellBrowser_fnGetWindow,
1445     IShellBrowser_fnContextSensitiveHelp,
1446     IShellBrowser_fnInsertMenusSB,
1447     IShellBrowser_fnSetMenuSB,
1448     IShellBrowser_fnRemoveMenusSB,
1449     IShellBrowser_fnSetStatusTextSB,
1450     IShellBrowser_fnEnableModelessSB,
1451     IShellBrowser_fnTranslateAcceleratorSB,
1452     IShellBrowser_fnBrowseObject,
1453     IShellBrowser_fnGetViewStateStream,
1454     IShellBrowser_fnGetControlWindow,
1455     IShellBrowser_fnSendControlMsg,
1456     IShellBrowser_fnQueryActiveShellView,
1457     IShellBrowser_fnOnViewWindowActive,
1458     IShellBrowser_fnSetToolbarItems
1459 };
1460
1461 /**************************************************************************
1462  * ICommDlgBrowser3 Implementation
1463  */
1464
1465 static inline ExplorerBrowserImpl *impl_from_ICommDlgBrowser3(ICommDlgBrowser3 *iface)
1466 {
1467     return (ExplorerBrowserImpl *)((char*)iface - FIELD_OFFSET(ExplorerBrowserImpl, lpcdb3Vtbl));
1468 }
1469
1470 static HRESULT WINAPI ICommDlgBrowser3_fnQueryInterface(ICommDlgBrowser3 *iface,
1471                                                         REFIID riid,
1472                                                         void **ppvObject)
1473 {
1474     ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1475     TRACE("%p\n", This);
1476     return IUnknown_QueryInterface((IUnknown*) This, riid, ppvObject);
1477 }
1478
1479 static ULONG WINAPI ICommDlgBrowser3_fnAddRef(ICommDlgBrowser3 *iface)
1480 {
1481     ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1482     TRACE("%p\n", This);
1483     return IUnknown_AddRef((IUnknown*) This);
1484 }
1485
1486 static ULONG WINAPI ICommDlgBrowser3_fnRelease(ICommDlgBrowser3 *iface)
1487 {
1488     ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1489     TRACE("%p\n", This);
1490     return IUnknown_Release((IUnknown*) This);
1491 }
1492
1493 static HRESULT WINAPI ICommDlgBrowser3_fnOnDefaultCommand(ICommDlgBrowser3 *iface,
1494                                                           IShellView *shv)
1495 {
1496     ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1497     IDataObject *pdo;
1498     HRESULT hr;
1499     HRESULT ret = S_FALSE;
1500
1501     TRACE("%p (%p)\n", This, shv);
1502
1503     hr = IShellView_GetItemObject(shv, SVGIO_SELECTION, &IID_IDataObject, (void**)&pdo);
1504     if(SUCCEEDED(hr))
1505     {
1506         FORMATETC fmt;
1507         STGMEDIUM medium;
1508
1509         fmt.cfFormat = RegisterClipboardFormatW(CFSTR_SHELLIDLISTW);
1510         fmt.ptd = NULL;
1511         fmt.dwAspect = DVASPECT_CONTENT;
1512         fmt.lindex = -1;
1513         fmt.tymed = TYMED_HGLOBAL;
1514
1515         hr = IDataObject_GetData(pdo, &fmt ,&medium);
1516         IDataObject_Release(pdo);
1517         if(SUCCEEDED(hr))
1518         {
1519             LPIDA pida = GlobalLock(medium.u.hGlobal);
1520             LPCITEMIDLIST pidl_child = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[1]);
1521
1522             /* Handle folders by browsing to them. */
1523             if(_ILIsFolder(pidl_child) || _ILIsDrive(pidl_child) || _ILIsSpecialFolder(pidl_child))
1524             {
1525                 IExplorerBrowser_BrowseToIDList((IExplorerBrowser*)This, pidl_child, SBSP_RELATIVE);
1526                 ret = S_OK;
1527             }
1528             GlobalUnlock(medium.u.hGlobal);
1529             GlobalFree(medium.u.hGlobal);
1530         }
1531         else
1532             ERR("Failed to get data from IDataObject.\n");
1533     } else
1534         ERR("Failed to get IDataObject.\n");
1535
1536     /* If we didn't handle the default command, check if we have a
1537      * client that does */
1538     if(ret == S_FALSE && This->pcdb_site)
1539         return ICommDlgBrowser_OnDefaultCommand(This->pcdb_site, shv);
1540
1541     return ret;
1542 }
1543 static HRESULT WINAPI ICommDlgBrowser3_fnOnStateChange(ICommDlgBrowser3 *iface,
1544                                                        IShellView *shv, ULONG uChange)
1545 {
1546     ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1547     TRACE("%p (%p, %d)\n", This, shv, uChange);
1548
1549     if(This->pcdb_site)
1550         return ICommDlgBrowser_OnStateChange(This->pcdb_site, shv, uChange);
1551
1552     return E_NOTIMPL;
1553 }
1554 static HRESULT WINAPI ICommDlgBrowser3_fnIncludeObject(ICommDlgBrowser3 *iface,
1555                                                        IShellView *pshv, LPCITEMIDLIST pidl)
1556 {
1557     ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1558     TRACE("%p (%p, %p)\n", This, pshv, pidl);
1559
1560     if(This->pcdb_site)
1561         return ICommDlgBrowser_IncludeObject(This->pcdb_site, pshv, pidl);
1562
1563     return S_OK;
1564 }
1565
1566 static HRESULT WINAPI ICommDlgBrowser3_fnNotify(ICommDlgBrowser3 *iface,
1567                                                 IShellView *pshv,
1568                                                 DWORD dwNotifyType)
1569 {
1570     ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1571     TRACE("%p (%p, 0x%x)\n", This, pshv, dwNotifyType);
1572
1573     if(This->pcdb2_site)
1574         return ICommDlgBrowser2_Notify(This->pcdb2_site, pshv, dwNotifyType);
1575
1576     return S_OK;
1577 }
1578
1579 static HRESULT WINAPI ICommDlgBrowser3_fnGetDefaultMenuText(ICommDlgBrowser3 *iface,
1580                                                             IShellView *pshv,
1581                                                             LPWSTR pszText, int cchMax)
1582 {
1583     ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1584     TRACE("%p (%p, %s, %d)\n", This, pshv, debugstr_w(pszText), cchMax);
1585
1586     if(This->pcdb2_site)
1587         return ICommDlgBrowser2_GetDefaultMenuText(This->pcdb2_site, pshv, pszText, cchMax);
1588
1589     return S_OK;
1590 }
1591
1592 static HRESULT WINAPI ICommDlgBrowser3_fnGetViewFlags(ICommDlgBrowser3 *iface,
1593                                                       DWORD *pdwFlags)
1594 {
1595     ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1596     TRACE("%p (%p)\n", This, pdwFlags);
1597
1598     if(This->pcdb2_site)
1599         return ICommDlgBrowser2_GetViewFlags(This->pcdb2_site, pdwFlags);
1600
1601     return S_OK;
1602 }
1603
1604 static HRESULT WINAPI ICommDlgBrowser3_fnOnColumnClicked(ICommDlgBrowser3 *iface,
1605                                                          IShellView *pshv, int iColumn)
1606 {
1607     ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1608     TRACE("%p (%p, %d)\n", This, pshv, iColumn);
1609
1610     if(This->pcdb3_site)
1611         return ICommDlgBrowser3_OnColumnClicked(This->pcdb3_site, pshv, iColumn);
1612
1613     return S_OK;
1614 }
1615
1616 static HRESULT WINAPI ICommDlgBrowser3_fnGetCurrentFilter(ICommDlgBrowser3 *iface,
1617                                                           LPWSTR pszFileSpec,
1618                                                           int cchFileSpec)
1619 {
1620     ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1621     TRACE("%p (%s, %d)\n", This, debugstr_w(pszFileSpec), cchFileSpec);
1622
1623     if(This->pcdb3_site)
1624         return ICommDlgBrowser3_GetCurrentFilter(This->pcdb3_site, pszFileSpec, cchFileSpec);
1625
1626     return S_OK;
1627 }
1628
1629 static HRESULT WINAPI ICommDlgBrowser3_fnOnPreviewCreated(ICommDlgBrowser3 *iface,
1630                                                           IShellView *pshv)
1631 {
1632     ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
1633     TRACE("%p (%p)\n", This, pshv);
1634
1635     if(This->pcdb3_site)
1636         return ICommDlgBrowser3_OnPreviewCreated(This->pcdb3_site, pshv);
1637
1638     return S_OK;
1639 }
1640
1641 static const ICommDlgBrowser3Vtbl vt_ICommDlgBrowser3 = {
1642     ICommDlgBrowser3_fnQueryInterface,
1643     ICommDlgBrowser3_fnAddRef,
1644     ICommDlgBrowser3_fnRelease,
1645     ICommDlgBrowser3_fnOnDefaultCommand,
1646     ICommDlgBrowser3_fnOnStateChange,
1647     ICommDlgBrowser3_fnIncludeObject,
1648     ICommDlgBrowser3_fnNotify,
1649     ICommDlgBrowser3_fnGetDefaultMenuText,
1650     ICommDlgBrowser3_fnGetViewFlags,
1651     ICommDlgBrowser3_fnOnColumnClicked,
1652     ICommDlgBrowser3_fnGetCurrentFilter,
1653     ICommDlgBrowser3_fnOnPreviewCreated
1654 };
1655
1656 /**************************************************************************
1657  * IObjectWithSite Implementation
1658  */
1659
1660 static inline ExplorerBrowserImpl *impl_from_IObjectWithSite(IObjectWithSite *iface)
1661 {
1662     return (ExplorerBrowserImpl *)((char*)iface - FIELD_OFFSET(ExplorerBrowserImpl, lpowsVtbl));
1663 }
1664
1665 static HRESULT WINAPI IObjectWithSite_fnQueryInterface(IObjectWithSite *iface,
1666                                                        REFIID riid, void **ppvObject)
1667 {
1668     ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
1669     TRACE("%p\n", This);
1670     return IUnknown_QueryInterface((IUnknown*)This, riid, ppvObject);
1671 }
1672
1673 static ULONG WINAPI IObjectWithSite_fnAddRef(IObjectWithSite *iface)
1674 {
1675     ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
1676     TRACE("%p\n", This);
1677     return IUnknown_AddRef((IUnknown*)This);
1678 }
1679
1680 static ULONG WINAPI IObjectWithSite_fnRelease(IObjectWithSite *iface)
1681 {
1682     ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
1683     TRACE("%p\n", This);
1684     return IUnknown_Release((IUnknown*)This);
1685 }
1686
1687 static HRESULT WINAPI IObjectWithSite_fnSetSite(IObjectWithSite *iface, IUnknown *punk_site)
1688 {
1689     ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
1690     TRACE("%p (%p)\n", This, punk_site);
1691
1692     if(This->punk_site)
1693     {
1694         IUnknown_Release(This->punk_site);
1695         This->punk_site = NULL;
1696         get_interfaces_from_site(This);
1697     }
1698
1699     This->punk_site = punk_site;
1700
1701     if(This->punk_site)
1702         IUnknown_AddRef(This->punk_site);
1703
1704     return S_OK;
1705 }
1706
1707 static HRESULT WINAPI IObjectWithSite_fnGetSite(IObjectWithSite *iface, REFIID riid, void **ppvSite)
1708 {
1709     ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
1710     TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppvSite);
1711
1712     if(!This->punk_site)
1713         return E_FAIL;
1714
1715     return IUnknown_QueryInterface(This->punk_site, riid, ppvSite);
1716 }
1717
1718 static const IObjectWithSiteVtbl vt_IObjectWithSite = {
1719     IObjectWithSite_fnQueryInterface,
1720     IObjectWithSite_fnAddRef,
1721     IObjectWithSite_fnRelease,
1722     IObjectWithSite_fnSetSite,
1723     IObjectWithSite_fnGetSite
1724 };
1725
1726 /**************************************************************************
1727  * INameSpaceTreeControlEvents Implementation
1728  */
1729 static inline ExplorerBrowserImpl *impl_from_INameSpaceTreeControlEvents(INameSpaceTreeControlEvents *iface)
1730 {
1731     return (ExplorerBrowserImpl *)((char*)iface - FIELD_OFFSET(ExplorerBrowserImpl, lpnstceVtbl));
1732 }
1733
1734 static HRESULT WINAPI NSTCEvents_fnQueryInterface(INameSpaceTreeControlEvents *iface,
1735                                                   REFIID riid, void **ppvObject)
1736 {
1737     ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1738     TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppvObject);
1739
1740     *ppvObject = NULL;
1741     if(IsEqualIID(riid, &IID_INameSpaceTreeControlEvents) ||
1742        IsEqualIID(riid, &IID_IUnknown))
1743     {
1744         *ppvObject = iface;
1745     }
1746
1747     if(*ppvObject)
1748     {
1749         IUnknown_AddRef((IUnknown*)*ppvObject);
1750         return S_OK;
1751     }
1752
1753     return E_NOINTERFACE;
1754 }
1755
1756 static ULONG WINAPI NSTCEvents_fnAddRef(INameSpaceTreeControlEvents *iface)
1757 {
1758     ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1759     TRACE("%p\n", This);
1760     return IUnknown_AddRef((IUnknown*)This);
1761 }
1762
1763 static ULONG WINAPI NSTCEvents_fnRelease(INameSpaceTreeControlEvents *iface)
1764 {
1765     ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1766     TRACE("%p\n", This);
1767     return IUnknown_Release((IUnknown*)This);
1768 }
1769
1770 static HRESULT WINAPI NSTCEvents_fnOnItemClick(INameSpaceTreeControlEvents *iface,
1771                                                IShellItem *psi,
1772                                                NSTCEHITTEST nstceHitTest,
1773                                                NSTCECLICKTYPE nstceClickType)
1774 {
1775     ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1776     TRACE("%p (%p, 0x%x, 0x%x)\n", This, psi, nstceHitTest, nstceClickType);
1777     return S_OK;
1778 }
1779
1780 static HRESULT WINAPI NSTCEvents_fnOnPropertyItemCommit(INameSpaceTreeControlEvents *iface,
1781                                                         IShellItem *psi)
1782 {
1783     ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1784     TRACE("%p (%p)\n", This, psi);
1785     return E_NOTIMPL;
1786 }
1787
1788 static HRESULT WINAPI NSTCEvents_fnOnItemStateChanging(INameSpaceTreeControlEvents *iface,
1789                                                        IShellItem *psi,
1790                                                        NSTCITEMSTATE nstcisMask,
1791                                                        NSTCITEMSTATE nstcisState)
1792 {
1793     ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1794     TRACE("%p (%p, 0x%x, 0x%x)\n", This, psi, nstcisMask, nstcisState);
1795     return E_NOTIMPL;
1796 }
1797
1798 static HRESULT WINAPI NSTCEvents_fnOnItemStateChanged(INameSpaceTreeControlEvents *iface,
1799                                                       IShellItem *psi,
1800                                                       NSTCITEMSTATE nstcisMask,
1801                                                       NSTCITEMSTATE nstcisState)
1802 {
1803     ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1804     TRACE("%p (%p, 0x%x, 0x%x)\n", This, psi, nstcisMask, nstcisState);
1805     return E_NOTIMPL;
1806 }
1807
1808 static HRESULT WINAPI NSTCEvents_fnOnSelectionChanged(INameSpaceTreeControlEvents *iface,
1809                                                       IShellItemArray *psiaSelection)
1810 {
1811     ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1812     TRACE("%p (%p)\n", This, psiaSelection);
1813     return E_NOTIMPL;
1814 }
1815
1816 static HRESULT WINAPI NSTCEvents_fnOnKeyboardInput(INameSpaceTreeControlEvents *iface,
1817                                                    UINT uMsg, WPARAM wParam, LPARAM lParam)
1818 {
1819     ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1820     TRACE("%p (%d, 0x%lx, 0x%lx)\n", This, uMsg, wParam, lParam);
1821     return S_OK;
1822 }
1823
1824 static HRESULT WINAPI NSTCEvents_fnOnBeforeExpand(INameSpaceTreeControlEvents *iface,
1825                                                   IShellItem *psi)
1826 {
1827     ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1828     TRACE("%p (%p)\n", This, psi);
1829     return E_NOTIMPL;
1830 }
1831
1832 static HRESULT WINAPI NSTCEvents_fnOnAfterExpand(INameSpaceTreeControlEvents *iface,
1833                                                  IShellItem *psi)
1834 {
1835     ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1836     TRACE("%p (%p)\n", This, psi);
1837     return E_NOTIMPL;
1838 }
1839
1840 static HRESULT WINAPI NSTCEvents_fnOnBeginLabelEdit(INameSpaceTreeControlEvents *iface,
1841                                                     IShellItem *psi)
1842 {
1843     ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1844     TRACE("%p (%p)\n", This, psi);
1845     return E_NOTIMPL;
1846 }
1847
1848 static HRESULT WINAPI NSTCEvents_fnOnEndLabelEdit(INameSpaceTreeControlEvents *iface,
1849                                                   IShellItem *psi)
1850 {
1851     ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1852     TRACE("%p (%p)\n", This, psi);
1853     return E_NOTIMPL;
1854 }
1855
1856 static HRESULT WINAPI NSTCEvents_fnOnGetToolTip(INameSpaceTreeControlEvents *iface,
1857                                                 IShellItem *psi, LPWSTR pszTip, int cchTip)
1858 {
1859     ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1860     TRACE("%p (%p, %p, %d)\n", This, psi, pszTip, cchTip);
1861     return E_NOTIMPL;
1862 }
1863
1864 static HRESULT WINAPI NSTCEvents_fnOnBeforeItemDelete(INameSpaceTreeControlEvents *iface,
1865                                                       IShellItem *psi)
1866 {
1867     ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1868     TRACE("%p (%p)\n", This, psi);
1869     return E_NOTIMPL;
1870 }
1871
1872 static HRESULT WINAPI NSTCEvents_fnOnItemAdded(INameSpaceTreeControlEvents *iface,
1873                                                IShellItem *psi, BOOL fIsRoot)
1874 {
1875     ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1876     TRACE("%p (%p, %d)\n", This, psi, fIsRoot);
1877     return E_NOTIMPL;
1878 }
1879
1880 static HRESULT WINAPI NSTCEvents_fnOnItemDeleted(INameSpaceTreeControlEvents *iface,
1881                                                  IShellItem *psi, BOOL fIsRoot)
1882 {
1883     ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1884     TRACE("%p (%p, %d)\n", This, psi, fIsRoot);
1885     return E_NOTIMPL;
1886 }
1887
1888 static HRESULT WINAPI NSTCEvents_fnOnBeforeContextMenu(INameSpaceTreeControlEvents *iface,
1889                                                        IShellItem *psi, REFIID riid, void **ppv)
1890 {
1891     ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1892     TRACE("%p (%p, %s, %p)\n", This, psi, shdebugstr_guid(riid), ppv);
1893     return E_NOTIMPL;
1894 }
1895
1896 static HRESULT WINAPI NSTCEvents_fnOnAfterContextMenu(INameSpaceTreeControlEvents *iface,
1897                                                       IShellItem *psi, IContextMenu *pcmIn,
1898                                                       REFIID riid, void **ppv)
1899 {
1900     ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1901     TRACE("%p (%p, %p, %s, %p)\n", This, psi, pcmIn, shdebugstr_guid(riid), ppv);
1902     return E_NOTIMPL;
1903 }
1904
1905 static HRESULT WINAPI NSTCEvents_fnOnBeforeStateImageChange(INameSpaceTreeControlEvents *iface,
1906                                                             IShellItem *psi)
1907 {
1908     ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1909     TRACE("%p (%p)\n", This, psi);
1910     return E_NOTIMPL;
1911 }
1912
1913 static HRESULT WINAPI NSTCEvents_fnOnGetDefaultIconIndex(INameSpaceTreeControlEvents* iface,
1914                                                          IShellItem *psi,
1915                                                          int *piDefaultIcon, int *piOpenIcon)
1916 {
1917     ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
1918     TRACE("%p (%p, %p, %p)\n", This, psi, piDefaultIcon, piOpenIcon);
1919     return E_NOTIMPL;
1920 }
1921
1922
1923 const INameSpaceTreeControlEventsVtbl vt_INameSpaceTreeControlEvents =  {
1924     NSTCEvents_fnQueryInterface,
1925     NSTCEvents_fnAddRef,
1926     NSTCEvents_fnRelease,
1927     NSTCEvents_fnOnItemClick,
1928     NSTCEvents_fnOnPropertyItemCommit,
1929     NSTCEvents_fnOnItemStateChanging,
1930     NSTCEvents_fnOnItemStateChanged,
1931     NSTCEvents_fnOnSelectionChanged,
1932     NSTCEvents_fnOnKeyboardInput,
1933     NSTCEvents_fnOnBeforeExpand,
1934     NSTCEvents_fnOnAfterExpand,
1935     NSTCEvents_fnOnBeginLabelEdit,
1936     NSTCEvents_fnOnEndLabelEdit,
1937     NSTCEvents_fnOnGetToolTip,
1938     NSTCEvents_fnOnBeforeItemDelete,
1939     NSTCEvents_fnOnItemAdded,
1940     NSTCEvents_fnOnItemDeleted,
1941     NSTCEvents_fnOnBeforeContextMenu,
1942     NSTCEvents_fnOnAfterContextMenu,
1943     NSTCEvents_fnOnBeforeStateImageChange,
1944     NSTCEvents_fnOnGetDefaultIconIndex
1945 };
1946
1947 HRESULT WINAPI ExplorerBrowser_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv)
1948 {
1949     ExplorerBrowserImpl *eb;
1950     HRESULT ret;
1951
1952     TRACE("%p %s %p\n", pUnkOuter, shdebugstr_guid (riid), ppv);
1953
1954     if(!ppv)
1955         return E_POINTER;
1956     if(pUnkOuter)
1957         return CLASS_E_NOAGGREGATION;
1958
1959     eb = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ExplorerBrowserImpl));
1960     eb->ref = 1;
1961     eb->lpVtbl = &vt_IExplorerBrowser;
1962     eb->lpsbVtbl = &vt_IShellBrowser;
1963     eb->lpcdb3Vtbl = &vt_ICommDlgBrowser3;
1964     eb->lpowsVtbl = &vt_IObjectWithSite;
1965     eb->lpnstceVtbl = &vt_INameSpaceTreeControlEvents;
1966
1967     /* Default settings */
1968     eb->navpane.width = 150;
1969     eb->navpane.show = TRUE;
1970
1971     list_init(&eb->event_clients);
1972     list_init(&eb->travellog);
1973
1974     ret = IExplorerBrowser_QueryInterface((IExplorerBrowser*)eb, riid, ppv);
1975     IExplorerBrowser_Release((IExplorerBrowser*)eb);
1976
1977     TRACE("--(%p)\n", ppv);
1978     return ret;
1979 }