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