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
;
90 LPWSTR custom_okbutton
;
91 LPWSTR custom_cancelbutton
;
92 LPWSTR custom_filenamelabel
;
95 /**************************************************************************
98 static UINT
get_file_name(FileDialogImpl
*This
, LPWSTR
*str
)
100 HWND hwnd_edit
= GetDlgItem(This
->dlg_hwnd
, IDC_FILENAME
);
105 if(This
->set_filename
)
107 len
= lstrlenW(This
->set_filename
);
108 *str
= CoTaskMemAlloc(sizeof(WCHAR
)*(len
+1));
109 lstrcpyW(*str
, This
->set_filename
);
115 len
= SendMessageW(hwnd_edit
, WM_GETTEXTLENGTH
, 0, 0);
116 *str
= CoTaskMemAlloc(sizeof(WCHAR
)*(len
+1));
120 SendMessageW(hwnd_edit
, WM_GETTEXT
, len
+1, (LPARAM
)*str
);
124 static BOOL
set_file_name(FileDialogImpl
*This
, LPCWSTR str
)
126 HWND hwnd_edit
= GetDlgItem(This
->dlg_hwnd
, IDC_FILENAME
);
128 if(This
->set_filename
)
129 LocalFree(This
->set_filename
);
131 This
->set_filename
= StrDupW(str
);
133 return SendMessageW(hwnd_edit
, WM_SETTEXT
, 0, (LPARAM
)str
);
136 static void fill_filename_from_selection(FileDialogImpl
*This
)
141 UINT item_count
, valid_count
;
144 if(!This
->psia_selection
)
147 hr
= IShellItemArray_GetCount(This
->psia_selection
, &item_count
);
148 if(FAILED(hr
) || !item_count
)
151 names
= HeapAlloc(GetProcessHeap(), 0, item_count
*sizeof(LPWSTR
));
153 /* Get names of the selected items */
154 valid_count
= 0; len_total
= 0;
155 for(i
= 0; i
< item_count
; i
++)
157 hr
= IShellItemArray_GetItemAt(This
->psia_selection
, i
, &psi
);
162 hr
= IShellItem_GetAttributes(psi
, SFGAO_FOLDER
, &attr
);
163 if(SUCCEEDED(hr
) && (attr
& SFGAO_FOLDER
))
164 continue; /* FIXME: FOS_PICKFOLDERS */
166 hr
= IShellItem_GetDisplayName(psi
, SIGDN_PARENTRELATIVEPARSING
, &names
[valid_count
]);
169 len_total
+= lstrlenW(names
[valid_count
]) + 3;
172 IShellItem_Release(psi
);
178 set_file_name(This
, names
[0]);
179 CoTaskMemFree(names
[0]);
181 else if(valid_count
> 1)
183 LPWSTR string
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
)*len_total
);
184 LPWSTR cur_point
= string
;
186 for(i
= 0; i
< valid_count
; i
++)
188 LPWSTR file
= names
[i
];
190 lstrcpyW(cur_point
, file
);
191 cur_point
+= lstrlenW(file
);
196 *(cur_point
-1) = '\0';
198 set_file_name(This
, string
);
199 HeapFree(GetProcessHeap(), 0, string
);
202 HeapFree(GetProcessHeap(), 0, names
);
206 static HRESULT
on_default_action(FileDialogImpl
*This
)
208 IShellFolder
*psf_parent
, *psf_desktop
;
210 LPITEMIDLIST current_folder
;
211 LPWSTR fn_iter
, files
, tmp_files
;
212 UINT file_count
= 0, len
, i
;
214 HRESULT hr
, ret
= E_FAIL
;
216 len
= get_file_name(This
, &tmp_files
);
220 file_count
= COMDLG32_SplitFileNames(tmp_files
, len
, &files
, &size_used
);
222 if(!file_count
) return E_FAIL
;
224 hr
= SHGetIDListFromObject((IUnknown
*)This
->psi_folder
, ¤t_folder
);
227 ERR("Failed to get pidl for current directory.\n");
231 TRACE("Acting on %d file(s).\n", file_count
);
233 pidla
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPITEMIDLIST
) * file_count
);
234 open_action
= ONOPEN_OPEN
;
237 for(i
= 0; i
< file_count
&& open_action
== ONOPEN_OPEN
; i
++)
239 WCHAR canon_filename
[MAX_PATH
];
242 COMDLG32_GetCanonicalPath(current_folder
, fn_iter
, canon_filename
);
244 if( (This
->options
& FOS_NOVALIDATE
) &&
245 !(This
->options
& FOS_FILEMUSTEXIST
) )
246 open_action
= ONOPEN_OPEN
;
248 open_action
= ONOPEN_BROWSE
;
250 open_action
= FILEDLG95_ValidatePathAction(canon_filename
, &psf_parent
, This
->dlg_hwnd
,
251 This
->options
, (This
->dlg_type
== ITEMDLG_TYPE_SAVE
),
254 pidla
[i
] = COMDLG32_SHSimpleIDListFromPathAW(canon_filename
);
256 if(psf_parent
&& !(open_action
== ONOPEN_BROWSE
))
257 IShellItem_Release(psf_parent
);
259 fn_iter
+= (WCHAR
)lstrlenW(fn_iter
) + 1;
262 HeapFree(GetProcessHeap(), 0, files
);
263 ILFree(current_folder
);
265 if((This
->options
& FOS_PICKFOLDERS
) && open_action
== ONOPEN_BROWSE
)
266 open_action
= ONOPEN_OPEN
; /* FIXME: Multiple folders? */
271 FIXME("Filtering not implemented.\n");
275 hr
= IExplorerBrowser_BrowseToObject(This
->peb
, (IUnknown
*)psf_parent
, SBSP_DEFBROWSER
);
277 ERR("Failed to browse to directory: %08x\n", hr
);
279 IShellItem_Release(psf_parent
);
283 hr
= SHGetDesktopFolder(&psf_desktop
);
286 if(This
->psia_results
)
287 IShellItemArray_Release(This
->psia_results
);
289 hr
= SHCreateShellItemArray(NULL
, psf_desktop
, file_count
, (PCUITEMID_CHILD_ARRAY
)pidla
,
290 &This
->psia_results
);
295 IShellFolder_Release(psf_desktop
);
305 for(i
= 0; i
< file_count
; i
++)
307 HeapFree(GetProcessHeap(), 0, pidla
);
309 /* Success closes the dialog */
313 /**************************************************************************
316 static void ctrl_resize(HWND hctrl
, UINT min_width
, UINT max_width
)
319 UINT len
, final_width
;
326 len
= SendMessageW(hctrl
, WM_GETTEXTLENGTH
, 0, 0);
327 text
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
)*(len
+1));
329 SendMessageW(hctrl
, WM_GETTEXT
, len
+1, (LPARAM
)text
);
332 GetTextExtentPoint32W(hdc
, text
, lstrlenW(text
), &size
);
333 ReleaseDC(hctrl
, hdc
);
335 GetWindowRect(hctrl
, &rc
);
336 final_width
= min(max(size
.cx
, min_width
) + 4, max_width
);
337 SetWindowPos(hctrl
, NULL
, 0, 0, final_width
, rc
.bottom
- rc
.top
,
338 SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOACTIVATE
);
340 HeapFree(GetProcessHeap(), 0, text
);
343 /**************************************************************************
344 * Window related functions.
346 static SIZE
update_layout(FileDialogImpl
*This
)
351 RECT cancel_rc
, open_rc
;
352 RECT filetype_rc
, filename_rc
, filenamelabel_rc
;
353 RECT toolbar_rc
, ebrowser_rc
;
354 int missing_width
, missing_height
;
355 static const UINT vspacing
= 4, hspacing
= 4;
358 GetClientRect(This
->dlg_hwnd
, &dialog_rc
);
360 missing_width
= max(0, 320 - dialog_rc
.right
);
361 missing_height
= max(0, 200 - dialog_rc
.bottom
);
363 if(missing_width
|| missing_height
)
365 TRACE("Missing (%d, %d)\n", missing_width
, missing_height
);
366 ret
.cx
= missing_width
;
367 ret
.cy
= missing_height
;
372 * Calculate the size of the dialog and all the parts.
376 hwnd
= GetDlgItem(This
->dlg_hwnd
, IDCANCEL
);
379 int cancel_width
, cancel_height
;
380 GetWindowRect(hwnd
, &cancel_rc
);
381 cancel_width
= cancel_rc
.right
- cancel_rc
.left
;
382 cancel_height
= cancel_rc
.bottom
- cancel_rc
.top
;
384 cancel_rc
.left
= dialog_rc
.right
- cancel_width
- hspacing
;
385 cancel_rc
.top
= dialog_rc
.bottom
- cancel_height
- vspacing
;
386 cancel_rc
.right
= cancel_rc
.left
+ cancel_width
;
387 cancel_rc
.bottom
= cancel_rc
.top
+ cancel_height
;
390 /* Open/Save button */
391 hwnd
= GetDlgItem(This
->dlg_hwnd
, IDOK
);
394 int open_width
, open_height
;
395 GetWindowRect(hwnd
, &open_rc
);
396 open_width
= open_rc
.right
- open_rc
.left
;
397 open_height
= open_rc
.bottom
- open_rc
.top
;
399 open_rc
.left
= cancel_rc
.left
- open_width
- hspacing
;
400 open_rc
.top
= cancel_rc
.top
;
401 open_rc
.right
= open_rc
.left
+ open_width
;
402 open_rc
.bottom
= open_rc
.top
+ open_height
;
405 /* The filetype combobox. */
406 hwnd
= GetDlgItem(This
->dlg_hwnd
, IDC_FILETYPE
);
409 int filetype_width
, filetype_height
;
410 GetWindowRect(hwnd
, &filetype_rc
);
412 filetype_width
= filetype_rc
.right
- filetype_rc
.left
;
413 filetype_height
= filetype_rc
.bottom
- filetype_rc
.top
;
415 filetype_rc
.right
= cancel_rc
.right
;
417 filetype_rc
.left
= filetype_rc
.right
- filetype_width
;
418 filetype_rc
.top
= cancel_rc
.top
- filetype_height
- vspacing
;
419 filetype_rc
.bottom
= filetype_rc
.top
+ filetype_height
;
421 if(!This
->filterspec_count
)
422 filetype_rc
.left
= filetype_rc
.right
;
425 /* Filename label. */
426 hwnd
= GetDlgItem(This
->dlg_hwnd
, IDC_FILENAMESTATIC
);
429 int filetypelabel_width
, filetypelabel_height
;
430 GetWindowRect(hwnd
, &filenamelabel_rc
);
432 filetypelabel_width
= filenamelabel_rc
.right
- filenamelabel_rc
.left
;
433 filetypelabel_height
= filenamelabel_rc
.bottom
- filenamelabel_rc
.top
;
435 filenamelabel_rc
.left
= 160; /* FIXME */
436 filenamelabel_rc
.top
= filetype_rc
.top
;
437 filenamelabel_rc
.right
= filenamelabel_rc
.left
+ filetypelabel_width
;
438 filenamelabel_rc
.bottom
= filenamelabel_rc
.top
+ filetypelabel_height
;
441 /* Filename edit box. */
442 hwnd
= GetDlgItem(This
->dlg_hwnd
, IDC_FILENAME
);
445 int filename_width
, filename_height
;
446 GetWindowRect(hwnd
, &filename_rc
);
448 filename_width
= filetype_rc
.left
- filenamelabel_rc
.right
- hspacing
*2;
449 filename_height
= filename_rc
.bottom
- filename_rc
.top
;
451 filename_rc
.left
= filenamelabel_rc
.right
+ hspacing
;
452 filename_rc
.top
= filetype_rc
.top
;
453 filename_rc
.right
= filename_rc
.left
+ filename_width
;
454 filename_rc
.bottom
= filename_rc
.top
+ filename_height
;
457 hwnd
= GetDlgItem(This
->dlg_hwnd
, IDC_NAV_TOOLBAR
);
460 GetWindowRect(hwnd
, &toolbar_rc
);
461 MapWindowPoints(NULL
, This
->dlg_hwnd
, (POINT
*)&toolbar_rc
, 2);
464 /* The ExplorerBrowser control. */
465 ebrowser_rc
.left
= dialog_rc
.left
+ vspacing
;
466 ebrowser_rc
.top
= toolbar_rc
.bottom
+ vspacing
;
467 ebrowser_rc
.right
= dialog_rc
.right
- hspacing
;
468 ebrowser_rc
.bottom
= filename_rc
.top
- hspacing
;
471 * Move everything to the right place.
474 /* FIXME: The Save Dialog uses a slightly different layout. */
475 hdwp
= BeginDeferWindowPos(6);
477 if(hdwp
&& This
->peb
)
478 IExplorerBrowser_SetRect(This
->peb
, &hdwp
, ebrowser_rc
);
480 /* The default controls */
481 if(hdwp
&& (hwnd
= GetDlgItem(This
->dlg_hwnd
, IDC_FILETYPE
)) )
482 DeferWindowPos(hdwp
, hwnd
, NULL
, filetype_rc
.left
, filetype_rc
.top
, 0, 0,
483 SWP_NOZORDER
| SWP_NOSIZE
| SWP_NOACTIVATE
);
485 if(hdwp
&& (hwnd
= GetDlgItem(This
->dlg_hwnd
, IDC_FILENAME
)) )
486 DeferWindowPos(hdwp
, hwnd
, NULL
, filename_rc
.left
, filename_rc
.top
,
487 filename_rc
.right
- filename_rc
.left
, filename_rc
.bottom
- filename_rc
.top
,
488 SWP_NOZORDER
| SWP_NOACTIVATE
);
490 if(hdwp
&& (hwnd
= GetDlgItem(This
->dlg_hwnd
, IDC_FILENAMESTATIC
)) )
491 DeferWindowPos(hdwp
, hwnd
, NULL
, filenamelabel_rc
.left
, filenamelabel_rc
.top
, 0, 0,
492 SWP_NOZORDER
| SWP_NOSIZE
| SWP_NOACTIVATE
);
494 if(hdwp
&& (hwnd
= GetDlgItem(This
->dlg_hwnd
, IDOK
)) )
495 DeferWindowPos(hdwp
, hwnd
, NULL
, open_rc
.left
, open_rc
.top
, 0, 0,
496 SWP_NOZORDER
| SWP_NOSIZE
| SWP_NOACTIVATE
);
498 if(hdwp
&& (hwnd
= GetDlgItem(This
->dlg_hwnd
, IDCANCEL
)) )
499 DeferWindowPos(hdwp
, hwnd
, NULL
, cancel_rc
.left
, cancel_rc
.top
, 0, 0,
500 SWP_NOZORDER
| SWP_NOSIZE
| SWP_NOACTIVATE
);
503 EndDeferWindowPos(hdwp
);
505 ERR("Failed to position dialog controls.\n");
507 ret
.cx
= 0; ret
.cy
= 0;
511 static HRESULT
init_explorerbrowser(FileDialogImpl
*This
)
513 IShellItem
*psi_folder
;
518 /* Create ExplorerBrowser instance */
521 hr
= CoCreateInstance(&CLSID_ExplorerBrowser
, NULL
, CLSCTX_INPROC_SERVER
,
522 &IID_IExplorerBrowser
, (void**)&This
->peb
);
525 ERR("Failed to instantiate ExplorerBrowser control.\n");
529 IExplorerBrowser_SetOptions(This
->peb
, EBO_SHOWFRAMES
);
531 hr
= IExplorerBrowser_Initialize(This
->peb
, This
->dlg_hwnd
, &rc
, NULL
);
534 ERR("Failed to initialize the ExplorerBrowser control.\n");
535 IExplorerBrowser_Release(This
->peb
);
539 hr
= IExplorerBrowser_Advise(This
->peb
, &This
->IExplorerBrowserEvents_iface
, &This
->ebevents_cookie
);
541 ERR("Advise (ExplorerBrowser) failed.\n");
543 /* Get previous options? */
544 fos
.ViewMode
= fos
.fFlags
= 0;
545 if(!(This
->options
& FOS_ALLOWMULTISELECT
))
546 fos
.fFlags
|= FWF_SINGLESEL
;
548 IExplorerBrowser_SetFolderSettings(This
->peb
, &fos
);
550 hr
= IUnknown_SetSite((IUnknown
*)This
->peb
, (IUnknown
*)This
);
552 ERR("SetSite (ExplorerBrowser) failed.\n");
554 /* Browse somewhere */
555 psi_folder
= This
->psi_setfolder
? This
->psi_setfolder
: This
->psi_defaultfolder
;
556 IExplorerBrowser_BrowseToObject(This
->peb
, (IUnknown
*)psi_folder
, SBSP_DEFBROWSER
);
561 static void init_toolbar(FileDialogImpl
*This
, HWND hwnd
)
567 htoolbar
= CreateWindowExW(0, TOOLBARCLASSNAMEW
, NULL
, TBSTYLE_FLAT
| WS_CHILD
| WS_VISIBLE
,
569 hwnd
, (HMENU
)IDC_NAV_TOOLBAR
, NULL
, NULL
);
571 tbab
.hInst
= HINST_COMMCTRL
;
572 tbab
.nID
= IDB_HIST_LARGE_COLOR
;
573 SendMessageW(htoolbar
, TB_ADDBITMAP
, 0, (LPARAM
)&tbab
);
575 button
[0].iBitmap
= HIST_BACK
;
576 button
[0].idCommand
= IDC_NAVBACK
;
577 button
[0].fsState
= TBSTATE_ENABLED
;
578 button
[0].fsStyle
= BTNS_BUTTON
;
579 button
[0].dwData
= 0;
580 button
[0].iString
= 0;
582 button
[1].iBitmap
= HIST_FORWARD
;
583 button
[1].idCommand
= IDC_NAVFORWARD
;
584 button
[1].fsState
= TBSTATE_ENABLED
;
585 button
[1].fsStyle
= BTNS_BUTTON
;
586 button
[1].dwData
= 0;
587 button
[1].iString
= 0;
589 SendMessageW(htoolbar
, TB_ADDBUTTONSW
, 2, (LPARAM
)&button
);
590 SendMessageW(htoolbar
, TB_SETBUTTONSIZE
, 0, MAKELPARAM(24,24));
591 SendMessageW(htoolbar
, TB_AUTOSIZE
, 0, 0);
594 static void update_control_text(FileDialogImpl
*This
)
597 if(This
->custom_title
)
598 SetWindowTextW(This
->dlg_hwnd
, This
->custom_title
);
600 if(This
->custom_okbutton
&&
601 (hitem
= GetDlgItem(This
->dlg_hwnd
, IDOK
)))
603 SetWindowTextW(hitem
, This
->custom_okbutton
);
604 ctrl_resize(hitem
, 50, 250);
607 if(This
->custom_cancelbutton
&&
608 (hitem
= GetDlgItem(This
->dlg_hwnd
, IDCANCEL
)))
610 SetWindowTextW(hitem
, This
->custom_cancelbutton
);
611 ctrl_resize(hitem
, 50, 250);
614 if(This
->custom_filenamelabel
&&
615 (hitem
= GetDlgItem(This
->dlg_hwnd
, IDC_FILENAMESTATIC
)))
617 SetWindowTextW(hitem
, This
->custom_filenamelabel
);
618 ctrl_resize(hitem
, 50, 250);
622 static LRESULT
on_wm_initdialog(HWND hwnd
, LPARAM lParam
)
624 FileDialogImpl
*This
= (FileDialogImpl
*)lParam
;
627 TRACE("(%p, %p)\n", This
, hwnd
);
629 SetWindowLongPtrW(hwnd
, GWLP_USERDATA
, (LPARAM
)This
);
630 This
->dlg_hwnd
= hwnd
;
632 hitem
= GetDlgItem(This
->dlg_hwnd
, pshHelp
);
633 if(hitem
) ShowWindow(hitem
, SW_HIDE
);
635 hitem
= GetDlgItem(This
->dlg_hwnd
, IDC_FILETYPESTATIC
);
636 if(hitem
) ShowWindow(hitem
, SW_HIDE
);
638 /* Fill filetypes combobox, or hide it. */
639 hitem
= GetDlgItem(This
->dlg_hwnd
, IDC_FILETYPE
);
640 if(This
->filterspec_count
)
643 for(i
= 0; i
< This
->filterspec_count
; i
++)
644 SendMessageW(hitem
, CB_ADDSTRING
, 0, (LPARAM
)This
->filterspecs
[i
].pszName
);
646 SendMessageW(hitem
, CB_SETCURSEL
, This
->filetypeindex
, 0);
649 ShowWindow(hitem
, SW_HIDE
);
651 if(This
->set_filename
&&
652 (hitem
= GetDlgItem(This
->dlg_hwnd
, IDC_FILENAME
)) )
653 SendMessageW(hitem
, WM_SETTEXT
, 0, (LPARAM
)This
->set_filename
);
655 init_explorerbrowser(This
);
656 init_toolbar(This
, hwnd
);
657 update_control_text(This
);
663 static LRESULT
on_wm_size(FileDialogImpl
*This
)
669 static LRESULT
on_wm_getminmaxinfo(FileDialogImpl
*This
, LPARAM lparam
)
671 MINMAXINFO
*mmi
= (MINMAXINFO
*)lparam
;
672 TRACE("%p (%p)\n", This
, mmi
);
675 mmi
->ptMinTrackSize
.x
= 640;
676 mmi
->ptMinTrackSize
.y
= 480;
681 static LRESULT
on_wm_destroy(FileDialogImpl
*This
)
687 IExplorerBrowser_Destroy(This
->peb
);
688 IExplorerBrowser_Release(This
->peb
);
692 This
->dlg_hwnd
= NULL
;
697 static LRESULT
on_idok(FileDialogImpl
*This
)
701 if(SUCCEEDED(on_default_action(This
)))
702 EndDialog(This
->dlg_hwnd
, S_OK
);
707 static LRESULT
on_idcancel(FileDialogImpl
*This
)
711 EndDialog(This
->dlg_hwnd
, HRESULT_FROM_WIN32(ERROR_CANCELLED
));
716 static LRESULT
on_browse_back(FileDialogImpl
*This
)
719 IExplorerBrowser_BrowseToIDList(This
->peb
, NULL
, SBSP_NAVIGATEBACK
);
723 static LRESULT
on_browse_forward(FileDialogImpl
*This
)
726 IExplorerBrowser_BrowseToIDList(This
->peb
, NULL
, SBSP_NAVIGATEFORWARD
);
730 static LRESULT
on_command_filetype(FileDialogImpl
*This
, WPARAM wparam
, LPARAM lparam
)
732 if(HIWORD(wparam
) == CBN_SELCHANGE
)
737 This
->filetypeindex
= SendMessageW((HWND
)lparam
, CB_GETCURSEL
, 0, 0);
738 TRACE("File type selection changed to %d.\n", This
->filetypeindex
);
740 hr
= IExplorerBrowser_GetCurrentView(This
->peb
, &IID_IShellView
, (void**)&psv
);
743 IShellView_Refresh(psv
);
744 IShellView_Release(psv
);
751 static LRESULT
on_wm_command(FileDialogImpl
*This
, WPARAM wparam
, LPARAM lparam
)
753 switch(LOWORD(wparam
))
755 case IDOK
: return on_idok(This
);
756 case IDCANCEL
: return on_idcancel(This
);
757 case IDC_NAVBACK
: return on_browse_back(This
);
758 case IDC_NAVFORWARD
: return on_browse_forward(This
);
759 case IDC_FILETYPE
: return on_command_filetype(This
, wparam
, lparam
);
760 default: TRACE("Unknown command.\n");
765 static LRESULT CALLBACK
itemdlg_dlgproc(HWND hwnd
, UINT umessage
, WPARAM wparam
, LPARAM lparam
)
767 FileDialogImpl
*This
= (FileDialogImpl
*)GetWindowLongPtrW(hwnd
, GWLP_USERDATA
);
771 case WM_INITDIALOG
: return on_wm_initdialog(hwnd
, lparam
);
772 case WM_COMMAND
: return on_wm_command(This
, wparam
, lparam
);
773 case WM_SIZE
: return on_wm_size(This
);
774 case WM_GETMINMAXINFO
: return on_wm_getminmaxinfo(This
, lparam
);
775 case WM_DESTROY
: return on_wm_destroy(This
);
781 static HRESULT
create_dialog(FileDialogImpl
*This
, HWND parent
)
786 res
= DialogBoxParamW(COMDLG32_hInstance
,
787 MAKEINTRESOURCEW(NEWFILEOPENV3ORD
),
788 parent
, itemdlg_dlgproc
, (LPARAM
)This
);
789 This
->dlg_hwnd
= NULL
;
792 ERR("Failed to show dialog (LastError: %d)\n", GetLastError());
796 TRACE("Returning 0x%08x\n", (HRESULT
)res
);
800 /**************************************************************************
801 * IFileDialog implementation
803 static inline FileDialogImpl
*impl_from_IFileDialog2(IFileDialog2
*iface
)
805 return CONTAINING_RECORD(iface
, FileDialogImpl
, IFileDialog2_iface
);
808 static HRESULT WINAPI
IFileDialog2_fnQueryInterface(IFileDialog2
*iface
,
812 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
813 TRACE("%p (%s, %p)\n", This
, debugstr_guid(riid
), ppvObject
);
816 if(IsEqualGUID(riid
, &IID_IUnknown
) ||
817 IsEqualGUID(riid
, &IID_IFileDialog
) ||
818 IsEqualGUID(riid
, &IID_IFileDialog2
))
822 else if(IsEqualGUID(riid
, &IID_IFileOpenDialog
) && This
->dlg_type
== ITEMDLG_TYPE_OPEN
)
824 *ppvObject
= &This
->u
.IFileOpenDialog_iface
;
826 else if(IsEqualGUID(riid
, &IID_IFileSaveDialog
) && This
->dlg_type
== ITEMDLG_TYPE_SAVE
)
828 *ppvObject
= &This
->u
.IFileSaveDialog_iface
;
830 else if(IsEqualGUID(riid
, &IID_IExplorerBrowserEvents
))
832 *ppvObject
= &This
->IExplorerBrowserEvents_iface
;
834 else if(IsEqualGUID(riid
, &IID_IServiceProvider
))
836 *ppvObject
= &This
->IServiceProvider_iface
;
838 else if(IsEqualGUID(&IID_ICommDlgBrowser3
, riid
) ||
839 IsEqualGUID(&IID_ICommDlgBrowser2
, riid
) ||
840 IsEqualGUID(&IID_ICommDlgBrowser
, riid
))
842 *ppvObject
= &This
->ICommDlgBrowser3_iface
;
845 FIXME("Unknown interface requested: %s.\n", debugstr_guid(riid
));
849 IUnknown_AddRef((IUnknown
*)*ppvObject
);
853 return E_NOINTERFACE
;
856 static ULONG WINAPI
IFileDialog2_fnAddRef(IFileDialog2
*iface
)
858 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
859 LONG ref
= InterlockedIncrement(&This
->ref
);
860 TRACE("%p - ref %d\n", This
, ref
);
865 static ULONG WINAPI
IFileDialog2_fnRelease(IFileDialog2
*iface
)
867 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
868 LONG ref
= InterlockedDecrement(&This
->ref
);
869 TRACE("%p - ref %d\n", This
, ref
);
874 for(i
= 0; i
< This
->filterspec_count
; i
++)
876 LocalFree((void*)This
->filterspecs
[i
].pszName
);
877 LocalFree((void*)This
->filterspecs
[i
].pszSpec
);
879 HeapFree(GetProcessHeap(), 0, This
->filterspecs
);
881 if(This
->psi_defaultfolder
) IShellItem_Release(This
->psi_defaultfolder
);
882 if(This
->psi_setfolder
) IShellItem_Release(This
->psi_setfolder
);
883 if(This
->psi_folder
) IShellItem_Release(This
->psi_folder
);
884 if(This
->psia_selection
) IShellItemArray_Release(This
->psia_selection
);
885 if(This
->psia_results
) IShellItemArray_Release(This
->psia_results
);
887 LocalFree(This
->set_filename
);
888 LocalFree(This
->custom_title
);
889 LocalFree(This
->custom_okbutton
);
890 LocalFree(This
->custom_cancelbutton
);
891 LocalFree(This
->custom_filenamelabel
);
893 HeapFree(GetProcessHeap(), 0, This
);
899 static HRESULT WINAPI
IFileDialog2_fnShow(IFileDialog2
*iface
, HWND hwndOwner
)
901 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
902 TRACE("%p (%p)\n", iface
, hwndOwner
);
904 return create_dialog(This
, hwndOwner
);
907 static HRESULT WINAPI
IFileDialog2_fnSetFileTypes(IFileDialog2
*iface
, UINT cFileTypes
,
908 const COMDLG_FILTERSPEC
*rgFilterSpec
)
910 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
912 TRACE("%p (%d, %p)\n", This
, cFileTypes
, rgFilterSpec
);
914 if(This
->filterspecs
)
923 This
->filterspecs
= HeapAlloc(GetProcessHeap(), 0, sizeof(COMDLG_FILTERSPEC
)*cFileTypes
);
924 for(i
= 0; i
< cFileTypes
; i
++)
926 This
->filterspecs
[i
].pszName
= StrDupW(rgFilterSpec
[i
].pszName
);
927 This
->filterspecs
[i
].pszSpec
= StrDupW(rgFilterSpec
[i
].pszSpec
);
929 This
->filterspec_count
= cFileTypes
;
934 static HRESULT WINAPI
IFileDialog2_fnSetFileTypeIndex(IFileDialog2
*iface
, UINT iFileType
)
936 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
937 TRACE("%p (%d)\n", This
, iFileType
);
939 if(!This
->filterspecs
)
942 if(iFileType
>= This
->filterspec_count
)
943 This
->filetypeindex
= This
->filterspec_count
- 1;
945 This
->filetypeindex
= iFileType
;
950 static HRESULT WINAPI
IFileDialog2_fnGetFileTypeIndex(IFileDialog2
*iface
, UINT
*piFileType
)
952 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
953 TRACE("%p (%p)\n", This
, piFileType
);
958 *piFileType
= This
->filetypeindex
;
963 static HRESULT WINAPI
IFileDialog2_fnAdvise(IFileDialog2
*iface
, IFileDialogEvents
*pfde
, DWORD
*pdwCookie
)
965 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
966 events_client
*client
;
967 TRACE("%p (%p, %p)\n", This
, pfde
, pdwCookie
);
969 if(!pfde
|| !pdwCookie
)
972 client
= HeapAlloc(GetProcessHeap(), 0, sizeof(events_client
));
974 client
->cookie
= ++This
->events_next_cookie
;
976 IFileDialogEvents_AddRef(pfde
);
977 *pdwCookie
= client
->cookie
;
979 list_add_tail(&This
->events_clients
, &client
->entry
);
984 static HRESULT WINAPI
IFileDialog2_fnUnadvise(IFileDialog2
*iface
, DWORD dwCookie
)
986 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
987 events_client
*client
, *found
= NULL
;
988 TRACE("%p (%d)\n", This
, dwCookie
);
990 LIST_FOR_EACH_ENTRY(client
, &This
->events_clients
, events_client
, entry
)
992 if(client
->cookie
== dwCookie
)
1001 list_remove(&found
->entry
);
1002 IFileDialogEvents_Release(found
->pfde
);
1003 HeapFree(GetProcessHeap(), 0, found
);
1007 return E_INVALIDARG
;
1010 static HRESULT WINAPI
IFileDialog2_fnSetOptions(IFileDialog2
*iface
, FILEOPENDIALOGOPTIONS fos
)
1012 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1013 TRACE("%p (0x%x)\n", This
, fos
);
1015 This
->options
= fos
;
1020 static HRESULT WINAPI
IFileDialog2_fnGetOptions(IFileDialog2
*iface
, FILEOPENDIALOGOPTIONS
*pfos
)
1022 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1023 TRACE("%p (%p)\n", This
, pfos
);
1026 return E_INVALIDARG
;
1028 *pfos
= This
->options
;
1033 static HRESULT WINAPI
IFileDialog2_fnSetDefaultFolder(IFileDialog2
*iface
, IShellItem
*psi
)
1035 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1036 TRACE("%p (%p)\n", This
, psi
);
1037 if(This
->psi_defaultfolder
)
1038 IShellItem_Release(This
->psi_defaultfolder
);
1040 This
->psi_defaultfolder
= psi
;
1042 if(This
->psi_defaultfolder
)
1043 IShellItem_AddRef(This
->psi_defaultfolder
);
1048 static HRESULT WINAPI
IFileDialog2_fnSetFolder(IFileDialog2
*iface
, IShellItem
*psi
)
1050 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1051 TRACE("%p (%p)\n", This
, psi
);
1052 if(This
->psi_setfolder
)
1053 IShellItem_Release(This
->psi_setfolder
);
1055 This
->psi_setfolder
= psi
;
1057 if(This
->psi_setfolder
)
1058 IShellItem_AddRef(This
->psi_setfolder
);
1063 static HRESULT WINAPI
IFileDialog2_fnGetFolder(IFileDialog2
*iface
, IShellItem
**ppsi
)
1065 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1066 TRACE("%p (%p)\n", This
, ppsi
);
1068 return E_INVALIDARG
;
1071 If the dialog is shown, return the current(ly selected) folder. */
1074 if(This
->psi_folder
)
1075 *ppsi
= This
->psi_folder
;
1076 else if(This
->psi_setfolder
)
1077 *ppsi
= This
->psi_setfolder
;
1078 else if(This
->psi_defaultfolder
)
1079 *ppsi
= This
->psi_defaultfolder
;
1083 IShellItem_AddRef(*ppsi
);
1090 static HRESULT WINAPI
IFileDialog2_fnGetCurrentSelection(IFileDialog2
*iface
, IShellItem
**ppsi
)
1092 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1094 TRACE("%p (%p)\n", This
, ppsi
);
1097 return E_INVALIDARG
;
1099 if(This
->psia_selection
)
1101 /* FIXME: Check filename edit box */
1102 hr
= IShellItemArray_GetItemAt(This
->psia_selection
, 0, ppsi
);
1109 static HRESULT WINAPI
IFileDialog2_fnSetFileName(IFileDialog2
*iface
, LPCWSTR pszName
)
1111 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1112 TRACE("%p (%p)\n", iface
, pszName
);
1114 set_file_name(This
, pszName
);
1119 static HRESULT WINAPI
IFileDialog2_fnGetFileName(IFileDialog2
*iface
, LPWSTR
*pszName
)
1121 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1122 TRACE("%p (%p)\n", iface
, pszName
);
1125 return E_INVALIDARG
;
1128 if(get_file_name(This
, pszName
))
1134 static HRESULT WINAPI
IFileDialog2_fnSetTitle(IFileDialog2
*iface
, LPCWSTR pszTitle
)
1136 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1137 TRACE("%p (%p)\n", This
, pszTitle
);
1139 LocalFree(This
->custom_title
);
1140 This
->custom_title
= StrDupW(pszTitle
);
1141 update_control_text(This
);
1146 static HRESULT WINAPI
IFileDialog2_fnSetOkButtonLabel(IFileDialog2
*iface
, LPCWSTR pszText
)
1148 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1149 TRACE("%p (%p)\n", This
, pszText
);
1151 LocalFree(This
->custom_okbutton
);
1152 This
->custom_okbutton
= StrDupW(pszText
);
1153 update_control_text(This
);
1154 update_layout(This
);
1159 static HRESULT WINAPI
IFileDialog2_fnSetFileNameLabel(IFileDialog2
*iface
, LPCWSTR pszLabel
)
1161 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1162 TRACE("%p (%p)\n", This
, pszLabel
);
1164 LocalFree(This
->custom_filenamelabel
);
1165 This
->custom_filenamelabel
= StrDupW(pszLabel
);
1166 update_control_text(This
);
1167 update_layout(This
);
1172 static HRESULT WINAPI
IFileDialog2_fnGetResult(IFileDialog2
*iface
, IShellItem
**ppsi
)
1174 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1176 TRACE("%p (%p)\n", This
, ppsi
);
1179 return E_INVALIDARG
;
1181 if(This
->psia_results
)
1184 hr
= IShellItemArray_GetCount(This
->psia_results
, &item_count
);
1190 /* Adds a reference. */
1191 hr
= IShellItemArray_GetItemAt(This
->psia_results
, 0, ppsi
);
1197 return E_UNEXPECTED
;
1200 static HRESULT WINAPI
IFileDialog2_fnAddPlace(IFileDialog2
*iface
, IShellItem
*psi
, FDAP fdap
)
1202 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1203 FIXME("stub - %p (%p, %d)\n", This
, psi
, fdap
);
1207 static HRESULT WINAPI
IFileDialog2_fnSetDefaultExtension(IFileDialog2
*iface
, LPCWSTR pszDefaultExtension
)
1209 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1210 FIXME("stub - %p (%s)\n", This
, debugstr_w(pszDefaultExtension
));
1214 static HRESULT WINAPI
IFileDialog2_fnClose(IFileDialog2
*iface
, HRESULT hr
)
1216 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1217 TRACE("%p (0x%08x)\n", This
, hr
);
1220 EndDialog(This
->dlg_hwnd
, hr
);
1225 static HRESULT WINAPI
IFileDialog2_fnSetClientGuid(IFileDialog2
*iface
, REFGUID guid
)
1227 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1228 FIXME("stub - %p (%s)\n", This
, debugstr_guid(guid
));
1232 static HRESULT WINAPI
IFileDialog2_fnClearClientData(IFileDialog2
*iface
)
1234 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1235 FIXME("stub - %p\n", This
);
1239 static HRESULT WINAPI
IFileDialog2_fnSetFilter(IFileDialog2
*iface
, IShellItemFilter
*pFilter
)
1241 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1242 FIXME("stub - %p (%p)\n", This
, pFilter
);
1246 static HRESULT WINAPI
IFileDialog2_fnSetCancelButtonLabel(IFileDialog2
*iface
, LPCWSTR pszLabel
)
1248 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1249 TRACE("%p (%p)\n", This
, pszLabel
);
1251 LocalFree(This
->custom_cancelbutton
);
1252 This
->custom_cancelbutton
= StrDupW(pszLabel
);
1253 update_control_text(This
);
1254 update_layout(This
);
1259 static HRESULT WINAPI
IFileDialog2_fnSetNavigationRoot(IFileDialog2
*iface
, IShellItem
*psi
)
1261 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1262 FIXME("stub - %p (%p)\n", This
, psi
);
1266 static const IFileDialog2Vtbl vt_IFileDialog2
= {
1267 IFileDialog2_fnQueryInterface
,
1268 IFileDialog2_fnAddRef
,
1269 IFileDialog2_fnRelease
,
1270 IFileDialog2_fnShow
,
1271 IFileDialog2_fnSetFileTypes
,
1272 IFileDialog2_fnSetFileTypeIndex
,
1273 IFileDialog2_fnGetFileTypeIndex
,
1274 IFileDialog2_fnAdvise
,
1275 IFileDialog2_fnUnadvise
,
1276 IFileDialog2_fnSetOptions
,
1277 IFileDialog2_fnGetOptions
,
1278 IFileDialog2_fnSetDefaultFolder
,
1279 IFileDialog2_fnSetFolder
,
1280 IFileDialog2_fnGetFolder
,
1281 IFileDialog2_fnGetCurrentSelection
,
1282 IFileDialog2_fnSetFileName
,
1283 IFileDialog2_fnGetFileName
,
1284 IFileDialog2_fnSetTitle
,
1285 IFileDialog2_fnSetOkButtonLabel
,
1286 IFileDialog2_fnSetFileNameLabel
,
1287 IFileDialog2_fnGetResult
,
1288 IFileDialog2_fnAddPlace
,
1289 IFileDialog2_fnSetDefaultExtension
,
1290 IFileDialog2_fnClose
,
1291 IFileDialog2_fnSetClientGuid
,
1292 IFileDialog2_fnClearClientData
,
1293 IFileDialog2_fnSetFilter
,
1294 IFileDialog2_fnSetCancelButtonLabel
,
1295 IFileDialog2_fnSetNavigationRoot
1298 /**************************************************************************
1301 static inline FileDialogImpl
*impl_from_IFileOpenDialog(IFileOpenDialog
*iface
)
1303 return CONTAINING_RECORD(iface
, FileDialogImpl
, u
.IFileOpenDialog_iface
);
1306 static HRESULT WINAPI
IFileOpenDialog_fnQueryInterface(IFileOpenDialog
*iface
,
1307 REFIID riid
, void **ppvObject
)
1309 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
1310 return IFileDialog2_QueryInterface(&This
->IFileDialog2_iface
, riid
, ppvObject
);
1313 static ULONG WINAPI
IFileOpenDialog_fnAddRef(IFileOpenDialog
*iface
)
1315 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
1316 return IFileDialog2_AddRef(&This
->IFileDialog2_iface
);
1319 static ULONG WINAPI
IFileOpenDialog_fnRelease(IFileOpenDialog
*iface
)
1321 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
1322 return IFileDialog2_Release(&This
->IFileDialog2_iface
);
1325 static HRESULT WINAPI
IFileOpenDialog_fnShow(IFileOpenDialog
*iface
, HWND hwndOwner
)
1327 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
1328 return IFileDialog2_Show(&This
->IFileDialog2_iface
, hwndOwner
);
1331 static HRESULT WINAPI
IFileOpenDialog_fnSetFileTypes(IFileOpenDialog
*iface
, UINT cFileTypes
,
1332 const COMDLG_FILTERSPEC
*rgFilterSpec
)
1334 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
1335 return IFileDialog2_SetFileTypes(&This
->IFileDialog2_iface
, cFileTypes
, rgFilterSpec
);
1338 static HRESULT WINAPI
IFileOpenDialog_fnSetFileTypeIndex(IFileOpenDialog
*iface
, UINT iFileType
)
1340 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
1341 return IFileDialog2_SetFileTypeIndex(&This
->IFileDialog2_iface
, iFileType
);
1344 static HRESULT WINAPI
IFileOpenDialog_fnGetFileTypeIndex(IFileOpenDialog
*iface
, UINT
*piFileType
)
1346 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
1347 return IFileDialog2_GetFileTypeIndex(&This
->IFileDialog2_iface
, piFileType
);
1350 static HRESULT WINAPI
IFileOpenDialog_fnAdvise(IFileOpenDialog
*iface
, IFileDialogEvents
*pfde
,
1353 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
1354 return IFileDialog2_Advise(&This
->IFileDialog2_iface
, pfde
, pdwCookie
);
1357 static HRESULT WINAPI
IFileOpenDialog_fnUnadvise(IFileOpenDialog
*iface
, DWORD dwCookie
)
1359 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
1360 return IFileDialog2_Unadvise(&This
->IFileDialog2_iface
, dwCookie
);
1363 static HRESULT WINAPI
IFileOpenDialog_fnSetOptions(IFileOpenDialog
*iface
, FILEOPENDIALOGOPTIONS fos
)
1365 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
1366 return IFileDialog2_SetOptions(&This
->IFileDialog2_iface
, fos
);
1369 static HRESULT WINAPI
IFileOpenDialog_fnGetOptions(IFileOpenDialog
*iface
, FILEOPENDIALOGOPTIONS
*pfos
)
1371 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
1372 return IFileDialog2_GetOptions(&This
->IFileDialog2_iface
, pfos
);
1375 static HRESULT WINAPI
IFileOpenDialog_fnSetDefaultFolder(IFileOpenDialog
*iface
, IShellItem
*psi
)
1377 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
1378 return IFileDialog2_SetDefaultFolder(&This
->IFileDialog2_iface
, psi
);
1381 static HRESULT WINAPI
IFileOpenDialog_fnSetFolder(IFileOpenDialog
*iface
, IShellItem
*psi
)
1383 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
1384 return IFileDialog2_SetFolder(&This
->IFileDialog2_iface
, psi
);
1387 static HRESULT WINAPI
IFileOpenDialog_fnGetFolder(IFileOpenDialog
*iface
, IShellItem
**ppsi
)
1389 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
1390 return IFileDialog2_GetFolder(&This
->IFileDialog2_iface
, ppsi
);
1393 static HRESULT WINAPI
IFileOpenDialog_fnGetCurrentSelection(IFileOpenDialog
*iface
, IShellItem
**ppsi
)
1395 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
1396 return IFileDialog2_GetCurrentSelection(&This
->IFileDialog2_iface
, ppsi
);
1399 static HRESULT WINAPI
IFileOpenDialog_fnSetFileName(IFileOpenDialog
*iface
, LPCWSTR pszName
)
1401 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
1402 return IFileDialog2_SetFileName(&This
->IFileDialog2_iface
, pszName
);
1405 static HRESULT WINAPI
IFileOpenDialog_fnGetFileName(IFileOpenDialog
*iface
, LPWSTR
*pszName
)
1407 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
1408 return IFileDialog2_GetFileName(&This
->IFileDialog2_iface
, pszName
);
1411 static HRESULT WINAPI
IFileOpenDialog_fnSetTitle(IFileOpenDialog
*iface
, LPCWSTR pszTitle
)
1413 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
1414 return IFileDialog2_SetTitle(&This
->IFileDialog2_iface
, pszTitle
);
1417 static HRESULT WINAPI
IFileOpenDialog_fnSetOkButtonLabel(IFileOpenDialog
*iface
, LPCWSTR pszText
)
1419 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
1420 return IFileDialog2_SetOkButtonLabel(&This
->IFileDialog2_iface
, pszText
);
1423 static HRESULT WINAPI
IFileOpenDialog_fnSetFileNameLabel(IFileOpenDialog
*iface
, LPCWSTR pszLabel
)
1425 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
1426 return IFileDialog2_SetFileNameLabel(&This
->IFileDialog2_iface
, pszLabel
);
1429 static HRESULT WINAPI
IFileOpenDialog_fnGetResult(IFileOpenDialog
*iface
, IShellItem
**ppsi
)
1431 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
1432 return IFileDialog2_GetResult(&This
->IFileDialog2_iface
, ppsi
);
1435 static HRESULT WINAPI
IFileOpenDialog_fnAddPlace(IFileOpenDialog
*iface
, IShellItem
*psi
, FDAP fdap
)
1437 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
1438 return IFileDialog2_AddPlace(&This
->IFileDialog2_iface
, psi
, fdap
);
1441 static HRESULT WINAPI
IFileOpenDialog_fnSetDefaultExtension(IFileOpenDialog
*iface
,
1442 LPCWSTR pszDefaultExtension
)
1444 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
1445 return IFileDialog2_SetDefaultExtension(&This
->IFileDialog2_iface
, pszDefaultExtension
);
1448 static HRESULT WINAPI
IFileOpenDialog_fnClose(IFileOpenDialog
*iface
, HRESULT hr
)
1450 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
1451 return IFileDialog2_Close(&This
->IFileDialog2_iface
, hr
);
1454 static HRESULT WINAPI
IFileOpenDialog_fnSetClientGuid(IFileOpenDialog
*iface
, REFGUID guid
)
1456 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
1457 return IFileDialog2_SetClientGuid(&This
->IFileDialog2_iface
, guid
);
1460 static HRESULT WINAPI
IFileOpenDialog_fnClearClientData(IFileOpenDialog
*iface
)
1462 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
1463 return IFileDialog2_ClearClientData(&This
->IFileDialog2_iface
);
1466 static HRESULT WINAPI
IFileOpenDialog_fnSetFilter(IFileOpenDialog
*iface
, IShellItemFilter
*pFilter
)
1468 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
1469 return IFileDialog2_SetFilter(&This
->IFileDialog2_iface
, pFilter
);
1472 static HRESULT WINAPI
IFileOpenDialog_fnGetResults(IFileOpenDialog
*iface
, IShellItemArray
**ppenum
)
1474 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
1475 TRACE("%p (%p)\n", This
, ppenum
);
1477 *ppenum
= This
->psia_results
;
1481 IShellItemArray_AddRef(*ppenum
);
1488 static HRESULT WINAPI
IFileOpenDialog_fnGetSelectedItems(IFileOpenDialog
*iface
, IShellItemArray
**ppsai
)
1490 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
1491 TRACE("%p (%p)\n", This
, ppsai
);
1493 if(This
->psia_selection
)
1495 *ppsai
= This
->psia_selection
;
1496 IShellItemArray_AddRef(*ppsai
);
1503 static const IFileOpenDialogVtbl vt_IFileOpenDialog
= {
1504 IFileOpenDialog_fnQueryInterface
,
1505 IFileOpenDialog_fnAddRef
,
1506 IFileOpenDialog_fnRelease
,
1507 IFileOpenDialog_fnShow
,
1508 IFileOpenDialog_fnSetFileTypes
,
1509 IFileOpenDialog_fnSetFileTypeIndex
,
1510 IFileOpenDialog_fnGetFileTypeIndex
,
1511 IFileOpenDialog_fnAdvise
,
1512 IFileOpenDialog_fnUnadvise
,
1513 IFileOpenDialog_fnSetOptions
,
1514 IFileOpenDialog_fnGetOptions
,
1515 IFileOpenDialog_fnSetDefaultFolder
,
1516 IFileOpenDialog_fnSetFolder
,
1517 IFileOpenDialog_fnGetFolder
,
1518 IFileOpenDialog_fnGetCurrentSelection
,
1519 IFileOpenDialog_fnSetFileName
,
1520 IFileOpenDialog_fnGetFileName
,
1521 IFileOpenDialog_fnSetTitle
,
1522 IFileOpenDialog_fnSetOkButtonLabel
,
1523 IFileOpenDialog_fnSetFileNameLabel
,
1524 IFileOpenDialog_fnGetResult
,
1525 IFileOpenDialog_fnAddPlace
,
1526 IFileOpenDialog_fnSetDefaultExtension
,
1527 IFileOpenDialog_fnClose
,
1528 IFileOpenDialog_fnSetClientGuid
,
1529 IFileOpenDialog_fnClearClientData
,
1530 IFileOpenDialog_fnSetFilter
,
1531 IFileOpenDialog_fnGetResults
,
1532 IFileOpenDialog_fnGetSelectedItems
1535 /**************************************************************************
1538 static inline FileDialogImpl
*impl_from_IFileSaveDialog(IFileSaveDialog
*iface
)
1540 return CONTAINING_RECORD(iface
, FileDialogImpl
, u
.IFileSaveDialog_iface
);
1543 static HRESULT WINAPI
IFileSaveDialog_fnQueryInterface(IFileSaveDialog
*iface
,
1547 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
1548 return IFileDialog2_QueryInterface(&This
->IFileDialog2_iface
, riid
, ppvObject
);
1551 static ULONG WINAPI
IFileSaveDialog_fnAddRef(IFileSaveDialog
*iface
)
1553 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
1554 return IFileDialog2_AddRef(&This
->IFileDialog2_iface
);
1557 static ULONG WINAPI
IFileSaveDialog_fnRelease(IFileSaveDialog
*iface
)
1559 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
1560 return IFileDialog2_Release(&This
->IFileDialog2_iface
);
1563 static HRESULT WINAPI
IFileSaveDialog_fnShow(IFileSaveDialog
*iface
, HWND hwndOwner
)
1565 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
1566 return IFileDialog2_Show(&This
->IFileDialog2_iface
, hwndOwner
);
1569 static HRESULT WINAPI
IFileSaveDialog_fnSetFileTypes(IFileSaveDialog
*iface
, UINT cFileTypes
,
1570 const COMDLG_FILTERSPEC
*rgFilterSpec
)
1572 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
1573 return IFileDialog2_SetFileTypes(&This
->IFileDialog2_iface
, cFileTypes
, rgFilterSpec
);
1576 static HRESULT WINAPI
IFileSaveDialog_fnSetFileTypeIndex(IFileSaveDialog
*iface
, UINT iFileType
)
1578 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
1579 return IFileDialog2_SetFileTypeIndex(&This
->IFileDialog2_iface
, iFileType
);
1582 static HRESULT WINAPI
IFileSaveDialog_fnGetFileTypeIndex(IFileSaveDialog
*iface
, UINT
*piFileType
)
1584 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
1585 return IFileDialog2_GetFileTypeIndex(&This
->IFileDialog2_iface
, piFileType
);
1588 static HRESULT WINAPI
IFileSaveDialog_fnAdvise(IFileSaveDialog
*iface
, IFileDialogEvents
*pfde
,
1591 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
1592 return IFileDialog2_Advise(&This
->IFileDialog2_iface
, pfde
, pdwCookie
);
1595 static HRESULT WINAPI
IFileSaveDialog_fnUnadvise(IFileSaveDialog
*iface
, DWORD dwCookie
)
1597 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
1598 return IFileDialog2_Unadvise(&This
->IFileDialog2_iface
, dwCookie
);
1601 static HRESULT WINAPI
IFileSaveDialog_fnSetOptions(IFileSaveDialog
*iface
, FILEOPENDIALOGOPTIONS fos
)
1603 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
1604 return IFileDialog2_SetOptions(&This
->IFileDialog2_iface
, fos
);
1607 static HRESULT WINAPI
IFileSaveDialog_fnGetOptions(IFileSaveDialog
*iface
, FILEOPENDIALOGOPTIONS
*pfos
)
1609 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
1610 return IFileDialog2_GetOptions(&This
->IFileDialog2_iface
, pfos
);
1613 static HRESULT WINAPI
IFileSaveDialog_fnSetDefaultFolder(IFileSaveDialog
*iface
, IShellItem
*psi
)
1615 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
1616 return IFileDialog2_SetDefaultFolder(&This
->IFileDialog2_iface
, psi
);
1619 static HRESULT WINAPI
IFileSaveDialog_fnSetFolder(IFileSaveDialog
*iface
, IShellItem
*psi
)
1621 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
1622 return IFileDialog2_SetFolder(&This
->IFileDialog2_iface
, psi
);
1625 static HRESULT WINAPI
IFileSaveDialog_fnGetFolder(IFileSaveDialog
*iface
, IShellItem
**ppsi
)
1627 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
1628 return IFileDialog2_GetFolder(&This
->IFileDialog2_iface
, ppsi
);
1631 static HRESULT WINAPI
IFileSaveDialog_fnGetCurrentSelection(IFileSaveDialog
*iface
, IShellItem
**ppsi
)
1633 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
1634 return IFileDialog2_GetCurrentSelection(&This
->IFileDialog2_iface
, ppsi
);
1637 static HRESULT WINAPI
IFileSaveDialog_fnSetFileName(IFileSaveDialog
*iface
, LPCWSTR pszName
)
1639 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
1640 return IFileDialog2_SetFileName(&This
->IFileDialog2_iface
, pszName
);
1643 static HRESULT WINAPI
IFileSaveDialog_fnGetFileName(IFileSaveDialog
*iface
, LPWSTR
*pszName
)
1645 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
1646 return IFileDialog2_GetFileName(&This
->IFileDialog2_iface
, pszName
);
1649 static HRESULT WINAPI
IFileSaveDialog_fnSetTitle(IFileSaveDialog
*iface
, LPCWSTR pszTitle
)
1651 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
1652 return IFileDialog2_SetTitle(&This
->IFileDialog2_iface
, pszTitle
);
1655 static HRESULT WINAPI
IFileSaveDialog_fnSetOkButtonLabel(IFileSaveDialog
*iface
, LPCWSTR pszText
)
1657 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
1658 return IFileDialog2_SetOkButtonLabel(&This
->IFileDialog2_iface
, pszText
);
1661 static HRESULT WINAPI
IFileSaveDialog_fnSetFileNameLabel(IFileSaveDialog
*iface
, LPCWSTR pszLabel
)
1663 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
1664 return IFileDialog2_SetFileNameLabel(&This
->IFileDialog2_iface
, pszLabel
);
1667 static HRESULT WINAPI
IFileSaveDialog_fnGetResult(IFileSaveDialog
*iface
, IShellItem
**ppsi
)
1669 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
1670 return IFileDialog2_GetResult(&This
->IFileDialog2_iface
, ppsi
);
1673 static HRESULT WINAPI
IFileSaveDialog_fnAddPlace(IFileSaveDialog
*iface
, IShellItem
*psi
, FDAP fdap
)
1675 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
1676 return IFileDialog2_AddPlace(&This
->IFileDialog2_iface
, psi
, fdap
);
1679 static HRESULT WINAPI
IFileSaveDialog_fnSetDefaultExtension(IFileSaveDialog
*iface
,
1680 LPCWSTR pszDefaultExtension
)
1682 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
1683 return IFileDialog2_SetDefaultExtension(&This
->IFileDialog2_iface
, pszDefaultExtension
);
1686 static HRESULT WINAPI
IFileSaveDialog_fnClose(IFileSaveDialog
*iface
, HRESULT hr
)
1688 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
1689 return IFileDialog2_Close(&This
->IFileDialog2_iface
, hr
);
1692 static HRESULT WINAPI
IFileSaveDialog_fnSetClientGuid(IFileSaveDialog
*iface
, REFGUID guid
)
1694 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
1695 return IFileDialog2_SetClientGuid(&This
->IFileDialog2_iface
, guid
);
1698 static HRESULT WINAPI
IFileSaveDialog_fnClearClientData(IFileSaveDialog
*iface
)
1700 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
1701 return IFileDialog2_ClearClientData(&This
->IFileDialog2_iface
);
1704 static HRESULT WINAPI
IFileSaveDialog_fnSetFilter(IFileSaveDialog
*iface
, IShellItemFilter
*pFilter
)
1706 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
1707 return IFileDialog2_SetFilter(&This
->IFileDialog2_iface
, pFilter
);
1710 static HRESULT WINAPI
IFileSaveDialog_fnSetSaveAsItem(IFileSaveDialog
* iface
, IShellItem
*psi
)
1712 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
1713 FIXME("stub - %p (%p)\n", This
, psi
);
1717 static HRESULT WINAPI
IFileSaveDialog_fnSetProperties(IFileSaveDialog
* iface
, IPropertyStore
*pStore
)
1719 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
1720 FIXME("stub - %p (%p)\n", This
, pStore
);
1724 static HRESULT WINAPI
IFileSaveDialog_fnSetCollectedProperties(IFileSaveDialog
* iface
,
1725 IPropertyDescriptionList
*pList
,
1726 BOOL fAppendDefault
)
1728 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
1729 FIXME("stub - %p (%p, %d)\n", This
, pList
, fAppendDefault
);
1733 static HRESULT WINAPI
IFileSaveDialog_fnGetProperties(IFileSaveDialog
* iface
, IPropertyStore
**ppStore
)
1735 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
1736 FIXME("stub - %p (%p)\n", This
, ppStore
);
1740 static HRESULT WINAPI
IFileSaveDialog_fnApplyProperties(IFileSaveDialog
* iface
,
1742 IPropertyStore
*pStore
,
1744 IFileOperationProgressSink
*pSink
)
1746 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
1747 FIXME("%p (%p, %p, %p, %p)\n", This
, psi
, pStore
, hwnd
, pSink
);
1751 static const IFileSaveDialogVtbl vt_IFileSaveDialog
= {
1752 IFileSaveDialog_fnQueryInterface
,
1753 IFileSaveDialog_fnAddRef
,
1754 IFileSaveDialog_fnRelease
,
1755 IFileSaveDialog_fnShow
,
1756 IFileSaveDialog_fnSetFileTypes
,
1757 IFileSaveDialog_fnSetFileTypeIndex
,
1758 IFileSaveDialog_fnGetFileTypeIndex
,
1759 IFileSaveDialog_fnAdvise
,
1760 IFileSaveDialog_fnUnadvise
,
1761 IFileSaveDialog_fnSetOptions
,
1762 IFileSaveDialog_fnGetOptions
,
1763 IFileSaveDialog_fnSetDefaultFolder
,
1764 IFileSaveDialog_fnSetFolder
,
1765 IFileSaveDialog_fnGetFolder
,
1766 IFileSaveDialog_fnGetCurrentSelection
,
1767 IFileSaveDialog_fnSetFileName
,
1768 IFileSaveDialog_fnGetFileName
,
1769 IFileSaveDialog_fnSetTitle
,
1770 IFileSaveDialog_fnSetOkButtonLabel
,
1771 IFileSaveDialog_fnSetFileNameLabel
,
1772 IFileSaveDialog_fnGetResult
,
1773 IFileSaveDialog_fnAddPlace
,
1774 IFileSaveDialog_fnSetDefaultExtension
,
1775 IFileSaveDialog_fnClose
,
1776 IFileSaveDialog_fnSetClientGuid
,
1777 IFileSaveDialog_fnClearClientData
,
1778 IFileSaveDialog_fnSetFilter
,
1779 IFileSaveDialog_fnSetSaveAsItem
,
1780 IFileSaveDialog_fnSetProperties
,
1781 IFileSaveDialog_fnSetCollectedProperties
,
1782 IFileSaveDialog_fnGetProperties
,
1783 IFileSaveDialog_fnApplyProperties
1786 /**************************************************************************
1787 * IExplorerBrowserEvents implementation
1789 static inline FileDialogImpl
*impl_from_IExplorerBrowserEvents(IExplorerBrowserEvents
*iface
)
1791 return CONTAINING_RECORD(iface
, FileDialogImpl
, IExplorerBrowserEvents_iface
);
1794 static HRESULT WINAPI
IExplorerBrowserEvents_fnQueryInterface(IExplorerBrowserEvents
*iface
,
1795 REFIID riid
, void **ppvObject
)
1797 FileDialogImpl
*This
= impl_from_IExplorerBrowserEvents(iface
);
1798 TRACE("%p (%s, %p)\n", This
, debugstr_guid(riid
), ppvObject
);
1800 return IFileDialog2_QueryInterface(&This
->IFileDialog2_iface
, riid
, ppvObject
);
1803 static ULONG WINAPI
IExplorerBrowserEvents_fnAddRef(IExplorerBrowserEvents
*iface
)
1805 FileDialogImpl
*This
= impl_from_IExplorerBrowserEvents(iface
);
1806 TRACE("%p\n", This
);
1807 return IFileDialog2_AddRef(&This
->IFileDialog2_iface
);
1810 static ULONG WINAPI
IExplorerBrowserEvents_fnRelease(IExplorerBrowserEvents
*iface
)
1812 FileDialogImpl
*This
= impl_from_IExplorerBrowserEvents(iface
);
1813 TRACE("%p\n", This
);
1814 return IFileDialog2_Release(&This
->IFileDialog2_iface
);
1817 static HRESULT WINAPI
IExplorerBrowserEvents_fnOnNavigationPending(IExplorerBrowserEvents
*iface
,
1818 PCIDLIST_ABSOLUTE pidlFolder
)
1820 FileDialogImpl
*This
= impl_from_IExplorerBrowserEvents(iface
);
1821 TRACE("%p (%p)\n", This
, pidlFolder
);
1825 static HRESULT WINAPI
IExplorerBrowserEvents_fnOnViewCreated(IExplorerBrowserEvents
*iface
,
1828 FileDialogImpl
*This
= impl_from_IExplorerBrowserEvents(iface
);
1829 TRACE("%p (%p)\n", This
, psv
);
1833 static HRESULT WINAPI
IExplorerBrowserEvents_fnOnNavigationComplete(IExplorerBrowserEvents
*iface
,
1834 PCIDLIST_ABSOLUTE pidlFolder
)
1836 FileDialogImpl
*This
= impl_from_IExplorerBrowserEvents(iface
);
1838 TRACE("%p (%p)\n", This
, pidlFolder
);
1840 if(This
->psi_folder
)
1841 IShellItem_Release(This
->psi_folder
);
1843 hr
= SHCreateItemFromIDList(pidlFolder
, &IID_IShellItem
, (void**)&This
->psi_folder
);
1846 ERR("Failed to get the current folder.\n");
1847 This
->psi_folder
= NULL
;
1853 static HRESULT WINAPI
IExplorerBrowserEvents_fnOnNavigationFailed(IExplorerBrowserEvents
*iface
,
1854 PCIDLIST_ABSOLUTE pidlFolder
)
1856 FileDialogImpl
*This
= impl_from_IExplorerBrowserEvents(iface
);
1857 TRACE("%p (%p)\n", This
, pidlFolder
);
1861 static const IExplorerBrowserEventsVtbl vt_IExplorerBrowserEvents
= {
1862 IExplorerBrowserEvents_fnQueryInterface
,
1863 IExplorerBrowserEvents_fnAddRef
,
1864 IExplorerBrowserEvents_fnRelease
,
1865 IExplorerBrowserEvents_fnOnNavigationPending
,
1866 IExplorerBrowserEvents_fnOnViewCreated
,
1867 IExplorerBrowserEvents_fnOnNavigationComplete
,
1868 IExplorerBrowserEvents_fnOnNavigationFailed
1871 /**************************************************************************
1872 * IServiceProvider implementation
1874 static inline FileDialogImpl
*impl_from_IServiceProvider(IServiceProvider
*iface
)
1876 return CONTAINING_RECORD(iface
, FileDialogImpl
, IServiceProvider_iface
);
1879 static HRESULT WINAPI
IServiceProvider_fnQueryInterface(IServiceProvider
*iface
,
1880 REFIID riid
, void **ppvObject
)
1882 FileDialogImpl
*This
= impl_from_IServiceProvider(iface
);
1883 TRACE("%p\n", This
);
1884 return IFileDialog2_QueryInterface(&This
->IFileDialog2_iface
, riid
, ppvObject
);
1887 static ULONG WINAPI
IServiceProvider_fnAddRef(IServiceProvider
*iface
)
1889 FileDialogImpl
*This
= impl_from_IServiceProvider(iface
);
1890 TRACE("%p\n", This
);
1891 return IFileDialog2_AddRef(&This
->IFileDialog2_iface
);
1894 static ULONG WINAPI
IServiceProvider_fnRelease(IServiceProvider
*iface
)
1896 FileDialogImpl
*This
= impl_from_IServiceProvider(iface
);
1897 TRACE("%p\n", This
);
1898 return IFileDialog2_Release(&This
->IFileDialog2_iface
);
1901 static HRESULT WINAPI
IServiceProvider_fnQueryService(IServiceProvider
*iface
,
1902 REFGUID guidService
,
1903 REFIID riid
, void **ppv
)
1905 FileDialogImpl
*This
= impl_from_IServiceProvider(iface
);
1906 HRESULT hr
= E_FAIL
;
1907 TRACE("%p (%s, %s, %p)\n", This
, debugstr_guid(guidService
), debugstr_guid(riid
), ppv
);
1910 if(IsEqualGUID(guidService
, &SID_STopLevelBrowser
) && This
->peb
)
1911 hr
= IExplorerBrowser_QueryInterface(This
->peb
, riid
, ppv
);
1912 else if(IsEqualGUID(guidService
, &SID_SExplorerBrowserFrame
))
1913 hr
= IFileDialog2_QueryInterface(&This
->IFileDialog2_iface
, riid
, ppv
);
1915 FIXME("Interface %s requested from unknown service %s\n",
1916 debugstr_guid(riid
), debugstr_guid(guidService
));
1918 if(SUCCEEDED(hr
) && *ppv
)
1920 IUnknown_AddRef((IUnknown
*)*ppv
);
1927 static const IServiceProviderVtbl vt_IServiceProvider
= {
1928 IServiceProvider_fnQueryInterface
,
1929 IServiceProvider_fnAddRef
,
1930 IServiceProvider_fnRelease
,
1931 IServiceProvider_fnQueryService
1934 /**************************************************************************
1935 * ICommDlgBrowser3 implementation
1937 static inline FileDialogImpl
*impl_from_ICommDlgBrowser3(ICommDlgBrowser3
*iface
)
1939 return CONTAINING_RECORD(iface
, FileDialogImpl
, ICommDlgBrowser3_iface
);
1942 static HRESULT WINAPI
ICommDlgBrowser3_fnQueryInterface(ICommDlgBrowser3
*iface
,
1943 REFIID riid
, void **ppvObject
)
1945 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
1946 TRACE("%p\n", This
);
1947 return IFileDialog2_QueryInterface(&This
->IFileDialog2_iface
, riid
, ppvObject
);
1950 static ULONG WINAPI
ICommDlgBrowser3_fnAddRef(ICommDlgBrowser3
*iface
)
1952 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
1953 TRACE("%p\n", This
);
1954 return IFileDialog2_AddRef(&This
->IFileDialog2_iface
);
1957 static ULONG WINAPI
ICommDlgBrowser3_fnRelease(ICommDlgBrowser3
*iface
)
1959 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
1960 TRACE("%p\n", This
);
1961 return IFileDialog2_Release(&This
->IFileDialog2_iface
);
1964 static HRESULT WINAPI
ICommDlgBrowser3_fnOnDefaultCommand(ICommDlgBrowser3
*iface
,
1967 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
1969 TRACE("%p (%p)\n", This
, shv
);
1971 hr
= on_default_action(This
);
1974 EndDialog(This
->dlg_hwnd
, S_OK
);
1979 static HRESULT WINAPI
ICommDlgBrowser3_fnOnStateChange(ICommDlgBrowser3
*iface
,
1980 IShellView
*shv
, ULONG uChange
)
1982 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
1983 IDataObject
*new_selection
;
1985 TRACE("%p (%p, %x)\n", This
, shv
, uChange
);
1989 case CDBOSC_SELCHANGE
:
1990 if(This
->psia_selection
)
1992 IShellItemArray_Release(This
->psia_selection
);
1993 This
->psia_selection
= NULL
;
1996 hr
= IShellView_GetItemObject(shv
, SVGIO_SELECTION
, &IID_IDataObject
, (void**)&new_selection
);
1999 hr
= SHCreateShellItemArrayFromDataObject(new_selection
, &IID_IShellItemArray
,
2000 (void**)&This
->psia_selection
);
2002 fill_filename_from_selection(This
);
2004 IDataObject_Release(new_selection
);
2008 TRACE("Unhandled state change\n");
2013 static HRESULT WINAPI
ICommDlgBrowser3_fnIncludeObject(ICommDlgBrowser3
*iface
,
2014 IShellView
*shv
, LPCITEMIDLIST pidl
)
2016 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
2019 LPITEMIDLIST parent_pidl
;
2022 TRACE("%p (%p, %p)\n", This
, shv
, pidl
);
2024 if(!This
->filterspec_count
)
2027 hr
= SHGetIDListFromObject((IUnknown
*)shv
, &parent_pidl
);
2030 LPITEMIDLIST full_pidl
= ILCombine(parent_pidl
, pidl
);
2031 hr
= SHCreateItemFromIDList(full_pidl
, &IID_IShellItem
, (void**)&psi
);
2032 ILFree(parent_pidl
);
2037 ERR("Failed to get shellitem (%08x).\n", hr
);
2041 hr
= IShellItem_GetAttributes(psi
, SFGAO_FOLDER
|SFGAO_LINK
, &attr
);
2042 if(FAILED(hr
) || (attr
& (SFGAO_FOLDER
| SFGAO_LINK
)))
2044 IShellItem_Release(psi
);
2049 if(SUCCEEDED(IShellItem_GetDisplayName(psi
, SIGDN_PARENTRELATIVEPARSING
, &filename
)))
2051 if(!PathMatchSpecW(filename
, This
->filterspecs
[This
->filetypeindex
].pszSpec
))
2053 CoTaskMemFree(filename
);
2056 IShellItem_Release(psi
);
2060 static HRESULT WINAPI
ICommDlgBrowser3_fnNotify(ICommDlgBrowser3
*iface
,
2061 IShellView
*ppshv
, DWORD dwNotifyType
)
2063 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
2064 FIXME("Stub: %p (%p, 0x%x)\n", This
, ppshv
, dwNotifyType
);
2068 static HRESULT WINAPI
ICommDlgBrowser3_fnGetDefaultMenuText(ICommDlgBrowser3
*iface
,
2070 LPWSTR pszText
, int cchMax
)
2072 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
2073 FIXME("Stub: %p (%p, %p, %d)\n", This
, pshv
, pszText
, cchMax
);
2077 static HRESULT WINAPI
ICommDlgBrowser3_fnGetViewFlags(ICommDlgBrowser3
*iface
, DWORD
*pdwFlags
)
2079 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
2080 FIXME("Stub: %p (%p)\n", This
, pdwFlags
);
2084 static HRESULT WINAPI
ICommDlgBrowser3_fnOnColumnClicked(ICommDlgBrowser3
*iface
,
2085 IShellView
*pshv
, int iColumn
)
2087 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
2088 FIXME("Stub: %p (%p, %d)\n", This
, pshv
, iColumn
);
2092 static HRESULT WINAPI
ICommDlgBrowser3_fnGetCurrentFilter(ICommDlgBrowser3
*iface
,
2093 LPWSTR pszFileSpec
, int cchFileSpec
)
2095 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
2096 FIXME("Stub: %p (%p, %d)\n", This
, pszFileSpec
, cchFileSpec
);
2100 static HRESULT WINAPI
ICommDlgBrowser3_fnOnPreviewCreated(ICommDlgBrowser3
*iface
,
2103 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
2104 FIXME("Stub: %p (%p)\n", This
, pshv
);
2108 static const ICommDlgBrowser3Vtbl vt_ICommDlgBrowser3
= {
2109 ICommDlgBrowser3_fnQueryInterface
,
2110 ICommDlgBrowser3_fnAddRef
,
2111 ICommDlgBrowser3_fnRelease
,
2112 ICommDlgBrowser3_fnOnDefaultCommand
,
2113 ICommDlgBrowser3_fnOnStateChange
,
2114 ICommDlgBrowser3_fnIncludeObject
,
2115 ICommDlgBrowser3_fnNotify
,
2116 ICommDlgBrowser3_fnGetDefaultMenuText
,
2117 ICommDlgBrowser3_fnGetViewFlags
,
2118 ICommDlgBrowser3_fnOnColumnClicked
,
2119 ICommDlgBrowser3_fnGetCurrentFilter
,
2120 ICommDlgBrowser3_fnOnPreviewCreated
2123 static HRESULT
FileDialog_constructor(IUnknown
*pUnkOuter
, REFIID riid
, void **ppv
, enum ITEMDLG_TYPE type
)
2125 FileDialogImpl
*fdimpl
;
2128 TRACE("%p, %s, %p\n", pUnkOuter
, debugstr_guid(riid
), ppv
);
2133 return CLASS_E_NOAGGREGATION
;
2135 fdimpl
= HeapAlloc(GetProcessHeap(), 0, sizeof(FileDialogImpl
));
2137 return E_OUTOFMEMORY
;
2140 fdimpl
->IFileDialog2_iface
.lpVtbl
= &vt_IFileDialog2
;
2141 fdimpl
->IExplorerBrowserEvents_iface
.lpVtbl
= &vt_IExplorerBrowserEvents
;
2142 fdimpl
->IServiceProvider_iface
.lpVtbl
= &vt_IServiceProvider
;
2143 fdimpl
->ICommDlgBrowser3_iface
.lpVtbl
= &vt_ICommDlgBrowser3
;
2145 if(type
== ITEMDLG_TYPE_OPEN
)
2147 fdimpl
->dlg_type
= ITEMDLG_TYPE_OPEN
;
2148 fdimpl
->u
.IFileOpenDialog_iface
.lpVtbl
= &vt_IFileOpenDialog
;
2149 fdimpl
->options
= FOS_PATHMUSTEXIST
| FOS_FILEMUSTEXIST
| FOS_NOCHANGEDIR
;
2150 fdimpl
->custom_title
= fdimpl
->custom_okbutton
= NULL
;
2155 fdimpl
->dlg_type
= ITEMDLG_TYPE_SAVE
;
2156 fdimpl
->u
.IFileSaveDialog_iface
.lpVtbl
= &vt_IFileSaveDialog
;
2157 fdimpl
->options
= FOS_OVERWRITEPROMPT
| FOS_NOREADONLYRETURN
| FOS_PATHMUSTEXIST
| FOS_NOCHANGEDIR
;
2159 LoadStringW(COMDLG32_hInstance
, IDS_SAVE
, buf
, sizeof(buf
)/sizeof(WCHAR
));
2160 fdimpl
->custom_title
= StrDupW(buf
);
2161 fdimpl
->custom_okbutton
= StrDupW(buf
);
2164 fdimpl
->filterspecs
= NULL
;
2165 fdimpl
->filterspec_count
= 0;
2166 fdimpl
->filetypeindex
= 0;
2168 fdimpl
->psia_selection
= fdimpl
->psia_results
= NULL
;
2169 fdimpl
->psi_setfolder
= fdimpl
->psi_folder
= NULL
;
2171 list_init(&fdimpl
->events_clients
);
2172 fdimpl
->events_next_cookie
= 0;
2174 fdimpl
->dlg_hwnd
= NULL
;
2177 fdimpl
->set_filename
= NULL
;
2178 fdimpl
->custom_cancelbutton
= fdimpl
->custom_filenamelabel
= NULL
;
2180 /* FIXME: The default folder setting should be restored for the
2181 * application if it was previously set. */
2182 SHGetDesktopFolder(&psf
);
2183 SHGetItemFromObject((IUnknown
*)psf
, &IID_IShellItem
, (void**)&fdimpl
->psi_defaultfolder
);
2184 IShellFolder_Release(psf
);
2186 hr
= IUnknown_QueryInterface((IUnknown
*)fdimpl
, riid
, ppv
);
2187 IUnknown_Release((IUnknown
*)fdimpl
);
2191 HRESULT
FileOpenDialog_Constructor(IUnknown
*pUnkOuter
, REFIID riid
, void **ppv
)
2193 return FileDialog_constructor(pUnkOuter
, riid
, ppv
, ITEMDLG_TYPE_OPEN
);
2196 HRESULT
FileSaveDialog_Constructor(IUnknown
*pUnkOuter
, REFIID riid
, void **ppv
)
2198 return FileDialog_constructor(pUnkOuter
, riid
, ppv
, ITEMDLG_TYPE_SAVE
);