shell32: Implement IExplorerBrowser::Initialize.
[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/debug.h"
32 #include "debughlp.h"
33
34 #include "shell32_main.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(shell);
37
38 typedef struct _ExplorerBrowserImpl {
39     const IExplorerBrowserVtbl *lpVtbl;
40     const IShellBrowserVtbl *lpsbVtbl;
41     LONG ref;
42     BOOL destroyed;
43
44     HWND hwnd_main;
45 } ExplorerBrowserImpl;
46
47 /**************************************************************************
48  * Main window related functions.
49  */
50 static LRESULT main_on_wm_create(HWND hWnd, CREATESTRUCTW *crs)
51 {
52     ExplorerBrowserImpl *This = crs->lpCreateParams;
53     TRACE("%p\n", This);
54
55     SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LPARAM)This);
56     This->hwnd_main = hWnd;
57
58     return TRUE;
59 }
60
61 static LRESULT CALLBACK main_wndproc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
62 {
63     switch(uMessage)
64     {
65     case WM_CREATE:           return main_on_wm_create(hWnd, (CREATESTRUCTW*)lParam);
66     default:                  return DefWindowProcW(hWnd, uMessage, wParam, lParam);
67     }
68
69     return 0;
70 }
71
72 /**************************************************************************
73  * IExplorerBrowser Implementation
74  */
75 static HRESULT WINAPI IExplorerBrowser_fnQueryInterface(IExplorerBrowser *iface,
76                                                         REFIID riid, void **ppvObject)
77 {
78     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
79     TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppvObject);
80
81     *ppvObject = NULL;
82     if(IsEqualIID(riid, &IID_IExplorerBrowser) ||
83        IsEqualIID(riid, &IID_IUnknown))
84     {
85         *ppvObject = This;
86     }
87     else if(IsEqualIID(riid, &IID_IShellBrowser))
88     {
89         *ppvObject = &This->lpsbVtbl;
90     }
91
92     if(*ppvObject)
93     {
94         IUnknown_AddRef((IUnknown*)*ppvObject);
95         return S_OK;
96     }
97
98     return E_NOINTERFACE;
99 }
100
101 static ULONG WINAPI IExplorerBrowser_fnAddRef(IExplorerBrowser *iface)
102 {
103     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
104     LONG ref = InterlockedIncrement(&This->ref);
105     TRACE("%p - ref %d\n", This, ref);
106
107     return ref;
108 }
109
110 static ULONG WINAPI IExplorerBrowser_fnRelease(IExplorerBrowser *iface)
111 {
112     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
113     LONG ref = InterlockedDecrement(&This->ref);
114     TRACE("%p - ref %d\n", This, ref);
115
116     if(!ref)
117     {
118         TRACE("Freeing.\n");
119
120         if(!This->destroyed)
121             IExplorerBrowser_Destroy(iface);
122
123         HeapFree(GetProcessHeap(), 0, This);
124         return 0;
125     }
126
127     return ref;
128 }
129
130 static HRESULT WINAPI IExplorerBrowser_fnInitialize(IExplorerBrowser *iface,
131                                                     HWND hwndParent, const RECT *prc,
132                                                     const FOLDERSETTINGS *pfs)
133 {
134     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
135     WNDCLASSW wc;
136     LONG style;
137     static const WCHAR EB_CLASS_NAME[] =
138         {'E','x','p','l','o','r','e','r','B','r','o','w','s','e','r','C','o','n','t','r','o','l',0};
139
140     TRACE("%p (%p, %p, %p)\n", This, hwndParent, prc, pfs);
141
142     if(This->hwnd_main)
143         return E_UNEXPECTED;
144
145     if(!hwndParent)
146         return E_INVALIDARG;
147
148     if( !GetClassInfoW(shell32_hInstance, EB_CLASS_NAME, &wc) )
149     {
150         wc.style            = CS_HREDRAW | CS_VREDRAW;
151         wc.lpfnWndProc      = main_wndproc;
152         wc.cbClsExtra       = 0;
153         wc.cbWndExtra       = 0;
154         wc.hInstance        = shell32_hInstance;
155         wc.hIcon            = 0;
156         wc.hCursor          = LoadCursorW(0, (LPWSTR)IDC_ARROW);
157         wc.hbrBackground    = (HBRUSH)(COLOR_WINDOW + 1);
158         wc.lpszMenuName     = NULL;
159         wc.lpszClassName    = EB_CLASS_NAME;
160
161         if (!RegisterClassW(&wc)) return E_FAIL;
162     }
163
164     style = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_BORDER;
165     This->hwnd_main = CreateWindowExW(WS_EX_CONTROLPARENT, EB_CLASS_NAME, NULL, style,
166                                       prc->left, prc->top,
167                                       prc->right - prc->left, prc->bottom - prc->top,
168                                       hwndParent, 0, shell32_hInstance, This);
169
170     if(!This->hwnd_main)
171     {
172         ERR("Failed to create the window.\n");
173         return E_FAIL;
174     }
175
176     return S_OK;
177 }
178
179 static HRESULT WINAPI IExplorerBrowser_fnDestroy(IExplorerBrowser *iface)
180 {
181     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
182     TRACE("%p\n", This);
183
184     DestroyWindow(This->hwnd_main);
185     This->destroyed = TRUE;
186
187     return S_OK;
188 }
189
190 static HRESULT WINAPI IExplorerBrowser_fnSetRect(IExplorerBrowser *iface,
191                                                  HDWP *phdwp, RECT rcBrowser)
192 {
193     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
194     FIXME("stub, %p (%p, %s)\n", This, phdwp, wine_dbgstr_rect(&rcBrowser));
195
196     return E_NOTIMPL;
197 }
198
199 static HRESULT WINAPI IExplorerBrowser_fnSetPropertyBag(IExplorerBrowser *iface,
200                                                         LPCWSTR pszPropertyBag)
201 {
202     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
203     FIXME("stub, %p (%s)\n", This, debugstr_w(pszPropertyBag));
204
205     return E_NOTIMPL;
206 }
207
208 static HRESULT WINAPI IExplorerBrowser_fnSetEmptyText(IExplorerBrowser *iface,
209                                                       LPCWSTR pszEmptyText)
210 {
211     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
212     FIXME("stub, %p (%s)\n", This, debugstr_w(pszEmptyText));
213
214     return E_NOTIMPL;
215 }
216
217 static HRESULT WINAPI IExplorerBrowser_fnSetFolderSettings(IExplorerBrowser *iface,
218                                                            const FOLDERSETTINGS *pfs)
219 {
220     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
221     FIXME("stub, %p (%p)\n", This, pfs);
222
223     return E_NOTIMPL;
224 }
225
226 static HRESULT WINAPI IExplorerBrowser_fnAdvise(IExplorerBrowser *iface,
227                                                 IExplorerBrowserEvents *psbe,
228                                                 DWORD *pdwCookie)
229 {
230     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
231     FIXME("stub, %p (%p, %p)\n", This, psbe, pdwCookie);
232
233     return E_NOTIMPL;
234 }
235
236 static HRESULT WINAPI IExplorerBrowser_fnUnadvise(IExplorerBrowser *iface,
237                                                   DWORD dwCookie)
238 {
239     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
240     FIXME("stub, %p (0x%x)\n", This, dwCookie);
241
242     return E_NOTIMPL;
243 }
244
245 static HRESULT WINAPI IExplorerBrowser_fnSetOptions(IExplorerBrowser *iface,
246                                                     EXPLORER_BROWSER_OPTIONS dwFlag)
247 {
248     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
249     FIXME("stub, %p (0x%x)\n", This, dwFlag);
250
251     return E_NOTIMPL;
252 }
253
254 static HRESULT WINAPI IExplorerBrowser_fnGetOptions(IExplorerBrowser *iface,
255                                                     EXPLORER_BROWSER_OPTIONS *pdwFlag)
256 {
257     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
258     FIXME("stub, %p (%p)\n", This, pdwFlag);
259
260     return E_NOTIMPL;
261 }
262
263 static HRESULT WINAPI IExplorerBrowser_fnBrowseToIDList(IExplorerBrowser *iface,
264                                                         PCUIDLIST_RELATIVE pidl,
265                                                         UINT uFlags)
266 {
267     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
268     FIXME("stub, %p (%p, 0x%x)\n", This, pidl, uFlags);
269
270     return E_NOTIMPL;
271 }
272
273 static HRESULT WINAPI IExplorerBrowser_fnBrowseToObject(IExplorerBrowser *iface,
274                                                         IUnknown *punk, UINT uFlags)
275 {
276     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
277     FIXME("stub, %p (%p, 0x%x)\n", This, punk, uFlags);
278
279     return E_NOTIMPL;
280 }
281
282 static HRESULT WINAPI IExplorerBrowser_fnFillFromObject(IExplorerBrowser *iface,
283                                                         IUnknown *punk,
284                                                         EXPLORER_BROWSER_FILL_FLAGS dwFlags)
285 {
286     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
287     FIXME("stub, %p (%p, 0x%x)\n", This, punk, dwFlags);
288
289     return E_NOTIMPL;
290 }
291
292 static HRESULT WINAPI IExplorerBrowser_fnRemoveAll(IExplorerBrowser *iface)
293 {
294     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
295     FIXME("stub, %p\n", This);
296
297     return E_NOTIMPL;
298 }
299
300 static HRESULT WINAPI IExplorerBrowser_fnGetCurrentView(IExplorerBrowser *iface,
301                                                         REFIID riid, void **ppv)
302 {
303     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
304     FIXME("stub, %p (%s, %p)\n", This, shdebugstr_guid(riid), ppv);
305
306     *ppv = NULL;
307     return E_FAIL;
308 }
309
310 static const IExplorerBrowserVtbl vt_IExplorerBrowser =
311 {
312     IExplorerBrowser_fnQueryInterface,
313     IExplorerBrowser_fnAddRef,
314     IExplorerBrowser_fnRelease,
315     IExplorerBrowser_fnInitialize,
316     IExplorerBrowser_fnDestroy,
317     IExplorerBrowser_fnSetRect,
318     IExplorerBrowser_fnSetPropertyBag,
319     IExplorerBrowser_fnSetEmptyText,
320     IExplorerBrowser_fnSetFolderSettings,
321     IExplorerBrowser_fnAdvise,
322     IExplorerBrowser_fnUnadvise,
323     IExplorerBrowser_fnSetOptions,
324     IExplorerBrowser_fnGetOptions,
325     IExplorerBrowser_fnBrowseToIDList,
326     IExplorerBrowser_fnBrowseToObject,
327     IExplorerBrowser_fnFillFromObject,
328     IExplorerBrowser_fnRemoveAll,
329     IExplorerBrowser_fnGetCurrentView
330 };
331
332 /**************************************************************************
333  * IShellBrowser Implementation
334  */
335
336 static inline ExplorerBrowserImpl *impl_from_IShellBrowser(IShellBrowser *iface)
337 {
338     return (ExplorerBrowserImpl *)((char*)iface - FIELD_OFFSET(ExplorerBrowserImpl, lpsbVtbl));
339 }
340
341 static HRESULT WINAPI IShellBrowser_fnQueryInterface(IShellBrowser *iface,
342                                                      REFIID riid, void **ppvObject)
343 {
344     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
345     TRACE("%p\n", This);
346     return IUnknown_QueryInterface((IUnknown*) This, riid, ppvObject);
347 }
348
349 static ULONG WINAPI IShellBrowser_fnAddRef(IShellBrowser *iface)
350 {
351     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
352     TRACE("%p\n", This);
353     return IUnknown_AddRef((IUnknown*) This);
354 }
355
356 static ULONG WINAPI IShellBrowser_fnRelease(IShellBrowser *iface)
357 {
358     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
359     TRACE("%p\n", This);
360     return IUnknown_Release((IUnknown*) This);
361 }
362
363 static HRESULT WINAPI IShellBrowser_fnGetWindow(IShellBrowser *iface, HWND *phwnd)
364 {
365     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
366     TRACE("%p (%p)\n", This, phwnd);
367
368     if(!This->hwnd_main)
369         return E_FAIL;
370
371     *phwnd = This->hwnd_main;
372     return S_OK;
373 }
374
375 static HRESULT WINAPI IShellBrowser_fnContextSensitiveHelp(IShellBrowser *iface,
376                                                            BOOL fEnterMode)
377 {
378     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
379     FIXME("stub, %p (%d)\n", This, fEnterMode);
380
381     return E_NOTIMPL;
382 }
383
384 static HRESULT WINAPI IShellBrowser_fnInsertMenusSB(IShellBrowser *iface,
385                                                     HMENU hmenuShared,
386                                                     LPOLEMENUGROUPWIDTHS lpMenuWidths)
387 {
388     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
389     TRACE("%p (%p, %p)\n", This, hmenuShared, lpMenuWidths);
390
391     /* Not implemented. */
392     return E_NOTIMPL;
393 }
394
395 static HRESULT WINAPI IShellBrowser_fnSetMenuSB(IShellBrowser *iface,
396                                                 HMENU hmenuShared,
397                                                 HOLEMENU holemenuReserved,
398                                                 HWND hwndActiveObject)
399 {
400     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
401     TRACE("%p (%p, %p, %p)\n", This, hmenuShared, holemenuReserved, hwndActiveObject);
402
403     /* Not implemented. */
404     return E_NOTIMPL;
405 }
406
407 static HRESULT WINAPI IShellBrowser_fnRemoveMenusSB(IShellBrowser *iface,
408                                                     HMENU hmenuShared)
409 {
410     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
411     TRACE("%p (%p)\n", This, hmenuShared);
412
413     /* Not implemented. */
414     return E_NOTIMPL;
415 }
416
417 static HRESULT WINAPI IShellBrowser_fnSetStatusTextSB(IShellBrowser *iface,
418                                                       LPCOLESTR pszStatusText)
419 {
420     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
421     FIXME("stub, %p (%s)\n", This, debugstr_w(pszStatusText));
422
423     return E_NOTIMPL;
424 }
425
426 static HRESULT WINAPI IShellBrowser_fnEnableModelessSB(IShellBrowser *iface,
427                                                        BOOL fEnable)
428 {
429     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
430     FIXME("stub, %p (%d)\n", This, fEnable);
431
432     return E_NOTIMPL;
433 }
434
435 static HRESULT WINAPI IShellBrowser_fnTranslateAcceleratorSB(IShellBrowser *iface,
436                                                              MSG *pmsg, WORD wID)
437 {
438     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
439     FIXME("stub, %p (%p, 0x%x)\n", This, pmsg, wID);
440
441     return E_NOTIMPL;
442 }
443
444 static HRESULT WINAPI IShellBrowser_fnBrowseObject(IShellBrowser *iface,
445                                                    LPCITEMIDLIST pidl, UINT wFlags)
446 {
447     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
448     FIXME("stub, %p\n", This);
449
450     return E_NOTIMPL;
451 }
452
453 static HRESULT WINAPI IShellBrowser_fnGetViewStateStream(IShellBrowser *iface,
454                                                          DWORD grfMode,
455                                                          IStream **ppStrm)
456 {
457     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
458     FIXME("stub, %p (0x%x, %p)\n", This, grfMode, ppStrm);
459
460     *ppStrm = NULL;
461     return E_FAIL;
462 }
463
464 static HRESULT WINAPI IShellBrowser_fnGetControlWindow(IShellBrowser *iface,
465                                                        UINT id, HWND *phwnd)
466 {
467     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
468     TRACE("%p (%d, %p)\n", This, id, phwnd);
469
470     /* Not implemented. */
471     return E_NOTIMPL;
472 }
473
474 static HRESULT WINAPI IShellBrowser_fnSendControlMsg(IShellBrowser *iface,
475                                                      UINT id, UINT uMsg,
476                                                      WPARAM wParam, LPARAM lParam,
477                                                      LRESULT *pret)
478 {
479     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
480     FIXME("stub, %p (%d, %d, %lx, %lx, %p)\n", This, id, uMsg, wParam, lParam, pret);
481
482     return E_NOTIMPL;
483 }
484
485 static HRESULT WINAPI IShellBrowser_fnQueryActiveShellView(IShellBrowser *iface,
486                                                            IShellView **ppshv)
487 {
488     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
489     FIXME("stub, %p (%p)\n", This, ppshv);
490
491     return E_NOTIMPL;
492 }
493
494 static HRESULT WINAPI IShellBrowser_fnOnViewWindowActive(IShellBrowser *iface,
495                                                          IShellView *pshv)
496 {
497     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
498     FIXME("stub, %p (%p)\n", This, pshv);
499
500     return E_NOTIMPL;
501 }
502
503 static HRESULT WINAPI IShellBrowser_fnSetToolbarItems(IShellBrowser *iface,
504                                                       LPTBBUTTONSB lpButtons,
505                                                       UINT nButtons, UINT uFlags)
506 {
507     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
508     FIXME("stub, %p (%p, %d, 0x%x)\n", This, lpButtons, nButtons, uFlags);
509
510     return E_NOTIMPL;
511 }
512
513 static const IShellBrowserVtbl vt_IShellBrowser = {
514     IShellBrowser_fnQueryInterface,
515     IShellBrowser_fnAddRef,
516     IShellBrowser_fnRelease,
517     IShellBrowser_fnGetWindow,
518     IShellBrowser_fnContextSensitiveHelp,
519     IShellBrowser_fnInsertMenusSB,
520     IShellBrowser_fnSetMenuSB,
521     IShellBrowser_fnRemoveMenusSB,
522     IShellBrowser_fnSetStatusTextSB,
523     IShellBrowser_fnEnableModelessSB,
524     IShellBrowser_fnTranslateAcceleratorSB,
525     IShellBrowser_fnBrowseObject,
526     IShellBrowser_fnGetViewStateStream,
527     IShellBrowser_fnGetControlWindow,
528     IShellBrowser_fnSendControlMsg,
529     IShellBrowser_fnQueryActiveShellView,
530     IShellBrowser_fnOnViewWindowActive,
531     IShellBrowser_fnSetToolbarItems
532 };
533
534 HRESULT WINAPI ExplorerBrowser_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv)
535 {
536     ExplorerBrowserImpl *eb;
537     HRESULT ret;
538
539     TRACE("%p %s %p\n", pUnkOuter, shdebugstr_guid (riid), ppv);
540
541     if(!ppv)
542         return E_POINTER;
543     if(pUnkOuter)
544         return CLASS_E_NOAGGREGATION;
545
546     eb = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ExplorerBrowserImpl));
547     eb->ref = 1;
548     eb->lpVtbl = &vt_IExplorerBrowser;
549     eb->lpsbVtbl = &vt_IShellBrowser;
550
551     ret = IExplorerBrowser_QueryInterface((IExplorerBrowser*)eb, riid, ppv);
552     IExplorerBrowser_Release((IExplorerBrowser*)eb);
553
554     TRACE("--(%p)\n", ppv);
555     return ret;
556 }