Updated Swedish translation.
[wine] / dlls / commdlg / filedlgbrowser.c
1 /*
2  *  Implementation of IShellBrowser for the File Open common dialog
3  * 
4  *
5  */
6
7 #include <stdio.h>
8 #include <string.h>
9
10 #include "windef.h"
11 #include "winbase.h"
12 #include "winnls.h"
13 #include "wingdi.h"
14 #include "winuser.h"
15 #include "winreg.h"
16
17 #define NO_SHLWAPI_STREAM
18 #include "shlwapi.h"
19 #include "filedlgbrowser.h"
20 #include "cdlg.h"
21 #include "shlguid.h"
22 #include "wine/obj_serviceprovider.h"
23 #include "debugtools.h"
24
25 DEFAULT_DEBUG_CHANNEL(commdlg);
26
27 typedef struct
28 {
29
30     ICOM_VTABLE(IShellBrowser)   * lpVtbl;
31     ICOM_VTABLE(ICommDlgBrowser) * lpVtblCommDlgBrowser;
32     ICOM_VTABLE(IServiceProvider)* lpVtblServiceProvider;
33     DWORD ref;                                  /* Reference counter */
34     HWND hwndOwner;                             /* Owner dialog of the interface */
35
36 } IShellBrowserImpl;
37
38 /**************************************************************************
39 *   vtable
40 */
41 static ICOM_VTABLE(IShellBrowser) IShellBrowserImpl_Vtbl;
42 static ICOM_VTABLE(ICommDlgBrowser) IShellBrowserImpl_ICommDlgBrowser_Vtbl;
43 static ICOM_VTABLE(IServiceProvider) IShellBrowserImpl_IServiceProvider_Vtbl;
44
45 /**************************************************************************
46 *   Local Prototypes
47 */
48
49 HRESULT IShellBrowserImpl_ICommDlgBrowser_OnSelChange(ICommDlgBrowser *iface, IShellView *ppshv);
50 #if 0
51 LPITEMIDLIST GetSelectedPidl(IShellView *ppshv);
52 #endif
53
54 /**************************************************************************
55 *   External Prototypes
56 */
57 extern const char *FileOpenDlgInfosStr; 
58
59 extern HRESULT          GetName(LPSHELLFOLDER lpsf, LPITEMIDLIST pidl,DWORD dwFlags,LPSTR lpstrFileName);
60 extern HRESULT          GetFileName(HWND hwnd, LPITEMIDLIST pidl, LPSTR lpstrFileName);
61 extern IShellFolder*    GetShellFolderFromPidl(LPITEMIDLIST pidlAbs);
62 extern LPITEMIDLIST     GetParentPidl(LPITEMIDLIST pidl);
63 extern LPITEMIDLIST     GetPidlFromName(IShellFolder *psf,LPCSTR lpcstrFileName);
64
65 extern BOOL    FILEDLG95_SHELL_FillIncludedItemList(HWND hwnd,
66                                                         LPITEMIDLIST pidlCurrentFolder,
67                                                         LPSTR lpstrMask);
68
69 extern int     FILEDLG95_LOOKIN_SelectItem(HWND hwnd,LPITEMIDLIST pidl);
70 extern BOOL    FILEDLG95_OnOpen(HWND hwnd);
71 extern HRESULT SendCustomDlgNotificationMessage(HWND hwndParentDlg, UINT uCode);
72
73
74 /*
75  *   Helper functions
76  */
77
78 static void COMDLG32_UpdateCurrentDir(FileOpenDlgInfos *fodInfos)
79 {
80     char lpstrPath[MAX_PATH];
81     SHGetPathFromIDListA(fodInfos->ShellInfos.pidlAbsCurrent,lpstrPath);
82     SetCurrentDirectoryA(lpstrPath);
83     TRACE("new current folder %s\n", lpstrPath);
84 }
85
86 /* copied from shell32 to avoid linking to it */
87 static HRESULT COMDLG32_StrRetToStrNW (LPVOID dest, DWORD len, LPSTRRET src, LPITEMIDLIST pidl)
88 {
89         TRACE("dest=0x%p len=0x%lx strret=0x%p pidl=%p stub\n",dest,len,src,pidl);
90
91         switch (src->uType)
92         {
93           case STRRET_WSTR:
94             lstrcpynW((LPWSTR)dest, src->u.pOleStr, len);
95             COMDLG32_SHFree(src->u.pOleStr);
96             break;
97
98           case STRRET_CSTRA:
99             if (len && !MultiByteToWideChar( CP_ACP, 0, src->u.cStr, -1, (LPWSTR)dest, len ))
100                 ((LPWSTR)dest)[len-1] = 0;
101             break;
102
103           case STRRET_OFFSETA:
104             if (pidl)
105             {
106                 if (len && !MultiByteToWideChar( CP_ACP, 0, ((LPCSTR)&pidl->mkid)+src->u.uOffset,
107                                                  -1, (LPWSTR)dest, len ))
108                     ((LPWSTR)dest)[len-1] = 0;
109             }
110             break;
111
112           default:
113             FIXME("unknown type!\n");
114             if (len)
115             { *(LPWSTR)dest = '\0';
116             }
117             return(FALSE);
118         }
119         return S_OK;
120 }
121
122 /*
123  *      IShellBrowser
124  */
125  
126 /**************************************************************************
127 *  IShellBrowserImpl_Construct
128 */
129 IShellBrowser * IShellBrowserImpl_Construct(HWND hwndOwner)
130 {
131     IShellBrowserImpl *sb;
132     FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwndOwner,FileOpenDlgInfosStr);
133
134     sb=(IShellBrowserImpl*)COMDLG32_SHAlloc(sizeof(IShellBrowserImpl));
135
136     /* Initialisation of the member variables */
137     sb->ref=1;
138     sb->hwndOwner = hwndOwner;
139
140     /* Initialisation of the vTables */
141     sb->lpVtbl = &IShellBrowserImpl_Vtbl;
142     sb->lpVtblCommDlgBrowser = &IShellBrowserImpl_ICommDlgBrowser_Vtbl;
143     sb->lpVtblServiceProvider = &IShellBrowserImpl_IServiceProvider_Vtbl;
144     SHGetSpecialFolderLocation(hwndOwner, CSIDL_DESKTOP,
145                                &fodInfos->ShellInfos.pidlAbsCurrent);
146
147     TRACE("%p\n", sb);
148
149     return (IShellBrowser *) sb;
150 }
151
152 /***************************************************************************
153 *  IShellBrowserImpl_QueryInterface
154 */
155 HRESULT WINAPI IShellBrowserImpl_QueryInterface(IShellBrowser *iface,
156                                             REFIID riid, 
157                                             LPVOID *ppvObj)
158 {
159     ICOM_THIS(IShellBrowserImpl, iface);
160
161     TRACE("(%p)\n\t%s\n", This, debugstr_guid(riid));
162
163     *ppvObj = NULL;
164
165     if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
166     { *ppvObj = This; 
167     }
168     else if(IsEqualIID(riid, &IID_IOleWindow))  /*IOleWindow*/
169     { *ppvObj = (IOleWindow*)This;
170     }
171
172     else if(IsEqualIID(riid, &IID_IShellBrowser))  /*IShellBrowser*/
173     { *ppvObj = (IShellBrowser*)This;
174     }
175
176     else if(IsEqualIID(riid, &IID_ICommDlgBrowser))  /*ICommDlgBrowser*/
177     { *ppvObj = (ICommDlgBrowser*) &(This->lpVtblCommDlgBrowser);
178     }
179
180     else if(IsEqualIID(riid, &IID_IServiceProvider))  /* IServiceProvider */
181     { *ppvObj = (ICommDlgBrowser*) &(This->lpVtblServiceProvider);
182     }
183
184     if(*ppvObj)
185     { IUnknown_AddRef( (IShellBrowser*) *ppvObj);
186       return S_OK;
187     }
188     FIXME("Unknown interface requested\n");
189     return E_NOINTERFACE;
190 }
191
192 /**************************************************************************
193 *  IShellBrowser::AddRef
194 */
195 ULONG WINAPI IShellBrowserImpl_AddRef(IShellBrowser * iface)
196 {
197     ICOM_THIS(IShellBrowserImpl, iface);
198
199     TRACE("(%p)\n", This);
200
201     return ++(This->ref);
202 }
203
204 /**************************************************************************
205 *  IShellBrowserImpl_Release
206 */
207 ULONG WINAPI IShellBrowserImpl_Release(IShellBrowser * iface)
208 {
209     ICOM_THIS(IShellBrowserImpl, iface);
210
211     TRACE("(%p)\n", This);
212
213     if (!--(This->ref)) 
214     { 
215       HeapFree(GetProcessHeap(),0, This);
216       return 0;
217     }
218     return This->ref;
219 }
220
221 /*
222  * IOleWindow
223  */
224
225 /**************************************************************************
226 *  IShellBrowserImpl_GetWindow  (IOleWindow)
227 *
228 *  Inherited from IOleWindow::GetWindow
229 *
230 *  See Windows documentation for more details
231 *
232 *  Note : We will never be window less in the File Open dialog
233 *  
234 */
235 HRESULT WINAPI IShellBrowserImpl_GetWindow(IShellBrowser * iface,  
236                                            HWND * phwnd)
237 {
238     ICOM_THIS(IShellBrowserImpl, iface);
239
240     TRACE("(%p)\n", This);
241
242     if(!This->hwndOwner)
243         return E_FAIL;
244
245     *phwnd = This->hwndOwner;
246
247     return (*phwnd) ? S_OK : E_UNEXPECTED; 
248
249 }
250
251 /**************************************************************************
252 *  IShellBrowserImpl_ContextSensitiveHelp
253 */
254 HRESULT WINAPI IShellBrowserImpl_ContextSensitiveHelp(IShellBrowser * iface,
255                                                       BOOL fEnterMode)
256 {
257     ICOM_THIS(IShellBrowserImpl, iface);
258
259     TRACE("(%p)\n", This);
260
261     /* Feature not implemented */
262     return E_NOTIMPL;
263 }
264
265 /*
266  * IShellBrowser
267  */
268
269 /**************************************************************************
270 *  IShellBrowserImpl_BrowseObject
271 *
272 *  See Windows documentation on IShellBrowser::BrowseObject for more details
273 *
274 *  This function will override user specified flags and will always 
275 *  use SBSP_DEFBROWSER and SBSP_DEFMODE.  
276 */
277 HRESULT WINAPI IShellBrowserImpl_BrowseObject(IShellBrowser *iface, 
278                                               LPCITEMIDLIST pidl, 
279                                               UINT wFlags)
280 {
281     HRESULT hRes;
282     IShellFolder *psfTmp;
283     IShellView *psvTmp;
284     FileOpenDlgInfos *fodInfos;
285     LPITEMIDLIST pidlTmp;
286     HWND hwndView;
287     HWND hDlgWnd;
288     BOOL bViewHasFocus;
289
290     ICOM_THIS(IShellBrowserImpl, iface);
291
292     TRACE("(%p)(%p,0x%08x)\n", This, pidl, wFlags);
293
294     fodInfos = (FileOpenDlgInfos *) GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
295
296     /* Format the pidl according to its parameter's category */
297     if(wFlags & SBSP_RELATIVE)
298     {
299         
300         /* SBSP_RELATIVE  A relative pidl (relative from the current folder) */
301         if(FAILED(hRes = IShellFolder_BindToObject(fodInfos->Shell.FOIShellFolder,
302              pidl, NULL, &IID_IShellFolder, (LPVOID *)&psfTmp)))
303         {
304             ERR("bind to object failed\n");
305             return hRes;
306         }
307         /* create an absolute pidl */
308         pidlTmp = COMDLG32_PIDL_ILCombine(fodInfos->ShellInfos.pidlAbsCurrent,
309                                                         (LPITEMIDLIST)pidl);
310     }
311     else if(wFlags & SBSP_PARENT)
312     {
313         /* Browse the parent folder (ignores the pidl) */
314         pidlTmp = GetParentPidl(fodInfos->ShellInfos.pidlAbsCurrent);
315         psfTmp = GetShellFolderFromPidl(pidlTmp);
316
317     }
318     else /* SBSP_ABSOLUTE is 0x0000 */
319     {
320         /* An absolute pidl (relative from the desktop) */
321         pidlTmp =  COMDLG32_PIDL_ILClone((LPITEMIDLIST)pidl);
322         psfTmp = GetShellFolderFromPidl(pidlTmp);
323     }
324     
325     if(!psfTmp)
326     {
327       ERR("could not browse to folder\n");
328       return E_FAIL;
329     }
330
331     /* If the pidl to browse to is equal to the actual pidl ... 
332        do nothing and pretend you did it*/
333     if(COMDLG32_PIDL_ILIsEqual(pidlTmp,fodInfos->ShellInfos.pidlAbsCurrent))
334     {
335         IShellFolder_Release(psfTmp);
336         COMDLG32_SHFree(pidlTmp);
337         TRACE("keep current folder\n");
338         return NOERROR;
339     }
340
341     /* Release the current DataObject */
342     if (fodInfos->Shell.FOIDataObject)
343     {
344       IDataObject_Release(fodInfos->Shell.FOIDataObject);
345       fodInfos->Shell.FOIDataObject = NULL;
346     }
347
348     /* Create the associated view */
349     TRACE("create view object\n");
350     if(FAILED(hRes = IShellFolder_CreateViewObject(psfTmp, fodInfos->ShellInfos.hwndOwner,
351            &IID_IShellView, (LPVOID *)&psvTmp))) goto error;
352
353     /* Check if listview has focus */
354     bViewHasFocus = IsChild(fodInfos->ShellInfos.hwndView,GetFocus());
355
356     /* Get the foldersettings from the old view */
357     if(fodInfos->Shell.FOIShellView)
358       IShellView_GetCurrentInfo(fodInfos->Shell.FOIShellView, &fodInfos->ShellInfos.folderSettings);
359
360     /* Release the old fodInfos->Shell.FOIShellView and update its value.
361     We have to update this early since ShellView_CreateViewWindow of native
362     shell32 calls OnStateChange and needs the correct view here.*/
363     if(fodInfos->Shell.FOIShellView)
364     {
365       IShellView_DestroyViewWindow(fodInfos->Shell.FOIShellView);
366       IShellView_Release(fodInfos->Shell.FOIShellView);
367     }
368     fodInfos->Shell.FOIShellView = psvTmp;
369
370     /* Release old FOIShellFolder and update its value */
371     if (fodInfos->Shell.FOIShellFolder)
372       IShellFolder_Release(fodInfos->Shell.FOIShellFolder);
373     fodInfos->Shell.FOIShellFolder = psfTmp;
374
375     /* Release old pidlAbsCurrent and update its value */
376     COMDLG32_SHFree((LPVOID)fodInfos->ShellInfos.pidlAbsCurrent);
377     fodInfos->ShellInfos.pidlAbsCurrent = pidlTmp;
378
379     COMDLG32_UpdateCurrentDir(fodInfos);
380
381     /* Create the window */
382     TRACE("create view window\n");
383     if(FAILED(hRes = IShellView_CreateViewWindow(psvTmp, NULL,
384          &fodInfos->ShellInfos.folderSettings, fodInfos->Shell.FOIShellBrowser,
385          &fodInfos->ShellInfos.rectView, &hwndView))) goto error;
386
387     fodInfos->ShellInfos.hwndView = hwndView;
388
389     /* Select the new folder in the Look In combo box of the Open file dialog */
390     FILEDLG95_LOOKIN_SelectItem(fodInfos->DlgInfos.hwndLookInCB,fodInfos->ShellInfos.pidlAbsCurrent);
391
392     /* changes the tab order of the ListView to reflect the window's File Dialog */
393     hDlgWnd = GetDlgItem(GetParent(hwndView), IDC_LOOKIN); 
394     SetWindowPos(hwndView, hDlgWnd, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE);
395
396     /* Since we destroyed the old view if it had focus set focus to the newly created view */
397     if (bViewHasFocus)
398       SetFocus(fodInfos->ShellInfos.hwndView);
399
400     return hRes; 
401 error:
402     ERR("Failed with error 0x%08lx\n", hRes);
403     return hRes;
404 }
405
406 /**************************************************************************
407 *  IShellBrowserImpl_EnableModelessSB
408 */
409 HRESULT WINAPI IShellBrowserImpl_EnableModelessSB(IShellBrowser *iface,    
410                                               BOOL fEnable)
411                                               
412 {
413     ICOM_THIS(IShellBrowserImpl, iface);
414
415     TRACE("(%p)\n", This);
416
417     /* Feature not implemented */
418     return E_NOTIMPL;
419 }
420
421 /**************************************************************************
422 *  IShellBrowserImpl_GetControlWindow
423 */
424 HRESULT WINAPI IShellBrowserImpl_GetControlWindow(IShellBrowser *iface,    
425                                               UINT id,    
426                                               HWND *lphwnd)
427                                               
428 {
429     ICOM_THIS(IShellBrowserImpl, iface);
430
431     TRACE("(%p)\n", This);
432
433     /* Feature not implemented */
434     return E_NOTIMPL;
435 }
436 /**************************************************************************
437 *  IShellBrowserImpl_GetViewStateStream
438 */
439 HRESULT WINAPI IShellBrowserImpl_GetViewStateStream(IShellBrowser *iface,
440                                                 DWORD grfMode,    
441                                                 LPSTREAM *ppStrm)
442                                               
443 {
444     ICOM_THIS(IShellBrowserImpl, iface);
445
446     FIXME("(%p 0x%08lx %p)\n", This, grfMode, ppStrm);
447
448     /* Feature not implemented */
449     return E_NOTIMPL;
450 }       
451 /**************************************************************************
452 *  IShellBrowserImpl_InsertMenusSB
453 */
454 HRESULT WINAPI IShellBrowserImpl_InsertMenusSB(IShellBrowser *iface,
455                                            HMENU hmenuShared,
456                                            LPOLEMENUGROUPWIDTHS lpMenuWidths)
457                                               
458 {
459     ICOM_THIS(IShellBrowserImpl, iface);
460
461     TRACE("(%p)\n", This);
462
463     /* Feature not implemented */
464     return E_NOTIMPL;
465 }
466 /**************************************************************************
467 *  IShellBrowserImpl_OnViewWindowActive
468 */
469 HRESULT WINAPI IShellBrowserImpl_OnViewWindowActive(IShellBrowser *iface,
470                                                 IShellView *ppshv)
471                                               
472 {
473     ICOM_THIS(IShellBrowserImpl, iface);
474
475     TRACE("(%p)\n", This);
476
477     /* Feature not implemented */
478     return E_NOTIMPL;
479 }   
480 /**************************************************************************
481 *  IShellBrowserImpl_QueryActiveShellView
482 */
483 HRESULT WINAPI IShellBrowserImpl_QueryActiveShellView(IShellBrowser *iface,
484                                                   IShellView **ppshv)
485                                               
486 {
487     ICOM_THIS(IShellBrowserImpl, iface);
488
489     FileOpenDlgInfos *fodInfos;
490
491     TRACE("(%p)\n", This);
492
493     fodInfos = (FileOpenDlgInfos *) GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
494
495     if(!(*ppshv = fodInfos->Shell.FOIShellView))
496     {
497         return E_FAIL;
498     }
499     IShellView_AddRef(fodInfos->Shell.FOIShellView);
500     return NOERROR;
501 }   
502 /**************************************************************************
503 *  IShellBrowserImpl_RemoveMenusSB
504 */
505 HRESULT WINAPI IShellBrowserImpl_RemoveMenusSB(IShellBrowser *iface,
506                                            HMENU hmenuShared)
507                                               
508 {
509     ICOM_THIS(IShellBrowserImpl, iface);
510
511     TRACE("(%p)\n", This);
512
513     /* Feature not implemented */
514     return E_NOTIMPL;
515 }   
516 /**************************************************************************
517 *  IShellBrowserImpl_SendControlMsg
518 */
519 HRESULT WINAPI IShellBrowserImpl_SendControlMsg(IShellBrowser *iface,    
520                                             UINT id,    
521                                             UINT uMsg,    
522                                             WPARAM wParam,    
523                                             LPARAM lParam,
524                                             LRESULT *pret)
525                                               
526 {
527     ICOM_THIS(IShellBrowserImpl, iface);
528     LRESULT lres;
529     
530     TRACE("(%p)->(0x%08x 0x%08x 0x%08x 0x%08lx %p)\n", This, id, uMsg, wParam, lParam, pret);
531
532     switch (id)
533     {
534       case FCW_TOOLBAR:
535         lres = SendDlgItemMessageA( This->hwndOwner, IDC_TOOLBAR, uMsg, wParam, lParam);
536         break;
537       default:
538         FIXME("ctrl id: %x\n", id);
539         return E_NOTIMPL;
540     }
541     if (pret) *pret = lres;
542     return S_OK;
543 }
544 /**************************************************************************
545 *  IShellBrowserImpl_SetMenuSB
546 */
547 HRESULT WINAPI IShellBrowserImpl_SetMenuSB(IShellBrowser *iface,
548                                        HMENU hmenuShared,    
549                                        HOLEMENU holemenuReserved,
550                                        HWND hwndActiveObject)
551                                               
552 {
553     ICOM_THIS(IShellBrowserImpl, iface);
554
555     TRACE("(%p)\n", This);
556
557     /* Feature not implemented */
558     return E_NOTIMPL;
559 }   
560 /**************************************************************************
561 *  IShellBrowserImpl_SetStatusTextSB
562 */
563 HRESULT WINAPI IShellBrowserImpl_SetStatusTextSB(IShellBrowser *iface,
564                                              LPCOLESTR lpszStatusText)
565                                               
566 {
567     ICOM_THIS(IShellBrowserImpl, iface);
568
569     TRACE("(%p)\n", This);
570
571     /* Feature not implemented */
572     return E_NOTIMPL;
573 }   
574 /**************************************************************************
575 *  IShellBrowserImpl_SetToolbarItems
576 */
577 HRESULT WINAPI IShellBrowserImpl_SetToolbarItems(IShellBrowser *iface,
578                                              LPTBBUTTON lpButtons,    
579                                              UINT nButtons,    
580                                              UINT uFlags)
581                                               
582 {
583     ICOM_THIS(IShellBrowserImpl, iface);
584
585     TRACE("(%p)\n", This);
586
587     /* Feature not implemented */
588     return E_NOTIMPL;
589 }   
590 /**************************************************************************
591 *  IShellBrowserImpl_TranslateAcceleratorSB
592 */
593 HRESULT WINAPI IShellBrowserImpl_TranslateAcceleratorSB(IShellBrowser *iface,
594                                                     LPMSG lpmsg,    
595                                                     WORD wID)
596                                               
597 {
598     ICOM_THIS(IShellBrowserImpl, iface);
599
600     TRACE("(%p)\n", This);
601
602     /* Feature not implemented */
603     return E_NOTIMPL;
604 }
605
606 static ICOM_VTABLE(IShellBrowser) IShellBrowserImpl_Vtbl =
607 {
608         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
609         /* IUnknown */
610         IShellBrowserImpl_QueryInterface,
611         IShellBrowserImpl_AddRef,
612         IShellBrowserImpl_Release,
613         /* IOleWindow */
614         IShellBrowserImpl_GetWindow,
615         IShellBrowserImpl_ContextSensitiveHelp,
616         /*  IShellBrowser */
617         IShellBrowserImpl_InsertMenusSB,
618         IShellBrowserImpl_SetMenuSB,
619         IShellBrowserImpl_RemoveMenusSB,
620         IShellBrowserImpl_SetStatusTextSB,
621         IShellBrowserImpl_EnableModelessSB,
622         IShellBrowserImpl_TranslateAcceleratorSB,
623         IShellBrowserImpl_BrowseObject,
624         IShellBrowserImpl_GetViewStateStream,
625         IShellBrowserImpl_GetControlWindow,
626         IShellBrowserImpl_SendControlMsg,
627         IShellBrowserImpl_QueryActiveShellView,
628         IShellBrowserImpl_OnViewWindowActive,
629         IShellBrowserImpl_SetToolbarItems
630 };
631
632
633
634 /*
635  * ICommDlgBrowser
636  */
637
638 /***************************************************************************
639 *  IShellBrowserImpl_ICommDlgBrowser_QueryInterface
640 */
641 HRESULT WINAPI IShellBrowserImpl_ICommDlgBrowser_QueryInterface(
642         ICommDlgBrowser *iface,
643         REFIID riid, 
644         LPVOID *ppvObj)
645 {
646     _ICOM_THIS_FromICommDlgBrowser(IShellBrowser,iface);
647
648     TRACE("(%p)\n", This);
649
650     return IShellBrowserImpl_QueryInterface(This,riid,ppvObj);
651 }
652
653 /**************************************************************************
654 *  IShellBrowserImpl_ICommDlgBrowser_AddRef
655 */
656 ULONG WINAPI IShellBrowserImpl_ICommDlgBrowser_AddRef(ICommDlgBrowser * iface)
657 {
658     _ICOM_THIS_FromICommDlgBrowser(IShellBrowser,iface);
659
660     TRACE("(%p)\n", This);
661
662     return IShellBrowserImpl_AddRef(This);
663 }
664
665 /**************************************************************************
666 *  IShellBrowserImpl_ICommDlgBrowser_Release
667 */
668 ULONG WINAPI IShellBrowserImpl_ICommDlgBrowser_Release(ICommDlgBrowser * iface)
669 {
670     _ICOM_THIS_FromICommDlgBrowser(IShellBrowser,iface);
671
672     TRACE("(%p)\n", This);
673
674     return IShellBrowserImpl_Release(This);
675 }
676 /**************************************************************************
677 *  IShellBrowserImpl_ICommDlgBrowser_OnDefaultCommand
678 *
679 *   Called when a user double-clicks in the view or presses the ENTER key
680 */
681 HRESULT WINAPI IShellBrowserImpl_ICommDlgBrowser_OnDefaultCommand(ICommDlgBrowser *iface,
682                                                                   IShellView *ppshv)
683 {
684     LPITEMIDLIST pidl;
685     FileOpenDlgInfos *fodInfos;
686
687     _ICOM_THIS_FromICommDlgBrowser(IShellBrowserImpl,iface);
688
689     TRACE("(%p)\n", This);
690
691     fodInfos = (FileOpenDlgInfos *) GetPropA(This->hwndOwner,FileOpenDlgInfosStr);  
692     
693     /* If the selected object is not a folder, send a IDOK command to parent window */
694     if((pidl = GetPidlFromDataObject(fodInfos->Shell.FOIDataObject, 1)))
695     {
696         HRESULT hRes;
697
698         ULONG  ulAttr = SFGAO_FOLDER | SFGAO_HASSUBFOLDER;
699         IShellFolder_GetAttributesOf(fodInfos->Shell.FOIShellFolder, 1, &pidl, &ulAttr);
700         if (ulAttr & (SFGAO_FOLDER | SFGAO_HASSUBFOLDER) )
701         {
702           hRes = IShellBrowser_BrowseObject((IShellBrowser *)This,pidl,SBSP_RELATIVE);
703         }
704         else
705         {
706           /* Tell the dialog that the user selected a file */
707           hRes = PostMessageA(This->hwndOwner, WM_COMMAND, IDOK, 0L);
708         }
709
710         /* Free memory used by pidl */
711         COMDLG32_SHFree((LPVOID)pidl);
712
713         return hRes;
714     }
715
716     return E_FAIL;
717 }
718
719 /**************************************************************************
720 *  IShellBrowserImpl_ICommDlgBrowser_OnStateChange
721 */
722 HRESULT WINAPI IShellBrowserImpl_ICommDlgBrowser_OnStateChange(ICommDlgBrowser *iface,
723                                                                IShellView *ppshv,
724                                                                ULONG uChange)
725 {
726
727     _ICOM_THIS_FromICommDlgBrowser(IShellBrowserImpl,iface);
728
729     TRACE("(%p shv=%p)\n", This, ppshv);
730
731     switch (uChange)
732     {
733         case CDBOSC_SETFOCUS:
734              /* FIXME: Reset the default button.
735                 This should be taken care of by defdlg. If control
736                 other than button receives focus the default button
737                 should be restored. */
738              SendMessageA(This->hwndOwner, DM_SETDEFID, IDOK, 0);
739
740             break;
741         case CDBOSC_KILLFOCUS: 
742             {
743                 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
744                 if(fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG)
745                     SetDlgItemTextA(fodInfos->ShellInfos.hwndOwner,IDOK,"&Save");
746             }
747             break;
748         case CDBOSC_SELCHANGE:
749             return IShellBrowserImpl_ICommDlgBrowser_OnSelChange(iface,ppshv);
750         case CDBOSC_RENAME:
751             /* nothing to do */
752             break;
753     }
754
755     return NOERROR;     
756 }
757
758 /**************************************************************************
759 *  IShellBrowserImpl_ICommDlgBrowser_IncludeObject
760 */
761 HRESULT WINAPI IShellBrowserImpl_ICommDlgBrowser_IncludeObject(ICommDlgBrowser *iface, 
762                                                                IShellView * ppshv,
763                                                                LPCITEMIDLIST pidl)
764 {
765     FileOpenDlgInfos *fodInfos;
766     ULONG ulAttr;
767     STRRET str;
768     WCHAR szPathW[MAX_PATH];
769
770     _ICOM_THIS_FromICommDlgBrowser(IShellBrowserImpl,iface);
771
772     TRACE("(%p)\n", This);
773
774     fodInfos = (FileOpenDlgInfos *) GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
775
776     ulAttr = SFGAO_HIDDEN | SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_FILESYSANCESTOR | SFGAO_LINK;
777     IShellFolder_GetAttributesOf(fodInfos->Shell.FOIShellFolder, 1, &pidl, &ulAttr);
778     
779     if( (ulAttr & SFGAO_HIDDEN)                                         /* hidden */
780       | !(ulAttr & (SFGAO_FILESYSTEM | SFGAO_FILESYSANCESTOR))) /* special folder */
781         return S_FALSE;
782
783     /* always include directories and links */
784     if(ulAttr & (SFGAO_FOLDER | SFGAO_LINK)) 
785         return S_OK;
786
787     /* Check if there is a mask to apply if not */
788     if(!fodInfos->ShellInfos.lpstrCurrentFilter || !lstrlenW(fodInfos->ShellInfos.lpstrCurrentFilter))
789         return S_OK;
790
791     if (SUCCEEDED(IShellFolder_GetDisplayNameOf(fodInfos->Shell.FOIShellFolder, pidl, SHGDN_INFOLDER | SHGDN_FORPARSING, &str)))
792     {
793       if (SUCCEEDED(COMDLG32_StrRetToStrNW(szPathW, MAX_PATH, &str, pidl)))
794       {
795           if (PathMatchSpecW(szPathW, fodInfos->ShellInfos.lpstrCurrentFilter))
796           return S_OK;
797       }
798     }
799     return S_FALSE;
800
801 }
802
803 /**************************************************************************
804 *  IShellBrowserImpl_ICommDlgBrowser_OnSelChange
805 */  
806 HRESULT IShellBrowserImpl_ICommDlgBrowser_OnSelChange(ICommDlgBrowser *iface, IShellView *ppshv)
807 {
808     FileOpenDlgInfos *fodInfos;
809
810     _ICOM_THIS_FromICommDlgBrowser(IShellBrowserImpl,iface);
811
812     fodInfos = (FileOpenDlgInfos *) GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
813     TRACE("(%p do=%p view=%p)\n", This, fodInfos->Shell.FOIDataObject, fodInfos->Shell.FOIShellView);
814     
815     /* release old selections */
816     if (fodInfos->Shell.FOIDataObject)
817       IDataObject_Release(fodInfos->Shell.FOIDataObject);
818     
819     /* get a new DataObject from the ShellView */
820     if(FAILED(IShellView_GetItemObject(fodInfos->Shell.FOIShellView, SVGIO_SELECTION,
821                               &IID_IDataObject, (LPVOID*)&fodInfos->Shell.FOIDataObject)))
822       return E_FAIL;
823                                           
824     FILEDLG95_FILENAME_FillFromSelection(This->hwndOwner);
825
826     SendCustomDlgNotificationMessage(This->hwndOwner, CDN_SELCHANGE);
827     return S_OK;
828 }
829
830 static ICOM_VTABLE(ICommDlgBrowser) IShellBrowserImpl_ICommDlgBrowser_Vtbl =
831 {
832         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
833         /* IUnknown */
834         IShellBrowserImpl_ICommDlgBrowser_QueryInterface,
835         IShellBrowserImpl_ICommDlgBrowser_AddRef,
836         IShellBrowserImpl_ICommDlgBrowser_Release,
837         /* ICommDlgBrowser */
838         IShellBrowserImpl_ICommDlgBrowser_OnDefaultCommand,
839         IShellBrowserImpl_ICommDlgBrowser_OnStateChange,
840         IShellBrowserImpl_ICommDlgBrowser_IncludeObject
841 };
842
843
844
845
846 /*
847  * IServiceProvider
848  */
849
850 /***************************************************************************
851 *  IShellBrowserImpl_IServiceProvider_QueryInterface
852 */
853 HRESULT WINAPI IShellBrowserImpl_IServiceProvider_QueryInterface(
854         IServiceProvider *iface,
855         REFIID riid, 
856         LPVOID *ppvObj)
857 {
858     _ICOM_THIS_FromIServiceProvider(IShellBrowser,iface);
859
860     FIXME("(%p)\n", This);
861
862     return IShellBrowserImpl_QueryInterface(This,riid,ppvObj);
863 }
864
865 /**************************************************************************
866 *  IShellBrowserImpl_IServiceProvider_AddRef
867 */
868 ULONG WINAPI IShellBrowserImpl_IServiceProvider_AddRef(IServiceProvider * iface)
869 {
870     _ICOM_THIS_FromIServiceProvider(IShellBrowser,iface);
871
872     FIXME("(%p)\n", This);
873
874     return IShellBrowserImpl_AddRef(This);
875 }
876
877 /**************************************************************************
878 *  IShellBrowserImpl_IServiceProvider_Release
879 */
880 ULONG WINAPI IShellBrowserImpl_IServiceProvider_Release(IServiceProvider * iface)
881 {
882     _ICOM_THIS_FromIServiceProvider(IShellBrowser,iface);
883
884     FIXME("(%p)\n", This);
885
886     return IShellBrowserImpl_Release(This);
887 }
888
889 /**************************************************************************
890 *  IShellBrowserImpl_IServiceProvider_Release
891 *
892 * NOTES
893 *  the w2k shellview asks for 
894 *   guidService = SID_STopLevelBrowser
895 *   riid = IShellBrowser
896 *
897 * FIXME
898 *  this is a hack!
899 */
900
901 HRESULT WINAPI IShellBrowserImpl_IServiceProvider_QueryService(
902         IServiceProvider * iface,
903         REFGUID guidService,
904         REFIID riid,
905         void** ppv)
906 {
907     _ICOM_THIS_FromIServiceProvider(IShellBrowser,iface);
908
909     FIXME("(%p)\n\t%s\n\t%s\n", This,debugstr_guid(guidService), debugstr_guid(riid) );
910
911     *ppv = NULL;
912     if(guidService && IsEqualIID(guidService, &SID_STopLevelBrowser))
913     {
914       return IShellBrowserImpl_QueryInterface(This,riid,ppv);
915     }
916     FIXME("(%p) unknown interface requested\n", This);
917     return E_NOINTERFACE;
918
919 }
920
921 static ICOM_VTABLE(IServiceProvider) IShellBrowserImpl_IServiceProvider_Vtbl =
922 {
923         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
924         /* IUnknown */
925         IShellBrowserImpl_IServiceProvider_QueryInterface,
926         IShellBrowserImpl_IServiceProvider_AddRef,
927         IShellBrowserImpl_IServiceProvider_Release,
928         /* IServiceProvider */
929         IShellBrowserImpl_IServiceProvider_QueryService
930 };