Release 20000326.
[wine/gsoc-2012-control.git] / dlls / commdlg / filedlgbrowser.c
bloba14a3fe5f582afe7c144726d60613f080eca78c7
1 /*
2 * Implementation of IShellBrowser for the File Open common dialog
3 *
5 */
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 "heap.h"
14 #include "wine/obj_dataobject.h"
15 #include "debugtools.h"
16 #include "cdlg.h"
17 #include "wine/undocshell.h"
19 DEFAULT_DEBUG_CHANNEL(commdlg)
21 #define SETDefFormatEtc(fe,cf,med) \
22 { \
23 (fe).cfFormat = cf;\
24 (fe).dwAspect = DVASPECT_CONTENT; \
25 (fe).ptd =NULL;\
26 (fe).tymed = med;\
27 (fe).lindex = -1;\
31 /**************************************************************************
32 * Structure
34 static ICOM_VTABLE(IShellBrowser) IShellBrowserImpl_Vtbl =
36 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
37 /* IUnknown */
38 IShellBrowserImpl_QueryInterface,
39 IShellBrowserImpl_AddRef,
40 IShellBrowserImpl_Release,
41 /* IOleWindow */
42 IShellBrowserImpl_GetWindow,
43 IShellBrowserImpl_ContextSensitiveHelp,
44 /* IShellBrowser */
45 IShellBrowserImpl_InsertMenusSB,
46 IShellBrowserImpl_SetMenuSB,
47 IShellBrowserImpl_RemoveMenusSB,
48 IShellBrowserImpl_SetStatusTextSB,
49 IShellBrowserImpl_EnableModelessSB,
50 IShellBrowserImpl_TranslateAcceleratorSB,
51 IShellBrowserImpl_BrowseObject,
52 IShellBrowserImpl_GetViewStateStream,
53 IShellBrowserImpl_GetControlWindow,
54 IShellBrowserImpl_SendControlMsg,
55 IShellBrowserImpl_QueryActiveShellView,
56 IShellBrowserImpl_OnViewWindowActive,
57 IShellBrowserImpl_SetToolbarItems
60 static ICOM_VTABLE(ICommDlgBrowser) IShellBrowserImpl_ICommDlgBrowser_Vtbl =
62 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
63 /* IUnknown */
64 IShellBrowserImpl_ICommDlgBrowser_QueryInterface,
65 IShellBrowserImpl_ICommDlgBrowser_AddRef,
66 IShellBrowserImpl_ICommDlgBrowser_Release,
67 /* ICommDlgBrowser */
68 IShellBrowserImpl_ICommDlgBrowser_OnDefaultCommand,
69 IShellBrowserImpl_ICommDlgBrowser_OnStateChange,
70 IShellBrowserImpl_ICommDlgBrowser_IncludeObject
74 /**************************************************************************
75 * Local Prototypes
78 HRESULT IShellBrowserImpl_ICommDlgBrowser_OnSelChange(ICommDlgBrowser *iface, IShellView *ppshv);
79 #if 0
80 LPITEMIDLIST GetSelectedPidl(IShellView *ppshv);
81 #endif
83 /**************************************************************************
84 * External Prototypes
86 extern const char *FileOpenDlgInfosStr;
88 extern HRESULT GetName(LPSHELLFOLDER lpsf, LPITEMIDLIST pidl,DWORD dwFlags,LPSTR lpstrFileName);
89 extern HRESULT GetFileName(HWND hwnd, LPITEMIDLIST pidl, LPSTR lpstrFileName);
90 extern IShellFolder* GetShellFolderFromPidl(LPITEMIDLIST pidlAbs);
91 extern LPITEMIDLIST GetParentPidl(LPITEMIDLIST pidl);
92 extern LPITEMIDLIST GetPidlFromName(IShellFolder *psf,LPCSTR lpcstrFileName);
94 extern BOOL FILEDLG95_SHELL_FillIncludedItemList(HWND hwnd,
95 LPITEMIDLIST pidlCurrentFolder,
96 LPSTR lpstrMask);
98 extern int FILEDLG95_LOOKIN_SelectItem(HWND hwnd,LPITEMIDLIST pidl);
99 extern BOOL FILEDLG95_OnOpen(HWND hwnd);
100 extern HRESULT SendCustomDlgNotificationMessage(HWND hwndParentDlg, UINT uCode);
103 /**************************************************************************
104 * IShellBrowserImpl_Construct
106 IShellBrowser * IShellBrowserImpl_Construct(HWND hwndOwner)
108 IShellBrowserImpl *sb;
109 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwndOwner,FileOpenDlgInfosStr);
111 sb=(IShellBrowserImpl*)SHAlloc(sizeof(IShellBrowserImpl));
113 /* Initialisation of the member variables */
114 sb->ref=1;
115 sb->hwndOwner = hwndOwner;
117 /* Initialisation of the vTables */
118 sb->lpVtbl = &IShellBrowserImpl_Vtbl;
119 sb->lpVtbl2 = &IShellBrowserImpl_ICommDlgBrowser_Vtbl;
121 COMDLG32_SHGetSpecialFolderLocation(hwndOwner,
122 CSIDL_DESKTOP,
123 &fodInfos->ShellInfos.pidlAbsCurrent);
125 TRACE("%p\n", sb);
127 return (IShellBrowser *) sb;
130 /**************************************************************************
133 * The INTERFACE of the IShellBrowser object
138 * IUnknown
141 /***************************************************************************
142 * IShellBrowserImpl_QueryInterface
144 HRESULT WINAPI IShellBrowserImpl_QueryInterface(IShellBrowser *iface,
145 REFIID riid,
146 LPVOID *ppvObj)
148 ICOM_THIS(IShellBrowserImpl, iface);
150 TRACE("(%p)\n", This);
152 *ppvObj = NULL;
154 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
155 { *ppvObj = This;
157 else if(IsEqualIID(riid, &IID_IOleWindow)) /*IOleWindow*/
158 { *ppvObj = (IOleWindow*)This;
161 else if(IsEqualIID(riid, &IID_IShellBrowser)) /*IShellBrowser*/
162 { *ppvObj = (IShellBrowser*)This;
165 else if(IsEqualIID(riid, &IID_ICommDlgBrowser)) /*ICommDlgBrowser*/
166 { *ppvObj = (ICommDlgBrowser*) &(This->lpVtbl2);
169 if(*ppvObj)
170 { IUnknown_AddRef( (IShellBrowser*) *ppvObj);
171 return S_OK;
173 return E_NOINTERFACE;
176 /**************************************************************************
177 * IShellBrowser::AddRef
179 ULONG WINAPI IShellBrowserImpl_AddRef(IShellBrowser * iface)
181 ICOM_THIS(IShellBrowserImpl, iface);
183 TRACE("(%p)\n", This);
185 return ++(This->ref);
188 /**************************************************************************
189 * IShellBrowserImpl_Release
191 ULONG WINAPI IShellBrowserImpl_Release(IShellBrowser * iface)
193 ICOM_THIS(IShellBrowserImpl, iface);
195 TRACE("(%p)\n", This);
197 if (!--(This->ref))
199 COMDLG32_SHFree(This);
200 return 0;
202 return This->ref;
206 * IOleWindow
209 /**************************************************************************
210 * IShellBrowserImpl_GetWindow (IOleWindow)
212 * Inherited from IOleWindow::GetWindow
214 * See Windows documentation for more details
216 * Note : We will never be window less in the File Open dialog
219 HRESULT WINAPI IShellBrowserImpl_GetWindow(IShellBrowser * iface,
220 HWND * phwnd)
222 ICOM_THIS(IShellBrowserImpl, iface);
224 TRACE("(%p)\n", This);
226 if(!This->hwndOwner)
227 return E_FAIL;
229 *phwnd = This->hwndOwner;
231 return (*phwnd) ? S_OK : E_UNEXPECTED;
235 /**************************************************************************
236 * IShellBrowserImpl_ContextSensitiveHelp
238 HRESULT WINAPI IShellBrowserImpl_ContextSensitiveHelp(IShellBrowser * iface,
239 BOOL fEnterMode)
241 ICOM_THIS(IShellBrowserImpl, iface);
243 TRACE("(%p)\n", This);
245 /* Feature not implemented */
246 return E_NOTIMPL;
250 * IShellBrowser
253 /**************************************************************************
254 * IShellBrowserImpl_BrowseObject
256 * See Windows documentation on IShellBrowser::BrowseObject for more details
258 * This function will override user specified flags and will always
259 * use SBSP_DEFBROWSER and SBSP_DEFMODE.
261 HRESULT WINAPI IShellBrowserImpl_BrowseObject(IShellBrowser *iface,
262 LPCITEMIDLIST pidl,
263 UINT wFlags)
265 HRESULT hRes;
266 IShellFolder *psfTmp;
267 IShellView *psvTmp;
268 FileOpenDlgInfos *fodInfos;
269 LPITEMIDLIST pidlTmp;
271 ICOM_THIS(IShellBrowserImpl, iface);
273 TRACE("(%p)\n", This);
275 fodInfos = (FileOpenDlgInfos *) GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
277 /* Format the pidl according to its parameter's category */
278 if(wFlags & SBSP_RELATIVE)
281 /* SBSP_RELATIVE A relative pidl (relative from the current folder) */
282 hRes = IShellFolder_BindToObject(fodInfos->Shell.FOIShellFolder,
283 pidl,
284 NULL,
285 &IID_IShellFolder,
286 (LPVOID *)&psfTmp);
287 if(FAILED(hRes))
289 return hRes;
291 /* create an absolute pidl */
292 pidlTmp = COMDLG32_PIDL_ILCombine(fodInfos->ShellInfos.pidlAbsCurrent,
293 (LPITEMIDLIST)pidl);
296 else if(wFlags & SBSP_PARENT)
298 /* Browse the parent folder (ignores the pidl) */
300 pidlTmp = GetParentPidl(fodInfos->ShellInfos.pidlAbsCurrent);
301 psfTmp = GetShellFolderFromPidl(pidlTmp);
304 else
306 /* An absolute pidl (relative from the desktop) */
307 pidlTmp = COMDLG32_PIDL_ILClone((LPITEMIDLIST)pidl);
308 psfTmp = GetShellFolderFromPidl(pidlTmp);
312 /* Retrieve the IShellFolder interface of the pidl specified folder */
313 if(!psfTmp)
314 return E_FAIL;
316 /* If the pidl to browse to is equal to the actual pidl ...
317 do nothing and pretend you did it*/
318 if(COMDLG32_PIDL_ILIsEqual(pidlTmp,fodInfos->ShellInfos.pidlAbsCurrent))
320 IShellFolder_Release(psfTmp);
321 COMDLG32_SHFree(pidlTmp);
322 return NOERROR;
325 /* Release the current fodInfos->Shell.FOIShellFolder and update its value */
326 IShellFolder_Release(fodInfos->Shell.FOIShellFolder);
327 fodInfos->Shell.FOIShellFolder = psfTmp;
329 /* Create the associated view */
330 if(SUCCEEDED(hRes = IShellFolder_CreateViewObject(psfTmp,
331 fodInfos->ShellInfos.hwndOwner,
332 &IID_IShellView,
333 (LPVOID *)&psvTmp)))
335 HWND hwndView;
336 HWND hDlgWnd;
337 /* Get the foldersettings from the old view */
338 if(fodInfos->Shell.FOIShellView)
340 IShellView_GetCurrentInfo(fodInfos->Shell.FOIShellView,
341 &fodInfos->ShellInfos.folderSettings);
344 /* Create the window */
345 if(SUCCEEDED(hRes = IShellView_CreateViewWindow(psvTmp,
346 NULL,
347 &fodInfos->ShellInfos.folderSettings,
348 fodInfos->Shell.FOIShellBrowser,
349 &fodInfos->ShellInfos.rectView,
350 &hwndView)))
352 /* Fit the created view in the appropriate RECT */
353 MoveWindow(hwndView,
354 fodInfos->ShellInfos.rectView.left,
355 fodInfos->ShellInfos.rectView.top,
356 fodInfos->ShellInfos.rectView.right-fodInfos->ShellInfos.rectView.left,
357 fodInfos->ShellInfos.rectView.bottom-fodInfos->ShellInfos.rectView.top,
358 FALSE);
360 /* Select the new folder in the Look In combo box of the Open file dialog */
362 FILEDLG95_LOOKIN_SelectItem(fodInfos->DlgInfos.hwndLookInCB,pidlTmp);
364 /* Release old pidlAbsCurrent memory and update its value */
365 COMDLG32_SHFree((LPVOID)fodInfos->ShellInfos.pidlAbsCurrent);
366 fodInfos->ShellInfos.pidlAbsCurrent = pidlTmp;
368 /* Release the current fodInfos->Shell.FOIShellView and update its value */
369 if(fodInfos->Shell.FOIShellView)
371 IShellView_DestroyViewWindow(fodInfos->Shell.FOIShellView);
372 IShellView_Release(fodInfos->Shell.FOIShellView);
374 #if 0
375 ShowWindow(fodInfos->ShellInfos.hwndView,SW_HIDE);
376 #endif
377 fodInfos->Shell.FOIShellView = psvTmp;
379 fodInfos->ShellInfos.hwndView = hwndView;
381 /* changes the tab order of the ListView to reflect the window's File Dialog */
382 hDlgWnd = GetDlgItem(GetParent(hwndView), IDC_LOOKIN);
383 SetWindowPos(hwndView, hDlgWnd, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE);
386 return NOERROR;
390 FILEDLG95_LOOKIN_SelectItem(fodInfos->DlgInfos.hwndLookInCB,fodInfos->ShellInfos.pidlAbsCurrent);
391 return hRes;
394 /**************************************************************************
395 * IShellBrowserImpl_EnableModelessSB
397 HRESULT WINAPI IShellBrowserImpl_EnableModelessSB(IShellBrowser *iface,
398 BOOL fEnable)
401 ICOM_THIS(IShellBrowserImpl, iface);
403 TRACE("(%p)\n", This);
405 /* Feature not implemented */
406 return E_NOTIMPL;
409 /**************************************************************************
410 * IShellBrowserImpl_GetControlWindow
412 HRESULT WINAPI IShellBrowserImpl_GetControlWindow(IShellBrowser *iface,
413 UINT id,
414 HWND *lphwnd)
417 ICOM_THIS(IShellBrowserImpl, iface);
419 TRACE("(%p)\n", This);
421 /* Feature not implemented */
422 return E_NOTIMPL;
424 /**************************************************************************
425 * IShellBrowserImpl_GetViewStateStream
427 HRESULT WINAPI IShellBrowserImpl_GetViewStateStream(IShellBrowser *iface,
428 DWORD grfMode,
429 LPSTREAM *ppStrm)
432 ICOM_THIS(IShellBrowserImpl, iface);
434 TRACE("(%p)\n", This);
436 /* Feature not implemented */
437 return E_NOTIMPL;
439 /**************************************************************************
440 * IShellBrowserImpl_InsertMenusSB
442 HRESULT WINAPI IShellBrowserImpl_InsertMenusSB(IShellBrowser *iface,
443 HMENU hmenuShared,
444 LPOLEMENUGROUPWIDTHS lpMenuWidths)
447 ICOM_THIS(IShellBrowserImpl, iface);
449 TRACE("(%p)\n", This);
451 /* Feature not implemented */
452 return E_NOTIMPL;
454 /**************************************************************************
455 * IShellBrowserImpl_OnViewWindowActive
457 HRESULT WINAPI IShellBrowserImpl_OnViewWindowActive(IShellBrowser *iface,
458 IShellView *ppshv)
461 ICOM_THIS(IShellBrowserImpl, iface);
463 TRACE("(%p)\n", This);
465 /* Feature not implemented */
466 return E_NOTIMPL;
468 /**************************************************************************
469 * IShellBrowserImpl_QueryActiveShellView
471 HRESULT WINAPI IShellBrowserImpl_QueryActiveShellView(IShellBrowser *iface,
472 IShellView **ppshv)
475 ICOM_THIS(IShellBrowserImpl, iface);
477 FileOpenDlgInfos *fodInfos;
479 TRACE("(%p)\n", This);
481 fodInfos = (FileOpenDlgInfos *) GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
483 if(!(*ppshv = fodInfos->Shell.FOIShellView))
485 return E_FAIL;
487 IShellView_AddRef(fodInfos->Shell.FOIShellView);
488 return NOERROR;
490 /**************************************************************************
491 * IShellBrowserImpl_RemoveMenusSB
493 HRESULT WINAPI IShellBrowserImpl_RemoveMenusSB(IShellBrowser *iface,
494 HMENU hmenuShared)
497 ICOM_THIS(IShellBrowserImpl, iface);
499 TRACE("(%p)\n", This);
501 /* Feature not implemented */
502 return E_NOTIMPL;
504 /**************************************************************************
505 * IShellBrowserImpl_SendControlMsg
507 HRESULT WINAPI IShellBrowserImpl_SendControlMsg(IShellBrowser *iface,
508 UINT id,
509 UINT uMsg,
510 WPARAM wParam,
511 LPARAM lParam,
512 LRESULT *pret)
515 ICOM_THIS(IShellBrowserImpl, iface);
516 LRESULT lres;
518 TRACE("(%p)->(0x%08x 0x%08x 0x%08x 0x%08lx %p)\n", This, id, uMsg, wParam, lParam, pret);
520 switch (id)
522 case FCW_TOOLBAR:
523 lres = SendDlgItemMessageA( This->hwndOwner, IDC_TOOLBAR, uMsg, wParam, lParam);
524 break;
525 default:
526 FIXME("ctrl id: %x\n", id);
527 return E_NOTIMPL;
529 if (pret) *pret = lres;
530 return S_OK;
532 /**************************************************************************
533 * IShellBrowserImpl_SetMenuSB
535 HRESULT WINAPI IShellBrowserImpl_SetMenuSB(IShellBrowser *iface,
536 HMENU hmenuShared,
537 HOLEMENU holemenuReserved,
538 HWND hwndActiveObject)
541 ICOM_THIS(IShellBrowserImpl, iface);
543 TRACE("(%p)\n", This);
545 /* Feature not implemented */
546 return E_NOTIMPL;
548 /**************************************************************************
549 * IShellBrowserImpl_SetStatusTextSB
551 HRESULT WINAPI IShellBrowserImpl_SetStatusTextSB(IShellBrowser *iface,
552 LPCOLESTR lpszStatusText)
555 ICOM_THIS(IShellBrowserImpl, iface);
557 TRACE("(%p)\n", This);
559 /* Feature not implemented */
560 return E_NOTIMPL;
562 /**************************************************************************
563 * IShellBrowserImpl_SetToolbarItems
565 HRESULT WINAPI IShellBrowserImpl_SetToolbarItems(IShellBrowser *iface,
566 LPTBBUTTON lpButtons,
567 UINT nButtons,
568 UINT uFlags)
571 ICOM_THIS(IShellBrowserImpl, iface);
573 TRACE("(%p)\n", This);
575 /* Feature not implemented */
576 return E_NOTIMPL;
578 /**************************************************************************
579 * IShellBrowserImpl_TranslateAcceleratorSB
581 HRESULT WINAPI IShellBrowserImpl_TranslateAcceleratorSB(IShellBrowser *iface,
582 LPMSG lpmsg,
583 WORD wID)
586 ICOM_THIS(IShellBrowserImpl, iface);
588 TRACE("(%p)\n", This);
590 /* Feature not implemented */
591 return E_NOTIMPL;
595 * ICommDlgBrowser
598 /***************************************************************************
599 * IShellBrowserImpl_ICommDlgBrowser_QueryInterface
601 HRESULT WINAPI IShellBrowserImpl_ICommDlgBrowser_QueryInterface(ICommDlgBrowser *iface,
602 REFIID riid,
603 LPVOID *ppvObj)
605 _ICOM_THIS_FromICommDlgBrowser(IShellBrowser,iface);
607 TRACE("(%p)\n", This);
609 return IShellBrowserImpl_QueryInterface(This,riid,ppvObj);
612 /**************************************************************************
613 * IShellBrowserImpl_ICommDlgBrowser_AddRef
615 ULONG WINAPI IShellBrowserImpl_ICommDlgBrowser_AddRef(ICommDlgBrowser * iface)
617 _ICOM_THIS_FromICommDlgBrowser(IShellBrowser,iface);
619 TRACE("(%p)\n", This);
621 return IShellBrowserImpl_AddRef(This);
624 /**************************************************************************
625 * IShellBrowserImpl_ICommDlgBrowser_Release
627 ULONG WINAPI IShellBrowserImpl_ICommDlgBrowser_Release(ICommDlgBrowser * iface)
629 _ICOM_THIS_FromICommDlgBrowser(IShellBrowser,iface);
631 TRACE("(%p)\n", This);
633 return IShellBrowserImpl_Release(This);
635 /**************************************************************************
636 * IShellBrowserImpl_ICommDlgBrowser_OnDefaultCommand
638 * Called when a user double-clicks in the view or presses the ENTER key
640 HRESULT WINAPI IShellBrowserImpl_ICommDlgBrowser_OnDefaultCommand(ICommDlgBrowser *iface,
641 IShellView *ppshv)
643 LPITEMIDLIST pidl;
644 FileOpenDlgInfos *fodInfos;
646 _ICOM_THIS_FromICommDlgBrowser(IShellBrowserImpl,iface);
648 TRACE("(%p)\n", This);
650 fodInfos = (FileOpenDlgInfos *) GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
652 /* If the selected object is not a folder, send a IDOK command to parent window */
653 if((pidl = GetSelectedPidl(ppshv)))
655 HRESULT hRes;
657 ULONG ulAttr = SFGAO_FOLDER | SFGAO_HASSUBFOLDER;
658 IShellFolder_GetAttributesOf(fodInfos->Shell.FOIShellFolder, 1, &pidl, &ulAttr);
659 if (ulAttr)
660 hRes = IShellBrowser_BrowseObject((IShellBrowser *)This,pidl,SBSP_RELATIVE);
661 /* Tell the dialog that the user selected a file */
662 else
664 hRes = PostMessageA(This->hwndOwner, WM_COMMAND, IDOK, 0L);
667 /* Free memory used by pidl */
668 COMDLG32_SHFree((LPVOID)pidl);
670 return hRes;
673 return E_FAIL;
676 /**************************************************************************
677 * IShellBrowserImpl_ICommDlgBrowser_OnStateChange
679 HRESULT WINAPI IShellBrowserImpl_ICommDlgBrowser_OnStateChange(ICommDlgBrowser *iface,
680 IShellView *ppshv,
681 ULONG uChange)
684 _ICOM_THIS_FromICommDlgBrowser(IShellBrowserImpl,iface);
686 TRACE("(%p)\n", This);
688 switch (uChange)
690 case CDBOSC_SETFOCUS:
691 break;
692 case CDBOSC_KILLFOCUS:
694 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
695 if(fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG)
696 SetDlgItemTextA(fodInfos->ShellInfos.hwndOwner,IDOK,"&Save");
698 break;
699 case CDBOSC_SELCHANGE:
700 return IShellBrowserImpl_ICommDlgBrowser_OnSelChange(iface,ppshv);
701 case CDBOSC_RENAME:
702 break;
705 return NOERROR;
707 /**************************************************************************
708 * IShellBrowserImpl_ICommDlgBrowser_IncludeObject
710 HRESULT WINAPI IShellBrowserImpl_ICommDlgBrowser_IncludeObject(ICommDlgBrowser *iface,
711 IShellView * ppshv,
712 LPCITEMIDLIST pidl)
714 FileOpenDlgInfos *fodInfos;
715 ULONG ulAttr;
716 STRRET str;
717 WCHAR szPathW[MAX_PATH];
719 _ICOM_THIS_FromICommDlgBrowser(IShellBrowserImpl,iface);
721 TRACE("(%p)\n", This);
723 fodInfos = (FileOpenDlgInfos *) GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
725 ulAttr = SFGAO_HIDDEN | SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_FILESYSANCESTOR | SFGAO_LINK;
726 IShellFolder_GetAttributesOf(fodInfos->Shell.FOIShellFolder, 1, &pidl, &ulAttr);
729 if( (ulAttr & SFGAO_HIDDEN) /* hidden */
730 | !(ulAttr & (SFGAO_FILESYSTEM | SFGAO_FILESYSANCESTOR))) /* special folder */
731 return S_FALSE;
732 /* always include directorys and links */
733 if(ulAttr & (SFGAO_FOLDER | SFGAO_LINK))
734 return S_OK;
735 /* Check if there is a mask to apply if not */
736 if(!fodInfos->ShellInfos.lpstrCurrentFilter ||
737 !lstrlenW(fodInfos->ShellInfos.lpstrCurrentFilter))
738 return S_OK;
740 if (SUCCEEDED(IShellFolder_GetDisplayNameOf(fodInfos->Shell.FOIShellFolder, pidl, SHGDN_FORPARSING, &str)))
741 { if (SUCCEEDED(StrRetToBufW(&str, pidl,szPathW, MAX_PATH)))
743 if (COMDLG32_PathMatchSpecW(szPathW, fodInfos->ShellInfos.lpstrCurrentFilter))
744 return S_OK;
747 return S_FALSE;
751 /**************************************************************************
752 * IShellBrowserImpl_ICommDlgBrowser_OnSelChange
754 HRESULT IShellBrowserImpl_ICommDlgBrowser_OnSelChange(ICommDlgBrowser *iface, IShellView *ppshv)
756 FileOpenDlgInfos *fodInfos;
757 UINT nFileSelected;
758 UINT nFileToOpen;
759 UINT nFiles = 0;
760 char lpstrFileList[MAX_PATH];
761 char lpstrTemp[MAX_PATH];
762 LPSTR lpstrCurrFile = lpstrFileList;
763 _ICOM_THIS_FromICommDlgBrowser(IShellBrowserImpl,iface);
765 fodInfos = (FileOpenDlgInfos *) GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
766 TRACE("(%p)\n", This);
768 nFileSelected = GetNumSelected( fodInfos->Shell.FOIShellView );
769 /* Count how many files we have */
770 for ( nFileToOpen = 0; nFileToOpen < nFileSelected; nFileToOpen++ )
772 LPITEMIDLIST pidlSelection;
773 ULONG uAttr = SFGAO_FOLDER | SFGAO_HASSUBFOLDER;
775 /* get the file selected */
776 EnumSelectedPidls( fodInfos->Shell.FOIShellView, nFileToOpen, &pidlSelection );
777 IShellFolder_GetAttributesOf( fodInfos->Shell.FOIShellFolder, 1, &pidlSelection, &uAttr );
779 if (!uAttr)
780 nFiles++;
782 COMDLG32_SHFree( (LPVOID) pidlSelection );
785 /* Generate the string for the edit control */
786 ZeroMemory(lpstrFileList, MAX_PATH);
787 if (nFiles)
789 for ( nFileToOpen = 0; nFileToOpen < nFileSelected; nFileToOpen++ )
791 LPITEMIDLIST pidlSelection;
792 ULONG uAttr = SFGAO_FOLDER | SFGAO_HASSUBFOLDER;
794 memset( lpstrTemp, 0x0, MAX_PATH * sizeof(char) );
796 /* get the file selected */
797 EnumSelectedPidls( fodInfos->Shell.FOIShellView, nFileToOpen, &pidlSelection );
798 GetName( fodInfos->Shell.FOIShellFolder, pidlSelection, SHGDN_NORMAL, lpstrTemp );
800 IShellFolder_GetAttributesOf( fodInfos->Shell.FOIShellFolder, 1, &pidlSelection, &uAttr );
802 if ( uAttr & SFGAO_FOLDER ) /* Ignore folders */
803 continue;
805 if (nFiles > 1) /* Quote files if we have more than one */
807 *lpstrCurrFile++ = '\"';
808 lstrcpyA( lpstrCurrFile, lpstrTemp );
809 lpstrCurrFile += lstrlenA( lpstrTemp );
810 lstrcpyA( lpstrCurrFile, "\" " );
811 lpstrCurrFile += 2;
813 else
815 lstrcpyA( lpstrCurrFile, lpstrTemp );
818 COMDLG32_SHFree( (LPVOID) pidlSelection );
821 SetWindowTextA(fodInfos->DlgInfos.hwndFileName,lpstrFileList);
822 if(fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG)
823 SetDlgItemTextA(fodInfos->ShellInfos.hwndOwner,IDOK,"&Save");
824 else
825 SetDlgItemTextA(fodInfos->ShellInfos.hwndOwner,IDOK,"&Open");
827 fodInfos->DlgInfos.dwDlgProp |= FODPROP_USEVIEW;
828 SendCustomDlgNotificationMessage(This->hwndOwner, CDN_SELCHANGE);
829 return S_OK;
832 if(fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG)
833 SetDlgItemTextA(fodInfos->ShellInfos.hwndOwner,IDOK,"&Save");
835 fodInfos->DlgInfos.dwDlgProp &= ~FODPROP_USEVIEW;
837 return nFileSelected ? S_OK : E_FAIL;
840 /***********************************************************************
841 * GetSelectedPidl
843 * Return the pidl of the first selected item in the view
845 LPITEMIDLIST GetSelectedPidl(IShellView *ppshv)
848 IDataObject *doSelected;
849 LPITEMIDLIST pidlSelected = NULL;
851 TRACE("sv=%p\n", ppshv);
853 /* Get an IDataObject from the view */
854 if(SUCCEEDED(IShellView_GetItemObject(ppshv,
855 SVGIO_SELECTION,
856 &IID_IDataObject,
857 (LPVOID *)&doSelected)))
859 STGMEDIUM medium;
860 FORMATETC formatetc;
862 /* Set the FORMATETC structure*/
863 SETDefFormatEtc(formatetc,
864 RegisterClipboardFormatA(CFSTR_SHELLIDLIST),
865 TYMED_HGLOBAL);
867 /* Get the pidl from IDataObject */
868 if(SUCCEEDED(IDataObject_GetData(doSelected,&formatetc,&medium)))
870 LPIDA cida = GlobalLock(medium.u.hGlobal);
871 TRACE("cida=%p\n", cida);
872 pidlSelected = COMDLG32_PIDL_ILClone((LPITEMIDLIST)(&((LPBYTE)cida)[cida->aoffset[1]]));
874 if(medium.pUnkForRelease)
875 IUnknown_Release(medium.pUnkForRelease);
876 else
878 GlobalUnlock(medium.u.hGlobal);
879 GlobalFree(medium.u.hGlobal);
882 IDataObject_Release(doSelected);
883 return pidlSelected;
886 return NULL;
889 /***********************************************************************
890 * EnumSelectedPidls
892 * Return the pidl(s) of the selected item(s) in the view.
895 BOOL EnumSelectedPidls( IShellView *ppshv, /*[in]*/
896 UINT nPidlIndex, /*[in]*/
897 LPITEMIDLIST *pidlSelected /*[out]*/ )
900 IDataObject *doSelected;
901 BOOL retVal = TRUE;
903 /* Get an IDataObject from the view */
904 if(SUCCEEDED(IShellView_GetItemObject(ppshv,
905 SVGIO_SELECTION,
906 &IID_IDataObject,
907 (LPVOID *)&doSelected)))
909 STGMEDIUM medium;
910 FORMATETC formatetc;
912 /* Set the FORMATETC structure*/
913 SETDefFormatEtc(formatetc,
914 RegisterClipboardFormatA(CFSTR_SHELLIDLIST),
915 TYMED_HGLOBAL);
917 /* Get the pidls from IDataObject */
918 if(SUCCEEDED(IDataObject_GetData(doSelected,&formatetc,&medium)))
920 LPIDA cida = GlobalLock(medium.u.hGlobal);
921 if(nPidlIndex < cida->cidl)
923 *pidlSelected = COMDLG32_PIDL_ILClone((LPITEMIDLIST)(&((LPBYTE)cida)[cida->aoffset[nPidlIndex + 1]]));
925 else
927 retVal = FALSE;
930 if(medium.pUnkForRelease)
932 IUnknown_Release(medium.pUnkForRelease);
934 else
936 GlobalUnlock(medium.u.hGlobal);
937 GlobalFree(medium.u.hGlobal);
940 IDataObject_Release(doSelected);
941 return retVal;
943 return FALSE;
946 /***********************************************************************
947 * GetNumSelected
949 * Return the number of selected items in the view.
952 UINT GetNumSelected( IShellView *ppshv )
954 IDataObject *doSelected;
955 UINT retVal = 0;
957 /* Get an IDataObject from the view */
958 if(SUCCEEDED(IShellView_GetItemObject(ppshv,
959 SVGIO_SELECTION,
960 &IID_IDataObject,
961 (LPVOID *)&doSelected)))
963 STGMEDIUM medium;
964 FORMATETC formatetc;
966 /* Set the FORMATETC structure*/
967 SETDefFormatEtc(formatetc,
968 RegisterClipboardFormatA(CFSTR_SHELLIDLIST),
969 TYMED_HGLOBAL);
971 /* Get the pidls from IDataObject */
972 if(SUCCEEDED(IDataObject_GetData(doSelected,&formatetc,&medium)))
974 LPIDA cida = GlobalLock(medium.u.hGlobal);
975 retVal = cida->cidl;
977 if(medium.pUnkForRelease)
979 IUnknown_Release(medium.pUnkForRelease);
981 else
983 GlobalUnlock(medium.u.hGlobal);
984 GlobalFree(medium.u.hGlobal);
987 IDataObject_Release(doSelected);
988 return retVal;
991 return 0;