4 * Copyright 2010,2011 David Hedberg
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #define NONAMELESSUNION
25 #define NONAMELESSSTRUCT
36 #include "filedlgbrowser.h"
38 #include "wine/debug.h"
39 #include "wine/list.h"
41 #define IDC_NAV_TOOLBAR 200
42 #define IDC_NAVBACK 201
43 #define IDC_NAVFORWARD 202
45 WINE_DEFAULT_DEBUG_CHANNEL(commdlg);
54 IFileDialogEvents *pfde;
58 typedef struct FileDialogImpl {
59 IFileDialog2 IFileDialog2_iface;
61 IFileOpenDialog IFileOpenDialog_iface;
62 IFileSaveDialog IFileSaveDialog_iface;
64 enum ITEMDLG_TYPE dlg_type;
65 IExplorerBrowserEvents IExplorerBrowserEvents_iface;
66 IServiceProvider IServiceProvider_iface;
67 ICommDlgBrowser3 ICommDlgBrowser3_iface;
70 FILEOPENDIALOGOPTIONS options;
71 COMDLG_FILTERSPEC *filterspecs;
72 UINT filterspec_count;
75 struct list events_clients;
76 DWORD events_next_cookie;
78 IShellItemArray *psia_selection;
79 IShellItemArray *psia_results;
80 IShellItem *psi_defaultfolder;
81 IShellItem *psi_setfolder;
82 IShellItem *psi_folder;
85 IExplorerBrowser *peb;
86 DWORD ebevents_cookie;
91 /**************************************************************************
94 static UINT get_file_name(FileDialogImpl *This, LPWSTR *str)
96 HWND hwnd_edit = GetDlgItem(This->dlg_hwnd, IDC_FILENAME);
101 if(This->set_filename)
103 len = lstrlenW(This->set_filename);
104 *str = CoTaskMemAlloc(sizeof(WCHAR)*(len+1));
105 lstrcpyW(*str, This->set_filename);
111 len = SendMessageW(hwnd_edit, WM_GETTEXTLENGTH, 0, 0);
112 *str = CoTaskMemAlloc(sizeof(WCHAR)*(len+1));
116 SendMessageW(hwnd_edit, WM_GETTEXT, len+1, (LPARAM)*str);
120 static BOOL set_file_name(FileDialogImpl *This, LPCWSTR str)
122 HWND hwnd_edit = GetDlgItem(This->dlg_hwnd, IDC_FILENAME);
124 if(This->set_filename)
125 LocalFree(This->set_filename);
127 This->set_filename = StrDupW(str);
129 return SendMessageW(hwnd_edit, WM_SETTEXT, 0, (LPARAM)str);
132 static void fill_filename_from_selection(FileDialogImpl *This)
137 UINT item_count, valid_count;
140 if(!This->psia_selection)
143 hr = IShellItemArray_GetCount(This->psia_selection, &item_count);
144 if(FAILED(hr) || !item_count)
147 names = HeapAlloc(GetProcessHeap(), 0, item_count*sizeof(LPWSTR));
149 /* Get names of the selected items */
150 valid_count = 0; len_total = 0;
151 for(i = 0; i < item_count; i++)
153 hr = IShellItemArray_GetItemAt(This->psia_selection, i, &psi);
158 hr = IShellItem_GetAttributes(psi, SFGAO_FOLDER, &attr);
159 if(SUCCEEDED(hr) && (attr & SFGAO_FOLDER))
160 continue; /* FIXME: FOS_PICKFOLDERS */
162 hr = IShellItem_GetDisplayName(psi, SIGDN_PARENTRELATIVEPARSING, &names[valid_count]);
165 len_total += lstrlenW(names[valid_count]) + 3;
168 IShellItem_Release(psi);
174 set_file_name(This, names[0]);
175 CoTaskMemFree(names[0]);
177 else if(valid_count > 1)
179 LPWSTR string = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*len_total);
180 LPWSTR cur_point = string;
182 for(i = 0; i < valid_count; i++)
184 LPWSTR file = names[i];
186 lstrcpyW(cur_point, file);
187 cur_point += lstrlenW(file);
192 *(cur_point-1) = '\0';
194 set_file_name(This, string);
195 HeapFree(GetProcessHeap(), 0, string);
198 HeapFree(GetProcessHeap(), 0, names);
202 static HRESULT on_default_action(FileDialogImpl *This)
204 IShellFolder *psf_parent, *psf_desktop;
206 LPITEMIDLIST current_folder;
207 LPWSTR fn_iter, files, tmp_files;
208 UINT file_count = 0, len, i;
210 HRESULT hr, ret = E_FAIL;
212 len = get_file_name(This, &tmp_files);
216 file_count = COMDLG32_SplitFileNames(tmp_files, len, &files, &size_used);
218 if(!file_count) return E_FAIL;
220 hr = SHGetIDListFromObject((IUnknown*)This->psi_folder, ¤t_folder);
223 ERR("Failed to get pidl for current directory.\n");
227 TRACE("Acting on %d file(s).\n", file_count);
229 pidla = HeapAlloc(GetProcessHeap(), 0, sizeof(LPITEMIDLIST) * file_count);
230 open_action = ONOPEN_OPEN;
233 for(i = 0; i < file_count && open_action == ONOPEN_OPEN; i++)
235 WCHAR canon_filename[MAX_PATH];
238 COMDLG32_GetCanonicalPath(current_folder, fn_iter, canon_filename);
240 if( (This->options & FOS_NOVALIDATE) &&
241 !(This->options & FOS_FILEMUSTEXIST) )
242 open_action = ONOPEN_OPEN;
244 open_action = ONOPEN_BROWSE;
246 open_action = FILEDLG95_ValidatePathAction(canon_filename, &psf_parent, This->dlg_hwnd,
247 This->options, (This->dlg_type == ITEMDLG_TYPE_SAVE),
250 pidla[i] = COMDLG32_SHSimpleIDListFromPathAW(canon_filename);
252 if(psf_parent && !(open_action == ONOPEN_BROWSE))
253 IShellItem_Release(psf_parent);
255 fn_iter += (WCHAR)lstrlenW(fn_iter) + 1;
258 HeapFree(GetProcessHeap(), 0, files);
259 ILFree(current_folder);
261 if((This->options & FOS_PICKFOLDERS) && open_action == ONOPEN_BROWSE)
262 open_action = ONOPEN_OPEN; /* FIXME: Multiple folders? */
267 FIXME("Filtering not implemented.\n");
271 hr = IExplorerBrowser_BrowseToObject(This->peb, (IUnknown*)psf_parent, SBSP_DEFBROWSER);
273 ERR("Failed to browse to directory: %08x\n", hr);
275 IShellItem_Release(psf_parent);
279 hr = SHGetDesktopFolder(&psf_desktop);
282 if(This->psia_results)
283 IShellItemArray_Release(This->psia_results);
285 hr = SHCreateShellItemArray(NULL, psf_desktop, file_count, (PCUITEMID_CHILD_ARRAY)pidla,
286 &This->psia_results);
291 IShellFolder_Release(psf_desktop);
301 for(i = 0; i < file_count; i++)
303 HeapFree(GetProcessHeap(), 0, pidla);
305 /* Success closes the dialog */
309 /**************************************************************************
310 * Window related functions.
312 static SIZE update_layout(FileDialogImpl *This)
317 RECT cancel_rc, open_rc;
318 RECT filetype_rc, filename_rc, filenamelabel_rc;
319 RECT toolbar_rc, ebrowser_rc;
320 int missing_width, missing_height;
321 static const UINT vspacing = 4, hspacing = 4;
324 GetClientRect(This->dlg_hwnd, &dialog_rc);
326 missing_width = max(0, 320 - dialog_rc.right);
327 missing_height = max(0, 200 - dialog_rc.bottom);
329 if(missing_width || missing_height)
331 TRACE("Missing (%d, %d)\n", missing_width, missing_height);
332 ret.cx = missing_width;
333 ret.cy = missing_height;
338 * Calculate the size of the dialog and all the parts.
342 hwnd = GetDlgItem(This->dlg_hwnd, IDCANCEL);
345 int cancel_width, cancel_height;
346 GetWindowRect(hwnd, &cancel_rc);
347 cancel_width = cancel_rc.right - cancel_rc.left;
348 cancel_height = cancel_rc.bottom - cancel_rc.top;
350 cancel_rc.left = dialog_rc.right - cancel_width - hspacing;
351 cancel_rc.top = dialog_rc.bottom - cancel_height - vspacing;
352 cancel_rc.right = cancel_rc.left + cancel_width;
353 cancel_rc.bottom = cancel_rc.top + cancel_height;
356 /* Open/Save button */
357 hwnd = GetDlgItem(This->dlg_hwnd, IDOK);
360 int open_width, open_height;
361 GetWindowRect(hwnd, &open_rc);
362 open_width = open_rc.right - open_rc.left;
363 open_height = open_rc.bottom - open_rc.top;
365 open_rc.left = cancel_rc.left - open_width - hspacing;
366 open_rc.top = cancel_rc.top;
367 open_rc.right = open_rc.left + open_width;
368 open_rc.bottom = open_rc.top + open_height;
371 /* The filetype combobox. */
372 hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILETYPE);
375 int filetype_width, filetype_height;
376 GetWindowRect(hwnd, &filetype_rc);
378 filetype_width = filetype_rc.right - filetype_rc.left;
379 filetype_height = filetype_rc.bottom - filetype_rc.top;
381 filetype_rc.right = cancel_rc.right;
383 filetype_rc.left = filetype_rc.right - filetype_width;
384 filetype_rc.top = cancel_rc.top - filetype_height - vspacing;
385 filetype_rc.bottom = filetype_rc.top + filetype_height;
387 if(!This->filterspec_count)
388 filetype_rc.left = filetype_rc.right;
391 /* Filename label. */
392 hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILENAMESTATIC);
395 int filetypelabel_width, filetypelabel_height;
396 GetWindowRect(hwnd, &filenamelabel_rc);
398 filetypelabel_width = filenamelabel_rc.right - filenamelabel_rc.left;
399 filetypelabel_height = filenamelabel_rc.bottom - filenamelabel_rc.top;
401 filenamelabel_rc.left = 160; /* FIXME */
402 filenamelabel_rc.top = filetype_rc.top;
403 filenamelabel_rc.right = filenamelabel_rc.left + filetypelabel_width;
404 filenamelabel_rc.bottom = filenamelabel_rc.top + filetypelabel_height;
407 /* Filename edit box. */
408 hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILENAME);
411 int filename_width, filename_height;
412 GetWindowRect(hwnd, &filename_rc);
414 filename_width = filetype_rc.left - filenamelabel_rc.right - hspacing*2;
415 filename_height = filename_rc.bottom - filename_rc.top;
417 filename_rc.left = filenamelabel_rc.right + hspacing;
418 filename_rc.top = filetype_rc.top;
419 filename_rc.right = filename_rc.left + filename_width;
420 filename_rc.bottom = filename_rc.top + filename_height;
423 hwnd = GetDlgItem(This->dlg_hwnd, IDC_NAV_TOOLBAR);
426 GetWindowRect(hwnd, &toolbar_rc);
427 MapWindowPoints(NULL, This->dlg_hwnd, (POINT*)&toolbar_rc, 2);
430 /* The ExplorerBrowser control. */
431 ebrowser_rc.left = dialog_rc.left + vspacing;
432 ebrowser_rc.top = toolbar_rc.bottom + vspacing;
433 ebrowser_rc.right = dialog_rc.right - hspacing;
434 ebrowser_rc.bottom = filename_rc.top - hspacing;
437 * Move everything to the right place.
440 /* FIXME: The Save Dialog uses a slightly different layout. */
441 hdwp = BeginDeferWindowPos(6);
443 if(hdwp && This->peb)
444 IExplorerBrowser_SetRect(This->peb, &hdwp, ebrowser_rc);
446 /* The default controls */
447 if(hdwp && (hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILETYPE)) )
448 DeferWindowPos(hdwp, hwnd, NULL, filetype_rc.left, filetype_rc.top, 0, 0,
449 SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
451 if(hdwp && (hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILENAME)) )
452 DeferWindowPos(hdwp, hwnd, NULL, filename_rc.left, filename_rc.top,
453 filename_rc.right - filename_rc.left, filename_rc.bottom - filename_rc.top,
454 SWP_NOZORDER | SWP_NOACTIVATE);
456 if(hdwp && (hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILENAMESTATIC)) )
457 DeferWindowPos(hdwp, hwnd, NULL, filenamelabel_rc.left, filenamelabel_rc.top, 0, 0,
458 SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
460 if(hdwp && (hwnd = GetDlgItem(This->dlg_hwnd, IDOK)) )
461 DeferWindowPos(hdwp, hwnd, NULL, open_rc.left, open_rc.top, 0, 0,
462 SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
464 if(hdwp && (hwnd = GetDlgItem(This->dlg_hwnd, IDCANCEL)) )
465 DeferWindowPos(hdwp, hwnd, NULL, cancel_rc.left, cancel_rc.top, 0, 0,
466 SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
469 EndDeferWindowPos(hdwp);
471 ERR("Failed to position dialog controls.\n");
473 ret.cx = 0; ret.cy = 0;
477 static HRESULT init_explorerbrowser(FileDialogImpl *This)
479 IShellItem *psi_folder;
484 /* Create ExplorerBrowser instance */
487 hr = CoCreateInstance(&CLSID_ExplorerBrowser, NULL, CLSCTX_INPROC_SERVER,
488 &IID_IExplorerBrowser, (void**)&This->peb);
491 ERR("Failed to instantiate ExplorerBrowser control.\n");
495 IExplorerBrowser_SetOptions(This->peb, EBO_SHOWFRAMES);
497 hr = IExplorerBrowser_Initialize(This->peb, This->dlg_hwnd, &rc, NULL);
500 ERR("Failed to initialize the ExplorerBrowser control.\n");
501 IExplorerBrowser_Release(This->peb);
505 hr = IExplorerBrowser_Advise(This->peb, &This->IExplorerBrowserEvents_iface, &This->ebevents_cookie);
507 ERR("Advise (ExplorerBrowser) failed.\n");
509 /* Get previous options? */
510 fos.ViewMode = fos.fFlags = 0;
511 if(!(This->options & FOS_ALLOWMULTISELECT))
512 fos.fFlags |= FWF_SINGLESEL;
514 IExplorerBrowser_SetFolderSettings(This->peb, &fos);
516 hr = IUnknown_SetSite((IUnknown*)This->peb, (IUnknown*)This);
518 ERR("SetSite (ExplorerBrowser) failed.\n");
520 /* Browse somewhere */
521 psi_folder = This->psi_setfolder ? This->psi_setfolder : This->psi_defaultfolder;
522 IExplorerBrowser_BrowseToObject(This->peb, (IUnknown*)psi_folder, SBSP_DEFBROWSER);
527 static void init_toolbar(FileDialogImpl *This, HWND hwnd)
533 htoolbar = CreateWindowExW(0, TOOLBARCLASSNAMEW, NULL, TBSTYLE_FLAT | WS_CHILD | WS_VISIBLE,
535 hwnd, (HMENU)IDC_NAV_TOOLBAR, NULL, NULL);
537 tbab.hInst = HINST_COMMCTRL;
538 tbab.nID = IDB_HIST_LARGE_COLOR;
539 SendMessageW(htoolbar, TB_ADDBITMAP, 0, (LPARAM)&tbab);
541 button[0].iBitmap = HIST_BACK;
542 button[0].idCommand = IDC_NAVBACK;
543 button[0].fsState = TBSTATE_ENABLED;
544 button[0].fsStyle = BTNS_BUTTON;
545 button[0].dwData = 0;
546 button[0].iString = 0;
548 button[1].iBitmap = HIST_FORWARD;
549 button[1].idCommand = IDC_NAVFORWARD;
550 button[1].fsState = TBSTATE_ENABLED;
551 button[1].fsStyle = BTNS_BUTTON;
552 button[1].dwData = 0;
553 button[1].iString = 0;
555 SendMessageW(htoolbar, TB_ADDBUTTONSW, 2, (LPARAM)&button);
556 SendMessageW(htoolbar, TB_SETBUTTONSIZE, 0, MAKELPARAM(24,24));
557 SendMessageW(htoolbar, TB_AUTOSIZE, 0, 0);
560 static LRESULT on_wm_initdialog(HWND hwnd, LPARAM lParam)
562 FileDialogImpl *This = (FileDialogImpl*)lParam;
565 TRACE("(%p, %p)\n", This, hwnd);
567 SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LPARAM)This);
568 This->dlg_hwnd = hwnd;
570 hitem = GetDlgItem(This->dlg_hwnd, pshHelp);
571 if(hitem) ShowWindow(hitem, SW_HIDE);
573 hitem = GetDlgItem(This->dlg_hwnd, IDC_FILETYPESTATIC);
574 if(hitem) ShowWindow(hitem, SW_HIDE);
576 /* Fill filetypes combobox, or hide it. */
577 hitem = GetDlgItem(This->dlg_hwnd, IDC_FILETYPE);
578 if(This->filterspec_count)
581 for(i = 0; i < This->filterspec_count; i++)
582 SendMessageW(hitem, CB_ADDSTRING, 0, (LPARAM)This->filterspecs[i].pszName);
584 SendMessageW(hitem, CB_SETCURSEL, This->filetypeindex, 0);
587 ShowWindow(hitem, SW_HIDE);
589 if(This->set_filename &&
590 (hitem = GetDlgItem(This->dlg_hwnd, IDC_FILENAME)) )
591 SendMessageW(hitem, WM_SETTEXT, 0, (LPARAM)This->set_filename);
593 init_explorerbrowser(This);
594 init_toolbar(This, hwnd);
600 static LRESULT on_wm_size(FileDialogImpl *This)
606 static LRESULT on_wm_getminmaxinfo(FileDialogImpl *This, LPARAM lparam)
608 MINMAXINFO *mmi = (MINMAXINFO*)lparam;
609 TRACE("%p (%p)\n", This, mmi);
612 mmi->ptMinTrackSize.x = 640;
613 mmi->ptMinTrackSize.y = 480;
618 static LRESULT on_wm_destroy(FileDialogImpl *This)
624 IExplorerBrowser_Destroy(This->peb);
625 IExplorerBrowser_Release(This->peb);
629 This->dlg_hwnd = NULL;
634 static LRESULT on_idok(FileDialogImpl *This)
638 if(SUCCEEDED(on_default_action(This)))
639 EndDialog(This->dlg_hwnd, S_OK);
644 static LRESULT on_idcancel(FileDialogImpl *This)
648 EndDialog(This->dlg_hwnd, HRESULT_FROM_WIN32(ERROR_CANCELLED));
653 static LRESULT on_browse_back(FileDialogImpl *This)
656 IExplorerBrowser_BrowseToIDList(This->peb, NULL, SBSP_NAVIGATEBACK);
660 static LRESULT on_browse_forward(FileDialogImpl *This)
663 IExplorerBrowser_BrowseToIDList(This->peb, NULL, SBSP_NAVIGATEFORWARD);
667 static LRESULT on_command_filetype(FileDialogImpl *This, WPARAM wparam, LPARAM lparam)
669 if(HIWORD(wparam) == CBN_SELCHANGE)
674 This->filetypeindex = SendMessageW((HWND)lparam, CB_GETCURSEL, 0, 0);
675 TRACE("File type selection changed to %d.\n", This->filetypeindex);
677 hr = IExplorerBrowser_GetCurrentView(This->peb, &IID_IShellView, (void**)&psv);
680 IShellView_Refresh(psv);
681 IShellView_Release(psv);
688 static LRESULT on_wm_command(FileDialogImpl *This, WPARAM wparam, LPARAM lparam)
690 switch(LOWORD(wparam))
692 case IDOK: return on_idok(This);
693 case IDCANCEL: return on_idcancel(This);
694 case IDC_NAVBACK: return on_browse_back(This);
695 case IDC_NAVFORWARD: return on_browse_forward(This);
696 case IDC_FILETYPE: return on_command_filetype(This, wparam, lparam);
697 default: TRACE("Unknown command.\n");
702 static LRESULT CALLBACK itemdlg_dlgproc(HWND hwnd, UINT umessage, WPARAM wparam, LPARAM lparam)
704 FileDialogImpl *This = (FileDialogImpl*)GetWindowLongPtrW(hwnd, GWLP_USERDATA);
708 case WM_INITDIALOG: return on_wm_initdialog(hwnd, lparam);
709 case WM_COMMAND: return on_wm_command(This, wparam, lparam);
710 case WM_SIZE: return on_wm_size(This);
711 case WM_GETMINMAXINFO: return on_wm_getminmaxinfo(This, lparam);
712 case WM_DESTROY: return on_wm_destroy(This);
718 static HRESULT create_dialog(FileDialogImpl *This, HWND parent)
723 res = DialogBoxParamW(COMDLG32_hInstance,
724 MAKEINTRESOURCEW(NEWFILEOPENV3ORD),
725 parent, itemdlg_dlgproc, (LPARAM)This);
726 This->dlg_hwnd = NULL;
729 ERR("Failed to show dialog (LastError: %d)\n", GetLastError());
733 TRACE("Returning 0x%08x\n", (HRESULT)res);
737 /**************************************************************************
738 * IFileDialog implementation
740 static inline FileDialogImpl *impl_from_IFileDialog2(IFileDialog2 *iface)
742 return CONTAINING_RECORD(iface, FileDialogImpl, IFileDialog2_iface);
745 static HRESULT WINAPI IFileDialog2_fnQueryInterface(IFileDialog2 *iface,
749 FileDialogImpl *This = impl_from_IFileDialog2(iface);
750 TRACE("%p (%s, %p)\n", This, debugstr_guid(riid), ppvObject);
753 if(IsEqualGUID(riid, &IID_IUnknown) ||
754 IsEqualGUID(riid, &IID_IFileDialog) ||
755 IsEqualGUID(riid, &IID_IFileDialog2))
759 else if(IsEqualGUID(riid, &IID_IFileOpenDialog) && This->dlg_type == ITEMDLG_TYPE_OPEN)
761 *ppvObject = &This->u.IFileOpenDialog_iface;
763 else if(IsEqualGUID(riid, &IID_IFileSaveDialog) && This->dlg_type == ITEMDLG_TYPE_SAVE)
765 *ppvObject = &This->u.IFileSaveDialog_iface;
767 else if(IsEqualGUID(riid, &IID_IExplorerBrowserEvents))
769 *ppvObject = &This->IExplorerBrowserEvents_iface;
771 else if(IsEqualGUID(riid, &IID_IServiceProvider))
773 *ppvObject = &This->IServiceProvider_iface;
775 else if(IsEqualGUID(&IID_ICommDlgBrowser3, riid) ||
776 IsEqualGUID(&IID_ICommDlgBrowser2, riid) ||
777 IsEqualGUID(&IID_ICommDlgBrowser, riid))
779 *ppvObject = &This->ICommDlgBrowser3_iface;
782 FIXME("Unknown interface requested: %s.\n", debugstr_guid(riid));
786 IUnknown_AddRef((IUnknown*)*ppvObject);
790 return E_NOINTERFACE;
793 static ULONG WINAPI IFileDialog2_fnAddRef(IFileDialog2 *iface)
795 FileDialogImpl *This = impl_from_IFileDialog2(iface);
796 LONG ref = InterlockedIncrement(&This->ref);
797 TRACE("%p - ref %d\n", This, ref);
802 static ULONG WINAPI IFileDialog2_fnRelease(IFileDialog2 *iface)
804 FileDialogImpl *This = impl_from_IFileDialog2(iface);
805 LONG ref = InterlockedDecrement(&This->ref);
806 TRACE("%p - ref %d\n", This, ref);
811 for(i = 0; i < This->filterspec_count; i++)
813 LocalFree((void*)This->filterspecs[i].pszName);
814 LocalFree((void*)This->filterspecs[i].pszSpec);
816 HeapFree(GetProcessHeap(), 0, This->filterspecs);
818 if(This->psi_defaultfolder) IShellItem_Release(This->psi_defaultfolder);
819 if(This->psi_setfolder) IShellItem_Release(This->psi_setfolder);
820 if(This->psi_folder) IShellItem_Release(This->psi_folder);
821 if(This->psia_selection) IShellItemArray_Release(This->psia_selection);
822 if(This->psia_results) IShellItemArray_Release(This->psia_results);
824 LocalFree(This->set_filename);
826 HeapFree(GetProcessHeap(), 0, This);
832 static HRESULT WINAPI IFileDialog2_fnShow(IFileDialog2 *iface, HWND hwndOwner)
834 FileDialogImpl *This = impl_from_IFileDialog2(iface);
835 TRACE("%p (%p)\n", iface, hwndOwner);
837 return create_dialog(This, hwndOwner);
840 static HRESULT WINAPI IFileDialog2_fnSetFileTypes(IFileDialog2 *iface, UINT cFileTypes,
841 const COMDLG_FILTERSPEC *rgFilterSpec)
843 FileDialogImpl *This = impl_from_IFileDialog2(iface);
845 TRACE("%p (%d, %p)\n", This, cFileTypes, rgFilterSpec);
847 if(This->filterspecs)
856 This->filterspecs = HeapAlloc(GetProcessHeap(), 0, sizeof(COMDLG_FILTERSPEC)*cFileTypes);
857 for(i = 0; i < cFileTypes; i++)
859 This->filterspecs[i].pszName = StrDupW(rgFilterSpec[i].pszName);
860 This->filterspecs[i].pszSpec = StrDupW(rgFilterSpec[i].pszSpec);
862 This->filterspec_count = cFileTypes;
867 static HRESULT WINAPI IFileDialog2_fnSetFileTypeIndex(IFileDialog2 *iface, UINT iFileType)
869 FileDialogImpl *This = impl_from_IFileDialog2(iface);
870 TRACE("%p (%d)\n", This, iFileType);
872 if(!This->filterspecs)
875 if(iFileType >= This->filterspec_count)
876 This->filetypeindex = This->filterspec_count - 1;
878 This->filetypeindex = iFileType;
883 static HRESULT WINAPI IFileDialog2_fnGetFileTypeIndex(IFileDialog2 *iface, UINT *piFileType)
885 FileDialogImpl *This = impl_from_IFileDialog2(iface);
886 TRACE("%p (%p)\n", This, piFileType);
891 *piFileType = This->filetypeindex;
896 static HRESULT WINAPI IFileDialog2_fnAdvise(IFileDialog2 *iface, IFileDialogEvents *pfde, DWORD *pdwCookie)
898 FileDialogImpl *This = impl_from_IFileDialog2(iface);
899 events_client *client;
900 TRACE("%p (%p, %p)\n", This, pfde, pdwCookie);
902 if(!pfde || !pdwCookie)
905 client = HeapAlloc(GetProcessHeap(), 0, sizeof(events_client));
907 client->cookie = ++This->events_next_cookie;
909 IFileDialogEvents_AddRef(pfde);
910 *pdwCookie = client->cookie;
912 list_add_tail(&This->events_clients, &client->entry);
917 static HRESULT WINAPI IFileDialog2_fnUnadvise(IFileDialog2 *iface, DWORD dwCookie)
919 FileDialogImpl *This = impl_from_IFileDialog2(iface);
920 events_client *client, *found = NULL;
921 TRACE("%p (%d)\n", This, dwCookie);
923 LIST_FOR_EACH_ENTRY(client, &This->events_clients, events_client, entry)
925 if(client->cookie == dwCookie)
934 list_remove(&found->entry);
935 IFileDialogEvents_Release(found->pfde);
936 HeapFree(GetProcessHeap(), 0, found);
943 static HRESULT WINAPI IFileDialog2_fnSetOptions(IFileDialog2 *iface, FILEOPENDIALOGOPTIONS fos)
945 FileDialogImpl *This = impl_from_IFileDialog2(iface);
946 TRACE("%p (0x%x)\n", This, fos);
953 static HRESULT WINAPI IFileDialog2_fnGetOptions(IFileDialog2 *iface, FILEOPENDIALOGOPTIONS *pfos)
955 FileDialogImpl *This = impl_from_IFileDialog2(iface);
956 TRACE("%p (%p)\n", This, pfos);
961 *pfos = This->options;
966 static HRESULT WINAPI IFileDialog2_fnSetDefaultFolder(IFileDialog2 *iface, IShellItem *psi)
968 FileDialogImpl *This = impl_from_IFileDialog2(iface);
969 TRACE("%p (%p)\n", This, psi);
970 if(This->psi_defaultfolder)
971 IShellItem_Release(This->psi_defaultfolder);
973 This->psi_defaultfolder = psi;
975 if(This->psi_defaultfolder)
976 IShellItem_AddRef(This->psi_defaultfolder);
981 static HRESULT WINAPI IFileDialog2_fnSetFolder(IFileDialog2 *iface, IShellItem *psi)
983 FileDialogImpl *This = impl_from_IFileDialog2(iface);
984 TRACE("%p (%p)\n", This, psi);
985 if(This->psi_setfolder)
986 IShellItem_Release(This->psi_setfolder);
988 This->psi_setfolder = psi;
990 if(This->psi_setfolder)
991 IShellItem_AddRef(This->psi_setfolder);
996 static HRESULT WINAPI IFileDialog2_fnGetFolder(IFileDialog2 *iface, IShellItem **ppsi)
998 FileDialogImpl *This = impl_from_IFileDialog2(iface);
999 TRACE("%p (%p)\n", This, ppsi);
1001 return E_INVALIDARG;
1004 If the dialog is shown, return the current(ly selected) folder. */
1007 if(This->psi_folder)
1008 *ppsi = This->psi_folder;
1009 else if(This->psi_setfolder)
1010 *ppsi = This->psi_setfolder;
1011 else if(This->psi_defaultfolder)
1012 *ppsi = This->psi_defaultfolder;
1016 IShellItem_AddRef(*ppsi);
1023 static HRESULT WINAPI IFileDialog2_fnGetCurrentSelection(IFileDialog2 *iface, IShellItem **ppsi)
1025 FileDialogImpl *This = impl_from_IFileDialog2(iface);
1027 TRACE("%p (%p)\n", This, ppsi);
1030 return E_INVALIDARG;
1032 if(This->psia_selection)
1034 /* FIXME: Check filename edit box */
1035 hr = IShellItemArray_GetItemAt(This->psia_selection, 0, ppsi);
1042 static HRESULT WINAPI IFileDialog2_fnSetFileName(IFileDialog2 *iface, LPCWSTR pszName)
1044 FileDialogImpl *This = impl_from_IFileDialog2(iface);
1045 TRACE("%p (%p)\n", iface, pszName);
1047 set_file_name(This, pszName);
1052 static HRESULT WINAPI IFileDialog2_fnGetFileName(IFileDialog2 *iface, LPWSTR *pszName)
1054 FileDialogImpl *This = impl_from_IFileDialog2(iface);
1055 TRACE("%p (%p)\n", iface, pszName);
1058 return E_INVALIDARG;
1061 if(get_file_name(This, pszName))
1067 static HRESULT WINAPI IFileDialog2_fnSetTitle(IFileDialog2 *iface, LPCWSTR pszTitle)
1069 FileDialogImpl *This = impl_from_IFileDialog2(iface);
1070 FIXME("stub - %p (%p)\n", This, pszTitle);
1074 static HRESULT WINAPI IFileDialog2_fnSetOkButtonLabel(IFileDialog2 *iface, LPCWSTR pszText)
1076 FileDialogImpl *This = impl_from_IFileDialog2(iface);
1077 FIXME("stub - %p (%p)\n", This, pszText);
1081 static HRESULT WINAPI IFileDialog2_fnSetFileNameLabel(IFileDialog2 *iface, LPCWSTR pszLabel)
1083 FileDialogImpl *This = impl_from_IFileDialog2(iface);
1084 FIXME("stub - %p (%p)\n", This, pszLabel);
1088 static HRESULT WINAPI IFileDialog2_fnGetResult(IFileDialog2 *iface, IShellItem **ppsi)
1090 FileDialogImpl *This = impl_from_IFileDialog2(iface);
1092 TRACE("%p (%p)\n", This, ppsi);
1095 return E_INVALIDARG;
1097 if(This->psia_results)
1100 hr = IShellItemArray_GetCount(This->psia_results, &item_count);
1106 /* Adds a reference. */
1107 hr = IShellItemArray_GetItemAt(This->psia_results, 0, ppsi);
1113 return E_UNEXPECTED;
1116 static HRESULT WINAPI IFileDialog2_fnAddPlace(IFileDialog2 *iface, IShellItem *psi, FDAP fdap)
1118 FileDialogImpl *This = impl_from_IFileDialog2(iface);
1119 FIXME("stub - %p (%p, %d)\n", This, psi, fdap);
1123 static HRESULT WINAPI IFileDialog2_fnSetDefaultExtension(IFileDialog2 *iface, LPCWSTR pszDefaultExtension)
1125 FileDialogImpl *This = impl_from_IFileDialog2(iface);
1126 FIXME("stub - %p (%s)\n", This, debugstr_w(pszDefaultExtension));
1130 static HRESULT WINAPI IFileDialog2_fnClose(IFileDialog2 *iface, HRESULT hr)
1132 FileDialogImpl *This = impl_from_IFileDialog2(iface);
1133 TRACE("%p (0x%08x)\n", This, hr);
1136 EndDialog(This->dlg_hwnd, hr);
1141 static HRESULT WINAPI IFileDialog2_fnSetClientGuid(IFileDialog2 *iface, REFGUID guid)
1143 FileDialogImpl *This = impl_from_IFileDialog2(iface);
1144 FIXME("stub - %p (%s)\n", This, debugstr_guid(guid));
1148 static HRESULT WINAPI IFileDialog2_fnClearClientData(IFileDialog2 *iface)
1150 FileDialogImpl *This = impl_from_IFileDialog2(iface);
1151 FIXME("stub - %p\n", This);
1155 static HRESULT WINAPI IFileDialog2_fnSetFilter(IFileDialog2 *iface, IShellItemFilter *pFilter)
1157 FileDialogImpl *This = impl_from_IFileDialog2(iface);
1158 FIXME("stub - %p (%p)\n", This, pFilter);
1162 static HRESULT WINAPI IFileDialog2_fnSetCancelButtonLabel(IFileDialog2 *iface, LPCWSTR pszLabel)
1164 FileDialogImpl *This = impl_from_IFileDialog2(iface);
1165 FIXME("stub - %p (%s)\n", This, debugstr_w(pszLabel));
1169 static HRESULT WINAPI IFileDialog2_fnSetNavigationRoot(IFileDialog2 *iface, IShellItem *psi)
1171 FileDialogImpl *This = impl_from_IFileDialog2(iface);
1172 FIXME("stub - %p (%p)\n", This, psi);
1176 static const IFileDialog2Vtbl vt_IFileDialog2 = {
1177 IFileDialog2_fnQueryInterface,
1178 IFileDialog2_fnAddRef,
1179 IFileDialog2_fnRelease,
1180 IFileDialog2_fnShow,
1181 IFileDialog2_fnSetFileTypes,
1182 IFileDialog2_fnSetFileTypeIndex,
1183 IFileDialog2_fnGetFileTypeIndex,
1184 IFileDialog2_fnAdvise,
1185 IFileDialog2_fnUnadvise,
1186 IFileDialog2_fnSetOptions,
1187 IFileDialog2_fnGetOptions,
1188 IFileDialog2_fnSetDefaultFolder,
1189 IFileDialog2_fnSetFolder,
1190 IFileDialog2_fnGetFolder,
1191 IFileDialog2_fnGetCurrentSelection,
1192 IFileDialog2_fnSetFileName,
1193 IFileDialog2_fnGetFileName,
1194 IFileDialog2_fnSetTitle,
1195 IFileDialog2_fnSetOkButtonLabel,
1196 IFileDialog2_fnSetFileNameLabel,
1197 IFileDialog2_fnGetResult,
1198 IFileDialog2_fnAddPlace,
1199 IFileDialog2_fnSetDefaultExtension,
1200 IFileDialog2_fnClose,
1201 IFileDialog2_fnSetClientGuid,
1202 IFileDialog2_fnClearClientData,
1203 IFileDialog2_fnSetFilter,
1204 IFileDialog2_fnSetCancelButtonLabel,
1205 IFileDialog2_fnSetNavigationRoot
1208 /**************************************************************************
1211 static inline FileDialogImpl *impl_from_IFileOpenDialog(IFileOpenDialog *iface)
1213 return CONTAINING_RECORD(iface, FileDialogImpl, u.IFileOpenDialog_iface);
1216 static HRESULT WINAPI IFileOpenDialog_fnQueryInterface(IFileOpenDialog *iface,
1217 REFIID riid, void **ppvObject)
1219 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1220 return IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppvObject);
1223 static ULONG WINAPI IFileOpenDialog_fnAddRef(IFileOpenDialog *iface)
1225 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1226 return IFileDialog2_AddRef(&This->IFileDialog2_iface);
1229 static ULONG WINAPI IFileOpenDialog_fnRelease(IFileOpenDialog *iface)
1231 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1232 return IFileDialog2_Release(&This->IFileDialog2_iface);
1235 static HRESULT WINAPI IFileOpenDialog_fnShow(IFileOpenDialog *iface, HWND hwndOwner)
1237 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1238 return IFileDialog2_Show(&This->IFileDialog2_iface, hwndOwner);
1241 static HRESULT WINAPI IFileOpenDialog_fnSetFileTypes(IFileOpenDialog *iface, UINT cFileTypes,
1242 const COMDLG_FILTERSPEC *rgFilterSpec)
1244 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1245 return IFileDialog2_SetFileTypes(&This->IFileDialog2_iface, cFileTypes, rgFilterSpec);
1248 static HRESULT WINAPI IFileOpenDialog_fnSetFileTypeIndex(IFileOpenDialog *iface, UINT iFileType)
1250 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1251 return IFileDialog2_SetFileTypeIndex(&This->IFileDialog2_iface, iFileType);
1254 static HRESULT WINAPI IFileOpenDialog_fnGetFileTypeIndex(IFileOpenDialog *iface, UINT *piFileType)
1256 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1257 return IFileDialog2_GetFileTypeIndex(&This->IFileDialog2_iface, piFileType);
1260 static HRESULT WINAPI IFileOpenDialog_fnAdvise(IFileOpenDialog *iface, IFileDialogEvents *pfde,
1263 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1264 return IFileDialog2_Advise(&This->IFileDialog2_iface, pfde, pdwCookie);
1267 static HRESULT WINAPI IFileOpenDialog_fnUnadvise(IFileOpenDialog *iface, DWORD dwCookie)
1269 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1270 return IFileDialog2_Unadvise(&This->IFileDialog2_iface, dwCookie);
1273 static HRESULT WINAPI IFileOpenDialog_fnSetOptions(IFileOpenDialog *iface, FILEOPENDIALOGOPTIONS fos)
1275 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1276 return IFileDialog2_SetOptions(&This->IFileDialog2_iface, fos);
1279 static HRESULT WINAPI IFileOpenDialog_fnGetOptions(IFileOpenDialog *iface, FILEOPENDIALOGOPTIONS *pfos)
1281 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1282 return IFileDialog2_GetOptions(&This->IFileDialog2_iface, pfos);
1285 static HRESULT WINAPI IFileOpenDialog_fnSetDefaultFolder(IFileOpenDialog *iface, IShellItem *psi)
1287 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1288 return IFileDialog2_SetDefaultFolder(&This->IFileDialog2_iface, psi);
1291 static HRESULT WINAPI IFileOpenDialog_fnSetFolder(IFileOpenDialog *iface, IShellItem *psi)
1293 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1294 return IFileDialog2_SetFolder(&This->IFileDialog2_iface, psi);
1297 static HRESULT WINAPI IFileOpenDialog_fnGetFolder(IFileOpenDialog *iface, IShellItem **ppsi)
1299 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1300 return IFileDialog2_GetFolder(&This->IFileDialog2_iface, ppsi);
1303 static HRESULT WINAPI IFileOpenDialog_fnGetCurrentSelection(IFileOpenDialog *iface, IShellItem **ppsi)
1305 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1306 return IFileDialog2_GetCurrentSelection(&This->IFileDialog2_iface, ppsi);
1309 static HRESULT WINAPI IFileOpenDialog_fnSetFileName(IFileOpenDialog *iface, LPCWSTR pszName)
1311 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1312 return IFileDialog2_SetFileName(&This->IFileDialog2_iface, pszName);
1315 static HRESULT WINAPI IFileOpenDialog_fnGetFileName(IFileOpenDialog *iface, LPWSTR *pszName)
1317 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1318 return IFileDialog2_GetFileName(&This->IFileDialog2_iface, pszName);
1321 static HRESULT WINAPI IFileOpenDialog_fnSetTitle(IFileOpenDialog *iface, LPCWSTR pszTitle)
1323 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1324 return IFileDialog2_SetTitle(&This->IFileDialog2_iface, pszTitle);
1327 static HRESULT WINAPI IFileOpenDialog_fnSetOkButtonLabel(IFileOpenDialog *iface, LPCWSTR pszText)
1329 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1330 return IFileDialog2_SetOkButtonLabel(&This->IFileDialog2_iface, pszText);
1333 static HRESULT WINAPI IFileOpenDialog_fnSetFileNameLabel(IFileOpenDialog *iface, LPCWSTR pszLabel)
1335 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1336 return IFileDialog2_SetFileNameLabel(&This->IFileDialog2_iface, pszLabel);
1339 static HRESULT WINAPI IFileOpenDialog_fnGetResult(IFileOpenDialog *iface, IShellItem **ppsi)
1341 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1342 return IFileDialog2_GetResult(&This->IFileDialog2_iface, ppsi);
1345 static HRESULT WINAPI IFileOpenDialog_fnAddPlace(IFileOpenDialog *iface, IShellItem *psi, FDAP fdap)
1347 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1348 return IFileDialog2_AddPlace(&This->IFileDialog2_iface, psi, fdap);
1351 static HRESULT WINAPI IFileOpenDialog_fnSetDefaultExtension(IFileOpenDialog *iface,
1352 LPCWSTR pszDefaultExtension)
1354 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1355 return IFileDialog2_SetDefaultExtension(&This->IFileDialog2_iface, pszDefaultExtension);
1358 static HRESULT WINAPI IFileOpenDialog_fnClose(IFileOpenDialog *iface, HRESULT hr)
1360 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1361 return IFileDialog2_Close(&This->IFileDialog2_iface, hr);
1364 static HRESULT WINAPI IFileOpenDialog_fnSetClientGuid(IFileOpenDialog *iface, REFGUID guid)
1366 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1367 return IFileDialog2_SetClientGuid(&This->IFileDialog2_iface, guid);
1370 static HRESULT WINAPI IFileOpenDialog_fnClearClientData(IFileOpenDialog *iface)
1372 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1373 return IFileDialog2_ClearClientData(&This->IFileDialog2_iface);
1376 static HRESULT WINAPI IFileOpenDialog_fnSetFilter(IFileOpenDialog *iface, IShellItemFilter *pFilter)
1378 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1379 return IFileDialog2_SetFilter(&This->IFileDialog2_iface, pFilter);
1382 static HRESULT WINAPI IFileOpenDialog_fnGetResults(IFileOpenDialog *iface, IShellItemArray **ppenum)
1384 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1385 TRACE("%p (%p)\n", This, ppenum);
1387 *ppenum = This->psia_results;
1391 IShellItemArray_AddRef(*ppenum);
1398 static HRESULT WINAPI IFileOpenDialog_fnGetSelectedItems(IFileOpenDialog *iface, IShellItemArray **ppsai)
1400 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1401 TRACE("%p (%p)\n", This, ppsai);
1403 if(This->psia_selection)
1405 *ppsai = This->psia_selection;
1406 IShellItemArray_AddRef(*ppsai);
1413 static const IFileOpenDialogVtbl vt_IFileOpenDialog = {
1414 IFileOpenDialog_fnQueryInterface,
1415 IFileOpenDialog_fnAddRef,
1416 IFileOpenDialog_fnRelease,
1417 IFileOpenDialog_fnShow,
1418 IFileOpenDialog_fnSetFileTypes,
1419 IFileOpenDialog_fnSetFileTypeIndex,
1420 IFileOpenDialog_fnGetFileTypeIndex,
1421 IFileOpenDialog_fnAdvise,
1422 IFileOpenDialog_fnUnadvise,
1423 IFileOpenDialog_fnSetOptions,
1424 IFileOpenDialog_fnGetOptions,
1425 IFileOpenDialog_fnSetDefaultFolder,
1426 IFileOpenDialog_fnSetFolder,
1427 IFileOpenDialog_fnGetFolder,
1428 IFileOpenDialog_fnGetCurrentSelection,
1429 IFileOpenDialog_fnSetFileName,
1430 IFileOpenDialog_fnGetFileName,
1431 IFileOpenDialog_fnSetTitle,
1432 IFileOpenDialog_fnSetOkButtonLabel,
1433 IFileOpenDialog_fnSetFileNameLabel,
1434 IFileOpenDialog_fnGetResult,
1435 IFileOpenDialog_fnAddPlace,
1436 IFileOpenDialog_fnSetDefaultExtension,
1437 IFileOpenDialog_fnClose,
1438 IFileOpenDialog_fnSetClientGuid,
1439 IFileOpenDialog_fnClearClientData,
1440 IFileOpenDialog_fnSetFilter,
1441 IFileOpenDialog_fnGetResults,
1442 IFileOpenDialog_fnGetSelectedItems
1445 /**************************************************************************
1448 static inline FileDialogImpl *impl_from_IFileSaveDialog(IFileSaveDialog *iface)
1450 return CONTAINING_RECORD(iface, FileDialogImpl, u.IFileSaveDialog_iface);
1453 static HRESULT WINAPI IFileSaveDialog_fnQueryInterface(IFileSaveDialog *iface,
1457 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1458 return IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppvObject);
1461 static ULONG WINAPI IFileSaveDialog_fnAddRef(IFileSaveDialog *iface)
1463 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1464 return IFileDialog2_AddRef(&This->IFileDialog2_iface);
1467 static ULONG WINAPI IFileSaveDialog_fnRelease(IFileSaveDialog *iface)
1469 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1470 return IFileDialog2_Release(&This->IFileDialog2_iface);
1473 static HRESULT WINAPI IFileSaveDialog_fnShow(IFileSaveDialog *iface, HWND hwndOwner)
1475 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1476 return IFileDialog2_Show(&This->IFileDialog2_iface, hwndOwner);
1479 static HRESULT WINAPI IFileSaveDialog_fnSetFileTypes(IFileSaveDialog *iface, UINT cFileTypes,
1480 const COMDLG_FILTERSPEC *rgFilterSpec)
1482 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1483 return IFileDialog2_SetFileTypes(&This->IFileDialog2_iface, cFileTypes, rgFilterSpec);
1486 static HRESULT WINAPI IFileSaveDialog_fnSetFileTypeIndex(IFileSaveDialog *iface, UINT iFileType)
1488 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1489 return IFileDialog2_SetFileTypeIndex(&This->IFileDialog2_iface, iFileType);
1492 static HRESULT WINAPI IFileSaveDialog_fnGetFileTypeIndex(IFileSaveDialog *iface, UINT *piFileType)
1494 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1495 return IFileDialog2_GetFileTypeIndex(&This->IFileDialog2_iface, piFileType);
1498 static HRESULT WINAPI IFileSaveDialog_fnAdvise(IFileSaveDialog *iface, IFileDialogEvents *pfde,
1501 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1502 return IFileDialog2_Advise(&This->IFileDialog2_iface, pfde, pdwCookie);
1505 static HRESULT WINAPI IFileSaveDialog_fnUnadvise(IFileSaveDialog *iface, DWORD dwCookie)
1507 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1508 return IFileDialog2_Unadvise(&This->IFileDialog2_iface, dwCookie);
1511 static HRESULT WINAPI IFileSaveDialog_fnSetOptions(IFileSaveDialog *iface, FILEOPENDIALOGOPTIONS fos)
1513 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1514 return IFileDialog2_SetOptions(&This->IFileDialog2_iface, fos);
1517 static HRESULT WINAPI IFileSaveDialog_fnGetOptions(IFileSaveDialog *iface, FILEOPENDIALOGOPTIONS *pfos)
1519 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1520 return IFileDialog2_GetOptions(&This->IFileDialog2_iface, pfos);
1523 static HRESULT WINAPI IFileSaveDialog_fnSetDefaultFolder(IFileSaveDialog *iface, IShellItem *psi)
1525 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1526 return IFileDialog2_SetDefaultFolder(&This->IFileDialog2_iface, psi);
1529 static HRESULT WINAPI IFileSaveDialog_fnSetFolder(IFileSaveDialog *iface, IShellItem *psi)
1531 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1532 return IFileDialog2_SetFolder(&This->IFileDialog2_iface, psi);
1535 static HRESULT WINAPI IFileSaveDialog_fnGetFolder(IFileSaveDialog *iface, IShellItem **ppsi)
1537 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1538 return IFileDialog2_GetFolder(&This->IFileDialog2_iface, ppsi);
1541 static HRESULT WINAPI IFileSaveDialog_fnGetCurrentSelection(IFileSaveDialog *iface, IShellItem **ppsi)
1543 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1544 return IFileDialog2_GetCurrentSelection(&This->IFileDialog2_iface, ppsi);
1547 static HRESULT WINAPI IFileSaveDialog_fnSetFileName(IFileSaveDialog *iface, LPCWSTR pszName)
1549 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1550 return IFileDialog2_SetFileName(&This->IFileDialog2_iface, pszName);
1553 static HRESULT WINAPI IFileSaveDialog_fnGetFileName(IFileSaveDialog *iface, LPWSTR *pszName)
1555 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1556 return IFileDialog2_GetFileName(&This->IFileDialog2_iface, pszName);
1559 static HRESULT WINAPI IFileSaveDialog_fnSetTitle(IFileSaveDialog *iface, LPCWSTR pszTitle)
1561 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1562 return IFileDialog2_SetTitle(&This->IFileDialog2_iface, pszTitle);
1565 static HRESULT WINAPI IFileSaveDialog_fnSetOkButtonLabel(IFileSaveDialog *iface, LPCWSTR pszText)
1567 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1568 return IFileDialog2_SetOkButtonLabel(&This->IFileDialog2_iface, pszText);
1571 static HRESULT WINAPI IFileSaveDialog_fnSetFileNameLabel(IFileSaveDialog *iface, LPCWSTR pszLabel)
1573 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1574 return IFileDialog2_SetFileNameLabel(&This->IFileDialog2_iface, pszLabel);
1577 static HRESULT WINAPI IFileSaveDialog_fnGetResult(IFileSaveDialog *iface, IShellItem **ppsi)
1579 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1580 return IFileDialog2_GetResult(&This->IFileDialog2_iface, ppsi);
1583 static HRESULT WINAPI IFileSaveDialog_fnAddPlace(IFileSaveDialog *iface, IShellItem *psi, FDAP fdap)
1585 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1586 return IFileDialog2_AddPlace(&This->IFileDialog2_iface, psi, fdap);
1589 static HRESULT WINAPI IFileSaveDialog_fnSetDefaultExtension(IFileSaveDialog *iface,
1590 LPCWSTR pszDefaultExtension)
1592 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1593 return IFileDialog2_SetDefaultExtension(&This->IFileDialog2_iface, pszDefaultExtension);
1596 static HRESULT WINAPI IFileSaveDialog_fnClose(IFileSaveDialog *iface, HRESULT hr)
1598 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1599 return IFileDialog2_Close(&This->IFileDialog2_iface, hr);
1602 static HRESULT WINAPI IFileSaveDialog_fnSetClientGuid(IFileSaveDialog *iface, REFGUID guid)
1604 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1605 return IFileDialog2_SetClientGuid(&This->IFileDialog2_iface, guid);
1608 static HRESULT WINAPI IFileSaveDialog_fnClearClientData(IFileSaveDialog *iface)
1610 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1611 return IFileDialog2_ClearClientData(&This->IFileDialog2_iface);
1614 static HRESULT WINAPI IFileSaveDialog_fnSetFilter(IFileSaveDialog *iface, IShellItemFilter *pFilter)
1616 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1617 return IFileDialog2_SetFilter(&This->IFileDialog2_iface, pFilter);
1620 static HRESULT WINAPI IFileSaveDialog_fnSetSaveAsItem(IFileSaveDialog* iface, IShellItem *psi)
1622 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1623 FIXME("stub - %p (%p)\n", This, psi);
1627 static HRESULT WINAPI IFileSaveDialog_fnSetProperties(IFileSaveDialog* iface, IPropertyStore *pStore)
1629 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1630 FIXME("stub - %p (%p)\n", This, pStore);
1634 static HRESULT WINAPI IFileSaveDialog_fnSetCollectedProperties(IFileSaveDialog* iface,
1635 IPropertyDescriptionList *pList,
1636 BOOL fAppendDefault)
1638 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1639 FIXME("stub - %p (%p, %d)\n", This, pList, fAppendDefault);
1643 static HRESULT WINAPI IFileSaveDialog_fnGetProperties(IFileSaveDialog* iface, IPropertyStore **ppStore)
1645 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1646 FIXME("stub - %p (%p)\n", This, ppStore);
1650 static HRESULT WINAPI IFileSaveDialog_fnApplyProperties(IFileSaveDialog* iface,
1652 IPropertyStore *pStore,
1654 IFileOperationProgressSink *pSink)
1656 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1657 FIXME("%p (%p, %p, %p, %p)\n", This, psi, pStore, hwnd, pSink);
1661 static const IFileSaveDialogVtbl vt_IFileSaveDialog = {
1662 IFileSaveDialog_fnQueryInterface,
1663 IFileSaveDialog_fnAddRef,
1664 IFileSaveDialog_fnRelease,
1665 IFileSaveDialog_fnShow,
1666 IFileSaveDialog_fnSetFileTypes,
1667 IFileSaveDialog_fnSetFileTypeIndex,
1668 IFileSaveDialog_fnGetFileTypeIndex,
1669 IFileSaveDialog_fnAdvise,
1670 IFileSaveDialog_fnUnadvise,
1671 IFileSaveDialog_fnSetOptions,
1672 IFileSaveDialog_fnGetOptions,
1673 IFileSaveDialog_fnSetDefaultFolder,
1674 IFileSaveDialog_fnSetFolder,
1675 IFileSaveDialog_fnGetFolder,
1676 IFileSaveDialog_fnGetCurrentSelection,
1677 IFileSaveDialog_fnSetFileName,
1678 IFileSaveDialog_fnGetFileName,
1679 IFileSaveDialog_fnSetTitle,
1680 IFileSaveDialog_fnSetOkButtonLabel,
1681 IFileSaveDialog_fnSetFileNameLabel,
1682 IFileSaveDialog_fnGetResult,
1683 IFileSaveDialog_fnAddPlace,
1684 IFileSaveDialog_fnSetDefaultExtension,
1685 IFileSaveDialog_fnClose,
1686 IFileSaveDialog_fnSetClientGuid,
1687 IFileSaveDialog_fnClearClientData,
1688 IFileSaveDialog_fnSetFilter,
1689 IFileSaveDialog_fnSetSaveAsItem,
1690 IFileSaveDialog_fnSetProperties,
1691 IFileSaveDialog_fnSetCollectedProperties,
1692 IFileSaveDialog_fnGetProperties,
1693 IFileSaveDialog_fnApplyProperties
1696 /**************************************************************************
1697 * IExplorerBrowserEvents implementation
1699 static inline FileDialogImpl *impl_from_IExplorerBrowserEvents(IExplorerBrowserEvents *iface)
1701 return CONTAINING_RECORD(iface, FileDialogImpl, IExplorerBrowserEvents_iface);
1704 static HRESULT WINAPI IExplorerBrowserEvents_fnQueryInterface(IExplorerBrowserEvents *iface,
1705 REFIID riid, void **ppvObject)
1707 FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface);
1708 TRACE("%p (%s, %p)\n", This, debugstr_guid(riid), ppvObject);
1710 return IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppvObject);
1713 static ULONG WINAPI IExplorerBrowserEvents_fnAddRef(IExplorerBrowserEvents *iface)
1715 FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface);
1716 TRACE("%p\n", This);
1717 return IFileDialog2_AddRef(&This->IFileDialog2_iface);
1720 static ULONG WINAPI IExplorerBrowserEvents_fnRelease(IExplorerBrowserEvents *iface)
1722 FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface);
1723 TRACE("%p\n", This);
1724 return IFileDialog2_Release(&This->IFileDialog2_iface);
1727 static HRESULT WINAPI IExplorerBrowserEvents_fnOnNavigationPending(IExplorerBrowserEvents *iface,
1728 PCIDLIST_ABSOLUTE pidlFolder)
1730 FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface);
1731 TRACE("%p (%p)\n", This, pidlFolder);
1735 static HRESULT WINAPI IExplorerBrowserEvents_fnOnViewCreated(IExplorerBrowserEvents *iface,
1738 FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface);
1739 TRACE("%p (%p)\n", This, psv);
1743 static HRESULT WINAPI IExplorerBrowserEvents_fnOnNavigationComplete(IExplorerBrowserEvents *iface,
1744 PCIDLIST_ABSOLUTE pidlFolder)
1746 FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface);
1748 TRACE("%p (%p)\n", This, pidlFolder);
1750 if(This->psi_folder)
1751 IShellItem_Release(This->psi_folder);
1753 hr = SHCreateItemFromIDList(pidlFolder, &IID_IShellItem, (void**)&This->psi_folder);
1756 ERR("Failed to get the current folder.\n");
1757 This->psi_folder = NULL;
1763 static HRESULT WINAPI IExplorerBrowserEvents_fnOnNavigationFailed(IExplorerBrowserEvents *iface,
1764 PCIDLIST_ABSOLUTE pidlFolder)
1766 FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface);
1767 TRACE("%p (%p)\n", This, pidlFolder);
1771 static const IExplorerBrowserEventsVtbl vt_IExplorerBrowserEvents = {
1772 IExplorerBrowserEvents_fnQueryInterface,
1773 IExplorerBrowserEvents_fnAddRef,
1774 IExplorerBrowserEvents_fnRelease,
1775 IExplorerBrowserEvents_fnOnNavigationPending,
1776 IExplorerBrowserEvents_fnOnViewCreated,
1777 IExplorerBrowserEvents_fnOnNavigationComplete,
1778 IExplorerBrowserEvents_fnOnNavigationFailed
1781 /**************************************************************************
1782 * IServiceProvider implementation
1784 static inline FileDialogImpl *impl_from_IServiceProvider(IServiceProvider *iface)
1786 return CONTAINING_RECORD(iface, FileDialogImpl, IServiceProvider_iface);
1789 static HRESULT WINAPI IServiceProvider_fnQueryInterface(IServiceProvider *iface,
1790 REFIID riid, void **ppvObject)
1792 FileDialogImpl *This = impl_from_IServiceProvider(iface);
1793 TRACE("%p\n", This);
1794 return IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppvObject);
1797 static ULONG WINAPI IServiceProvider_fnAddRef(IServiceProvider *iface)
1799 FileDialogImpl *This = impl_from_IServiceProvider(iface);
1800 TRACE("%p\n", This);
1801 return IFileDialog2_AddRef(&This->IFileDialog2_iface);
1804 static ULONG WINAPI IServiceProvider_fnRelease(IServiceProvider *iface)
1806 FileDialogImpl *This = impl_from_IServiceProvider(iface);
1807 TRACE("%p\n", This);
1808 return IFileDialog2_Release(&This->IFileDialog2_iface);
1811 static HRESULT WINAPI IServiceProvider_fnQueryService(IServiceProvider *iface,
1812 REFGUID guidService,
1813 REFIID riid, void **ppv)
1815 FileDialogImpl *This = impl_from_IServiceProvider(iface);
1816 HRESULT hr = E_FAIL;
1817 TRACE("%p (%s, %s, %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);
1820 if(IsEqualGUID(guidService, &SID_STopLevelBrowser) && This->peb)
1821 hr = IExplorerBrowser_QueryInterface(This->peb, riid, ppv);
1822 else if(IsEqualGUID(guidService, &SID_SExplorerBrowserFrame))
1823 hr = IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppv);
1825 FIXME("Interface %s requested from unknown service %s\n",
1826 debugstr_guid(riid), debugstr_guid(guidService));
1828 if(SUCCEEDED(hr) && *ppv)
1830 IUnknown_AddRef((IUnknown*)*ppv);
1837 static const IServiceProviderVtbl vt_IServiceProvider = {
1838 IServiceProvider_fnQueryInterface,
1839 IServiceProvider_fnAddRef,
1840 IServiceProvider_fnRelease,
1841 IServiceProvider_fnQueryService
1844 /**************************************************************************
1845 * ICommDlgBrowser3 implementation
1847 static inline FileDialogImpl *impl_from_ICommDlgBrowser3(ICommDlgBrowser3 *iface)
1849 return CONTAINING_RECORD(iface, FileDialogImpl, ICommDlgBrowser3_iface);
1852 static HRESULT WINAPI ICommDlgBrowser3_fnQueryInterface(ICommDlgBrowser3 *iface,
1853 REFIID riid, void **ppvObject)
1855 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
1856 TRACE("%p\n", This);
1857 return IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppvObject);
1860 static ULONG WINAPI ICommDlgBrowser3_fnAddRef(ICommDlgBrowser3 *iface)
1862 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
1863 TRACE("%p\n", This);
1864 return IFileDialog2_AddRef(&This->IFileDialog2_iface);
1867 static ULONG WINAPI ICommDlgBrowser3_fnRelease(ICommDlgBrowser3 *iface)
1869 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
1870 TRACE("%p\n", This);
1871 return IFileDialog2_Release(&This->IFileDialog2_iface);
1874 static HRESULT WINAPI ICommDlgBrowser3_fnOnDefaultCommand(ICommDlgBrowser3 *iface,
1877 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
1879 TRACE("%p (%p)\n", This, shv);
1881 hr = on_default_action(This);
1884 EndDialog(This->dlg_hwnd, S_OK);
1889 static HRESULT WINAPI ICommDlgBrowser3_fnOnStateChange(ICommDlgBrowser3 *iface,
1890 IShellView *shv, ULONG uChange )
1892 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
1893 IDataObject *new_selection;
1895 TRACE("%p (%p, %x)\n", This, shv, uChange);
1899 case CDBOSC_SELCHANGE:
1900 if(This->psia_selection)
1902 IShellItemArray_Release(This->psia_selection);
1903 This->psia_selection = NULL;
1906 hr = IShellView_GetItemObject(shv, SVGIO_SELECTION, &IID_IDataObject, (void**)&new_selection);
1909 hr = SHCreateShellItemArrayFromDataObject(new_selection, &IID_IShellItemArray,
1910 (void**)&This->psia_selection);
1912 fill_filename_from_selection(This);
1914 IDataObject_Release(new_selection);
1918 TRACE("Unhandled state change\n");
1923 static HRESULT WINAPI ICommDlgBrowser3_fnIncludeObject(ICommDlgBrowser3 *iface,
1924 IShellView *shv, LPCITEMIDLIST pidl)
1926 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
1929 LPITEMIDLIST parent_pidl;
1932 TRACE("%p (%p, %p)\n", This, shv, pidl);
1934 if(!This->filterspec_count)
1937 hr = SHGetIDListFromObject((IUnknown*)shv, &parent_pidl);
1940 LPITEMIDLIST full_pidl = ILCombine(parent_pidl, pidl);
1941 hr = SHCreateItemFromIDList(full_pidl, &IID_IShellItem, (void**)&psi);
1942 ILFree(parent_pidl);
1947 ERR("Failed to get shellitem (%08x).\n", hr);
1951 hr = IShellItem_GetAttributes(psi, SFGAO_FOLDER|SFGAO_LINK, &attr);
1952 if(FAILED(hr) || (attr & (SFGAO_FOLDER | SFGAO_LINK)))
1954 IShellItem_Release(psi);
1959 if(SUCCEEDED(IShellItem_GetDisplayName(psi, SIGDN_PARENTRELATIVEPARSING, &filename)))
1961 if(!PathMatchSpecW(filename, This->filterspecs[This->filetypeindex].pszSpec))
1963 CoTaskMemFree(filename);
1966 IShellItem_Release(psi);
1970 static HRESULT WINAPI ICommDlgBrowser3_fnNotify(ICommDlgBrowser3 *iface,
1971 IShellView *ppshv, DWORD dwNotifyType)
1973 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
1974 FIXME("Stub: %p (%p, 0x%x)\n", This, ppshv, dwNotifyType);
1978 static HRESULT WINAPI ICommDlgBrowser3_fnGetDefaultMenuText(ICommDlgBrowser3 *iface,
1980 LPWSTR pszText, int cchMax)
1982 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
1983 FIXME("Stub: %p (%p, %p, %d)\n", This, pshv, pszText, cchMax);
1987 static HRESULT WINAPI ICommDlgBrowser3_fnGetViewFlags(ICommDlgBrowser3 *iface, DWORD *pdwFlags)
1989 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
1990 FIXME("Stub: %p (%p)\n", This, pdwFlags);
1994 static HRESULT WINAPI ICommDlgBrowser3_fnOnColumnClicked(ICommDlgBrowser3 *iface,
1995 IShellView *pshv, int iColumn)
1997 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
1998 FIXME("Stub: %p (%p, %d)\n", This, pshv, iColumn);
2002 static HRESULT WINAPI ICommDlgBrowser3_fnGetCurrentFilter(ICommDlgBrowser3 *iface,
2003 LPWSTR pszFileSpec, int cchFileSpec)
2005 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
2006 FIXME("Stub: %p (%p, %d)\n", This, pszFileSpec, cchFileSpec);
2010 static HRESULT WINAPI ICommDlgBrowser3_fnOnPreviewCreated(ICommDlgBrowser3 *iface,
2013 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
2014 FIXME("Stub: %p (%p)\n", This, pshv);
2018 static const ICommDlgBrowser3Vtbl vt_ICommDlgBrowser3 = {
2019 ICommDlgBrowser3_fnQueryInterface,
2020 ICommDlgBrowser3_fnAddRef,
2021 ICommDlgBrowser3_fnRelease,
2022 ICommDlgBrowser3_fnOnDefaultCommand,
2023 ICommDlgBrowser3_fnOnStateChange,
2024 ICommDlgBrowser3_fnIncludeObject,
2025 ICommDlgBrowser3_fnNotify,
2026 ICommDlgBrowser3_fnGetDefaultMenuText,
2027 ICommDlgBrowser3_fnGetViewFlags,
2028 ICommDlgBrowser3_fnOnColumnClicked,
2029 ICommDlgBrowser3_fnGetCurrentFilter,
2030 ICommDlgBrowser3_fnOnPreviewCreated
2033 static HRESULT FileDialog_constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv, enum ITEMDLG_TYPE type)
2035 FileDialogImpl *fdimpl;
2038 TRACE("%p, %s, %p\n", pUnkOuter, debugstr_guid(riid), ppv);
2043 return CLASS_E_NOAGGREGATION;
2045 fdimpl = HeapAlloc(GetProcessHeap(), 0, sizeof(FileDialogImpl));
2047 return E_OUTOFMEMORY;
2050 fdimpl->IFileDialog2_iface.lpVtbl = &vt_IFileDialog2;
2051 fdimpl->IExplorerBrowserEvents_iface.lpVtbl = &vt_IExplorerBrowserEvents;
2052 fdimpl->IServiceProvider_iface.lpVtbl = &vt_IServiceProvider;
2053 fdimpl->ICommDlgBrowser3_iface.lpVtbl = &vt_ICommDlgBrowser3;
2055 if(type == ITEMDLG_TYPE_OPEN)
2057 fdimpl->dlg_type = ITEMDLG_TYPE_OPEN;
2058 fdimpl->u.IFileOpenDialog_iface.lpVtbl = &vt_IFileOpenDialog;
2059 fdimpl->options = FOS_PATHMUSTEXIST | FOS_FILEMUSTEXIST | FOS_NOCHANGEDIR;
2063 fdimpl->dlg_type = ITEMDLG_TYPE_SAVE;
2064 fdimpl->u.IFileSaveDialog_iface.lpVtbl = &vt_IFileSaveDialog;
2065 fdimpl->options = FOS_OVERWRITEPROMPT | FOS_NOREADONLYRETURN | FOS_PATHMUSTEXIST | FOS_NOCHANGEDIR;
2068 fdimpl->filterspecs = NULL;
2069 fdimpl->filterspec_count = 0;
2070 fdimpl->filetypeindex = 0;
2072 fdimpl->psia_selection = fdimpl->psia_results = NULL;
2073 fdimpl->psi_setfolder = fdimpl->psi_folder = NULL;
2075 list_init(&fdimpl->events_clients);
2076 fdimpl->events_next_cookie = 0;
2078 fdimpl->dlg_hwnd = NULL;
2081 fdimpl->set_filename = NULL;
2083 /* FIXME: The default folder setting should be restored for the
2084 * application if it was previously set. */
2085 SHGetDesktopFolder(&psf);
2086 SHGetItemFromObject((IUnknown*)psf, &IID_IShellItem, (void**)&fdimpl->psi_defaultfolder);
2087 IShellFolder_Release(psf);
2089 hr = IUnknown_QueryInterface((IUnknown*)fdimpl, riid, ppv);
2090 IUnknown_Release((IUnknown*)fdimpl);
2094 HRESULT FileOpenDialog_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv)
2096 return FileDialog_constructor(pUnkOuter, riid, ppv, ITEMDLG_TYPE_OPEN);
2099 HRESULT FileSaveDialog_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv)
2101 return FileDialog_constructor(pUnkOuter, riid, ppv, ITEMDLG_TYPE_SAVE);