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