comdlg32: Add ICommDlgBrowser3 stub to Item Dialog.
[wine.git] / dlls / comdlg32 / itemdlg.c
blob35812f2febad895832b19e56dfdfb99cbcb57aa9
1 /*
2 * Common Item Dialog
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
21 #include <stdarg.h>
23 #define COBJMACROS
24 #define NONAMELESSUNION
25 #define NONAMELESSSTRUCT
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winuser.h"
30 #include "wingdi.h"
31 #include "winreg.h"
32 #include "shlwapi.h"
34 #include "commdlg.h"
35 #include "cdlg.h"
36 #include "filedlgbrowser.h"
38 #include "wine/debug.h"
39 #include "wine/list.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(commdlg);
43 enum ITEMDLG_TYPE {
44 ITEMDLG_TYPE_OPEN,
45 ITEMDLG_TYPE_SAVE
48 typedef struct {
49 struct list entry;
50 IFileDialogEvents *pfde;
51 DWORD cookie;
52 } events_client;
54 typedef struct FileDialogImpl {
55 IFileDialog2 IFileDialog2_iface;
56 union {
57 IFileOpenDialog IFileOpenDialog_iface;
58 IFileSaveDialog IFileSaveDialog_iface;
59 } u;
60 enum ITEMDLG_TYPE dlg_type;
61 IExplorerBrowserEvents IExplorerBrowserEvents_iface;
62 IServiceProvider IServiceProvider_iface;
63 ICommDlgBrowser3 ICommDlgBrowser3_iface;
64 LONG ref;
66 FILEOPENDIALOGOPTIONS options;
67 COMDLG_FILTERSPEC *filterspecs;
68 UINT filterspec_count;
69 UINT filetypeindex;
71 struct list events_clients;
72 DWORD events_next_cookie;
74 IShellItemArray *psia_selection;
75 IShellItemArray *psia_results;
76 IShellItem *psi_defaultfolder;
77 IShellItem *psi_setfolder;
78 IShellItem *psi_folder;
80 HWND dlg_hwnd;
81 IExplorerBrowser *peb;
82 DWORD ebevents_cookie;
83 } FileDialogImpl;
85 /**************************************************************************
86 * Window related functions.
88 static SIZE update_layout(FileDialogImpl *This)
90 HDWP hdwp;
91 HWND hwnd;
92 RECT dialog_rc;
93 RECT cancel_rc, open_rc;
94 RECT filetype_rc, filename_rc, filenamelabel_rc;
95 RECT ebrowser_rc;
96 int missing_width, missing_height;
97 static const UINT vspacing = 4, hspacing = 4;
98 SIZE ret;
100 GetClientRect(This->dlg_hwnd, &dialog_rc);
102 missing_width = max(0, 320 - dialog_rc.right);
103 missing_height = max(0, 200 - dialog_rc.bottom);
105 if(missing_width || missing_height)
107 TRACE("Missing (%d, %d)\n", missing_width, missing_height);
108 ret.cx = missing_width;
109 ret.cy = missing_height;
110 return ret;
113 /****
114 * Calculate the size of the dialog and all the parts.
117 /* Cancel button */
118 hwnd = GetDlgItem(This->dlg_hwnd, IDCANCEL);
119 if(hwnd)
121 int cancel_width, cancel_height;
122 GetWindowRect(hwnd, &cancel_rc);
123 cancel_width = cancel_rc.right - cancel_rc.left;
124 cancel_height = cancel_rc.bottom - cancel_rc.top;
126 cancel_rc.left = dialog_rc.right - cancel_width - hspacing;
127 cancel_rc.top = dialog_rc.bottom - cancel_height - vspacing;
128 cancel_rc.right = cancel_rc.left + cancel_width;
129 cancel_rc.bottom = cancel_rc.top + cancel_height;
132 /* Open/Save button */
133 if(hwnd)
135 int open_width, open_height;
136 GetWindowRect(hwnd, &open_rc);
137 open_width = open_rc.right - open_rc.left;
138 open_height = open_rc.bottom - open_rc.top;
140 open_rc.left = cancel_rc.left - open_width - hspacing;
141 open_rc.top = cancel_rc.top;
142 open_rc.right = open_rc.left + open_width;
143 open_rc.bottom = open_rc.top + open_height;
146 /* The filetype combobox. */
147 hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILETYPE);
148 if(hwnd)
150 int filetype_width, filetype_height;
151 GetWindowRect(hwnd, &filetype_rc);
153 filetype_width = filetype_rc.right - filetype_rc.left;
154 filetype_height = filetype_rc.bottom - filetype_rc.top;
156 filetype_rc.right = cancel_rc.right;
158 filetype_rc.left = filetype_rc.right - filetype_width;
159 filetype_rc.top = cancel_rc.top - filetype_height - vspacing;
160 filetype_rc.bottom = filetype_rc.top + filetype_height;
162 if(!This->filterspec_count)
163 filetype_rc.left = filetype_rc.right;
166 /* Filename label. */
167 hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILENAMESTATIC);
168 if(hwnd)
170 int filetypelabel_width, filetypelabel_height;
171 GetWindowRect(hwnd, &filenamelabel_rc);
173 filetypelabel_width = filenamelabel_rc.right - filenamelabel_rc.left;
174 filetypelabel_height = filenamelabel_rc.bottom - filenamelabel_rc.top;
176 filenamelabel_rc.left = 160; /* FIXME */
177 filenamelabel_rc.top = filetype_rc.top;
178 filenamelabel_rc.right = filenamelabel_rc.left + filetypelabel_width;
179 filenamelabel_rc.bottom = filenamelabel_rc.top + filetypelabel_height;
182 /* Filename edit box. */
183 hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILENAME);
184 if(hwnd)
186 int filename_width, filename_height;
187 GetWindowRect(hwnd, &filename_rc);
189 filename_width = filetype_rc.left - filenamelabel_rc.right - hspacing*2;
190 filename_height = filename_rc.bottom - filename_rc.top;
192 filename_rc.left = filenamelabel_rc.right + hspacing;
193 filename_rc.top = filetype_rc.top;
194 filename_rc.right = filename_rc.left + filename_width;
195 filename_rc.bottom = filename_rc.top + filename_height;
198 /* The ExplorerBrowser control. */
199 ebrowser_rc.left = dialog_rc.left + vspacing;
200 ebrowser_rc.top = 0;
201 ebrowser_rc.right = dialog_rc.right - vspacing;
202 ebrowser_rc.bottom = filename_rc.top - hspacing;
204 /****
205 * Move everything to the right place.
208 /* FIXME: The Save Dialog uses a slightly different layout. */
209 hdwp = BeginDeferWindowPos(6);
211 if(hdwp && This->peb)
212 IExplorerBrowser_SetRect(This->peb, &hdwp, ebrowser_rc);
214 /* The default controls */
215 if(hdwp && (hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILETYPE)) )
216 DeferWindowPos(hdwp, hwnd, NULL, filetype_rc.left, filetype_rc.top, 0, 0,
217 SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
219 if(hdwp && (hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILENAME)) )
220 DeferWindowPos(hdwp, hwnd, NULL, filename_rc.left, filename_rc.top,
221 filename_rc.right - filename_rc.left, filename_rc.bottom - filename_rc.top,
222 SWP_NOZORDER | SWP_NOACTIVATE);
224 if(hdwp && (hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILENAMESTATIC)) )
225 DeferWindowPos(hdwp, hwnd, NULL, filenamelabel_rc.left, filenamelabel_rc.top, 0, 0,
226 SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
228 if(hdwp && (hwnd = GetDlgItem(This->dlg_hwnd, IDOK)) )
229 DeferWindowPos(hdwp, hwnd, NULL, open_rc.left, open_rc.top, 0, 0,
230 SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
232 if(hdwp && (hwnd = GetDlgItem(This->dlg_hwnd, IDCANCEL)) )
233 DeferWindowPos(hdwp, hwnd, NULL, cancel_rc.left, cancel_rc.top, 0, 0,
234 SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
236 if(hdwp)
237 EndDeferWindowPos(hdwp);
238 else
239 ERR("Failed to position dialog controls.\n");
241 ret.cx = 0; ret.cy = 0;
242 return ret;
245 static HRESULT init_explorerbrowser(FileDialogImpl *This)
247 IShellItem *psi_folder;
248 FOLDERSETTINGS fos;
249 RECT rc = {0};
250 HRESULT hr;
252 /* Create ExplorerBrowser instance */
253 OleInitialize(NULL);
255 hr = CoCreateInstance(&CLSID_ExplorerBrowser, NULL, CLSCTX_INPROC_SERVER,
256 &IID_IExplorerBrowser, (void**)&This->peb);
257 if(FAILED(hr))
259 ERR("Failed to instantiate ExplorerBrowser control.\n");
260 return hr;
263 IExplorerBrowser_SetOptions(This->peb, EBO_SHOWFRAMES);
265 hr = IExplorerBrowser_Initialize(This->peb, This->dlg_hwnd, &rc, NULL);
266 if(FAILED(hr))
268 ERR("Failed to initialize the ExplorerBrowser control.\n");
269 IExplorerBrowser_Release(This->peb);
270 This->peb = NULL;
271 return hr;
273 hr = IExplorerBrowser_Advise(This->peb, &This->IExplorerBrowserEvents_iface, &This->ebevents_cookie);
274 if(FAILED(hr))
275 ERR("Advise (ExplorerBrowser) failed.\n");
277 /* Get previous options? */
278 fos.ViewMode = fos.fFlags = 0;
279 if(!(This->options & FOS_ALLOWMULTISELECT))
280 fos.fFlags |= FWF_SINGLESEL;
282 IExplorerBrowser_SetFolderSettings(This->peb, &fos);
284 /* Browse somewhere */
285 psi_folder = This->psi_setfolder ? This->psi_setfolder : This->psi_defaultfolder;
286 IExplorerBrowser_BrowseToObject(This->peb, (IUnknown*)psi_folder, SBSP_DEFBROWSER);
288 hr = IUnknown_SetSite((IUnknown*)This->peb, (IUnknown*)This);
289 if(FAILED(hr))
290 ERR("SetSite (ExplorerBrowser) failed.\n");
292 return S_OK;
295 static LRESULT on_wm_initdialog(HWND hwnd, LPARAM lParam)
297 FileDialogImpl *This = (FileDialogImpl*)lParam;
298 HWND hitem;
299 TRACE("(%p, %p)\n", This, hwnd);
301 SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LPARAM)This);
302 This->dlg_hwnd = hwnd;
304 hitem = GetDlgItem(This->dlg_hwnd, pshHelp);
305 if(hitem) ShowWindow(hitem, SW_HIDE);
307 hitem = GetDlgItem(This->dlg_hwnd, IDC_FILETYPESTATIC);
308 if(hitem) ShowWindow(hitem, SW_HIDE);
310 /* Fill filetypes combobox, or hide it. */
311 hitem = GetDlgItem(This->dlg_hwnd, IDC_FILETYPE);
312 if(This->filterspec_count)
314 UINT i;
315 for(i = 0; i < This->filterspec_count; i++)
316 SendMessageW(hitem, CB_ADDSTRING, 0, (LPARAM)This->filterspecs[i].pszName);
318 SendMessageW(hitem, CB_SETCURSEL, This->filetypeindex, 0);
320 else
321 ShowWindow(hitem, SW_HIDE);
323 init_explorerbrowser(This);
324 update_layout(This);
326 return TRUE;
329 static LRESULT on_wm_size(FileDialogImpl *This)
331 update_layout(This);
332 return FALSE;
335 static LRESULT on_wm_getminmaxinfo(FileDialogImpl *This, LPARAM lparam)
337 MINMAXINFO *mmi = (MINMAXINFO*)lparam;
338 TRACE("%p (%p)\n", This, mmi);
340 /* FIXME */
341 mmi->ptMinTrackSize.x = 640;
342 mmi->ptMinTrackSize.y = 480;
344 return FALSE;
347 static LRESULT on_wm_destroy(FileDialogImpl *This)
349 TRACE("%p\n", This);
351 if(This->peb)
353 IExplorerBrowser_Destroy(This->peb);
354 IExplorerBrowser_Release(This->peb);
355 This->peb = NULL;
358 This->dlg_hwnd = NULL;
360 return TRUE;
363 static LRESULT on_idok(FileDialogImpl *This)
365 TRACE("%p\n", This);
367 EndDialog(This->dlg_hwnd, S_OK);
369 return FALSE;
372 static LRESULT on_idcancel(FileDialogImpl *This)
374 TRACE("%p\n", This);
376 EndDialog(This->dlg_hwnd, HRESULT_FROM_WIN32(ERROR_CANCELLED));
378 return FALSE;
381 static LRESULT on_command_filetype(FileDialogImpl *This, WPARAM wparam, LPARAM lparam)
383 if(HIWORD(wparam) == CBN_SELCHANGE)
385 IShellView *psv;
386 HRESULT hr;
388 This->filetypeindex = SendMessageW((HWND)lparam, CB_GETCURSEL, 0, 0);
389 TRACE("File type selection changed to %d.\n", This->filetypeindex);
391 hr = IExplorerBrowser_GetCurrentView(This->peb, &IID_IShellView, (void**)&psv);
392 if(SUCCEEDED(hr))
394 IShellView_Refresh(psv);
395 IShellView_Release(psv);
399 return FALSE;
402 static LRESULT on_wm_command(FileDialogImpl *This, WPARAM wparam, LPARAM lparam)
404 switch(wparam)
406 case IDOK: return on_idok(This);
407 case IDCANCEL: return on_idcancel(This);
408 case IDC_FILETYPE: return on_command_filetype(This, wparam, lparam);
409 default: TRACE("Unknown command.\n");
411 return FALSE;
414 static LRESULT CALLBACK itemdlg_dlgproc(HWND hwnd, UINT umessage, WPARAM wparam, LPARAM lparam)
416 FileDialogImpl *This = (FileDialogImpl*)GetWindowLongPtrW(hwnd, GWLP_USERDATA);
418 switch(umessage)
420 case WM_INITDIALOG: return on_wm_initdialog(hwnd, lparam);
421 case WM_COMMAND: return on_wm_command(This, wparam, lparam);
422 case WM_SIZE: return on_wm_size(This);
423 case WM_GETMINMAXINFO: return on_wm_getminmaxinfo(This, lparam);
424 case WM_DESTROY: return on_wm_destroy(This);
427 return FALSE;
430 static HRESULT create_dialog(FileDialogImpl *This, HWND parent)
432 INT_PTR res;
434 SetLastError(0);
435 res = DialogBoxParamW(COMDLG32_hInstance,
436 MAKEINTRESOURCEW(NEWFILEOPENV3ORD),
437 parent, itemdlg_dlgproc, (LPARAM)This);
438 This->dlg_hwnd = NULL;
439 if(res == -1)
441 ERR("Failed to show dialog (LastError: %d)\n", GetLastError());
442 return E_FAIL;
445 TRACE("Returning 0x%08x\n", (HRESULT)res);
446 return (HRESULT)res;
449 /**************************************************************************
450 * IFileDialog implementation
452 static inline FileDialogImpl *impl_from_IFileDialog2(IFileDialog2 *iface)
454 return CONTAINING_RECORD(iface, FileDialogImpl, IFileDialog2_iface);
457 static HRESULT WINAPI IFileDialog2_fnQueryInterface(IFileDialog2 *iface,
458 REFIID riid,
459 void **ppvObject)
461 FileDialogImpl *This = impl_from_IFileDialog2(iface);
462 TRACE("%p (%s, %p)\n", This, debugstr_guid(riid), ppvObject);
464 *ppvObject = NULL;
465 if(IsEqualGUID(riid, &IID_IUnknown) ||
466 IsEqualGUID(riid, &IID_IFileDialog) ||
467 IsEqualGUID(riid, &IID_IFileDialog2))
469 *ppvObject = iface;
471 else if(IsEqualGUID(riid, &IID_IFileOpenDialog) && This->dlg_type == ITEMDLG_TYPE_OPEN)
473 *ppvObject = &This->u.IFileOpenDialog_iface;
475 else if(IsEqualGUID(riid, &IID_IFileSaveDialog) && This->dlg_type == ITEMDLG_TYPE_SAVE)
477 *ppvObject = &This->u.IFileSaveDialog_iface;
479 else if(IsEqualGUID(riid, &IID_IExplorerBrowserEvents))
481 *ppvObject = &This->IExplorerBrowserEvents_iface;
483 else if(IsEqualGUID(riid, &IID_IServiceProvider))
485 *ppvObject = &This->IServiceProvider_iface;
487 else if(IsEqualGUID(&IID_ICommDlgBrowser3, riid) ||
488 IsEqualGUID(&IID_ICommDlgBrowser2, riid) ||
489 IsEqualGUID(&IID_ICommDlgBrowser, riid))
491 *ppvObject = &This->ICommDlgBrowser3_iface;
493 else
494 FIXME("Unknown interface requested: %s.\n", debugstr_guid(riid));
496 if(*ppvObject)
498 IUnknown_AddRef((IUnknown*)*ppvObject);
499 return S_OK;
502 return E_NOINTERFACE;
505 static ULONG WINAPI IFileDialog2_fnAddRef(IFileDialog2 *iface)
507 FileDialogImpl *This = impl_from_IFileDialog2(iface);
508 LONG ref = InterlockedIncrement(&This->ref);
509 TRACE("%p - ref %d\n", This, ref);
511 return ref;
514 static ULONG WINAPI IFileDialog2_fnRelease(IFileDialog2 *iface)
516 FileDialogImpl *This = impl_from_IFileDialog2(iface);
517 LONG ref = InterlockedDecrement(&This->ref);
518 TRACE("%p - ref %d\n", This, ref);
520 if(!ref)
522 UINT i;
523 for(i = 0; i < This->filterspec_count; i++)
525 LocalFree((void*)This->filterspecs[i].pszName);
526 LocalFree((void*)This->filterspecs[i].pszSpec);
528 HeapFree(GetProcessHeap(), 0, This->filterspecs);
530 if(This->psi_defaultfolder) IShellItem_Release(This->psi_defaultfolder);
531 if(This->psi_setfolder) IShellItem_Release(This->psi_setfolder);
532 if(This->psi_folder) IShellItem_Release(This->psi_folder);
533 if(This->psia_selection) IShellItemArray_Release(This->psia_selection);
534 if(This->psia_results) IShellItemArray_Release(This->psia_results);
536 HeapFree(GetProcessHeap(), 0, This);
539 return ref;
542 static HRESULT WINAPI IFileDialog2_fnShow(IFileDialog2 *iface, HWND hwndOwner)
544 FileDialogImpl *This = impl_from_IFileDialog2(iface);
545 TRACE("%p (%p)\n", iface, hwndOwner);
547 return create_dialog(This, hwndOwner);
550 static HRESULT WINAPI IFileDialog2_fnSetFileTypes(IFileDialog2 *iface, UINT cFileTypes,
551 const COMDLG_FILTERSPEC *rgFilterSpec)
553 FileDialogImpl *This = impl_from_IFileDialog2(iface);
554 UINT i;
555 TRACE("%p (%d, %p)\n", This, cFileTypes, rgFilterSpec);
557 if(This->filterspecs)
558 return E_UNEXPECTED;
560 if(!rgFilterSpec)
561 return E_INVALIDARG;
563 if(!cFileTypes)
564 return S_OK;
566 This->filterspecs = HeapAlloc(GetProcessHeap(), 0, sizeof(COMDLG_FILTERSPEC)*cFileTypes);
567 for(i = 0; i < cFileTypes; i++)
569 This->filterspecs[i].pszName = StrDupW(rgFilterSpec[i].pszName);
570 This->filterspecs[i].pszSpec = StrDupW(rgFilterSpec[i].pszSpec);
572 This->filterspec_count = cFileTypes;
574 return S_OK;
577 static HRESULT WINAPI IFileDialog2_fnSetFileTypeIndex(IFileDialog2 *iface, UINT iFileType)
579 FileDialogImpl *This = impl_from_IFileDialog2(iface);
580 TRACE("%p (%d)\n", This, iFileType);
582 if(!This->filterspecs)
583 return E_FAIL;
585 if(iFileType >= This->filterspec_count)
586 This->filetypeindex = This->filterspec_count - 1;
587 else
588 This->filetypeindex = iFileType;
590 return S_OK;
593 static HRESULT WINAPI IFileDialog2_fnGetFileTypeIndex(IFileDialog2 *iface, UINT *piFileType)
595 FileDialogImpl *This = impl_from_IFileDialog2(iface);
596 TRACE("%p (%p)\n", This, piFileType);
598 if(!piFileType)
599 return E_INVALIDARG;
601 *piFileType = This->filetypeindex;
603 return S_OK;
606 static HRESULT WINAPI IFileDialog2_fnAdvise(IFileDialog2 *iface, IFileDialogEvents *pfde, DWORD *pdwCookie)
608 FileDialogImpl *This = impl_from_IFileDialog2(iface);
609 events_client *client;
610 TRACE("%p (%p, %p)\n", This, pfde, pdwCookie);
612 if(!pfde || !pdwCookie)
613 return E_INVALIDARG;
615 client = HeapAlloc(GetProcessHeap(), 0, sizeof(events_client));
616 client->pfde = pfde;
617 client->cookie = ++This->events_next_cookie;
619 IFileDialogEvents_AddRef(pfde);
620 *pdwCookie = client->cookie;
622 list_add_tail(&This->events_clients, &client->entry);
624 return S_OK;
627 static HRESULT WINAPI IFileDialog2_fnUnadvise(IFileDialog2 *iface, DWORD dwCookie)
629 FileDialogImpl *This = impl_from_IFileDialog2(iface);
630 events_client *client, *found = NULL;
631 TRACE("%p (%d)\n", This, dwCookie);
633 LIST_FOR_EACH_ENTRY(client, &This->events_clients, events_client, entry)
635 if(client->cookie == dwCookie)
637 found = client;
638 break;
642 if(found)
644 list_remove(&found->entry);
645 IFileDialogEvents_Release(found->pfde);
646 HeapFree(GetProcessHeap(), 0, found);
647 return S_OK;
650 return E_INVALIDARG;
653 static HRESULT WINAPI IFileDialog2_fnSetOptions(IFileDialog2 *iface, FILEOPENDIALOGOPTIONS fos)
655 FileDialogImpl *This = impl_from_IFileDialog2(iface);
656 TRACE("%p (0x%x)\n", This, fos);
658 This->options = fos;
660 return S_OK;
663 static HRESULT WINAPI IFileDialog2_fnGetOptions(IFileDialog2 *iface, FILEOPENDIALOGOPTIONS *pfos)
665 FileDialogImpl *This = impl_from_IFileDialog2(iface);
666 TRACE("%p (%p)\n", This, pfos);
668 if(!pfos)
669 return E_INVALIDARG;
671 *pfos = This->options;
673 return S_OK;
676 static HRESULT WINAPI IFileDialog2_fnSetDefaultFolder(IFileDialog2 *iface, IShellItem *psi)
678 FileDialogImpl *This = impl_from_IFileDialog2(iface);
679 TRACE("%p (%p)\n", This, psi);
680 if(This->psi_defaultfolder)
681 IShellItem_Release(This->psi_defaultfolder);
683 This->psi_defaultfolder = psi;
685 if(This->psi_defaultfolder)
686 IShellItem_AddRef(This->psi_defaultfolder);
688 return S_OK;
691 static HRESULT WINAPI IFileDialog2_fnSetFolder(IFileDialog2 *iface, IShellItem *psi)
693 FileDialogImpl *This = impl_from_IFileDialog2(iface);
694 TRACE("%p (%p)\n", This, psi);
695 if(This->psi_setfolder)
696 IShellItem_Release(This->psi_setfolder);
698 This->psi_setfolder = psi;
700 if(This->psi_setfolder)
701 IShellItem_AddRef(This->psi_setfolder);
703 return S_OK;
706 static HRESULT WINAPI IFileDialog2_fnGetFolder(IFileDialog2 *iface, IShellItem **ppsi)
708 FileDialogImpl *This = impl_from_IFileDialog2(iface);
709 TRACE("%p (%p)\n", This, ppsi);
710 if(!ppsi)
711 return E_INVALIDARG;
713 /* FIXME:
714 If the dialog is shown, return the current(ly selected) folder. */
716 *ppsi = NULL;
717 if(This->psi_folder)
718 *ppsi = This->psi_folder;
719 else if(This->psi_setfolder)
720 *ppsi = This->psi_setfolder;
721 else if(This->psi_defaultfolder)
722 *ppsi = This->psi_defaultfolder;
724 if(*ppsi)
726 IShellItem_AddRef(*ppsi);
727 return S_OK;
730 return E_FAIL;
733 static HRESULT WINAPI IFileDialog2_fnGetCurrentSelection(IFileDialog2 *iface, IShellItem **ppsi)
735 FileDialogImpl *This = impl_from_IFileDialog2(iface);
736 HRESULT hr;
737 TRACE("%p (%p)\n", This, ppsi);
739 if(!ppsi)
740 return E_INVALIDARG;
742 if(This->psia_selection)
744 /* FIXME: Check filename edit box */
745 hr = IShellItemArray_GetItemAt(This->psia_selection, 0, ppsi);
746 return hr;
749 return E_FAIL;
752 static HRESULT WINAPI IFileDialog2_fnSetFileName(IFileDialog2 *iface, LPCWSTR pszName)
754 FileDialogImpl *This = impl_from_IFileDialog2(iface);
755 FIXME("stub - %p (%p)\n", This, pszName);
756 return E_NOTIMPL;
759 static HRESULT WINAPI IFileDialog2_fnGetFileName(IFileDialog2 *iface, LPWSTR *pszName)
761 FileDialogImpl *This = impl_from_IFileDialog2(iface);
762 FIXME("stub - %p (%p)\n", This, pszName);
763 return E_NOTIMPL;
766 static HRESULT WINAPI IFileDialog2_fnSetTitle(IFileDialog2 *iface, LPCWSTR pszTitle)
768 FileDialogImpl *This = impl_from_IFileDialog2(iface);
769 FIXME("stub - %p (%p)\n", This, pszTitle);
770 return E_NOTIMPL;
773 static HRESULT WINAPI IFileDialog2_fnSetOkButtonLabel(IFileDialog2 *iface, LPCWSTR pszText)
775 FileDialogImpl *This = impl_from_IFileDialog2(iface);
776 FIXME("stub - %p (%p)\n", This, pszText);
777 return E_NOTIMPL;
780 static HRESULT WINAPI IFileDialog2_fnSetFileNameLabel(IFileDialog2 *iface, LPCWSTR pszLabel)
782 FileDialogImpl *This = impl_from_IFileDialog2(iface);
783 FIXME("stub - %p (%p)\n", This, pszLabel);
784 return E_NOTIMPL;
787 static HRESULT WINAPI IFileDialog2_fnGetResult(IFileDialog2 *iface, IShellItem **ppsi)
789 FileDialogImpl *This = impl_from_IFileDialog2(iface);
790 HRESULT hr;
791 TRACE("%p (%p)\n", This, ppsi);
793 if(!ppsi)
794 return E_INVALIDARG;
796 if(This->psia_results)
798 UINT item_count;
799 hr = IShellItemArray_GetCount(This->psia_results, &item_count);
800 if(SUCCEEDED(hr))
802 if(item_count != 1)
803 return E_FAIL;
805 /* Adds a reference. */
806 hr = IShellItemArray_GetItemAt(This->psia_results, 0, ppsi);
809 return hr;
812 return E_UNEXPECTED;
815 static HRESULT WINAPI IFileDialog2_fnAddPlace(IFileDialog2 *iface, IShellItem *psi, FDAP fdap)
817 FileDialogImpl *This = impl_from_IFileDialog2(iface);
818 FIXME("stub - %p (%p, %d)\n", This, psi, fdap);
819 return E_NOTIMPL;
822 static HRESULT WINAPI IFileDialog2_fnSetDefaultExtension(IFileDialog2 *iface, LPCWSTR pszDefaultExtension)
824 FileDialogImpl *This = impl_from_IFileDialog2(iface);
825 FIXME("stub - %p (%s)\n", This, debugstr_w(pszDefaultExtension));
826 return E_NOTIMPL;
829 static HRESULT WINAPI IFileDialog2_fnClose(IFileDialog2 *iface, HRESULT hr)
831 FileDialogImpl *This = impl_from_IFileDialog2(iface);
832 TRACE("%p (0x%08x)\n", This, hr);
834 if(This->dlg_hwnd)
835 EndDialog(This->dlg_hwnd, hr);
837 return S_OK;
840 static HRESULT WINAPI IFileDialog2_fnSetClientGuid(IFileDialog2 *iface, REFGUID guid)
842 FileDialogImpl *This = impl_from_IFileDialog2(iface);
843 FIXME("stub - %p (%s)\n", This, debugstr_guid(guid));
844 return E_NOTIMPL;
847 static HRESULT WINAPI IFileDialog2_fnClearClientData(IFileDialog2 *iface)
849 FileDialogImpl *This = impl_from_IFileDialog2(iface);
850 FIXME("stub - %p\n", This);
851 return E_NOTIMPL;
854 static HRESULT WINAPI IFileDialog2_fnSetFilter(IFileDialog2 *iface, IShellItemFilter *pFilter)
856 FileDialogImpl *This = impl_from_IFileDialog2(iface);
857 FIXME("stub - %p (%p)\n", This, pFilter);
858 return E_NOTIMPL;
861 static HRESULT WINAPI IFileDialog2_fnSetCancelButtonLabel(IFileDialog2 *iface, LPCWSTR pszLabel)
863 FileDialogImpl *This = impl_from_IFileDialog2(iface);
864 FIXME("stub - %p (%s)\n", This, debugstr_w(pszLabel));
865 return E_NOTIMPL;
868 static HRESULT WINAPI IFileDialog2_fnSetNavigationRoot(IFileDialog2 *iface, IShellItem *psi)
870 FileDialogImpl *This = impl_from_IFileDialog2(iface);
871 FIXME("stub - %p (%p)\n", This, psi);
872 return E_NOTIMPL;
875 static const IFileDialog2Vtbl vt_IFileDialog2 = {
876 IFileDialog2_fnQueryInterface,
877 IFileDialog2_fnAddRef,
878 IFileDialog2_fnRelease,
879 IFileDialog2_fnShow,
880 IFileDialog2_fnSetFileTypes,
881 IFileDialog2_fnSetFileTypeIndex,
882 IFileDialog2_fnGetFileTypeIndex,
883 IFileDialog2_fnAdvise,
884 IFileDialog2_fnUnadvise,
885 IFileDialog2_fnSetOptions,
886 IFileDialog2_fnGetOptions,
887 IFileDialog2_fnSetDefaultFolder,
888 IFileDialog2_fnSetFolder,
889 IFileDialog2_fnGetFolder,
890 IFileDialog2_fnGetCurrentSelection,
891 IFileDialog2_fnSetFileName,
892 IFileDialog2_fnGetFileName,
893 IFileDialog2_fnSetTitle,
894 IFileDialog2_fnSetOkButtonLabel,
895 IFileDialog2_fnSetFileNameLabel,
896 IFileDialog2_fnGetResult,
897 IFileDialog2_fnAddPlace,
898 IFileDialog2_fnSetDefaultExtension,
899 IFileDialog2_fnClose,
900 IFileDialog2_fnSetClientGuid,
901 IFileDialog2_fnClearClientData,
902 IFileDialog2_fnSetFilter,
903 IFileDialog2_fnSetCancelButtonLabel,
904 IFileDialog2_fnSetNavigationRoot
907 /**************************************************************************
908 * IFileOpenDialog
910 static inline FileDialogImpl *impl_from_IFileOpenDialog(IFileOpenDialog *iface)
912 return CONTAINING_RECORD(iface, FileDialogImpl, u.IFileOpenDialog_iface);
915 static HRESULT WINAPI IFileOpenDialog_fnQueryInterface(IFileOpenDialog *iface,
916 REFIID riid, void **ppvObject)
918 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
919 return IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppvObject);
922 static ULONG WINAPI IFileOpenDialog_fnAddRef(IFileOpenDialog *iface)
924 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
925 return IFileDialog2_AddRef(&This->IFileDialog2_iface);
928 static ULONG WINAPI IFileOpenDialog_fnRelease(IFileOpenDialog *iface)
930 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
931 return IFileDialog2_Release(&This->IFileDialog2_iface);
934 static HRESULT WINAPI IFileOpenDialog_fnShow(IFileOpenDialog *iface, HWND hwndOwner)
936 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
937 return IFileDialog2_Show(&This->IFileDialog2_iface, hwndOwner);
940 static HRESULT WINAPI IFileOpenDialog_fnSetFileTypes(IFileOpenDialog *iface, UINT cFileTypes,
941 const COMDLG_FILTERSPEC *rgFilterSpec)
943 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
944 return IFileDialog2_SetFileTypes(&This->IFileDialog2_iface, cFileTypes, rgFilterSpec);
947 static HRESULT WINAPI IFileOpenDialog_fnSetFileTypeIndex(IFileOpenDialog *iface, UINT iFileType)
949 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
950 return IFileDialog2_SetFileTypeIndex(&This->IFileDialog2_iface, iFileType);
953 static HRESULT WINAPI IFileOpenDialog_fnGetFileTypeIndex(IFileOpenDialog *iface, UINT *piFileType)
955 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
956 return IFileDialog2_GetFileTypeIndex(&This->IFileDialog2_iface, piFileType);
959 static HRESULT WINAPI IFileOpenDialog_fnAdvise(IFileOpenDialog *iface, IFileDialogEvents *pfde,
960 DWORD *pdwCookie)
962 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
963 return IFileDialog2_Advise(&This->IFileDialog2_iface, pfde, pdwCookie);
966 static HRESULT WINAPI IFileOpenDialog_fnUnadvise(IFileOpenDialog *iface, DWORD dwCookie)
968 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
969 return IFileDialog2_Unadvise(&This->IFileDialog2_iface, dwCookie);
972 static HRESULT WINAPI IFileOpenDialog_fnSetOptions(IFileOpenDialog *iface, FILEOPENDIALOGOPTIONS fos)
974 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
975 return IFileDialog2_SetOptions(&This->IFileDialog2_iface, fos);
978 static HRESULT WINAPI IFileOpenDialog_fnGetOptions(IFileOpenDialog *iface, FILEOPENDIALOGOPTIONS *pfos)
980 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
981 return IFileDialog2_GetOptions(&This->IFileDialog2_iface, pfos);
984 static HRESULT WINAPI IFileOpenDialog_fnSetDefaultFolder(IFileOpenDialog *iface, IShellItem *psi)
986 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
987 return IFileDialog2_SetDefaultFolder(&This->IFileDialog2_iface, psi);
990 static HRESULT WINAPI IFileOpenDialog_fnSetFolder(IFileOpenDialog *iface, IShellItem *psi)
992 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
993 return IFileDialog2_SetFolder(&This->IFileDialog2_iface, psi);
996 static HRESULT WINAPI IFileOpenDialog_fnGetFolder(IFileOpenDialog *iface, IShellItem **ppsi)
998 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
999 return IFileDialog2_GetFolder(&This->IFileDialog2_iface, ppsi);
1002 static HRESULT WINAPI IFileOpenDialog_fnGetCurrentSelection(IFileOpenDialog *iface, IShellItem **ppsi)
1004 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1005 return IFileDialog2_GetCurrentSelection(&This->IFileDialog2_iface, ppsi);
1008 static HRESULT WINAPI IFileOpenDialog_fnSetFileName(IFileOpenDialog *iface, LPCWSTR pszName)
1010 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1011 return IFileDialog2_SetFileName(&This->IFileDialog2_iface, pszName);
1014 static HRESULT WINAPI IFileOpenDialog_fnGetFileName(IFileOpenDialog *iface, LPWSTR *pszName)
1016 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1017 return IFileDialog2_GetFileName(&This->IFileDialog2_iface, pszName);
1020 static HRESULT WINAPI IFileOpenDialog_fnSetTitle(IFileOpenDialog *iface, LPCWSTR pszTitle)
1022 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1023 return IFileDialog2_SetTitle(&This->IFileDialog2_iface, pszTitle);
1026 static HRESULT WINAPI IFileOpenDialog_fnSetOkButtonLabel(IFileOpenDialog *iface, LPCWSTR pszText)
1028 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1029 return IFileDialog2_SetOkButtonLabel(&This->IFileDialog2_iface, pszText);
1032 static HRESULT WINAPI IFileOpenDialog_fnSetFileNameLabel(IFileOpenDialog *iface, LPCWSTR pszLabel)
1034 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1035 return IFileDialog2_SetFileNameLabel(&This->IFileDialog2_iface, pszLabel);
1038 static HRESULT WINAPI IFileOpenDialog_fnGetResult(IFileOpenDialog *iface, IShellItem **ppsi)
1040 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1041 return IFileDialog2_GetResult(&This->IFileDialog2_iface, ppsi);
1044 static HRESULT WINAPI IFileOpenDialog_fnAddPlace(IFileOpenDialog *iface, IShellItem *psi, FDAP fdap)
1046 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1047 return IFileDialog2_AddPlace(&This->IFileDialog2_iface, psi, fdap);
1050 static HRESULT WINAPI IFileOpenDialog_fnSetDefaultExtension(IFileOpenDialog *iface,
1051 LPCWSTR pszDefaultExtension)
1053 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1054 return IFileDialog2_SetDefaultExtension(&This->IFileDialog2_iface, pszDefaultExtension);
1057 static HRESULT WINAPI IFileOpenDialog_fnClose(IFileOpenDialog *iface, HRESULT hr)
1059 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1060 return IFileDialog2_Close(&This->IFileDialog2_iface, hr);
1063 static HRESULT WINAPI IFileOpenDialog_fnSetClientGuid(IFileOpenDialog *iface, REFGUID guid)
1065 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1066 return IFileDialog2_SetClientGuid(&This->IFileDialog2_iface, guid);
1069 static HRESULT WINAPI IFileOpenDialog_fnClearClientData(IFileOpenDialog *iface)
1071 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1072 return IFileDialog2_ClearClientData(&This->IFileDialog2_iface);
1075 static HRESULT WINAPI IFileOpenDialog_fnSetFilter(IFileOpenDialog *iface, IShellItemFilter *pFilter)
1077 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1078 return IFileDialog2_SetFilter(&This->IFileDialog2_iface, pFilter);
1081 static HRESULT WINAPI IFileOpenDialog_fnGetResults(IFileOpenDialog *iface, IShellItemArray **ppenum)
1083 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1084 TRACE("%p (%p)\n", This, ppenum);
1086 *ppenum = This->psia_results;
1088 if(*ppenum)
1090 IShellItemArray_AddRef(*ppenum);
1091 return S_OK;
1094 return E_FAIL;
1097 static HRESULT WINAPI IFileOpenDialog_fnGetSelectedItems(IFileOpenDialog *iface, IShellItemArray **ppsai)
1099 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
1100 TRACE("%p (%p)\n", This, ppsai);
1102 if(This->psia_selection)
1104 *ppsai = This->psia_selection;
1105 IShellItemArray_AddRef(*ppsai);
1106 return S_OK;
1109 return E_FAIL;
1112 static const IFileOpenDialogVtbl vt_IFileOpenDialog = {
1113 IFileOpenDialog_fnQueryInterface,
1114 IFileOpenDialog_fnAddRef,
1115 IFileOpenDialog_fnRelease,
1116 IFileOpenDialog_fnShow,
1117 IFileOpenDialog_fnSetFileTypes,
1118 IFileOpenDialog_fnSetFileTypeIndex,
1119 IFileOpenDialog_fnGetFileTypeIndex,
1120 IFileOpenDialog_fnAdvise,
1121 IFileOpenDialog_fnUnadvise,
1122 IFileOpenDialog_fnSetOptions,
1123 IFileOpenDialog_fnGetOptions,
1124 IFileOpenDialog_fnSetDefaultFolder,
1125 IFileOpenDialog_fnSetFolder,
1126 IFileOpenDialog_fnGetFolder,
1127 IFileOpenDialog_fnGetCurrentSelection,
1128 IFileOpenDialog_fnSetFileName,
1129 IFileOpenDialog_fnGetFileName,
1130 IFileOpenDialog_fnSetTitle,
1131 IFileOpenDialog_fnSetOkButtonLabel,
1132 IFileOpenDialog_fnSetFileNameLabel,
1133 IFileOpenDialog_fnGetResult,
1134 IFileOpenDialog_fnAddPlace,
1135 IFileOpenDialog_fnSetDefaultExtension,
1136 IFileOpenDialog_fnClose,
1137 IFileOpenDialog_fnSetClientGuid,
1138 IFileOpenDialog_fnClearClientData,
1139 IFileOpenDialog_fnSetFilter,
1140 IFileOpenDialog_fnGetResults,
1141 IFileOpenDialog_fnGetSelectedItems
1144 /**************************************************************************
1145 * IFileSaveDialog
1147 static inline FileDialogImpl *impl_from_IFileSaveDialog(IFileSaveDialog *iface)
1149 return CONTAINING_RECORD(iface, FileDialogImpl, u.IFileSaveDialog_iface);
1152 static HRESULT WINAPI IFileSaveDialog_fnQueryInterface(IFileSaveDialog *iface,
1153 REFIID riid,
1154 void **ppvObject)
1156 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1157 return IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppvObject);
1160 static ULONG WINAPI IFileSaveDialog_fnAddRef(IFileSaveDialog *iface)
1162 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1163 return IFileDialog2_AddRef(&This->IFileDialog2_iface);
1166 static ULONG WINAPI IFileSaveDialog_fnRelease(IFileSaveDialog *iface)
1168 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1169 return IFileDialog2_Release(&This->IFileDialog2_iface);
1172 static HRESULT WINAPI IFileSaveDialog_fnShow(IFileSaveDialog *iface, HWND hwndOwner)
1174 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1175 return IFileDialog2_Show(&This->IFileDialog2_iface, hwndOwner);
1178 static HRESULT WINAPI IFileSaveDialog_fnSetFileTypes(IFileSaveDialog *iface, UINT cFileTypes,
1179 const COMDLG_FILTERSPEC *rgFilterSpec)
1181 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1182 return IFileDialog2_SetFileTypes(&This->IFileDialog2_iface, cFileTypes, rgFilterSpec);
1185 static HRESULT WINAPI IFileSaveDialog_fnSetFileTypeIndex(IFileSaveDialog *iface, UINT iFileType)
1187 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1188 return IFileDialog2_SetFileTypeIndex(&This->IFileDialog2_iface, iFileType);
1191 static HRESULT WINAPI IFileSaveDialog_fnGetFileTypeIndex(IFileSaveDialog *iface, UINT *piFileType)
1193 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1194 return IFileDialog2_GetFileTypeIndex(&This->IFileDialog2_iface, piFileType);
1197 static HRESULT WINAPI IFileSaveDialog_fnAdvise(IFileSaveDialog *iface, IFileDialogEvents *pfde,
1198 DWORD *pdwCookie)
1200 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1201 return IFileDialog2_Advise(&This->IFileDialog2_iface, pfde, pdwCookie);
1204 static HRESULT WINAPI IFileSaveDialog_fnUnadvise(IFileSaveDialog *iface, DWORD dwCookie)
1206 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1207 return IFileDialog2_Unadvise(&This->IFileDialog2_iface, dwCookie);
1210 static HRESULT WINAPI IFileSaveDialog_fnSetOptions(IFileSaveDialog *iface, FILEOPENDIALOGOPTIONS fos)
1212 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1213 return IFileDialog2_SetOptions(&This->IFileDialog2_iface, fos);
1216 static HRESULT WINAPI IFileSaveDialog_fnGetOptions(IFileSaveDialog *iface, FILEOPENDIALOGOPTIONS *pfos)
1218 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1219 return IFileDialog2_GetOptions(&This->IFileDialog2_iface, pfos);
1222 static HRESULT WINAPI IFileSaveDialog_fnSetDefaultFolder(IFileSaveDialog *iface, IShellItem *psi)
1224 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1225 return IFileDialog2_SetDefaultFolder(&This->IFileDialog2_iface, psi);
1228 static HRESULT WINAPI IFileSaveDialog_fnSetFolder(IFileSaveDialog *iface, IShellItem *psi)
1230 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1231 return IFileDialog2_SetFolder(&This->IFileDialog2_iface, psi);
1234 static HRESULT WINAPI IFileSaveDialog_fnGetFolder(IFileSaveDialog *iface, IShellItem **ppsi)
1236 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1237 return IFileDialog2_GetFolder(&This->IFileDialog2_iface, ppsi);
1240 static HRESULT WINAPI IFileSaveDialog_fnGetCurrentSelection(IFileSaveDialog *iface, IShellItem **ppsi)
1242 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1243 return IFileDialog2_GetCurrentSelection(&This->IFileDialog2_iface, ppsi);
1246 static HRESULT WINAPI IFileSaveDialog_fnSetFileName(IFileSaveDialog *iface, LPCWSTR pszName)
1248 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1249 return IFileDialog2_SetFileName(&This->IFileDialog2_iface, pszName);
1252 static HRESULT WINAPI IFileSaveDialog_fnGetFileName(IFileSaveDialog *iface, LPWSTR *pszName)
1254 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1255 return IFileDialog2_GetFileName(&This->IFileDialog2_iface, pszName);
1258 static HRESULT WINAPI IFileSaveDialog_fnSetTitle(IFileSaveDialog *iface, LPCWSTR pszTitle)
1260 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1261 return IFileDialog2_SetTitle(&This->IFileDialog2_iface, pszTitle);
1264 static HRESULT WINAPI IFileSaveDialog_fnSetOkButtonLabel(IFileSaveDialog *iface, LPCWSTR pszText)
1266 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1267 return IFileDialog2_SetOkButtonLabel(&This->IFileDialog2_iface, pszText);
1270 static HRESULT WINAPI IFileSaveDialog_fnSetFileNameLabel(IFileSaveDialog *iface, LPCWSTR pszLabel)
1272 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1273 return IFileDialog2_SetFileNameLabel(&This->IFileDialog2_iface, pszLabel);
1276 static HRESULT WINAPI IFileSaveDialog_fnGetResult(IFileSaveDialog *iface, IShellItem **ppsi)
1278 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1279 return IFileDialog2_GetResult(&This->IFileDialog2_iface, ppsi);
1282 static HRESULT WINAPI IFileSaveDialog_fnAddPlace(IFileSaveDialog *iface, IShellItem *psi, FDAP fdap)
1284 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1285 return IFileDialog2_AddPlace(&This->IFileDialog2_iface, psi, fdap);
1288 static HRESULT WINAPI IFileSaveDialog_fnSetDefaultExtension(IFileSaveDialog *iface,
1289 LPCWSTR pszDefaultExtension)
1291 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1292 return IFileDialog2_SetDefaultExtension(&This->IFileDialog2_iface, pszDefaultExtension);
1295 static HRESULT WINAPI IFileSaveDialog_fnClose(IFileSaveDialog *iface, HRESULT hr)
1297 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1298 return IFileDialog2_Close(&This->IFileDialog2_iface, hr);
1301 static HRESULT WINAPI IFileSaveDialog_fnSetClientGuid(IFileSaveDialog *iface, REFGUID guid)
1303 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1304 return IFileDialog2_SetClientGuid(&This->IFileDialog2_iface, guid);
1307 static HRESULT WINAPI IFileSaveDialog_fnClearClientData(IFileSaveDialog *iface)
1309 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1310 return IFileDialog2_ClearClientData(&This->IFileDialog2_iface);
1313 static HRESULT WINAPI IFileSaveDialog_fnSetFilter(IFileSaveDialog *iface, IShellItemFilter *pFilter)
1315 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1316 return IFileDialog2_SetFilter(&This->IFileDialog2_iface, pFilter);
1319 static HRESULT WINAPI IFileSaveDialog_fnSetSaveAsItem(IFileSaveDialog* iface, IShellItem *psi)
1321 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1322 FIXME("stub - %p (%p)\n", This, psi);
1323 return E_NOTIMPL;
1326 static HRESULT WINAPI IFileSaveDialog_fnSetProperties(IFileSaveDialog* iface, IPropertyStore *pStore)
1328 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1329 FIXME("stub - %p (%p)\n", This, pStore);
1330 return E_NOTIMPL;
1333 static HRESULT WINAPI IFileSaveDialog_fnSetCollectedProperties(IFileSaveDialog* iface,
1334 IPropertyDescriptionList *pList,
1335 BOOL fAppendDefault)
1337 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1338 FIXME("stub - %p (%p, %d)\n", This, pList, fAppendDefault);
1339 return E_NOTIMPL;
1342 static HRESULT WINAPI IFileSaveDialog_fnGetProperties(IFileSaveDialog* iface, IPropertyStore **ppStore)
1344 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1345 FIXME("stub - %p (%p)\n", This, ppStore);
1346 return E_NOTIMPL;
1349 static HRESULT WINAPI IFileSaveDialog_fnApplyProperties(IFileSaveDialog* iface,
1350 IShellItem *psi,
1351 IPropertyStore *pStore,
1352 HWND hwnd,
1353 IFileOperationProgressSink *pSink)
1355 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
1356 FIXME("%p (%p, %p, %p, %p)\n", This, psi, pStore, hwnd, pSink);
1357 return E_NOTIMPL;
1360 static const IFileSaveDialogVtbl vt_IFileSaveDialog = {
1361 IFileSaveDialog_fnQueryInterface,
1362 IFileSaveDialog_fnAddRef,
1363 IFileSaveDialog_fnRelease,
1364 IFileSaveDialog_fnShow,
1365 IFileSaveDialog_fnSetFileTypes,
1366 IFileSaveDialog_fnSetFileTypeIndex,
1367 IFileSaveDialog_fnGetFileTypeIndex,
1368 IFileSaveDialog_fnAdvise,
1369 IFileSaveDialog_fnUnadvise,
1370 IFileSaveDialog_fnSetOptions,
1371 IFileSaveDialog_fnGetOptions,
1372 IFileSaveDialog_fnSetDefaultFolder,
1373 IFileSaveDialog_fnSetFolder,
1374 IFileSaveDialog_fnGetFolder,
1375 IFileSaveDialog_fnGetCurrentSelection,
1376 IFileSaveDialog_fnSetFileName,
1377 IFileSaveDialog_fnGetFileName,
1378 IFileSaveDialog_fnSetTitle,
1379 IFileSaveDialog_fnSetOkButtonLabel,
1380 IFileSaveDialog_fnSetFileNameLabel,
1381 IFileSaveDialog_fnGetResult,
1382 IFileSaveDialog_fnAddPlace,
1383 IFileSaveDialog_fnSetDefaultExtension,
1384 IFileSaveDialog_fnClose,
1385 IFileSaveDialog_fnSetClientGuid,
1386 IFileSaveDialog_fnClearClientData,
1387 IFileSaveDialog_fnSetFilter,
1388 IFileSaveDialog_fnSetSaveAsItem,
1389 IFileSaveDialog_fnSetProperties,
1390 IFileSaveDialog_fnSetCollectedProperties,
1391 IFileSaveDialog_fnGetProperties,
1392 IFileSaveDialog_fnApplyProperties
1395 /**************************************************************************
1396 * IExplorerBrowserEvents implementation
1398 static inline FileDialogImpl *impl_from_IExplorerBrowserEvents(IExplorerBrowserEvents *iface)
1400 return CONTAINING_RECORD(iface, FileDialogImpl, IExplorerBrowserEvents_iface);
1403 static HRESULT WINAPI IExplorerBrowserEvents_fnQueryInterface(IExplorerBrowserEvents *iface,
1404 REFIID riid, void **ppvObject)
1406 FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface);
1407 TRACE("%p (%s, %p)\n", This, debugstr_guid(riid), ppvObject);
1409 return IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppvObject);
1412 static ULONG WINAPI IExplorerBrowserEvents_fnAddRef(IExplorerBrowserEvents *iface)
1414 FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface);
1415 TRACE("%p\n", This);
1416 return IFileDialog2_AddRef(&This->IFileDialog2_iface);
1419 static ULONG WINAPI IExplorerBrowserEvents_fnRelease(IExplorerBrowserEvents *iface)
1421 FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface);
1422 TRACE("%p\n", This);
1423 return IFileDialog2_Release(&This->IFileDialog2_iface);
1426 static HRESULT WINAPI IExplorerBrowserEvents_fnOnNavigationPending(IExplorerBrowserEvents *iface,
1427 PCIDLIST_ABSOLUTE pidlFolder)
1429 FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface);
1430 TRACE("%p (%p)\n", This, pidlFolder);
1431 return S_OK;
1434 static HRESULT WINAPI IExplorerBrowserEvents_fnOnViewCreated(IExplorerBrowserEvents *iface,
1435 IShellView *psv)
1437 FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface);
1438 TRACE("%p (%p)\n", This, psv);
1439 return S_OK;
1442 static HRESULT WINAPI IExplorerBrowserEvents_fnOnNavigationComplete(IExplorerBrowserEvents *iface,
1443 PCIDLIST_ABSOLUTE pidlFolder)
1445 FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface);
1446 HRESULT hr;
1447 TRACE("%p (%p)\n", This, pidlFolder);
1449 if(This->psi_folder)
1450 IShellItem_Release(This->psi_folder);
1452 hr = SHCreateItemFromIDList(pidlFolder, &IID_IShellItem, (void**)&This->psi_folder);
1453 if(FAILED(hr))
1455 ERR("Failed to get the current folder.\n");
1456 This->psi_folder = NULL;
1459 return S_OK;
1462 static HRESULT WINAPI IExplorerBrowserEvents_fnOnNavigationFailed(IExplorerBrowserEvents *iface,
1463 PCIDLIST_ABSOLUTE pidlFolder)
1465 FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface);
1466 TRACE("%p (%p)\n", This, pidlFolder);
1467 return S_OK;
1470 static const IExplorerBrowserEventsVtbl vt_IExplorerBrowserEvents = {
1471 IExplorerBrowserEvents_fnQueryInterface,
1472 IExplorerBrowserEvents_fnAddRef,
1473 IExplorerBrowserEvents_fnRelease,
1474 IExplorerBrowserEvents_fnOnNavigationPending,
1475 IExplorerBrowserEvents_fnOnViewCreated,
1476 IExplorerBrowserEvents_fnOnNavigationComplete,
1477 IExplorerBrowserEvents_fnOnNavigationFailed
1480 /**************************************************************************
1481 * IServiceProvider implementation
1483 static inline FileDialogImpl *impl_from_IServiceProvider(IServiceProvider *iface)
1485 return CONTAINING_RECORD(iface, FileDialogImpl, IServiceProvider_iface);
1488 static HRESULT WINAPI IServiceProvider_fnQueryInterface(IServiceProvider *iface,
1489 REFIID riid, void **ppvObject)
1491 FileDialogImpl *This = impl_from_IServiceProvider(iface);
1492 TRACE("%p\n", This);
1493 return IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppvObject);
1496 static ULONG WINAPI IServiceProvider_fnAddRef(IServiceProvider *iface)
1498 FileDialogImpl *This = impl_from_IServiceProvider(iface);
1499 TRACE("%p\n", This);
1500 return IFileDialog2_AddRef(&This->IFileDialog2_iface);
1503 static ULONG WINAPI IServiceProvider_fnRelease(IServiceProvider *iface)
1505 FileDialogImpl *This = impl_from_IServiceProvider(iface);
1506 TRACE("%p\n", This);
1507 return IFileDialog2_Release(&This->IFileDialog2_iface);
1510 static HRESULT WINAPI IServiceProvider_fnQueryService(IServiceProvider *iface,
1511 REFGUID guidService,
1512 REFIID riid, void **ppv)
1514 FileDialogImpl *This = impl_from_IServiceProvider(iface);
1515 HRESULT hr = E_FAIL;
1516 TRACE("%p (%s, %s, %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);
1518 *ppv = NULL;
1519 if(IsEqualGUID(guidService, &SID_STopLevelBrowser) && This->peb)
1520 hr = IExplorerBrowser_QueryInterface(This->peb, riid, ppv);
1521 else if(IsEqualGUID(guidService, &SID_SExplorerBrowserFrame))
1522 hr = IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppv);
1523 else
1524 FIXME("Interface %s requested from unknown service %s\n",
1525 debugstr_guid(riid), debugstr_guid(guidService));
1527 if(SUCCEEDED(hr) && *ppv)
1529 IUnknown_AddRef((IUnknown*)*ppv);
1530 return S_OK;
1533 return E_FAIL;
1536 static const IServiceProviderVtbl vt_IServiceProvider = {
1537 IServiceProvider_fnQueryInterface,
1538 IServiceProvider_fnAddRef,
1539 IServiceProvider_fnRelease,
1540 IServiceProvider_fnQueryService
1543 /**************************************************************************
1544 * ICommDlgBrowser3 implementation
1546 static inline FileDialogImpl *impl_from_ICommDlgBrowser3(ICommDlgBrowser3 *iface)
1548 return CONTAINING_RECORD(iface, FileDialogImpl, ICommDlgBrowser3_iface);
1551 static HRESULT WINAPI ICommDlgBrowser3_fnQueryInterface(ICommDlgBrowser3 *iface,
1552 REFIID riid, void **ppvObject)
1554 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
1555 TRACE("%p\n", This);
1556 return IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppvObject);
1559 static ULONG WINAPI ICommDlgBrowser3_fnAddRef(ICommDlgBrowser3 *iface)
1561 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
1562 TRACE("%p\n", This);
1563 return IFileDialog2_AddRef(&This->IFileDialog2_iface);
1566 static ULONG WINAPI ICommDlgBrowser3_fnRelease(ICommDlgBrowser3 *iface)
1568 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
1569 TRACE("%p\n", This);
1570 return IFileDialog2_Release(&This->IFileDialog2_iface);
1573 static HRESULT WINAPI ICommDlgBrowser3_fnOnDefaultCommand(ICommDlgBrowser3 *iface,
1574 IShellView *shv)
1576 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
1577 FIXME("Stub: %p (%p)\n", This, shv);
1578 return S_OK;
1581 static HRESULT WINAPI ICommDlgBrowser3_fnOnStateChange(ICommDlgBrowser3 *iface,
1582 IShellView *shv, ULONG uChange )
1584 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
1585 FIXME("Stub: %p (%p, %x)\n", This, shv, uChange);
1586 return S_OK;
1589 static HRESULT WINAPI ICommDlgBrowser3_fnIncludeObject(ICommDlgBrowser3 *iface,
1590 IShellView *shv, LPCITEMIDLIST pidl)
1592 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
1593 FIXME("Stub: %p (%p, %p)\n", This, shv, pidl);
1594 return S_OK;
1597 static HRESULT WINAPI ICommDlgBrowser3_fnNotify(ICommDlgBrowser3 *iface,
1598 IShellView *ppshv, DWORD dwNotifyType)
1600 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
1601 FIXME("Stub: %p (%p, 0x%x)\n", This, ppshv, dwNotifyType);
1602 return E_NOTIMPL;
1605 static HRESULT WINAPI ICommDlgBrowser3_fnGetDefaultMenuText(ICommDlgBrowser3 *iface,
1606 IShellView *pshv,
1607 LPWSTR pszText, int cchMax)
1609 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
1610 FIXME("Stub: %p (%p, %p, %d)\n", This, pshv, pszText, cchMax);
1611 return E_NOTIMPL;
1614 static HRESULT WINAPI ICommDlgBrowser3_fnGetViewFlags(ICommDlgBrowser3 *iface, DWORD *pdwFlags)
1616 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
1617 FIXME("Stub: %p (%p)\n", This, pdwFlags);
1618 return E_NOTIMPL;
1621 static HRESULT WINAPI ICommDlgBrowser3_fnOnColumnClicked(ICommDlgBrowser3 *iface,
1622 IShellView *pshv, int iColumn)
1624 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
1625 FIXME("Stub: %p (%p, %d)\n", This, pshv, iColumn);
1626 return E_NOTIMPL;
1629 static HRESULT WINAPI ICommDlgBrowser3_fnGetCurrentFilter(ICommDlgBrowser3 *iface,
1630 LPWSTR pszFileSpec, int cchFileSpec)
1632 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
1633 FIXME("Stub: %p (%p, %d)\n", This, pszFileSpec, cchFileSpec);
1634 return E_NOTIMPL;
1637 static HRESULT WINAPI ICommDlgBrowser3_fnOnPreviewCreated(ICommDlgBrowser3 *iface,
1638 IShellView *pshv)
1640 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
1641 FIXME("Stub: %p (%p)\n", This, pshv);
1642 return E_NOTIMPL;
1645 static const ICommDlgBrowser3Vtbl vt_ICommDlgBrowser3 = {
1646 ICommDlgBrowser3_fnQueryInterface,
1647 ICommDlgBrowser3_fnAddRef,
1648 ICommDlgBrowser3_fnRelease,
1649 ICommDlgBrowser3_fnOnDefaultCommand,
1650 ICommDlgBrowser3_fnOnStateChange,
1651 ICommDlgBrowser3_fnIncludeObject,
1652 ICommDlgBrowser3_fnNotify,
1653 ICommDlgBrowser3_fnGetDefaultMenuText,
1654 ICommDlgBrowser3_fnGetViewFlags,
1655 ICommDlgBrowser3_fnOnColumnClicked,
1656 ICommDlgBrowser3_fnGetCurrentFilter,
1657 ICommDlgBrowser3_fnOnPreviewCreated
1660 static HRESULT FileDialog_constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv, enum ITEMDLG_TYPE type)
1662 FileDialogImpl *fdimpl;
1663 HRESULT hr;
1664 IShellFolder *psf;
1665 TRACE("%p, %s, %p\n", pUnkOuter, debugstr_guid(riid), ppv);
1667 if(!ppv)
1668 return E_POINTER;
1669 if(pUnkOuter)
1670 return CLASS_E_NOAGGREGATION;
1672 fdimpl = HeapAlloc(GetProcessHeap(), 0, sizeof(FileDialogImpl));
1673 if(!fdimpl)
1674 return E_OUTOFMEMORY;
1676 fdimpl->ref = 1;
1677 fdimpl->IFileDialog2_iface.lpVtbl = &vt_IFileDialog2;
1678 fdimpl->IExplorerBrowserEvents_iface.lpVtbl = &vt_IExplorerBrowserEvents;
1679 fdimpl->IServiceProvider_iface.lpVtbl = &vt_IServiceProvider;
1680 fdimpl->ICommDlgBrowser3_iface.lpVtbl = &vt_ICommDlgBrowser3;
1682 if(type == ITEMDLG_TYPE_OPEN)
1684 fdimpl->dlg_type = ITEMDLG_TYPE_OPEN;
1685 fdimpl->u.IFileOpenDialog_iface.lpVtbl = &vt_IFileOpenDialog;
1686 fdimpl->options = FOS_PATHMUSTEXIST | FOS_FILEMUSTEXIST | FOS_NOCHANGEDIR;
1688 else
1690 fdimpl->dlg_type = ITEMDLG_TYPE_SAVE;
1691 fdimpl->u.IFileSaveDialog_iface.lpVtbl = &vt_IFileSaveDialog;
1692 fdimpl->options = FOS_OVERWRITEPROMPT | FOS_NOREADONLYRETURN | FOS_PATHMUSTEXIST | FOS_NOCHANGEDIR;
1695 fdimpl->filterspecs = NULL;
1696 fdimpl->filterspec_count = 0;
1697 fdimpl->filetypeindex = 0;
1699 fdimpl->psia_selection = fdimpl->psia_results = NULL;
1700 fdimpl->psi_setfolder = fdimpl->psi_folder = NULL;
1702 list_init(&fdimpl->events_clients);
1703 fdimpl->events_next_cookie = 0;
1705 fdimpl->dlg_hwnd = NULL;
1706 fdimpl->peb = NULL;
1708 /* FIXME: The default folder setting should be restored for the
1709 * application if it was previously set. */
1710 SHGetDesktopFolder(&psf);
1711 SHGetItemFromObject((IUnknown*)psf, &IID_IShellItem, (void**)&fdimpl->psi_defaultfolder);
1712 IShellFolder_Release(psf);
1714 hr = IUnknown_QueryInterface((IUnknown*)fdimpl, riid, ppv);
1715 IUnknown_Release((IUnknown*)fdimpl);
1716 return hr;
1719 HRESULT FileOpenDialog_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv)
1721 return FileDialog_constructor(pUnkOuter, riid, ppv, ITEMDLG_TYPE_OPEN);
1724 HRESULT FileSaveDialog_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv)
1726 return FileDialog_constructor(pUnkOuter, riid, ppv, ITEMDLG_TYPE_SAVE);