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 #ifndef __REACTOS__ /* Win 7 */
26 #define NONAMELESSUNION
27 #define NONAMELESSSTRUCT
38 #include "filedlgbrowser.h"
40 #include "wine/debug.h"
41 #include "wine/list.h"
43 #define IDC_NAV_TOOLBAR 200
44 #define IDC_NAVBACK 201
45 #define IDC_NAVFORWARD 202
48 /* This seems to be another version of IID_IFileDialogCustomize. If
49 * there is any difference I have yet to find it. */
50 DEFINE_GUID(IID_IFileDialogCustomizeAlt
, 0x8016B7B3, 0x3D49, 0x4504, 0xA0,0xAA, 0x2A,0x37,0x49,0x4E,0x60,0x6F);
52 WINE_DEFAULT_DEBUG_CHANNEL(commdlg
);
54 static const WCHAR notifysink_childW
[] = {'n','f','s','_','c','h','i','l','d',0};
55 static const WCHAR floatnotifysinkW
[] = {'F','l','o','a','t','N','o','t','i','f','y','S','i','n','k',0};
62 enum ITEMDLG_CCTRL_TYPE
{
64 IDLG_CCTRL_PUSHBUTTON
,
66 IDLG_CCTRL_RADIOBUTTONLIST
,
67 IDLG_CCTRL_CHECKBUTTON
,
71 IDLG_CCTRL_VISUALGROUP
75 HWND hwnd
, wrapper_hwnd
;
77 enum ITEMDLG_CCTRL_TYPE type
;
78 CDCONTROLSTATEF cdcstate
;
81 struct list sub_cctrls
;
82 struct list sub_cctrls_entry
;
87 IFileDialogEvents
*pfde
;
91 typedef struct FileDialogImpl
{
92 IFileDialog2 IFileDialog2_iface
;
94 IFileOpenDialog IFileOpenDialog_iface
;
95 IFileSaveDialog IFileSaveDialog_iface
;
97 enum ITEMDLG_TYPE dlg_type
;
98 IExplorerBrowserEvents IExplorerBrowserEvents_iface
;
99 IServiceProvider IServiceProvider_iface
;
100 ICommDlgBrowser3 ICommDlgBrowser3_iface
;
101 IOleWindow IOleWindow_iface
;
102 IFileDialogCustomize IFileDialogCustomize_iface
;
105 FILEOPENDIALOGOPTIONS options
;
106 COMDLG_FILTERSPEC
*filterspecs
;
107 UINT filterspec_count
;
110 struct list events_clients
;
111 DWORD events_next_cookie
;
113 IShellItemArray
*psia_selection
;
114 IShellItemArray
*psia_results
;
115 IShellItem
*psi_defaultfolder
;
116 IShellItem
*psi_setfolder
;
117 IShellItem
*psi_folder
;
120 IExplorerBrowser
*peb
;
121 DWORD ebevents_cookie
;
126 LPWSTR custom_okbutton
;
127 LPWSTR custom_cancelbutton
;
128 LPWSTR custom_filenamelabel
;
130 UINT cctrl_width
, cctrl_def_height
, cctrls_cols
;
134 UINT_PTR cctrl_next_dlgid
;
135 customctrl
*cctrl_active_vg
;
140 /**************************************************************************
143 static HRESULT
events_OnFileOk(FileDialogImpl
*This
)
145 events_client
*cursor
;
149 LIST_FOR_EACH_ENTRY(cursor
, &This
->events_clients
, events_client
, entry
)
151 TRACE("Notifying %p\n", cursor
);
152 hr
= IFileDialogEvents_OnFileOk(cursor
->pfde
, (IFileDialog
*)&This
->IFileDialog2_iface
);
153 if(FAILED(hr
) && hr
!= E_NOTIMPL
)
163 static HRESULT
events_OnFolderChanging(FileDialogImpl
*This
, IShellItem
*folder
)
165 events_client
*cursor
;
167 TRACE("%p (%p)\n", This
, folder
);
169 LIST_FOR_EACH_ENTRY(cursor
, &This
->events_clients
, events_client
, entry
)
171 TRACE("Notifying %p\n", cursor
);
172 hr
= IFileDialogEvents_OnFolderChanging(cursor
->pfde
, (IFileDialog
*)&This
->IFileDialog2_iface
, folder
);
173 if(FAILED(hr
) && hr
!= E_NOTIMPL
)
183 static void events_OnFolderChange(FileDialogImpl
*This
)
185 events_client
*cursor
;
188 LIST_FOR_EACH_ENTRY(cursor
, &This
->events_clients
, events_client
, entry
)
190 TRACE("Notifying %p\n", cursor
);
191 IFileDialogEvents_OnFolderChange(cursor
->pfde
, (IFileDialog
*)&This
->IFileDialog2_iface
);
195 static void events_OnSelectionChange(FileDialogImpl
*This
)
197 events_client
*cursor
;
200 LIST_FOR_EACH_ENTRY(cursor
, &This
->events_clients
, events_client
, entry
)
202 TRACE("Notifying %p\n", cursor
);
203 IFileDialogEvents_OnSelectionChange(cursor
->pfde
, (IFileDialog
*)&This
->IFileDialog2_iface
);
207 static void events_OnTypeChange(FileDialogImpl
*This
)
209 events_client
*cursor
;
212 LIST_FOR_EACH_ENTRY(cursor
, &This
->events_clients
, events_client
, entry
)
214 TRACE("Notifying %p\n", cursor
);
215 IFileDialogEvents_OnTypeChange(cursor
->pfde
, (IFileDialog
*)&This
->IFileDialog2_iface
);
219 static inline HRESULT
get_cctrl_event(IFileDialogEvents
*pfde
, IFileDialogControlEvents
**pfdce
)
221 return IFileDialogEvents_QueryInterface(pfde
, &IID_IFileDialogControlEvents
, (void**)pfdce
);
224 static HRESULT
cctrl_event_OnButtonClicked(FileDialogImpl
*This
, DWORD ctl_id
)
226 events_client
*cursor
;
229 LIST_FOR_EACH_ENTRY(cursor
, &This
->events_clients
, events_client
, entry
)
231 IFileDialogControlEvents
*pfdce
;
232 if(SUCCEEDED(get_cctrl_event(cursor
->pfde
, &pfdce
)))
234 TRACE("Notifying %p\n", cursor
);
235 IFileDialogControlEvents_OnButtonClicked(pfdce
, &This
->IFileDialogCustomize_iface
, ctl_id
);
236 IFileDialogControlEvents_Release(pfdce
);
243 static HRESULT
cctrl_event_OnItemSelected(FileDialogImpl
*This
, DWORD ctl_id
, DWORD item_id
)
245 events_client
*cursor
;
248 LIST_FOR_EACH_ENTRY(cursor
, &This
->events_clients
, events_client
, entry
)
250 IFileDialogControlEvents
*pfdce
;
251 if(SUCCEEDED(get_cctrl_event(cursor
->pfde
, &pfdce
)))
253 TRACE("Notifying %p\n", cursor
);
254 IFileDialogControlEvents_OnItemSelected(pfdce
, &This
->IFileDialogCustomize_iface
, ctl_id
, item_id
);
255 IFileDialogControlEvents_Release(pfdce
);
262 static HRESULT
cctrl_event_OnCheckButtonToggled(FileDialogImpl
*This
, DWORD ctl_id
, BOOL checked
)
264 events_client
*cursor
;
267 LIST_FOR_EACH_ENTRY(cursor
, &This
->events_clients
, events_client
, entry
)
269 IFileDialogControlEvents
*pfdce
;
270 if(SUCCEEDED(get_cctrl_event(cursor
->pfde
, &pfdce
)))
272 TRACE("Notifying %p\n", cursor
);
273 IFileDialogControlEvents_OnCheckButtonToggled(pfdce
, &This
->IFileDialogCustomize_iface
, ctl_id
, checked
);
274 IFileDialogControlEvents_Release(pfdce
);
281 static HRESULT
cctrl_event_OnControlActivating(FileDialogImpl
*This
,
284 events_client
*cursor
;
287 LIST_FOR_EACH_ENTRY(cursor
, &This
->events_clients
, events_client
, entry
)
289 IFileDialogControlEvents
*pfdce
;
290 if(SUCCEEDED(get_cctrl_event(cursor
->pfde
, &pfdce
)))
292 TRACE("Notifying %p\n", cursor
);
293 IFileDialogControlEvents_OnControlActivating(pfdce
, &This
->IFileDialogCustomize_iface
, ctl_id
);
294 IFileDialogControlEvents_Release(pfdce
);
301 /**************************************************************************
304 static UINT
get_file_name(FileDialogImpl
*This
, LPWSTR
*str
)
306 HWND hwnd_edit
= GetDlgItem(This
->dlg_hwnd
, IDC_FILENAME
);
311 if(This
->set_filename
)
313 len
= lstrlenW(This
->set_filename
);
314 *str
= CoTaskMemAlloc(sizeof(WCHAR
)*(len
+1));
315 lstrcpyW(*str
, This
->set_filename
);
321 len
= SendMessageW(hwnd_edit
, WM_GETTEXTLENGTH
, 0, 0);
322 *str
= CoTaskMemAlloc(sizeof(WCHAR
)*(len
+1));
326 SendMessageW(hwnd_edit
, WM_GETTEXT
, len
+1, (LPARAM
)*str
);
330 static BOOL
set_file_name(FileDialogImpl
*This
, LPCWSTR str
)
332 HWND hwnd_edit
= GetDlgItem(This
->dlg_hwnd
, IDC_FILENAME
);
334 if(This
->set_filename
)
335 LocalFree(This
->set_filename
);
337 This
->set_filename
= StrDupW(str
);
339 return SendMessageW(hwnd_edit
, WM_SETTEXT
, 0, (LPARAM
)str
);
342 static void fill_filename_from_selection(FileDialogImpl
*This
)
347 UINT item_count
, valid_count
;
350 if(!This
->psia_selection
)
353 hr
= IShellItemArray_GetCount(This
->psia_selection
, &item_count
);
354 if(FAILED(hr
) || !item_count
)
357 names
= HeapAlloc(GetProcessHeap(), 0, item_count
*sizeof(LPWSTR
));
359 /* Get names of the selected items */
360 valid_count
= 0; len_total
= 0;
361 for(i
= 0; i
< item_count
; i
++)
363 hr
= IShellItemArray_GetItemAt(This
->psia_selection
, i
, &psi
);
368 hr
= IShellItem_GetAttributes(psi
, SFGAO_FOLDER
, &attr
);
370 (( (This
->options
& FOS_PICKFOLDERS
) && !(attr
& SFGAO_FOLDER
)) ||
371 (!(This
->options
& FOS_PICKFOLDERS
) && (attr
& SFGAO_FOLDER
))))
374 hr
= IShellItem_GetDisplayName(psi
, SIGDN_PARENTRELATIVEPARSING
, &names
[valid_count
]);
377 len_total
+= lstrlenW(names
[valid_count
]) + 3;
380 IShellItem_Release(psi
);
386 set_file_name(This
, names
[0]);
387 CoTaskMemFree(names
[0]);
389 else if(valid_count
> 1)
391 LPWSTR string
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
)*len_total
);
392 LPWSTR cur_point
= string
;
394 for(i
= 0; i
< valid_count
; i
++)
396 LPWSTR file
= names
[i
];
398 lstrcpyW(cur_point
, file
);
399 cur_point
+= lstrlenW(file
);
404 *(cur_point
-1) = '\0';
406 set_file_name(This
, string
);
407 HeapFree(GetProcessHeap(), 0, string
);
410 HeapFree(GetProcessHeap(), 0, names
);
414 static LPWSTR
get_first_ext_from_spec(LPWSTR buf
, LPCWSTR spec
)
419 if( (endpos
= StrChrW(buf
, ';')) )
422 ext
= PathFindExtensionW(buf
);
423 if(StrChrW(ext
, '*'))
429 static HRESULT
on_default_action(FileDialogImpl
*This
)
431 IShellFolder
*psf_parent
, *psf_desktop
;
433 LPITEMIDLIST current_folder
;
434 LPWSTR fn_iter
, files
= NULL
, tmp_files
;
435 UINT file_count
= 0, len
, i
;
437 HRESULT hr
, ret
= E_FAIL
;
439 len
= get_file_name(This
, &tmp_files
);
443 file_count
= COMDLG32_SplitFileNames(tmp_files
, len
, &files
, &size_used
);
444 CoTaskMemFree(tmp_files
);
446 if(!file_count
) return E_FAIL
;
448 hr
= SHGetIDListFromObject((IUnknown
*)This
->psi_folder
, ¤t_folder
);
451 ERR("Failed to get pidl for current directory.\n");
452 HeapFree(GetProcessHeap(), 0, files
);
456 TRACE("Acting on %d file(s).\n", file_count
);
458 pidla
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPITEMIDLIST
) * file_count
);
459 open_action
= ONOPEN_OPEN
;
462 for(i
= 0; i
< file_count
&& open_action
== ONOPEN_OPEN
; i
++)
464 WCHAR canon_filename
[MAX_PATH
];
467 COMDLG32_GetCanonicalPath(current_folder
, fn_iter
, canon_filename
);
469 if( (This
->options
& FOS_NOVALIDATE
) &&
470 !(This
->options
& FOS_FILEMUSTEXIST
) )
471 open_action
= ONOPEN_OPEN
;
473 open_action
= ONOPEN_BROWSE
;
475 open_action
= FILEDLG95_ValidatePathAction(canon_filename
, &psf_parent
, This
->dlg_hwnd
,
476 This
->options
& ~FOS_FILEMUSTEXIST
,
477 (This
->dlg_type
== ITEMDLG_TYPE_SAVE
),
480 /* Add the proper extension */
481 if(open_action
== ONOPEN_OPEN
)
483 static const WCHAR dotW
[] = {'.',0};
485 if(This
->dlg_type
== ITEMDLG_TYPE_SAVE
)
487 WCHAR extbuf
[MAX_PATH
], *newext
= NULL
;
489 if(This
->filterspec_count
)
491 newext
= get_first_ext_from_spec(extbuf
, This
->filterspecs
[This
->filetypeindex
].pszSpec
);
493 else if(This
->default_ext
)
495 lstrcpyW(extbuf
, dotW
);
496 lstrcatW(extbuf
, This
->default_ext
);
502 WCHAR
*ext
= PathFindExtensionW(canon_filename
);
503 if(lstrcmpW(ext
, newext
))
504 lstrcatW(canon_filename
, newext
);
509 if( !(This
->options
& FOS_NOVALIDATE
) && (This
->options
& FOS_FILEMUSTEXIST
) &&
510 !PathFileExistsW(canon_filename
))
512 if(This
->default_ext
)
514 lstrcatW(canon_filename
, dotW
);
515 lstrcatW(canon_filename
, This
->default_ext
);
517 if(!PathFileExistsW(canon_filename
))
519 FILEDLG95_OnOpenMessage(This
->dlg_hwnd
, 0, IDS_FILENOTEXISTING
);
520 open_action
= ONOPEN_BROWSE
;
525 FILEDLG95_OnOpenMessage(This
->dlg_hwnd
, 0, IDS_FILENOTEXISTING
);
526 open_action
= ONOPEN_BROWSE
;
532 pidla
[i
] = COMDLG32_SHSimpleIDListFromPathAW(canon_filename
);
534 if(psf_parent
&& !(open_action
== ONOPEN_BROWSE
))
535 IShellFolder_Release(psf_parent
);
537 fn_iter
+= (WCHAR
)lstrlenW(fn_iter
) + 1;
540 HeapFree(GetProcessHeap(), 0, files
);
541 ILFree(current_folder
);
543 if((This
->options
& FOS_PICKFOLDERS
) && open_action
== ONOPEN_BROWSE
)
544 open_action
= ONOPEN_OPEN
; /* FIXME: Multiple folders? */
549 FIXME("Filtering not implemented.\n");
553 hr
= IExplorerBrowser_BrowseToObject(This
->peb
, (IUnknown
*)psf_parent
, SBSP_DEFBROWSER
);
555 ERR("Failed to browse to directory: %08x\n", hr
);
557 IShellFolder_Release(psf_parent
);
561 hr
= SHGetDesktopFolder(&psf_desktop
);
564 if(This
->psia_results
)
566 IShellItemArray_Release(This
->psia_results
);
567 This
->psia_results
= NULL
;
570 hr
= SHCreateShellItemArray(NULL
, psf_desktop
, file_count
, (PCUITEMID_CHILD_ARRAY
)pidla
,
571 &This
->psia_results
);
573 IShellFolder_Release(psf_desktop
);
578 if(This
->options
& FOS_PICKFOLDERS
)
581 hr
= IShellItemArray_GetAttributes(This
->psia_results
, SIATTRIBFLAGS_AND
, SFGAO_FOLDER
, &attributes
);
585 LoadStringW(COMDLG32_hInstance
, IDS_INVALID_FOLDERNAME
, buf
, sizeof(buf
)/sizeof(WCHAR
));
587 MessageBoxW(This
->dlg_hwnd
, buf
, This
->custom_title
, MB_OK
| MB_ICONEXCLAMATION
);
589 IShellItemArray_Release(This
->psia_results
);
590 This
->psia_results
= NULL
;
595 if(events_OnFileOk(This
) == S_OK
)
606 for(i
= 0; i
< file_count
; i
++)
608 HeapFree(GetProcessHeap(), 0, pidla
);
610 /* Success closes the dialog */
614 /**************************************************************************
617 static inline customctrl
*get_cctrl_from_dlgid(FileDialogImpl
*This
, DWORD dlgid
)
619 customctrl
*ctrl
, *sub_ctrl
;
621 LIST_FOR_EACH_ENTRY(ctrl
, &This
->cctrls
, customctrl
, entry
)
623 if(ctrl
->dlgid
== dlgid
)
626 LIST_FOR_EACH_ENTRY(sub_ctrl
, &ctrl
->sub_cctrls
, customctrl
, sub_cctrls_entry
)
627 if(sub_ctrl
->dlgid
== dlgid
)
631 ERR("Failed to find control with dialog id %d\n", dlgid
);
635 static inline customctrl
*get_cctrl(FileDialogImpl
*This
, DWORD ctlid
)
637 customctrl
*ctrl
, *sub_ctrl
;
639 LIST_FOR_EACH_ENTRY(ctrl
, &This
->cctrls
, customctrl
, entry
)
641 if(ctrl
->id
== ctlid
)
644 LIST_FOR_EACH_ENTRY(sub_ctrl
, &ctrl
->sub_cctrls
, customctrl
, sub_cctrls_entry
)
645 if(sub_ctrl
->id
== ctlid
)
650 TRACE("No existing control with control id %d\n", ctlid
);
654 static void ctrl_resize(HWND hctrl
, UINT min_width
, UINT max_width
, BOOL multiline
)
657 UINT len
, final_width
;
658 UINT lines
, final_height
;
666 len
= SendMessageW(hctrl
, WM_GETTEXTLENGTH
, 0, 0);
667 text
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
)*(len
+1));
669 SendMessageW(hctrl
, WM_GETTEXT
, len
+1, (LPARAM
)text
);
672 GetTextExtentPoint32W(hdc
, text
, lstrlenW(text
), &size
);
673 ReleaseDC(hctrl
, hdc
);
677 /* FIXME: line-wrap */
678 for(lines
= 1, c
= text
; *c
!= '\0'; c
++)
679 if(*c
== '\n') lines
++;
681 final_height
= size
.cy
*lines
+ 2*4;
685 GetWindowRect(hctrl
, &rc
);
686 final_height
= rc
.bottom
- rc
.top
;
689 final_width
= min(max(size
.cx
, min_width
) + 4, max_width
);
690 SetWindowPos(hctrl
, NULL
, 0, 0, final_width
, final_height
,
691 SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOACTIVATE
);
693 HeapFree(GetProcessHeap(), 0, text
);
696 static UINT
ctrl_get_height(customctrl
*ctrl
) {
698 GetWindowRect(ctrl
->wrapper_hwnd
, &rc
);
699 return rc
.bottom
- rc
.top
;
702 static void ctrl_free(customctrl
*ctrl
)
704 customctrl
*sub_cur1
, *sub_cur2
;
706 TRACE("Freeing control %p\n", ctrl
);
707 if(ctrl
->type
== IDLG_CCTRL_MENU
)
710 SendMessageW(ctrl
->hwnd
, TB_GETBUTTON
, 0, (LPARAM
)&tbb
);
711 DestroyMenu((HMENU
)tbb
.dwData
);
714 LIST_FOR_EACH_ENTRY_SAFE(sub_cur1
, sub_cur2
, &ctrl
->sub_cctrls
, customctrl
, sub_cctrls_entry
)
716 list_remove(&sub_cur1
->sub_cctrls_entry
);
720 DestroyWindow(ctrl
->hwnd
);
721 HeapFree(GetProcessHeap(), 0, ctrl
);
724 static void customctrl_resize(FileDialogImpl
*This
, customctrl
*ctrl
)
728 customctrl
*sub_ctrl
;
732 case IDLG_CCTRL_PUSHBUTTON
:
733 case IDLG_CCTRL_COMBOBOX
:
734 case IDLG_CCTRL_CHECKBUTTON
:
735 case IDLG_CCTRL_TEXT
:
736 ctrl_resize(ctrl
->hwnd
, 160, 160, TRUE
);
737 GetWindowRect(ctrl
->hwnd
, &rc
);
738 SetWindowPos(ctrl
->wrapper_hwnd
, NULL
, 0, 0, rc
.right
-rc
.left
, rc
.bottom
-rc
.top
,
739 SWP_NOZORDER
|SWP_NOMOVE
);
741 case IDLG_CCTRL_VISUALGROUP
:
743 ctrl_resize(ctrl
->hwnd
, 0, This
->cctrl_indent
, TRUE
);
745 LIST_FOR_EACH_ENTRY(sub_ctrl
, &ctrl
->sub_cctrls
, customctrl
, sub_cctrls_entry
)
747 customctrl_resize(This
, sub_ctrl
);
748 SetWindowPos(sub_ctrl
->wrapper_hwnd
, NULL
, This
->cctrl_indent
, total_height
, 0, 0,
749 SWP_NOZORDER
|SWP_NOSIZE
);
751 total_height
+= ctrl_get_height(sub_ctrl
);
754 /* The label should be right adjusted */
758 GetWindowRect(ctrl
->hwnd
, &rc
);
759 width
= rc
.right
- rc
.left
;
760 height
= rc
.bottom
- rc
.top
;
762 SetWindowPos(ctrl
->hwnd
, NULL
, This
->cctrl_indent
- width
, 0, width
, height
, SWP_NOZORDER
);
765 /* Resize the wrapper window to fit all the sub controls */
766 SetWindowPos(ctrl
->wrapper_hwnd
, NULL
, 0, 0, This
->cctrl_width
+ This
->cctrl_indent
, total_height
,
767 SWP_NOZORDER
|SWP_NOMOVE
);
769 case IDLG_CCTRL_RADIOBUTTONLIST
:
770 case IDLG_CCTRL_EDITBOX
:
771 case IDLG_CCTRL_SEPARATOR
:
772 case IDLG_CCTRL_MENU
:
778 static LRESULT
notifysink_on_create(HWND hwnd
, CREATESTRUCTW
*crs
)
780 FileDialogImpl
*This
= crs
->lpCreateParams
;
783 SetWindowLongPtrW(hwnd
, GWLP_USERDATA
, (LPARAM
)This
);
787 static LRESULT
notifysink_on_bn_clicked(FileDialogImpl
*This
, HWND hwnd
, WPARAM wparam
)
789 customctrl
*ctrl
= get_cctrl_from_dlgid(This
, LOWORD(wparam
));
791 TRACE("%p, %lx\n", This
, wparam
);
795 if(ctrl
->type
== IDLG_CCTRL_CHECKBUTTON
)
797 BOOL checked
= (SendMessageW(ctrl
->hwnd
, BM_GETCHECK
, 0, 0) == BST_CHECKED
);
798 cctrl_event_OnCheckButtonToggled(This
, ctrl
->id
, checked
);
801 cctrl_event_OnButtonClicked(This
, ctrl
->id
);
807 static LRESULT
notifysink_on_cbn_selchange(FileDialogImpl
*This
, HWND hwnd
, WPARAM wparam
)
809 customctrl
*ctrl
= get_cctrl_from_dlgid(This
, LOWORD(wparam
));
810 TRACE("%p, %p (%lx)\n", This
, ctrl
, wparam
);
814 UINT index
= SendMessageW(ctrl
->hwnd
, CB_GETCURSEL
, 0, 0);
815 UINT selid
= SendMessageW(ctrl
->hwnd
, CB_GETITEMDATA
, index
, 0);
817 cctrl_event_OnItemSelected(This
, ctrl
->id
, selid
);
822 static LRESULT
notifysink_on_tvn_dropdown(FileDialogImpl
*This
, LPARAM lparam
)
824 NMTOOLBARW
*nmtb
= (NMTOOLBARW
*)lparam
;
825 customctrl
*ctrl
= get_cctrl_from_dlgid(This
, GetDlgCtrlID(nmtb
->hdr
.hwndFrom
));
826 POINT pt
= { 0, nmtb
->rcButton
.bottom
};
830 TRACE("%p, %p (%lx)\n", This
, ctrl
, lparam
);
834 cctrl_event_OnControlActivating(This
,ctrl
->id
);
836 SendMessageW(ctrl
->hwnd
, TB_GETBUTTON
, 0, (LPARAM
)&tbb
);
837 ClientToScreen(ctrl
->hwnd
, &pt
);
838 idcmd
= TrackPopupMenu((HMENU
)tbb
.dwData
, TPM_RETURNCMD
, pt
.x
, pt
.y
, 0, This
->dlg_hwnd
, NULL
);
840 cctrl_event_OnItemSelected(This
, ctrl
->id
, idcmd
);
843 return TBDDRET_DEFAULT
;
846 static LRESULT
notifysink_on_wm_command(FileDialogImpl
*This
, HWND hwnd
, WPARAM wparam
, LPARAM lparam
)
848 switch(HIWORD(wparam
))
850 case BN_CLICKED
: return notifysink_on_bn_clicked(This
, hwnd
, wparam
);
851 case CBN_SELCHANGE
: return notifysink_on_cbn_selchange(This
, hwnd
, wparam
);
857 static LRESULT
notifysink_on_wm_notify(FileDialogImpl
*This
, HWND hwnd
, WPARAM wparam
, LPARAM lparam
)
859 NMHDR
*nmhdr
= (NMHDR
*)lparam
;
863 case TBN_DROPDOWN
: return notifysink_on_tvn_dropdown(This
, lparam
);
869 static LRESULT CALLBACK
notifysink_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
871 FileDialogImpl
*This
= (FileDialogImpl
*)GetWindowLongPtrW(hwnd
, GWLP_USERDATA
);
878 case WM_NCCREATE
: return notifysink_on_create(hwnd
, (CREATESTRUCTW
*)lparam
);
879 case WM_COMMAND
: return notifysink_on_wm_command(This
, hwnd
, wparam
, lparam
);
880 case WM_NOTIFY
: return notifysink_on_wm_notify(This
, hwnd
, wparam
, lparam
);
882 hwnd_child
= GetPropW(hwnd
, notifysink_childW
);
883 ctrl
= (customctrl
*)GetWindowLongPtrW(hwnd_child
, GWLP_USERDATA
);
884 if(ctrl
&& ctrl
->type
!= IDLG_CCTRL_VISUALGROUP
)
886 GetClientRect(hwnd
, &rc
);
887 SetWindowPos(hwnd_child
, NULL
, 0, 0, rc
.right
, rc
.bottom
, SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_NOZORDER
);
892 return DefWindowProcW(hwnd
, message
, wparam
, lparam
);
895 static HRESULT
cctrl_create_new(FileDialogImpl
*This
, DWORD id
,
896 LPCWSTR text
, LPCWSTR wndclass
, DWORD ctrl_wsflags
,
897 DWORD ctrl_exflags
, UINT height
, customctrl
**ppctrl
)
899 HWND ns_hwnd
, control_hwnd
, parent_hwnd
;
900 DWORD wsflags
= WS_CHILD
| WS_VISIBLE
| WS_CLIPSIBLINGS
;
903 if(get_cctrl(This
, id
))
904 return E_UNEXPECTED
; /* Duplicate id */
906 if(This
->cctrl_active_vg
)
907 parent_hwnd
= This
->cctrl_active_vg
->wrapper_hwnd
;
909 parent_hwnd
= This
->cctrls_hwnd
;
911 ns_hwnd
= CreateWindowExW(0, floatnotifysinkW
, NULL
, wsflags
,
912 0, 0, This
->cctrl_width
, height
, parent_hwnd
,
913 (HMENU
)This
->cctrl_next_dlgid
, COMDLG32_hInstance
, This
);
914 control_hwnd
= CreateWindowExW(ctrl_exflags
, wndclass
, text
, wsflags
| ctrl_wsflags
,
915 0, 0, This
->cctrl_width
, height
, ns_hwnd
,
916 (HMENU
)This
->cctrl_next_dlgid
, COMDLG32_hInstance
, 0);
918 if(!ns_hwnd
|| !control_hwnd
)
920 ERR("Failed to create wrapper (%p) or control (%p)\n", ns_hwnd
, control_hwnd
);
921 DestroyWindow(ns_hwnd
);
922 DestroyWindow(control_hwnd
);
927 SetPropW(ns_hwnd
, notifysink_childW
, control_hwnd
);
929 ctrl
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(customctrl
));
931 return E_OUTOFMEMORY
;
933 ctrl
->hwnd
= control_hwnd
;
934 ctrl
->wrapper_hwnd
= ns_hwnd
;
936 ctrl
->dlgid
= This
->cctrl_next_dlgid
;
937 ctrl
->cdcstate
= CDCS_ENABLED
| CDCS_VISIBLE
;
938 list_init(&ctrl
->sub_cctrls
);
940 if(This
->cctrl_active_vg
)
941 list_add_tail(&This
->cctrl_active_vg
->sub_cctrls
, &ctrl
->sub_cctrls_entry
);
943 list_add_tail(&This
->cctrls
, &ctrl
->entry
);
945 SetWindowLongPtrW(ctrl
->hwnd
, GWLP_USERDATA
, (LPARAM
)ctrl
);
947 if(ppctrl
) *ppctrl
= ctrl
;
949 This
->cctrl_next_dlgid
++;
953 /**************************************************************************
954 * Container functions.
956 static UINT
ctrl_container_resize(FileDialogImpl
*This
, UINT container_width
)
958 UINT container_height
;
961 UINT max_control_height
, total_height
= 0;
962 UINT cur_col_pos
, cur_row_pos
;
965 static const UINT cspacing
= 90; /* Columns are spaced with 90px */
966 static const UINT rspacing
= 4; /* Rows are spaced with 4 px. */
968 /* Given the new width of the container, this function determines the
969 * needed height of the container and places the controls according to
970 * the new layout. Returns the new height.
975 column_width
= This
->cctrl_width
+ cspacing
;
976 nr_of_cols
= (container_width
- This
->cctrl_indent
+ cspacing
) / column_width
;
978 /* We don't need to do anything unless the number of visible columns has changed. */
979 if(nr_of_cols
== This
->cctrls_cols
)
982 GetWindowRect(This
->cctrls_hwnd
, &rc
);
983 return rc
.bottom
- rc
.top
;
986 This
->cctrls_cols
= nr_of_cols
;
988 /* Get the size of the tallest control, and the total size of
989 * all the controls to figure out the number of slots we need.
991 max_control_height
= 0;
992 LIST_FOR_EACH_ENTRY(ctrl
, &This
->cctrls
, customctrl
, entry
)
994 if(ctrl
->cdcstate
& CDCS_VISIBLE
)
996 UINT control_height
= ctrl_get_height(ctrl
);
997 max_control_height
= max(max_control_height
, control_height
);
999 total_height
+= control_height
+ rspacing
;
1006 container_height
= max(total_height
/ nr_of_cols
, max_control_height
+ rspacing
);
1007 TRACE("Guess: container_height: %d\n",container_height
);
1009 /* Incrementally increase container_height until all the controls
1013 UINT columns_needed
= 1;
1017 LIST_FOR_EACH_ENTRY(ctrl
, &This
->cctrls
, customctrl
, entry
)
1019 if(ctrl
->cdcstate
& CDCS_VISIBLE
)
1021 UINT control_height
= ctrl_get_height(ctrl
);
1023 if(cur_row_pos
+ control_height
> container_height
)
1025 if(++columns_needed
> nr_of_cols
)
1027 container_height
+= 1;
1028 fits_height
= FALSE
;
1034 cur_row_pos
+= control_height
+ rspacing
;
1037 } while(!fits_height
);
1039 TRACE("Final container height: %d\n", container_height
);
1041 /* Move the controls to their final destination
1043 cur_col_pos
= 0, cur_row_pos
= 0;
1044 LIST_FOR_EACH_ENTRY(ctrl
, &This
->cctrls
, customctrl
, entry
)
1046 if(ctrl
->cdcstate
& CDCS_VISIBLE
)
1049 UINT control_height
, control_indent
;
1050 GetWindowRect(ctrl
->wrapper_hwnd
, &rc
);
1051 control_height
= rc
.bottom
- rc
.top
;
1053 if(cur_row_pos
+ control_height
> container_height
)
1056 cur_col_pos
+= This
->cctrl_width
+ cspacing
;
1060 if(ctrl
->type
== IDLG_CCTRL_VISUALGROUP
)
1063 control_indent
= This
->cctrl_indent
;
1065 SetWindowPos(ctrl
->wrapper_hwnd
, NULL
, cur_col_pos
+ control_indent
, cur_row_pos
, 0, 0,
1066 SWP_NOACTIVATE
| SWP_NOSIZE
| SWP_NOZORDER
);
1068 cur_row_pos
+= control_height
+ rspacing
;
1073 if(cur_row_pos
+ This
->cctrl_width
> container_width
)
1074 ERR("-- Failed to place controls properly.\n");
1076 return container_height
;
1079 static void ctrl_container_reparent(FileDialogImpl
*This
, HWND parent
)
1085 customctrl
*ctrl
, *sub_ctrl
;
1088 wndstyle
= GetWindowLongW(This
->cctrls_hwnd
, GWL_STYLE
);
1089 wndstyle
&= ~(WS_POPUP
);
1090 wndstyle
|= WS_CHILD
;
1091 SetWindowLongW(This
->cctrls_hwnd
, GWL_STYLE
, wndstyle
);
1093 SetParent(This
->cctrls_hwnd
, parent
);
1094 ShowWindow(This
->cctrls_hwnd
, TRUE
);
1096 /* Set the fonts to match the dialog font. */
1097 font
= (HFONT
)SendMessageW(parent
, WM_GETFONT
, 0, 0);
1099 ERR("Failed to get font handle from dialog.\n");
1101 LIST_FOR_EACH_ENTRY(ctrl
, &This
->cctrls
, customctrl
, entry
)
1103 if(font
) SendMessageW(ctrl
->hwnd
, WM_SETFONT
, (WPARAM
)font
, TRUE
);
1105 /* If this is a VisualGroup */
1106 LIST_FOR_EACH_ENTRY(sub_ctrl
, &ctrl
->sub_cctrls
, customctrl
, sub_cctrls_entry
)
1108 if(font
) SendMessageW(sub_ctrl
->hwnd
, WM_SETFONT
, (WPARAM
)font
, TRUE
);
1111 customctrl_resize(This
, ctrl
);
1116 ShowWindow(This
->cctrls_hwnd
, FALSE
);
1118 wndstyle
= GetWindowLongW(This
->cctrls_hwnd
, GWL_STYLE
);
1119 wndstyle
&= ~(WS_CHILD
);
1120 wndstyle
|= WS_POPUP
;
1121 SetWindowLongW(This
->cctrls_hwnd
, GWL_STYLE
, wndstyle
);
1123 SetParent(This
->cctrls_hwnd
, NULL
);
1127 static LRESULT
ctrl_container_on_create(HWND hwnd
, CREATESTRUCTW
*crs
)
1129 FileDialogImpl
*This
= crs
->lpCreateParams
;
1130 TRACE("%p\n", This
);
1132 SetWindowLongPtrW(hwnd
, GWLP_USERDATA
, (LPARAM
)This
);
1136 static LRESULT
ctrl_container_on_wm_destroy(FileDialogImpl
*This
)
1138 customctrl
*cur1
, *cur2
;
1139 TRACE("%p\n", This
);
1141 LIST_FOR_EACH_ENTRY_SAFE(cur1
, cur2
, &This
->cctrls
, customctrl
, entry
)
1143 list_remove(&cur1
->entry
);
1150 static LRESULT CALLBACK
ctrl_container_wndproc(HWND hwnd
, UINT umessage
, WPARAM wparam
, LPARAM lparam
)
1152 FileDialogImpl
*This
= (FileDialogImpl
*)GetWindowLongPtrW(hwnd
, GWLP_USERDATA
);
1156 case WM_NCCREATE
: return ctrl_container_on_create(hwnd
, (CREATESTRUCTW
*)lparam
);
1157 case WM_DESTROY
: return ctrl_container_on_wm_destroy(This
);
1158 default: return DefWindowProcW(hwnd
, umessage
, wparam
, lparam
);
1164 static HRESULT
init_custom_controls(FileDialogImpl
*This
)
1167 static const WCHAR ctrl_container_classname
[] =
1168 {'i','d','l','g','_','c','o','n','t','a','i','n','e','r','_','p','a','n','e',0};
1170 InitCommonControlsEx(NULL
);
1172 This
->cctrl_width
= 160; /* Controls have a fixed width */
1173 This
->cctrl_indent
= 100;
1174 This
->cctrl_def_height
= 23;
1175 This
->cctrls_cols
= 0;
1177 This
->cctrl_next_dlgid
= 0x2000;
1178 list_init(&This
->cctrls
);
1179 This
->cctrl_active_vg
= NULL
;
1181 if( !GetClassInfoW(COMDLG32_hInstance
, ctrl_container_classname
, &wc
) )
1183 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
1184 wc
.lpfnWndProc
= ctrl_container_wndproc
;
1187 wc
.hInstance
= COMDLG32_hInstance
;
1189 wc
.hCursor
= LoadCursorW(0, (LPWSTR
)IDC_ARROW
);
1190 wc
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
1191 wc
.lpszMenuName
= NULL
;
1192 wc
.lpszClassName
= ctrl_container_classname
;
1194 if(!RegisterClassW(&wc
)) return E_FAIL
;
1197 This
->cctrls_hwnd
= CreateWindowExW(0, ctrl_container_classname
, NULL
,
1198 WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
,
1199 0, 0, 0, 0, NULL
, 0,
1200 COMDLG32_hInstance
, (void*)This
);
1201 if(!This
->cctrls_hwnd
)
1204 SetWindowLongW(This
->cctrls_hwnd
, GWL_STYLE
, WS_TABSTOP
);
1206 /* Register class for */
1207 if( !GetClassInfoW(COMDLG32_hInstance
, floatnotifysinkW
, &wc
) ||
1208 wc
.hInstance
!= COMDLG32_hInstance
)
1210 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
1211 wc
.lpfnWndProc
= notifysink_proc
;
1214 wc
.hInstance
= COMDLG32_hInstance
;
1216 wc
.hCursor
= LoadCursorW(0, (LPWSTR
)IDC_ARROW
);
1217 wc
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
1218 wc
.lpszMenuName
= NULL
;
1219 wc
.lpszClassName
= floatnotifysinkW
;
1221 if (!RegisterClassW(&wc
))
1222 ERR("Failed to register FloatNotifySink window class.\n");
1228 /**************************************************************************
1229 * Window related functions.
1231 static SIZE
update_layout(FileDialogImpl
*This
)
1236 RECT cancel_rc
, open_rc
;
1237 RECT filetype_rc
, filename_rc
, filenamelabel_rc
;
1238 RECT toolbar_rc
, ebrowser_rc
, customctrls_rc
;
1239 int missing_width
, missing_height
;
1240 static const UINT vspacing
= 4, hspacing
= 4;
1243 GetClientRect(This
->dlg_hwnd
, &dialog_rc
);
1245 missing_width
= max(0, 320 - dialog_rc
.right
);
1246 missing_height
= max(0, 200 - dialog_rc
.bottom
);
1248 if(missing_width
|| missing_height
)
1250 TRACE("Missing (%d, %d)\n", missing_width
, missing_height
);
1251 ret
.cx
= missing_width
;
1252 ret
.cy
= missing_height
;
1257 * Calculate the size of the dialog and all the parts.
1261 hwnd
= GetDlgItem(This
->dlg_hwnd
, IDCANCEL
);
1264 int cancel_width
, cancel_height
;
1265 GetWindowRect(hwnd
, &cancel_rc
);
1266 cancel_width
= cancel_rc
.right
- cancel_rc
.left
;
1267 cancel_height
= cancel_rc
.bottom
- cancel_rc
.top
;
1269 cancel_rc
.left
= dialog_rc
.right
- cancel_width
- hspacing
;
1270 cancel_rc
.top
= dialog_rc
.bottom
- cancel_height
- vspacing
;
1271 cancel_rc
.right
= cancel_rc
.left
+ cancel_width
;
1272 cancel_rc
.bottom
= cancel_rc
.top
+ cancel_height
;
1275 /* Open/Save button */
1276 hwnd
= GetDlgItem(This
->dlg_hwnd
, IDOK
);
1279 int open_width
, open_height
;
1280 GetWindowRect(hwnd
, &open_rc
);
1281 open_width
= open_rc
.right
- open_rc
.left
;
1282 open_height
= open_rc
.bottom
- open_rc
.top
;
1284 open_rc
.left
= cancel_rc
.left
- open_width
- hspacing
;
1285 open_rc
.top
= cancel_rc
.top
;
1286 open_rc
.right
= open_rc
.left
+ open_width
;
1287 open_rc
.bottom
= open_rc
.top
+ open_height
;
1290 /* The filetype combobox. */
1291 hwnd
= GetDlgItem(This
->dlg_hwnd
, IDC_FILETYPE
);
1294 int filetype_width
, filetype_height
;
1295 GetWindowRect(hwnd
, &filetype_rc
);
1297 filetype_width
= filetype_rc
.right
- filetype_rc
.left
;
1298 filetype_height
= filetype_rc
.bottom
- filetype_rc
.top
;
1300 filetype_rc
.right
= cancel_rc
.right
;
1302 filetype_rc
.left
= filetype_rc
.right
- filetype_width
;
1303 filetype_rc
.top
= cancel_rc
.top
- filetype_height
- vspacing
;
1304 filetype_rc
.bottom
= filetype_rc
.top
+ filetype_height
;
1306 if(!This
->filterspec_count
)
1307 filetype_rc
.left
= filetype_rc
.right
;
1310 /* Filename label. */
1311 hwnd
= GetDlgItem(This
->dlg_hwnd
, IDC_FILENAMESTATIC
);
1314 int filetypelabel_width
, filetypelabel_height
;
1315 GetWindowRect(hwnd
, &filenamelabel_rc
);
1317 filetypelabel_width
= filenamelabel_rc
.right
- filenamelabel_rc
.left
;
1318 filetypelabel_height
= filenamelabel_rc
.bottom
- filenamelabel_rc
.top
;
1320 filenamelabel_rc
.left
= 160; /* FIXME */
1321 filenamelabel_rc
.top
= filetype_rc
.top
;
1322 filenamelabel_rc
.right
= filenamelabel_rc
.left
+ filetypelabel_width
;
1323 filenamelabel_rc
.bottom
= filenamelabel_rc
.top
+ filetypelabel_height
;
1326 /* Filename edit box. */
1327 hwnd
= GetDlgItem(This
->dlg_hwnd
, IDC_FILENAME
);
1330 int filename_width
, filename_height
;
1331 GetWindowRect(hwnd
, &filename_rc
);
1333 filename_width
= filetype_rc
.left
- filenamelabel_rc
.right
- hspacing
*2;
1334 filename_height
= filename_rc
.bottom
- filename_rc
.top
;
1336 filename_rc
.left
= filenamelabel_rc
.right
+ hspacing
;
1337 filename_rc
.top
= filetype_rc
.top
;
1338 filename_rc
.right
= filename_rc
.left
+ filename_width
;
1339 filename_rc
.bottom
= filename_rc
.top
+ filename_height
;
1342 hwnd
= GetDlgItem(This
->dlg_hwnd
, IDC_NAV_TOOLBAR
);
1345 GetWindowRect(hwnd
, &toolbar_rc
);
1346 MapWindowPoints(NULL
, This
->dlg_hwnd
, (POINT
*)&toolbar_rc
, 2);
1349 /* The custom controls */
1350 customctrls_rc
.left
= dialog_rc
.left
+ hspacing
;
1351 customctrls_rc
.right
= dialog_rc
.right
- hspacing
;
1352 customctrls_rc
.bottom
= filename_rc
.top
- vspacing
;
1353 customctrls_rc
.top
= customctrls_rc
.bottom
-
1354 ctrl_container_resize(This
, customctrls_rc
.right
- customctrls_rc
.left
);
1356 /* The ExplorerBrowser control. */
1357 ebrowser_rc
.left
= dialog_rc
.left
+ hspacing
;
1358 ebrowser_rc
.top
= toolbar_rc
.bottom
+ vspacing
;
1359 ebrowser_rc
.right
= dialog_rc
.right
- hspacing
;
1360 ebrowser_rc
.bottom
= customctrls_rc
.top
- vspacing
;
1363 * Move everything to the right place.
1366 /* FIXME: The Save Dialog uses a slightly different layout. */
1367 hdwp
= BeginDeferWindowPos(7);
1369 if(hdwp
&& This
->peb
)
1370 IExplorerBrowser_SetRect(This
->peb
, &hdwp
, ebrowser_rc
);
1372 if(hdwp
&& This
->cctrls_hwnd
)
1373 DeferWindowPos(hdwp
, This
->cctrls_hwnd
, NULL
,
1374 customctrls_rc
.left
, customctrls_rc
.top
,
1375 customctrls_rc
.right
- customctrls_rc
.left
, customctrls_rc
.bottom
- customctrls_rc
.top
,
1376 SWP_NOZORDER
| SWP_NOACTIVATE
);
1378 /* The default controls */
1379 if(hdwp
&& (hwnd
= GetDlgItem(This
->dlg_hwnd
, IDC_FILETYPE
)) )
1380 DeferWindowPos(hdwp
, hwnd
, NULL
, filetype_rc
.left
, filetype_rc
.top
, 0, 0,
1381 SWP_NOZORDER
| SWP_NOSIZE
| SWP_NOACTIVATE
);
1383 if(hdwp
&& (hwnd
= GetDlgItem(This
->dlg_hwnd
, IDC_FILENAME
)) )
1384 DeferWindowPos(hdwp
, hwnd
, NULL
, filename_rc
.left
, filename_rc
.top
,
1385 filename_rc
.right
- filename_rc
.left
, filename_rc
.bottom
- filename_rc
.top
,
1386 SWP_NOZORDER
| SWP_NOACTIVATE
);
1388 if(hdwp
&& (hwnd
= GetDlgItem(This
->dlg_hwnd
, IDC_FILENAMESTATIC
)) )
1389 DeferWindowPos(hdwp
, hwnd
, NULL
, filenamelabel_rc
.left
, filenamelabel_rc
.top
, 0, 0,
1390 SWP_NOZORDER
| SWP_NOSIZE
| SWP_NOACTIVATE
);
1392 if(hdwp
&& (hwnd
= GetDlgItem(This
->dlg_hwnd
, IDOK
)) )
1393 DeferWindowPos(hdwp
, hwnd
, NULL
, open_rc
.left
, open_rc
.top
, 0, 0,
1394 SWP_NOZORDER
| SWP_NOSIZE
| SWP_NOACTIVATE
);
1396 if(hdwp
&& (hwnd
= GetDlgItem(This
->dlg_hwnd
, IDCANCEL
)) )
1397 DeferWindowPos(hdwp
, hwnd
, NULL
, cancel_rc
.left
, cancel_rc
.top
, 0, 0,
1398 SWP_NOZORDER
| SWP_NOSIZE
| SWP_NOACTIVATE
);
1401 EndDeferWindowPos(hdwp
);
1403 ERR("Failed to position dialog controls.\n");
1405 ret
.cx
= 0; ret
.cy
= 0;
1409 static HRESULT
init_explorerbrowser(FileDialogImpl
*This
)
1411 IShellItem
*psi_folder
;
1416 /* Create ExplorerBrowser instance */
1417 OleInitialize(NULL
);
1419 hr
= CoCreateInstance(&CLSID_ExplorerBrowser
, NULL
, CLSCTX_INPROC_SERVER
,
1420 &IID_IExplorerBrowser
, (void**)&This
->peb
);
1423 ERR("Failed to instantiate ExplorerBrowser control.\n");
1427 IExplorerBrowser_SetOptions(This
->peb
, EBO_SHOWFRAMES
);
1429 hr
= IExplorerBrowser_Initialize(This
->peb
, This
->dlg_hwnd
, &rc
, NULL
);
1432 ERR("Failed to initialize the ExplorerBrowser control.\n");
1433 IExplorerBrowser_Release(This
->peb
);
1437 hr
= IExplorerBrowser_Advise(This
->peb
, &This
->IExplorerBrowserEvents_iface
, &This
->ebevents_cookie
);
1439 ERR("Advise (ExplorerBrowser) failed.\n");
1441 /* Get previous options? */
1442 fos
.ViewMode
= fos
.fFlags
= 0;
1443 if(!(This
->options
& FOS_ALLOWMULTISELECT
))
1444 fos
.fFlags
|= FWF_SINGLESEL
;
1446 IExplorerBrowser_SetFolderSettings(This
->peb
, &fos
);
1448 hr
= IUnknown_SetSite((IUnknown
*)This
->peb
, (IUnknown
*)This
);
1450 ERR("SetSite (ExplorerBrowser) failed.\n");
1452 /* Browse somewhere */
1453 psi_folder
= This
->psi_setfolder
? This
->psi_setfolder
: This
->psi_defaultfolder
;
1454 IExplorerBrowser_BrowseToObject(This
->peb
, (IUnknown
*)psi_folder
, SBSP_DEFBROWSER
);
1459 static void init_toolbar(FileDialogImpl
*This
, HWND hwnd
)
1465 htoolbar
= CreateWindowExW(0, TOOLBARCLASSNAMEW
, NULL
, TBSTYLE_FLAT
| WS_CHILD
| WS_VISIBLE
,
1467 hwnd
, (HMENU
)IDC_NAV_TOOLBAR
, NULL
, NULL
);
1469 tbab
.hInst
= HINST_COMMCTRL
;
1470 tbab
.nID
= IDB_HIST_LARGE_COLOR
;
1471 SendMessageW(htoolbar
, TB_ADDBITMAP
, 0, (LPARAM
)&tbab
);
1473 button
[0].iBitmap
= HIST_BACK
;
1474 button
[0].idCommand
= IDC_NAVBACK
;
1475 button
[0].fsState
= TBSTATE_ENABLED
;
1476 button
[0].fsStyle
= BTNS_BUTTON
;
1477 button
[0].dwData
= 0;
1478 button
[0].iString
= 0;
1480 button
[1].iBitmap
= HIST_FORWARD
;
1481 button
[1].idCommand
= IDC_NAVFORWARD
;
1482 button
[1].fsState
= TBSTATE_ENABLED
;
1483 button
[1].fsStyle
= BTNS_BUTTON
;
1484 button
[1].dwData
= 0;
1485 button
[1].iString
= 0;
1487 SendMessageW(htoolbar
, TB_ADDBUTTONSW
, 2, (LPARAM
)button
);
1488 SendMessageW(htoolbar
, TB_SETBUTTONSIZE
, 0, MAKELPARAM(24,24));
1489 SendMessageW(htoolbar
, TB_AUTOSIZE
, 0, 0);
1492 static void update_control_text(FileDialogImpl
*This
)
1495 if(This
->custom_title
)
1496 SetWindowTextW(This
->dlg_hwnd
, This
->custom_title
);
1498 if(This
->custom_okbutton
&&
1499 (hitem
= GetDlgItem(This
->dlg_hwnd
, IDOK
)))
1501 SetWindowTextW(hitem
, This
->custom_okbutton
);
1502 ctrl_resize(hitem
, 50, 250, FALSE
);
1505 if(This
->custom_cancelbutton
&&
1506 (hitem
= GetDlgItem(This
->dlg_hwnd
, IDCANCEL
)))
1508 SetWindowTextW(hitem
, This
->custom_cancelbutton
);
1509 ctrl_resize(hitem
, 50, 250, FALSE
);
1512 if(This
->custom_filenamelabel
&&
1513 (hitem
= GetDlgItem(This
->dlg_hwnd
, IDC_FILENAMESTATIC
)))
1515 SetWindowTextW(hitem
, This
->custom_filenamelabel
);
1516 ctrl_resize(hitem
, 50, 250, FALSE
);
1520 static LRESULT
on_wm_initdialog(HWND hwnd
, LPARAM lParam
)
1522 FileDialogImpl
*This
= (FileDialogImpl
*)lParam
;
1525 TRACE("(%p, %p)\n", This
, hwnd
);
1527 SetWindowLongPtrW(hwnd
, GWLP_USERDATA
, (LPARAM
)This
);
1528 This
->dlg_hwnd
= hwnd
;
1530 hitem
= GetDlgItem(This
->dlg_hwnd
, pshHelp
);
1531 if(hitem
) ShowWindow(hitem
, SW_HIDE
);
1533 hitem
= GetDlgItem(This
->dlg_hwnd
, IDC_FILETYPESTATIC
);
1534 if(hitem
) ShowWindow(hitem
, SW_HIDE
);
1536 /* Fill filetypes combobox, or hide it. */
1537 hitem
= GetDlgItem(This
->dlg_hwnd
, IDC_FILETYPE
);
1538 if(This
->filterspec_count
)
1543 UINT i
, maxwidth
= 0;
1546 font
= (HFONT
)SendMessageW(hitem
, WM_GETFONT
, 0, 0);
1547 SelectObject(hdc
, font
);
1549 for(i
= 0; i
< This
->filterspec_count
; i
++)
1551 SendMessageW(hitem
, CB_ADDSTRING
, 0, (LPARAM
)This
->filterspecs
[i
].pszName
);
1553 if(GetTextExtentPoint32W(hdc
, This
->filterspecs
[i
].pszName
, lstrlenW(This
->filterspecs
[i
].pszName
), &size
))
1554 maxwidth
= max(maxwidth
, size
.cx
);
1556 ReleaseDC(hitem
, hdc
);
1560 maxwidth
+= GetSystemMetrics(SM_CXVSCROLL
) + 4;
1561 SendMessageW(hitem
, CB_SETDROPPEDWIDTH
, (WPARAM
)maxwidth
, 0);
1564 ERR("Failed to calculate width of filetype dropdown\n");
1566 SendMessageW(hitem
, CB_SETCURSEL
, This
->filetypeindex
, 0);
1569 ShowWindow(hitem
, SW_HIDE
);
1571 if(This
->set_filename
&&
1572 (hitem
= GetDlgItem(This
->dlg_hwnd
, IDC_FILENAME
)) )
1573 SendMessageW(hitem
, WM_SETTEXT
, 0, (LPARAM
)This
->set_filename
);
1575 ctrl_container_reparent(This
, This
->dlg_hwnd
);
1576 init_explorerbrowser(This
);
1577 init_toolbar(This
, hwnd
);
1578 update_control_text(This
);
1579 update_layout(This
);
1581 if(This
->filterspec_count
)
1582 events_OnTypeChange(This
);
1587 static LRESULT
on_wm_size(FileDialogImpl
*This
)
1589 update_layout(This
);
1593 static LRESULT
on_wm_getminmaxinfo(FileDialogImpl
*This
, LPARAM lparam
)
1595 MINMAXINFO
*mmi
= (MINMAXINFO
*)lparam
;
1596 TRACE("%p (%p)\n", This
, mmi
);
1599 mmi
->ptMinTrackSize
.x
= 640;
1600 mmi
->ptMinTrackSize
.y
= 480;
1605 static LRESULT
on_wm_destroy(FileDialogImpl
*This
)
1607 TRACE("%p\n", This
);
1611 IExplorerBrowser_Destroy(This
->peb
);
1612 IExplorerBrowser_Release(This
->peb
);
1616 ctrl_container_reparent(This
, NULL
);
1617 This
->dlg_hwnd
= NULL
;
1622 static LRESULT
on_idok(FileDialogImpl
*This
)
1624 TRACE("%p\n", This
);
1626 if(SUCCEEDED(on_default_action(This
)))
1627 EndDialog(This
->dlg_hwnd
, S_OK
);
1632 static LRESULT
on_idcancel(FileDialogImpl
*This
)
1634 TRACE("%p\n", This
);
1636 EndDialog(This
->dlg_hwnd
, HRESULT_FROM_WIN32(ERROR_CANCELLED
));
1641 static LRESULT
on_browse_back(FileDialogImpl
*This
)
1643 TRACE("%p\n", This
);
1644 IExplorerBrowser_BrowseToIDList(This
->peb
, NULL
, SBSP_NAVIGATEBACK
);
1648 static LRESULT
on_browse_forward(FileDialogImpl
*This
)
1650 TRACE("%p\n", This
);
1651 IExplorerBrowser_BrowseToIDList(This
->peb
, NULL
, SBSP_NAVIGATEFORWARD
);
1655 static LRESULT
on_command_filetype(FileDialogImpl
*This
, WPARAM wparam
, LPARAM lparam
)
1657 if(HIWORD(wparam
) == CBN_SELCHANGE
)
1662 UINT prev_index
= This
->filetypeindex
;
1664 This
->filetypeindex
= SendMessageW((HWND
)lparam
, CB_GETCURSEL
, 0, 0);
1665 TRACE("File type selection changed to %d.\n", This
->filetypeindex
);
1667 if(prev_index
== This
->filetypeindex
)
1670 hr
= IExplorerBrowser_GetCurrentView(This
->peb
, &IID_IShellView
, (void**)&psv
);
1673 IShellView_Refresh(psv
);
1674 IShellView_Release(psv
);
1677 if(This
->dlg_type
== ITEMDLG_TYPE_SAVE
&& get_file_name(This
, &filename
))
1679 WCHAR buf
[MAX_PATH
], extbuf
[MAX_PATH
], *ext
;
1681 ext
= get_first_ext_from_spec(extbuf
, This
->filterspecs
[This
->filetypeindex
].pszSpec
);
1684 lstrcpyW(buf
, filename
);
1686 if(PathMatchSpecW(buf
, This
->filterspecs
[prev_index
].pszSpec
))
1687 PathRemoveExtensionW(buf
);
1690 set_file_name(This
, buf
);
1692 CoTaskMemFree(filename
);
1695 /* The documentation claims that OnTypeChange is called only
1696 * when the dialog is opened, but this is obviously not the
1698 events_OnTypeChange(This
);
1704 static LRESULT
on_wm_command(FileDialogImpl
*This
, WPARAM wparam
, LPARAM lparam
)
1706 switch(LOWORD(wparam
))
1708 case IDOK
: return on_idok(This
);
1709 case IDCANCEL
: return on_idcancel(This
);
1710 case IDC_NAVBACK
: return on_browse_back(This
);
1711 case IDC_NAVFORWARD
: return on_browse_forward(This
);
1712 case IDC_FILETYPE
: return on_command_filetype(This
, wparam
, lparam
);
1713 default: TRACE("Unknown command.\n");
1718 static LRESULT CALLBACK
itemdlg_dlgproc(HWND hwnd
, UINT umessage
, WPARAM wparam
, LPARAM lparam
)
1720 FileDialogImpl
*This
= (FileDialogImpl
*)GetWindowLongPtrW(hwnd
, GWLP_USERDATA
);
1724 case WM_INITDIALOG
: return on_wm_initdialog(hwnd
, lparam
);
1725 case WM_COMMAND
: return on_wm_command(This
, wparam
, lparam
);
1726 case WM_SIZE
: return on_wm_size(This
);
1727 case WM_GETMINMAXINFO
: return on_wm_getminmaxinfo(This
, lparam
);
1728 case WM_DESTROY
: return on_wm_destroy(This
);
1734 static HRESULT
create_dialog(FileDialogImpl
*This
, HWND parent
)
1739 res
= DialogBoxParamW(COMDLG32_hInstance
,
1740 MAKEINTRESOURCEW(NEWFILEOPENV3ORD
),
1741 parent
, itemdlg_dlgproc
, (LPARAM
)This
);
1742 This
->dlg_hwnd
= NULL
;
1745 ERR("Failed to show dialog (LastError: %d)\n", GetLastError());
1749 TRACE("Returning 0x%08x\n", (HRESULT
)res
);
1750 return (HRESULT
)res
;
1753 /**************************************************************************
1754 * IFileDialog implementation
1756 static inline FileDialogImpl
*impl_from_IFileDialog2(IFileDialog2
*iface
)
1758 return CONTAINING_RECORD(iface
, FileDialogImpl
, IFileDialog2_iface
);
1761 static HRESULT WINAPI
IFileDialog2_fnQueryInterface(IFileDialog2
*iface
,
1765 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1766 TRACE("%p (%s, %p)\n", This
, debugstr_guid(riid
), ppvObject
);
1769 if(IsEqualGUID(riid
, &IID_IUnknown
) ||
1770 IsEqualGUID(riid
, &IID_IFileDialog
) ||
1771 IsEqualGUID(riid
, &IID_IFileDialog2
))
1775 else if(IsEqualGUID(riid
, &IID_IFileOpenDialog
) && This
->dlg_type
== ITEMDLG_TYPE_OPEN
)
1777 *ppvObject
= &This
->u
.IFileOpenDialog_iface
;
1779 else if(IsEqualGUID(riid
, &IID_IFileSaveDialog
) && This
->dlg_type
== ITEMDLG_TYPE_SAVE
)
1781 *ppvObject
= &This
->u
.IFileSaveDialog_iface
;
1783 else if(IsEqualGUID(riid
, &IID_IExplorerBrowserEvents
))
1785 *ppvObject
= &This
->IExplorerBrowserEvents_iface
;
1787 else if(IsEqualGUID(riid
, &IID_IServiceProvider
))
1789 *ppvObject
= &This
->IServiceProvider_iface
;
1791 else if(IsEqualGUID(&IID_ICommDlgBrowser3
, riid
) ||
1792 IsEqualGUID(&IID_ICommDlgBrowser2
, riid
) ||
1793 IsEqualGUID(&IID_ICommDlgBrowser
, riid
))
1795 *ppvObject
= &This
->ICommDlgBrowser3_iface
;
1797 else if(IsEqualGUID(&IID_IOleWindow
, riid
))
1799 *ppvObject
= &This
->IOleWindow_iface
;
1801 else if(IsEqualGUID(riid
, &IID_IFileDialogCustomize
) ||
1802 IsEqualGUID(riid
, &IID_IFileDialogCustomizeAlt
))
1804 *ppvObject
= &This
->IFileDialogCustomize_iface
;
1807 FIXME("Unknown interface requested: %s.\n", debugstr_guid(riid
));
1811 IUnknown_AddRef((IUnknown
*)*ppvObject
);
1815 return E_NOINTERFACE
;
1818 static ULONG WINAPI
IFileDialog2_fnAddRef(IFileDialog2
*iface
)
1820 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1821 LONG ref
= InterlockedIncrement(&This
->ref
);
1822 TRACE("%p - ref %d\n", This
, ref
);
1827 static ULONG WINAPI
IFileDialog2_fnRelease(IFileDialog2
*iface
)
1829 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1830 LONG ref
= InterlockedDecrement(&This
->ref
);
1831 TRACE("%p - ref %d\n", This
, ref
);
1836 for(i
= 0; i
< This
->filterspec_count
; i
++)
1838 LocalFree((void*)This
->filterspecs
[i
].pszName
);
1839 LocalFree((void*)This
->filterspecs
[i
].pszSpec
);
1841 HeapFree(GetProcessHeap(), 0, This
->filterspecs
);
1843 DestroyWindow(This
->cctrls_hwnd
);
1845 if(This
->psi_defaultfolder
) IShellItem_Release(This
->psi_defaultfolder
);
1846 if(This
->psi_setfolder
) IShellItem_Release(This
->psi_setfolder
);
1847 if(This
->psi_folder
) IShellItem_Release(This
->psi_folder
);
1848 if(This
->psia_selection
) IShellItemArray_Release(This
->psia_selection
);
1849 if(This
->psia_results
) IShellItemArray_Release(This
->psia_results
);
1851 LocalFree(This
->set_filename
);
1852 LocalFree(This
->default_ext
);
1853 LocalFree(This
->custom_title
);
1854 LocalFree(This
->custom_okbutton
);
1855 LocalFree(This
->custom_cancelbutton
);
1856 LocalFree(This
->custom_filenamelabel
);
1858 HeapFree(GetProcessHeap(), 0, This
);
1864 static HRESULT WINAPI
IFileDialog2_fnShow(IFileDialog2
*iface
, HWND hwndOwner
)
1866 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1867 TRACE("%p (%p)\n", iface
, hwndOwner
);
1869 return create_dialog(This
, hwndOwner
);
1872 static HRESULT WINAPI
IFileDialog2_fnSetFileTypes(IFileDialog2
*iface
, UINT cFileTypes
,
1873 const COMDLG_FILTERSPEC
*rgFilterSpec
)
1875 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1877 TRACE("%p (%d, %p)\n", This
, cFileTypes
, rgFilterSpec
);
1879 if(This
->filterspecs
)
1880 return E_UNEXPECTED
;
1883 return E_INVALIDARG
;
1888 This
->filterspecs
= HeapAlloc(GetProcessHeap(), 0, sizeof(COMDLG_FILTERSPEC
)*cFileTypes
);
1889 for(i
= 0; i
< cFileTypes
; i
++)
1891 This
->filterspecs
[i
].pszName
= StrDupW(rgFilterSpec
[i
].pszName
);
1892 This
->filterspecs
[i
].pszSpec
= StrDupW(rgFilterSpec
[i
].pszSpec
);
1894 This
->filterspec_count
= cFileTypes
;
1899 static HRESULT WINAPI
IFileDialog2_fnSetFileTypeIndex(IFileDialog2
*iface
, UINT iFileType
)
1901 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1902 TRACE("%p (%d)\n", This
, iFileType
);
1904 if(!This
->filterspecs
)
1907 iFileType
= max(iFileType
, 1);
1908 iFileType
= min(iFileType
, This
->filterspec_count
);
1909 This
->filetypeindex
= iFileType
-1;
1914 static HRESULT WINAPI
IFileDialog2_fnGetFileTypeIndex(IFileDialog2
*iface
, UINT
*piFileType
)
1916 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1917 TRACE("%p (%p)\n", This
, piFileType
);
1920 return E_INVALIDARG
;
1922 if(This
->filterspec_count
== 0)
1925 *piFileType
= This
->filetypeindex
+ 1;
1930 static HRESULT WINAPI
IFileDialog2_fnAdvise(IFileDialog2
*iface
, IFileDialogEvents
*pfde
, DWORD
*pdwCookie
)
1932 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1933 events_client
*client
;
1934 TRACE("%p (%p, %p)\n", This
, pfde
, pdwCookie
);
1936 if(!pfde
|| !pdwCookie
)
1937 return E_INVALIDARG
;
1939 client
= HeapAlloc(GetProcessHeap(), 0, sizeof(events_client
));
1940 client
->pfde
= pfde
;
1941 client
->cookie
= ++This
->events_next_cookie
;
1943 IFileDialogEvents_AddRef(pfde
);
1944 *pdwCookie
= client
->cookie
;
1946 list_add_tail(&This
->events_clients
, &client
->entry
);
1951 static HRESULT WINAPI
IFileDialog2_fnUnadvise(IFileDialog2
*iface
, DWORD dwCookie
)
1953 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1954 events_client
*client
, *found
= NULL
;
1955 TRACE("%p (%d)\n", This
, dwCookie
);
1957 LIST_FOR_EACH_ENTRY(client
, &This
->events_clients
, events_client
, entry
)
1959 if(client
->cookie
== dwCookie
)
1968 list_remove(&found
->entry
);
1969 IFileDialogEvents_Release(found
->pfde
);
1970 HeapFree(GetProcessHeap(), 0, found
);
1974 return E_INVALIDARG
;
1977 static HRESULT WINAPI
IFileDialog2_fnSetOptions(IFileDialog2
*iface
, FILEOPENDIALOGOPTIONS fos
)
1979 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1980 TRACE("%p (0x%x)\n", This
, fos
);
1982 if( !(This
->options
& FOS_PICKFOLDERS
) && (fos
& FOS_PICKFOLDERS
) )
1985 LoadStringW(COMDLG32_hInstance
, IDS_SELECT_FOLDER
, buf
, sizeof(buf
)/sizeof(WCHAR
));
1986 IFileDialog2_SetTitle(iface
, buf
);
1989 This
->options
= fos
;
1994 static HRESULT WINAPI
IFileDialog2_fnGetOptions(IFileDialog2
*iface
, FILEOPENDIALOGOPTIONS
*pfos
)
1996 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1997 TRACE("%p (%p)\n", This
, pfos
);
2000 return E_INVALIDARG
;
2002 *pfos
= This
->options
;
2007 static HRESULT WINAPI
IFileDialog2_fnSetDefaultFolder(IFileDialog2
*iface
, IShellItem
*psi
)
2009 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2010 TRACE("%p (%p)\n", This
, psi
);
2011 if(This
->psi_defaultfolder
)
2012 IShellItem_Release(This
->psi_defaultfolder
);
2014 This
->psi_defaultfolder
= psi
;
2016 if(This
->psi_defaultfolder
)
2017 IShellItem_AddRef(This
->psi_defaultfolder
);
2022 static HRESULT WINAPI
IFileDialog2_fnSetFolder(IFileDialog2
*iface
, IShellItem
*psi
)
2024 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2025 TRACE("%p (%p)\n", This
, psi
);
2026 if(This
->psi_setfolder
)
2027 IShellItem_Release(This
->psi_setfolder
);
2029 This
->psi_setfolder
= psi
;
2031 if(This
->psi_setfolder
)
2032 IShellItem_AddRef(This
->psi_setfolder
);
2037 static HRESULT WINAPI
IFileDialog2_fnGetFolder(IFileDialog2
*iface
, IShellItem
**ppsi
)
2039 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2040 TRACE("%p (%p)\n", This
, ppsi
);
2042 return E_INVALIDARG
;
2045 If the dialog is shown, return the current(ly selected) folder. */
2048 if(This
->psi_folder
)
2049 *ppsi
= This
->psi_folder
;
2050 else if(This
->psi_setfolder
)
2051 *ppsi
= This
->psi_setfolder
;
2052 else if(This
->psi_defaultfolder
)
2053 *ppsi
= This
->psi_defaultfolder
;
2057 IShellItem_AddRef(*ppsi
);
2064 static HRESULT WINAPI
IFileDialog2_fnGetCurrentSelection(IFileDialog2
*iface
, IShellItem
**ppsi
)
2066 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2068 TRACE("%p (%p)\n", This
, ppsi
);
2071 return E_INVALIDARG
;
2073 if(This
->psia_selection
)
2075 /* FIXME: Check filename edit box */
2076 hr
= IShellItemArray_GetItemAt(This
->psia_selection
, 0, ppsi
);
2083 static HRESULT WINAPI
IFileDialog2_fnSetFileName(IFileDialog2
*iface
, LPCWSTR pszName
)
2085 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2086 TRACE("%p (%s)\n", iface
, debugstr_w(pszName
));
2088 set_file_name(This
, pszName
);
2093 static HRESULT WINAPI
IFileDialog2_fnGetFileName(IFileDialog2
*iface
, LPWSTR
*pszName
)
2095 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2096 TRACE("%p (%p)\n", iface
, pszName
);
2099 return E_INVALIDARG
;
2102 if(get_file_name(This
, pszName
))
2108 static HRESULT WINAPI
IFileDialog2_fnSetTitle(IFileDialog2
*iface
, LPCWSTR pszTitle
)
2110 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2111 TRACE("%p (%s)\n", This
, debugstr_w(pszTitle
));
2113 LocalFree(This
->custom_title
);
2114 This
->custom_title
= StrDupW(pszTitle
);
2115 update_control_text(This
);
2120 static HRESULT WINAPI
IFileDialog2_fnSetOkButtonLabel(IFileDialog2
*iface
, LPCWSTR pszText
)
2122 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2123 TRACE("%p (%s)\n", This
, debugstr_w(pszText
));
2125 LocalFree(This
->custom_okbutton
);
2126 This
->custom_okbutton
= StrDupW(pszText
);
2127 update_control_text(This
);
2128 update_layout(This
);
2133 static HRESULT WINAPI
IFileDialog2_fnSetFileNameLabel(IFileDialog2
*iface
, LPCWSTR pszLabel
)
2135 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2136 TRACE("%p (%s)\n", This
, debugstr_w(pszLabel
));
2138 LocalFree(This
->custom_filenamelabel
);
2139 This
->custom_filenamelabel
= StrDupW(pszLabel
);
2140 update_control_text(This
);
2141 update_layout(This
);
2146 static HRESULT WINAPI
IFileDialog2_fnGetResult(IFileDialog2
*iface
, IShellItem
**ppsi
)
2148 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2150 TRACE("%p (%p)\n", This
, ppsi
);
2153 return E_INVALIDARG
;
2155 if(This
->psia_results
)
2158 hr
= IShellItemArray_GetCount(This
->psia_results
, &item_count
);
2164 /* Adds a reference. */
2165 hr
= IShellItemArray_GetItemAt(This
->psia_results
, 0, ppsi
);
2171 return E_UNEXPECTED
;
2174 static HRESULT WINAPI
IFileDialog2_fnAddPlace(IFileDialog2
*iface
, IShellItem
*psi
, FDAP fdap
)
2176 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2177 FIXME("stub - %p (%p, %d)\n", This
, psi
, fdap
);
2181 static HRESULT WINAPI
IFileDialog2_fnSetDefaultExtension(IFileDialog2
*iface
, LPCWSTR pszDefaultExtension
)
2183 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2184 TRACE("%p (%s)\n", This
, debugstr_w(pszDefaultExtension
));
2186 LocalFree(This
->default_ext
);
2187 This
->default_ext
= StrDupW(pszDefaultExtension
);
2192 static HRESULT WINAPI
IFileDialog2_fnClose(IFileDialog2
*iface
, HRESULT hr
)
2194 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2195 TRACE("%p (0x%08x)\n", This
, hr
);
2198 EndDialog(This
->dlg_hwnd
, hr
);
2203 static HRESULT WINAPI
IFileDialog2_fnSetClientGuid(IFileDialog2
*iface
, REFGUID guid
)
2205 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2206 TRACE("%p (%s)\n", This
, debugstr_guid(guid
));
2207 This
->client_guid
= *guid
;
2211 static HRESULT WINAPI
IFileDialog2_fnClearClientData(IFileDialog2
*iface
)
2213 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2214 FIXME("stub - %p\n", This
);
2218 static HRESULT WINAPI
IFileDialog2_fnSetFilter(IFileDialog2
*iface
, IShellItemFilter
*pFilter
)
2220 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2221 FIXME("stub - %p (%p)\n", This
, pFilter
);
2225 static HRESULT WINAPI
IFileDialog2_fnSetCancelButtonLabel(IFileDialog2
*iface
, LPCWSTR pszLabel
)
2227 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2228 TRACE("%p (%s)\n", This
, debugstr_w(pszLabel
));
2230 LocalFree(This
->custom_cancelbutton
);
2231 This
->custom_cancelbutton
= StrDupW(pszLabel
);
2232 update_control_text(This
);
2233 update_layout(This
);
2238 static HRESULT WINAPI
IFileDialog2_fnSetNavigationRoot(IFileDialog2
*iface
, IShellItem
*psi
)
2240 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2241 FIXME("stub - %p (%p)\n", This
, psi
);
2245 static const IFileDialog2Vtbl vt_IFileDialog2
= {
2246 IFileDialog2_fnQueryInterface
,
2247 IFileDialog2_fnAddRef
,
2248 IFileDialog2_fnRelease
,
2249 IFileDialog2_fnShow
,
2250 IFileDialog2_fnSetFileTypes
,
2251 IFileDialog2_fnSetFileTypeIndex
,
2252 IFileDialog2_fnGetFileTypeIndex
,
2253 IFileDialog2_fnAdvise
,
2254 IFileDialog2_fnUnadvise
,
2255 IFileDialog2_fnSetOptions
,
2256 IFileDialog2_fnGetOptions
,
2257 IFileDialog2_fnSetDefaultFolder
,
2258 IFileDialog2_fnSetFolder
,
2259 IFileDialog2_fnGetFolder
,
2260 IFileDialog2_fnGetCurrentSelection
,
2261 IFileDialog2_fnSetFileName
,
2262 IFileDialog2_fnGetFileName
,
2263 IFileDialog2_fnSetTitle
,
2264 IFileDialog2_fnSetOkButtonLabel
,
2265 IFileDialog2_fnSetFileNameLabel
,
2266 IFileDialog2_fnGetResult
,
2267 IFileDialog2_fnAddPlace
,
2268 IFileDialog2_fnSetDefaultExtension
,
2269 IFileDialog2_fnClose
,
2270 IFileDialog2_fnSetClientGuid
,
2271 IFileDialog2_fnClearClientData
,
2272 IFileDialog2_fnSetFilter
,
2273 IFileDialog2_fnSetCancelButtonLabel
,
2274 IFileDialog2_fnSetNavigationRoot
2277 /**************************************************************************
2280 static inline FileDialogImpl
*impl_from_IFileOpenDialog(IFileOpenDialog
*iface
)
2282 return CONTAINING_RECORD(iface
, FileDialogImpl
, u
.IFileOpenDialog_iface
);
2285 static HRESULT WINAPI
IFileOpenDialog_fnQueryInterface(IFileOpenDialog
*iface
,
2286 REFIID riid
, void **ppvObject
)
2288 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2289 return IFileDialog2_QueryInterface(&This
->IFileDialog2_iface
, riid
, ppvObject
);
2292 static ULONG WINAPI
IFileOpenDialog_fnAddRef(IFileOpenDialog
*iface
)
2294 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2295 return IFileDialog2_AddRef(&This
->IFileDialog2_iface
);
2298 static ULONG WINAPI
IFileOpenDialog_fnRelease(IFileOpenDialog
*iface
)
2300 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2301 return IFileDialog2_Release(&This
->IFileDialog2_iface
);
2304 static HRESULT WINAPI
IFileOpenDialog_fnShow(IFileOpenDialog
*iface
, HWND hwndOwner
)
2306 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2307 return IFileDialog2_Show(&This
->IFileDialog2_iface
, hwndOwner
);
2310 static HRESULT WINAPI
IFileOpenDialog_fnSetFileTypes(IFileOpenDialog
*iface
, UINT cFileTypes
,
2311 const COMDLG_FILTERSPEC
*rgFilterSpec
)
2313 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2314 return IFileDialog2_SetFileTypes(&This
->IFileDialog2_iface
, cFileTypes
, rgFilterSpec
);
2317 static HRESULT WINAPI
IFileOpenDialog_fnSetFileTypeIndex(IFileOpenDialog
*iface
, UINT iFileType
)
2319 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2320 return IFileDialog2_SetFileTypeIndex(&This
->IFileDialog2_iface
, iFileType
);
2323 static HRESULT WINAPI
IFileOpenDialog_fnGetFileTypeIndex(IFileOpenDialog
*iface
, UINT
*piFileType
)
2325 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2326 return IFileDialog2_GetFileTypeIndex(&This
->IFileDialog2_iface
, piFileType
);
2329 static HRESULT WINAPI
IFileOpenDialog_fnAdvise(IFileOpenDialog
*iface
, IFileDialogEvents
*pfde
,
2332 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2333 return IFileDialog2_Advise(&This
->IFileDialog2_iface
, pfde
, pdwCookie
);
2336 static HRESULT WINAPI
IFileOpenDialog_fnUnadvise(IFileOpenDialog
*iface
, DWORD dwCookie
)
2338 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2339 return IFileDialog2_Unadvise(&This
->IFileDialog2_iface
, dwCookie
);
2342 static HRESULT WINAPI
IFileOpenDialog_fnSetOptions(IFileOpenDialog
*iface
, FILEOPENDIALOGOPTIONS fos
)
2344 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2345 return IFileDialog2_SetOptions(&This
->IFileDialog2_iface
, fos
);
2348 static HRESULT WINAPI
IFileOpenDialog_fnGetOptions(IFileOpenDialog
*iface
, FILEOPENDIALOGOPTIONS
*pfos
)
2350 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2351 return IFileDialog2_GetOptions(&This
->IFileDialog2_iface
, pfos
);
2354 static HRESULT WINAPI
IFileOpenDialog_fnSetDefaultFolder(IFileOpenDialog
*iface
, IShellItem
*psi
)
2356 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2357 return IFileDialog2_SetDefaultFolder(&This
->IFileDialog2_iface
, psi
);
2360 static HRESULT WINAPI
IFileOpenDialog_fnSetFolder(IFileOpenDialog
*iface
, IShellItem
*psi
)
2362 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2363 return IFileDialog2_SetFolder(&This
->IFileDialog2_iface
, psi
);
2366 static HRESULT WINAPI
IFileOpenDialog_fnGetFolder(IFileOpenDialog
*iface
, IShellItem
**ppsi
)
2368 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2369 return IFileDialog2_GetFolder(&This
->IFileDialog2_iface
, ppsi
);
2372 static HRESULT WINAPI
IFileOpenDialog_fnGetCurrentSelection(IFileOpenDialog
*iface
, IShellItem
**ppsi
)
2374 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2375 return IFileDialog2_GetCurrentSelection(&This
->IFileDialog2_iface
, ppsi
);
2378 static HRESULT WINAPI
IFileOpenDialog_fnSetFileName(IFileOpenDialog
*iface
, LPCWSTR pszName
)
2380 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2381 return IFileDialog2_SetFileName(&This
->IFileDialog2_iface
, pszName
);
2384 static HRESULT WINAPI
IFileOpenDialog_fnGetFileName(IFileOpenDialog
*iface
, LPWSTR
*pszName
)
2386 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2387 return IFileDialog2_GetFileName(&This
->IFileDialog2_iface
, pszName
);
2390 static HRESULT WINAPI
IFileOpenDialog_fnSetTitle(IFileOpenDialog
*iface
, LPCWSTR pszTitle
)
2392 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2393 return IFileDialog2_SetTitle(&This
->IFileDialog2_iface
, pszTitle
);
2396 static HRESULT WINAPI
IFileOpenDialog_fnSetOkButtonLabel(IFileOpenDialog
*iface
, LPCWSTR pszText
)
2398 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2399 return IFileDialog2_SetOkButtonLabel(&This
->IFileDialog2_iface
, pszText
);
2402 static HRESULT WINAPI
IFileOpenDialog_fnSetFileNameLabel(IFileOpenDialog
*iface
, LPCWSTR pszLabel
)
2404 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2405 return IFileDialog2_SetFileNameLabel(&This
->IFileDialog2_iface
, pszLabel
);
2408 static HRESULT WINAPI
IFileOpenDialog_fnGetResult(IFileOpenDialog
*iface
, IShellItem
**ppsi
)
2410 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2411 return IFileDialog2_GetResult(&This
->IFileDialog2_iface
, ppsi
);
2414 static HRESULT WINAPI
IFileOpenDialog_fnAddPlace(IFileOpenDialog
*iface
, IShellItem
*psi
, FDAP fdap
)
2416 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2417 return IFileDialog2_AddPlace(&This
->IFileDialog2_iface
, psi
, fdap
);
2420 static HRESULT WINAPI
IFileOpenDialog_fnSetDefaultExtension(IFileOpenDialog
*iface
,
2421 LPCWSTR pszDefaultExtension
)
2423 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2424 return IFileDialog2_SetDefaultExtension(&This
->IFileDialog2_iface
, pszDefaultExtension
);
2427 static HRESULT WINAPI
IFileOpenDialog_fnClose(IFileOpenDialog
*iface
, HRESULT hr
)
2429 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2430 return IFileDialog2_Close(&This
->IFileDialog2_iface
, hr
);
2433 static HRESULT WINAPI
IFileOpenDialog_fnSetClientGuid(IFileOpenDialog
*iface
, REFGUID guid
)
2435 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2436 return IFileDialog2_SetClientGuid(&This
->IFileDialog2_iface
, guid
);
2439 static HRESULT WINAPI
IFileOpenDialog_fnClearClientData(IFileOpenDialog
*iface
)
2441 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2442 return IFileDialog2_ClearClientData(&This
->IFileDialog2_iface
);
2445 static HRESULT WINAPI
IFileOpenDialog_fnSetFilter(IFileOpenDialog
*iface
, IShellItemFilter
*pFilter
)
2447 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2448 return IFileDialog2_SetFilter(&This
->IFileDialog2_iface
, pFilter
);
2451 static HRESULT WINAPI
IFileOpenDialog_fnGetResults(IFileOpenDialog
*iface
, IShellItemArray
**ppenum
)
2453 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2454 TRACE("%p (%p)\n", This
, ppenum
);
2456 *ppenum
= This
->psia_results
;
2460 IShellItemArray_AddRef(*ppenum
);
2467 static HRESULT WINAPI
IFileOpenDialog_fnGetSelectedItems(IFileOpenDialog
*iface
, IShellItemArray
**ppsai
)
2469 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2470 TRACE("%p (%p)\n", This
, ppsai
);
2472 if(This
->psia_selection
)
2474 *ppsai
= This
->psia_selection
;
2475 IShellItemArray_AddRef(*ppsai
);
2482 static const IFileOpenDialogVtbl vt_IFileOpenDialog
= {
2483 IFileOpenDialog_fnQueryInterface
,
2484 IFileOpenDialog_fnAddRef
,
2485 IFileOpenDialog_fnRelease
,
2486 IFileOpenDialog_fnShow
,
2487 IFileOpenDialog_fnSetFileTypes
,
2488 IFileOpenDialog_fnSetFileTypeIndex
,
2489 IFileOpenDialog_fnGetFileTypeIndex
,
2490 IFileOpenDialog_fnAdvise
,
2491 IFileOpenDialog_fnUnadvise
,
2492 IFileOpenDialog_fnSetOptions
,
2493 IFileOpenDialog_fnGetOptions
,
2494 IFileOpenDialog_fnSetDefaultFolder
,
2495 IFileOpenDialog_fnSetFolder
,
2496 IFileOpenDialog_fnGetFolder
,
2497 IFileOpenDialog_fnGetCurrentSelection
,
2498 IFileOpenDialog_fnSetFileName
,
2499 IFileOpenDialog_fnGetFileName
,
2500 IFileOpenDialog_fnSetTitle
,
2501 IFileOpenDialog_fnSetOkButtonLabel
,
2502 IFileOpenDialog_fnSetFileNameLabel
,
2503 IFileOpenDialog_fnGetResult
,
2504 IFileOpenDialog_fnAddPlace
,
2505 IFileOpenDialog_fnSetDefaultExtension
,
2506 IFileOpenDialog_fnClose
,
2507 IFileOpenDialog_fnSetClientGuid
,
2508 IFileOpenDialog_fnClearClientData
,
2509 IFileOpenDialog_fnSetFilter
,
2510 IFileOpenDialog_fnGetResults
,
2511 IFileOpenDialog_fnGetSelectedItems
2514 /**************************************************************************
2517 static inline FileDialogImpl
*impl_from_IFileSaveDialog(IFileSaveDialog
*iface
)
2519 return CONTAINING_RECORD(iface
, FileDialogImpl
, u
.IFileSaveDialog_iface
);
2522 static HRESULT WINAPI
IFileSaveDialog_fnQueryInterface(IFileSaveDialog
*iface
,
2526 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2527 return IFileDialog2_QueryInterface(&This
->IFileDialog2_iface
, riid
, ppvObject
);
2530 static ULONG WINAPI
IFileSaveDialog_fnAddRef(IFileSaveDialog
*iface
)
2532 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2533 return IFileDialog2_AddRef(&This
->IFileDialog2_iface
);
2536 static ULONG WINAPI
IFileSaveDialog_fnRelease(IFileSaveDialog
*iface
)
2538 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2539 return IFileDialog2_Release(&This
->IFileDialog2_iface
);
2542 static HRESULT WINAPI
IFileSaveDialog_fnShow(IFileSaveDialog
*iface
, HWND hwndOwner
)
2544 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2545 return IFileDialog2_Show(&This
->IFileDialog2_iface
, hwndOwner
);
2548 static HRESULT WINAPI
IFileSaveDialog_fnSetFileTypes(IFileSaveDialog
*iface
, UINT cFileTypes
,
2549 const COMDLG_FILTERSPEC
*rgFilterSpec
)
2551 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2552 return IFileDialog2_SetFileTypes(&This
->IFileDialog2_iface
, cFileTypes
, rgFilterSpec
);
2555 static HRESULT WINAPI
IFileSaveDialog_fnSetFileTypeIndex(IFileSaveDialog
*iface
, UINT iFileType
)
2557 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2558 return IFileDialog2_SetFileTypeIndex(&This
->IFileDialog2_iface
, iFileType
);
2561 static HRESULT WINAPI
IFileSaveDialog_fnGetFileTypeIndex(IFileSaveDialog
*iface
, UINT
*piFileType
)
2563 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2564 return IFileDialog2_GetFileTypeIndex(&This
->IFileDialog2_iface
, piFileType
);
2567 static HRESULT WINAPI
IFileSaveDialog_fnAdvise(IFileSaveDialog
*iface
, IFileDialogEvents
*pfde
,
2570 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2571 return IFileDialog2_Advise(&This
->IFileDialog2_iface
, pfde
, pdwCookie
);
2574 static HRESULT WINAPI
IFileSaveDialog_fnUnadvise(IFileSaveDialog
*iface
, DWORD dwCookie
)
2576 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2577 return IFileDialog2_Unadvise(&This
->IFileDialog2_iface
, dwCookie
);
2580 static HRESULT WINAPI
IFileSaveDialog_fnSetOptions(IFileSaveDialog
*iface
, FILEOPENDIALOGOPTIONS fos
)
2582 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2583 return IFileDialog2_SetOptions(&This
->IFileDialog2_iface
, fos
);
2586 static HRESULT WINAPI
IFileSaveDialog_fnGetOptions(IFileSaveDialog
*iface
, FILEOPENDIALOGOPTIONS
*pfos
)
2588 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2589 return IFileDialog2_GetOptions(&This
->IFileDialog2_iface
, pfos
);
2592 static HRESULT WINAPI
IFileSaveDialog_fnSetDefaultFolder(IFileSaveDialog
*iface
, IShellItem
*psi
)
2594 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2595 return IFileDialog2_SetDefaultFolder(&This
->IFileDialog2_iface
, psi
);
2598 static HRESULT WINAPI
IFileSaveDialog_fnSetFolder(IFileSaveDialog
*iface
, IShellItem
*psi
)
2600 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2601 return IFileDialog2_SetFolder(&This
->IFileDialog2_iface
, psi
);
2604 static HRESULT WINAPI
IFileSaveDialog_fnGetFolder(IFileSaveDialog
*iface
, IShellItem
**ppsi
)
2606 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2607 return IFileDialog2_GetFolder(&This
->IFileDialog2_iface
, ppsi
);
2610 static HRESULT WINAPI
IFileSaveDialog_fnGetCurrentSelection(IFileSaveDialog
*iface
, IShellItem
**ppsi
)
2612 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2613 return IFileDialog2_GetCurrentSelection(&This
->IFileDialog2_iface
, ppsi
);
2616 static HRESULT WINAPI
IFileSaveDialog_fnSetFileName(IFileSaveDialog
*iface
, LPCWSTR pszName
)
2618 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2619 return IFileDialog2_SetFileName(&This
->IFileDialog2_iface
, pszName
);
2622 static HRESULT WINAPI
IFileSaveDialog_fnGetFileName(IFileSaveDialog
*iface
, LPWSTR
*pszName
)
2624 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2625 return IFileDialog2_GetFileName(&This
->IFileDialog2_iface
, pszName
);
2628 static HRESULT WINAPI
IFileSaveDialog_fnSetTitle(IFileSaveDialog
*iface
, LPCWSTR pszTitle
)
2630 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2631 return IFileDialog2_SetTitle(&This
->IFileDialog2_iface
, pszTitle
);
2634 static HRESULT WINAPI
IFileSaveDialog_fnSetOkButtonLabel(IFileSaveDialog
*iface
, LPCWSTR pszText
)
2636 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2637 return IFileDialog2_SetOkButtonLabel(&This
->IFileDialog2_iface
, pszText
);
2640 static HRESULT WINAPI
IFileSaveDialog_fnSetFileNameLabel(IFileSaveDialog
*iface
, LPCWSTR pszLabel
)
2642 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2643 return IFileDialog2_SetFileNameLabel(&This
->IFileDialog2_iface
, pszLabel
);
2646 static HRESULT WINAPI
IFileSaveDialog_fnGetResult(IFileSaveDialog
*iface
, IShellItem
**ppsi
)
2648 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2649 return IFileDialog2_GetResult(&This
->IFileDialog2_iface
, ppsi
);
2652 static HRESULT WINAPI
IFileSaveDialog_fnAddPlace(IFileSaveDialog
*iface
, IShellItem
*psi
, FDAP fdap
)
2654 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2655 return IFileDialog2_AddPlace(&This
->IFileDialog2_iface
, psi
, fdap
);
2658 static HRESULT WINAPI
IFileSaveDialog_fnSetDefaultExtension(IFileSaveDialog
*iface
,
2659 LPCWSTR pszDefaultExtension
)
2661 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2662 return IFileDialog2_SetDefaultExtension(&This
->IFileDialog2_iface
, pszDefaultExtension
);
2665 static HRESULT WINAPI
IFileSaveDialog_fnClose(IFileSaveDialog
*iface
, HRESULT hr
)
2667 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2668 return IFileDialog2_Close(&This
->IFileDialog2_iface
, hr
);
2671 static HRESULT WINAPI
IFileSaveDialog_fnSetClientGuid(IFileSaveDialog
*iface
, REFGUID guid
)
2673 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2674 return IFileDialog2_SetClientGuid(&This
->IFileDialog2_iface
, guid
);
2677 static HRESULT WINAPI
IFileSaveDialog_fnClearClientData(IFileSaveDialog
*iface
)
2679 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2680 return IFileDialog2_ClearClientData(&This
->IFileDialog2_iface
);
2683 static HRESULT WINAPI
IFileSaveDialog_fnSetFilter(IFileSaveDialog
*iface
, IShellItemFilter
*pFilter
)
2685 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2686 return IFileDialog2_SetFilter(&This
->IFileDialog2_iface
, pFilter
);
2689 static HRESULT WINAPI
IFileSaveDialog_fnSetSaveAsItem(IFileSaveDialog
* iface
, IShellItem
*psi
)
2691 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2692 FIXME("stub - %p (%p)\n", This
, psi
);
2696 static HRESULT WINAPI
IFileSaveDialog_fnSetProperties(IFileSaveDialog
* iface
, IPropertyStore
*pStore
)
2698 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2699 FIXME("stub - %p (%p)\n", This
, pStore
);
2703 static HRESULT WINAPI
IFileSaveDialog_fnSetCollectedProperties(IFileSaveDialog
* iface
,
2704 IPropertyDescriptionList
*pList
,
2705 BOOL fAppendDefault
)
2707 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2708 FIXME("stub - %p (%p, %d)\n", This
, pList
, fAppendDefault
);
2712 static HRESULT WINAPI
IFileSaveDialog_fnGetProperties(IFileSaveDialog
* iface
, IPropertyStore
**ppStore
)
2714 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2715 FIXME("stub - %p (%p)\n", This
, ppStore
);
2719 static HRESULT WINAPI
IFileSaveDialog_fnApplyProperties(IFileSaveDialog
* iface
,
2721 IPropertyStore
*pStore
,
2723 IFileOperationProgressSink
*pSink
)
2725 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2726 FIXME("%p (%p, %p, %p, %p)\n", This
, psi
, pStore
, hwnd
, pSink
);
2730 static const IFileSaveDialogVtbl vt_IFileSaveDialog
= {
2731 IFileSaveDialog_fnQueryInterface
,
2732 IFileSaveDialog_fnAddRef
,
2733 IFileSaveDialog_fnRelease
,
2734 IFileSaveDialog_fnShow
,
2735 IFileSaveDialog_fnSetFileTypes
,
2736 IFileSaveDialog_fnSetFileTypeIndex
,
2737 IFileSaveDialog_fnGetFileTypeIndex
,
2738 IFileSaveDialog_fnAdvise
,
2739 IFileSaveDialog_fnUnadvise
,
2740 IFileSaveDialog_fnSetOptions
,
2741 IFileSaveDialog_fnGetOptions
,
2742 IFileSaveDialog_fnSetDefaultFolder
,
2743 IFileSaveDialog_fnSetFolder
,
2744 IFileSaveDialog_fnGetFolder
,
2745 IFileSaveDialog_fnGetCurrentSelection
,
2746 IFileSaveDialog_fnSetFileName
,
2747 IFileSaveDialog_fnGetFileName
,
2748 IFileSaveDialog_fnSetTitle
,
2749 IFileSaveDialog_fnSetOkButtonLabel
,
2750 IFileSaveDialog_fnSetFileNameLabel
,
2751 IFileSaveDialog_fnGetResult
,
2752 IFileSaveDialog_fnAddPlace
,
2753 IFileSaveDialog_fnSetDefaultExtension
,
2754 IFileSaveDialog_fnClose
,
2755 IFileSaveDialog_fnSetClientGuid
,
2756 IFileSaveDialog_fnClearClientData
,
2757 IFileSaveDialog_fnSetFilter
,
2758 IFileSaveDialog_fnSetSaveAsItem
,
2759 IFileSaveDialog_fnSetProperties
,
2760 IFileSaveDialog_fnSetCollectedProperties
,
2761 IFileSaveDialog_fnGetProperties
,
2762 IFileSaveDialog_fnApplyProperties
2765 /**************************************************************************
2766 * IExplorerBrowserEvents implementation
2768 static inline FileDialogImpl
*impl_from_IExplorerBrowserEvents(IExplorerBrowserEvents
*iface
)
2770 return CONTAINING_RECORD(iface
, FileDialogImpl
, IExplorerBrowserEvents_iface
);
2773 static HRESULT WINAPI
IExplorerBrowserEvents_fnQueryInterface(IExplorerBrowserEvents
*iface
,
2774 REFIID riid
, void **ppvObject
)
2776 FileDialogImpl
*This
= impl_from_IExplorerBrowserEvents(iface
);
2777 TRACE("%p (%s, %p)\n", This
, debugstr_guid(riid
), ppvObject
);
2779 return IFileDialog2_QueryInterface(&This
->IFileDialog2_iface
, riid
, ppvObject
);
2782 static ULONG WINAPI
IExplorerBrowserEvents_fnAddRef(IExplorerBrowserEvents
*iface
)
2784 FileDialogImpl
*This
= impl_from_IExplorerBrowserEvents(iface
);
2785 TRACE("%p\n", This
);
2786 return IFileDialog2_AddRef(&This
->IFileDialog2_iface
);
2789 static ULONG WINAPI
IExplorerBrowserEvents_fnRelease(IExplorerBrowserEvents
*iface
)
2791 FileDialogImpl
*This
= impl_from_IExplorerBrowserEvents(iface
);
2792 TRACE("%p\n", This
);
2793 return IFileDialog2_Release(&This
->IFileDialog2_iface
);
2796 static HRESULT WINAPI
IExplorerBrowserEvents_fnOnNavigationPending(IExplorerBrowserEvents
*iface
,
2797 PCIDLIST_ABSOLUTE pidlFolder
)
2799 FileDialogImpl
*This
= impl_from_IExplorerBrowserEvents(iface
);
2802 TRACE("%p (%p)\n", This
, pidlFolder
);
2804 hr
= SHCreateItemFromIDList(pidlFolder
, &IID_IShellItem
, (void**)&psi
);
2807 hr
= events_OnFolderChanging(This
, psi
);
2808 IShellItem_Release(psi
);
2810 /* The ExplorerBrowser treats S_FALSE as S_OK, we don't. */
2817 ERR("Failed to convert pidl (%p) to a shellitem.\n", pidlFolder
);
2822 static HRESULT WINAPI
IExplorerBrowserEvents_fnOnViewCreated(IExplorerBrowserEvents
*iface
,
2825 FileDialogImpl
*This
= impl_from_IExplorerBrowserEvents(iface
);
2826 TRACE("%p (%p)\n", This
, psv
);
2830 static HRESULT WINAPI
IExplorerBrowserEvents_fnOnNavigationComplete(IExplorerBrowserEvents
*iface
,
2831 PCIDLIST_ABSOLUTE pidlFolder
)
2833 FileDialogImpl
*This
= impl_from_IExplorerBrowserEvents(iface
);
2835 TRACE("%p (%p)\n", This
, pidlFolder
);
2837 if(This
->psi_folder
)
2838 IShellItem_Release(This
->psi_folder
);
2840 hr
= SHCreateItemFromIDList(pidlFolder
, &IID_IShellItem
, (void**)&This
->psi_folder
);
2843 ERR("Failed to get the current folder.\n");
2844 This
->psi_folder
= NULL
;
2847 events_OnFolderChange(This
);
2852 static HRESULT WINAPI
IExplorerBrowserEvents_fnOnNavigationFailed(IExplorerBrowserEvents
*iface
,
2853 PCIDLIST_ABSOLUTE pidlFolder
)
2855 FileDialogImpl
*This
= impl_from_IExplorerBrowserEvents(iface
);
2856 TRACE("%p (%p)\n", This
, pidlFolder
);
2860 static const IExplorerBrowserEventsVtbl vt_IExplorerBrowserEvents
= {
2861 IExplorerBrowserEvents_fnQueryInterface
,
2862 IExplorerBrowserEvents_fnAddRef
,
2863 IExplorerBrowserEvents_fnRelease
,
2864 IExplorerBrowserEvents_fnOnNavigationPending
,
2865 IExplorerBrowserEvents_fnOnViewCreated
,
2866 IExplorerBrowserEvents_fnOnNavigationComplete
,
2867 IExplorerBrowserEvents_fnOnNavigationFailed
2870 /**************************************************************************
2871 * IServiceProvider implementation
2873 static inline FileDialogImpl
*impl_from_IServiceProvider(IServiceProvider
*iface
)
2875 return CONTAINING_RECORD(iface
, FileDialogImpl
, IServiceProvider_iface
);
2878 static HRESULT WINAPI
IServiceProvider_fnQueryInterface(IServiceProvider
*iface
,
2879 REFIID riid
, void **ppvObject
)
2881 FileDialogImpl
*This
= impl_from_IServiceProvider(iface
);
2882 TRACE("%p\n", This
);
2883 return IFileDialog2_QueryInterface(&This
->IFileDialog2_iface
, riid
, ppvObject
);
2886 static ULONG WINAPI
IServiceProvider_fnAddRef(IServiceProvider
*iface
)
2888 FileDialogImpl
*This
= impl_from_IServiceProvider(iface
);
2889 TRACE("%p\n", This
);
2890 return IFileDialog2_AddRef(&This
->IFileDialog2_iface
);
2893 static ULONG WINAPI
IServiceProvider_fnRelease(IServiceProvider
*iface
)
2895 FileDialogImpl
*This
= impl_from_IServiceProvider(iface
);
2896 TRACE("%p\n", This
);
2897 return IFileDialog2_Release(&This
->IFileDialog2_iface
);
2900 static HRESULT WINAPI
IServiceProvider_fnQueryService(IServiceProvider
*iface
,
2901 REFGUID guidService
,
2902 REFIID riid
, void **ppv
)
2904 FileDialogImpl
*This
= impl_from_IServiceProvider(iface
);
2905 HRESULT hr
= E_NOTIMPL
;
2906 TRACE("%p (%s, %s, %p)\n", This
, debugstr_guid(guidService
), debugstr_guid(riid
), ppv
);
2909 if(IsEqualGUID(guidService
, &SID_STopLevelBrowser
) && This
->peb
)
2910 hr
= IExplorerBrowser_QueryInterface(This
->peb
, riid
, ppv
);
2911 else if(IsEqualGUID(guidService
, &SID_SExplorerBrowserFrame
))
2912 hr
= IFileDialog2_QueryInterface(&This
->IFileDialog2_iface
, riid
, ppv
);
2914 FIXME("Interface %s requested from unknown service %s\n",
2915 debugstr_guid(riid
), debugstr_guid(guidService
));
2920 static const IServiceProviderVtbl vt_IServiceProvider
= {
2921 IServiceProvider_fnQueryInterface
,
2922 IServiceProvider_fnAddRef
,
2923 IServiceProvider_fnRelease
,
2924 IServiceProvider_fnQueryService
2927 /**************************************************************************
2928 * ICommDlgBrowser3 implementation
2930 static inline FileDialogImpl
*impl_from_ICommDlgBrowser3(ICommDlgBrowser3
*iface
)
2932 return CONTAINING_RECORD(iface
, FileDialogImpl
, ICommDlgBrowser3_iface
);
2935 static HRESULT WINAPI
ICommDlgBrowser3_fnQueryInterface(ICommDlgBrowser3
*iface
,
2936 REFIID riid
, void **ppvObject
)
2938 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
2939 TRACE("%p\n", This
);
2940 return IFileDialog2_QueryInterface(&This
->IFileDialog2_iface
, riid
, ppvObject
);
2943 static ULONG WINAPI
ICommDlgBrowser3_fnAddRef(ICommDlgBrowser3
*iface
)
2945 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
2946 TRACE("%p\n", This
);
2947 return IFileDialog2_AddRef(&This
->IFileDialog2_iface
);
2950 static ULONG WINAPI
ICommDlgBrowser3_fnRelease(ICommDlgBrowser3
*iface
)
2952 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
2953 TRACE("%p\n", This
);
2954 return IFileDialog2_Release(&This
->IFileDialog2_iface
);
2957 static HRESULT WINAPI
ICommDlgBrowser3_fnOnDefaultCommand(ICommDlgBrowser3
*iface
,
2960 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
2962 TRACE("%p (%p)\n", This
, shv
);
2964 hr
= on_default_action(This
);
2967 EndDialog(This
->dlg_hwnd
, S_OK
);
2972 static HRESULT WINAPI
ICommDlgBrowser3_fnOnStateChange(ICommDlgBrowser3
*iface
,
2973 IShellView
*shv
, ULONG uChange
)
2975 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
2976 IDataObject
*new_selection
;
2978 TRACE("%p (%p, %x)\n", This
, shv
, uChange
);
2982 case CDBOSC_SELCHANGE
:
2983 if(This
->psia_selection
)
2985 IShellItemArray_Release(This
->psia_selection
);
2986 This
->psia_selection
= NULL
;
2989 hr
= IShellView_GetItemObject(shv
, SVGIO_SELECTION
, &IID_IDataObject
, (void**)&new_selection
);
2992 hr
= SHCreateShellItemArrayFromDataObject(new_selection
, &IID_IShellItemArray
,
2993 (void**)&This
->psia_selection
);
2996 fill_filename_from_selection(This
);
2997 events_OnSelectionChange(This
);
3000 IDataObject_Release(new_selection
);
3004 TRACE("Unhandled state change\n");
3009 static HRESULT WINAPI
ICommDlgBrowser3_fnIncludeObject(ICommDlgBrowser3
*iface
,
3010 IShellView
*shv
, LPCITEMIDLIST pidl
)
3012 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
3015 LPITEMIDLIST parent_pidl
;
3018 TRACE("%p (%p, %p)\n", This
, shv
, pidl
);
3020 if(!This
->filterspec_count
&& !(This
->options
& FOS_PICKFOLDERS
))
3023 hr
= SHGetIDListFromObject((IUnknown
*)shv
, &parent_pidl
);
3026 LPITEMIDLIST full_pidl
= ILCombine(parent_pidl
, pidl
);
3027 hr
= SHCreateItemFromIDList(full_pidl
, &IID_IShellItem
, (void**)&psi
);
3028 ILFree(parent_pidl
);
3033 ERR("Failed to get shellitem (%08x).\n", hr
);
3037 hr
= IShellItem_GetAttributes(psi
, SFGAO_FOLDER
|SFGAO_LINK
, &attr
);
3038 if(FAILED(hr
) || (attr
& (SFGAO_FOLDER
| SFGAO_LINK
)))
3040 IShellItem_Release(psi
);
3044 if((This
->options
& FOS_PICKFOLDERS
) && !(attr
& (SFGAO_FOLDER
| SFGAO_LINK
)))
3046 IShellItem_Release(psi
);
3051 if(SUCCEEDED(IShellItem_GetDisplayName(psi
, SIGDN_PARENTRELATIVEPARSING
, &filename
)))
3053 if(!PathMatchSpecW(filename
, This
->filterspecs
[This
->filetypeindex
].pszSpec
))
3055 CoTaskMemFree(filename
);
3058 IShellItem_Release(psi
);
3062 static HRESULT WINAPI
ICommDlgBrowser3_fnNotify(ICommDlgBrowser3
*iface
,
3063 IShellView
*ppshv
, DWORD dwNotifyType
)
3065 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
3066 FIXME("Stub: %p (%p, 0x%x)\n", This
, ppshv
, dwNotifyType
);
3070 static HRESULT WINAPI
ICommDlgBrowser3_fnGetDefaultMenuText(ICommDlgBrowser3
*iface
,
3072 LPWSTR pszText
, int cchMax
)
3074 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
3075 FIXME("Stub: %p (%p, %p, %d)\n", This
, pshv
, pszText
, cchMax
);
3079 static HRESULT WINAPI
ICommDlgBrowser3_fnGetViewFlags(ICommDlgBrowser3
*iface
, DWORD
*pdwFlags
)
3081 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
3082 FIXME("Stub: %p (%p)\n", This
, pdwFlags
);
3086 static HRESULT WINAPI
ICommDlgBrowser3_fnOnColumnClicked(ICommDlgBrowser3
*iface
,
3087 IShellView
*pshv
, int iColumn
)
3089 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
3090 FIXME("Stub: %p (%p, %d)\n", This
, pshv
, iColumn
);
3094 static HRESULT WINAPI
ICommDlgBrowser3_fnGetCurrentFilter(ICommDlgBrowser3
*iface
,
3095 LPWSTR pszFileSpec
, int cchFileSpec
)
3097 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
3098 FIXME("Stub: %p (%p, %d)\n", This
, pszFileSpec
, cchFileSpec
);
3102 static HRESULT WINAPI
ICommDlgBrowser3_fnOnPreviewCreated(ICommDlgBrowser3
*iface
,
3105 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
3106 FIXME("Stub: %p (%p)\n", This
, pshv
);
3110 static const ICommDlgBrowser3Vtbl vt_ICommDlgBrowser3
= {
3111 ICommDlgBrowser3_fnQueryInterface
,
3112 ICommDlgBrowser3_fnAddRef
,
3113 ICommDlgBrowser3_fnRelease
,
3114 ICommDlgBrowser3_fnOnDefaultCommand
,
3115 ICommDlgBrowser3_fnOnStateChange
,
3116 ICommDlgBrowser3_fnIncludeObject
,
3117 ICommDlgBrowser3_fnNotify
,
3118 ICommDlgBrowser3_fnGetDefaultMenuText
,
3119 ICommDlgBrowser3_fnGetViewFlags
,
3120 ICommDlgBrowser3_fnOnColumnClicked
,
3121 ICommDlgBrowser3_fnGetCurrentFilter
,
3122 ICommDlgBrowser3_fnOnPreviewCreated
3125 /**************************************************************************
3126 * IOleWindow implementation
3128 static inline FileDialogImpl
*impl_from_IOleWindow(IOleWindow
*iface
)
3130 return CONTAINING_RECORD(iface
, FileDialogImpl
, IOleWindow_iface
);
3133 static HRESULT WINAPI
IOleWindow_fnQueryInterface(IOleWindow
*iface
, REFIID riid
, void **ppvObject
)
3135 FileDialogImpl
*This
= impl_from_IOleWindow(iface
);
3136 return IFileDialog2_QueryInterface(&This
->IFileDialog2_iface
, riid
, ppvObject
);
3139 static ULONG WINAPI
IOleWindow_fnAddRef(IOleWindow
*iface
)
3141 FileDialogImpl
*This
= impl_from_IOleWindow(iface
);
3142 return IFileDialog2_AddRef(&This
->IFileDialog2_iface
);
3145 static ULONG WINAPI
IOleWindow_fnRelease(IOleWindow
*iface
)
3147 FileDialogImpl
*This
= impl_from_IOleWindow(iface
);
3148 return IFileDialog2_Release(&This
->IFileDialog2_iface
);
3151 static HRESULT WINAPI
IOleWindow_fnContextSensitiveHelp(IOleWindow
*iface
, BOOL fEnterMOde
)
3153 FileDialogImpl
*This
= impl_from_IOleWindow(iface
);
3154 FIXME("Stub: %p (%d)\n", This
, fEnterMOde
);
3158 static HRESULT WINAPI
IOleWindow_fnGetWindow(IOleWindow
*iface
, HWND
*phwnd
)
3160 FileDialogImpl
*This
= impl_from_IOleWindow(iface
);
3161 TRACE("%p (%p)\n", This
, phwnd
);
3162 *phwnd
= This
->dlg_hwnd
;
3166 static const IOleWindowVtbl vt_IOleWindow
= {
3167 IOleWindow_fnQueryInterface
,
3168 IOleWindow_fnAddRef
,
3169 IOleWindow_fnRelease
,
3170 IOleWindow_fnGetWindow
,
3171 IOleWindow_fnContextSensitiveHelp
3174 /**************************************************************************
3175 * IFileDialogCustomize implementation
3177 static inline FileDialogImpl
*impl_from_IFileDialogCustomize(IFileDialogCustomize
*iface
)
3179 return CONTAINING_RECORD(iface
, FileDialogImpl
, IFileDialogCustomize_iface
);
3182 static HRESULT WINAPI
IFileDialogCustomize_fnQueryInterface(IFileDialogCustomize
*iface
,
3183 REFIID riid
, void **ppvObject
)
3185 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3186 return IFileDialog2_QueryInterface(&This
->IFileDialog2_iface
, riid
, ppvObject
);
3189 static ULONG WINAPI
IFileDialogCustomize_fnAddRef(IFileDialogCustomize
*iface
)
3191 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3192 return IFileDialog2_AddRef(&This
->IFileDialog2_iface
);
3195 static ULONG WINAPI
IFileDialogCustomize_fnRelease(IFileDialogCustomize
*iface
)
3197 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3198 return IFileDialog2_Release(&This
->IFileDialog2_iface
);
3201 static HRESULT WINAPI
IFileDialogCustomize_fnEnableOpenDropDown(IFileDialogCustomize
*iface
,
3204 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3205 FIXME("stub - %p (%d)\n", This
, dwIDCtl
);
3209 static HRESULT WINAPI
IFileDialogCustomize_fnAddMenu(IFileDialogCustomize
*iface
,
3213 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3217 TRACE("%p (%d, %p)\n", This
, dwIDCtl
, pszLabel
);
3219 hr
= cctrl_create_new(This
, dwIDCtl
, NULL
, TOOLBARCLASSNAMEW
,
3220 TBSTYLE_FLAT
| CCS_NODIVIDER
, 0,
3221 This
->cctrl_def_height
, &ctrl
);
3224 SendMessageW(ctrl
->hwnd
, TB_BUTTONSTRUCTSIZE
, sizeof(tbb
), 0);
3225 ctrl
->type
= IDLG_CCTRL_MENU
;
3227 /* Add the actual button with a popup menu. */
3228 tbb
.iBitmap
= I_IMAGENONE
;
3229 tbb
.dwData
= (DWORD_PTR
)CreatePopupMenu();
3230 tbb
.iString
= (DWORD_PTR
)pszLabel
;
3231 tbb
.fsState
= TBSTATE_ENABLED
;
3232 tbb
.fsStyle
= BTNS_WHOLEDROPDOWN
;
3235 SendMessageW(ctrl
->hwnd
, TB_ADDBUTTONSW
, 1, (LPARAM
)&tbb
);
3241 static HRESULT WINAPI
IFileDialogCustomize_fnAddPushButton(IFileDialogCustomize
*iface
,
3245 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3248 TRACE("%p (%d, %p)\n", This
, dwIDCtl
, pszLabel
);
3250 hr
= cctrl_create_new(This
, dwIDCtl
, pszLabel
, WC_BUTTONW
, BS_MULTILINE
, 0,
3251 This
->cctrl_def_height
, &ctrl
);
3253 ctrl
->type
= IDLG_CCTRL_PUSHBUTTON
;
3258 static HRESULT WINAPI
IFileDialogCustomize_fnAddComboBox(IFileDialogCustomize
*iface
,
3261 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3264 TRACE("%p (%d)\n", This
, dwIDCtl
);
3266 hr
= cctrl_create_new(This
, dwIDCtl
, NULL
, WC_COMBOBOXW
, CBS_DROPDOWNLIST
, 0,
3267 This
->cctrl_def_height
, &ctrl
);
3269 ctrl
->type
= IDLG_CCTRL_COMBOBOX
;
3274 static HRESULT WINAPI
IFileDialogCustomize_fnAddRadioButtonList(IFileDialogCustomize
*iface
,
3277 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3278 FIXME("stub - %p (%d)\n", This
, dwIDCtl
);
3282 static HRESULT WINAPI
IFileDialogCustomize_fnAddCheckButton(IFileDialogCustomize
*iface
,
3287 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3290 TRACE("%p (%d, %p, %d)\n", This
, dwIDCtl
, pszLabel
, bChecked
);
3292 hr
= cctrl_create_new(This
, dwIDCtl
, pszLabel
, WC_BUTTONW
, BS_AUTOCHECKBOX
|BS_MULTILINE
, 0,
3293 This
->cctrl_def_height
, &ctrl
);
3296 ctrl
->type
= IDLG_CCTRL_CHECKBUTTON
;
3297 SendMessageW(ctrl
->hwnd
, BM_SETCHECK
, bChecked
? BST_CHECKED
: BST_UNCHECKED
, 0);
3303 static HRESULT WINAPI
IFileDialogCustomize_fnAddEditBox(IFileDialogCustomize
*iface
,
3307 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3310 TRACE("%p (%d, %p)\n", This
, dwIDCtl
, pszText
);
3312 hr
= cctrl_create_new(This
, dwIDCtl
, pszText
, WC_EDITW
, ES_AUTOHSCROLL
, WS_EX_CLIENTEDGE
,
3313 This
->cctrl_def_height
, &ctrl
);
3315 ctrl
->type
= IDLG_CCTRL_EDITBOX
;
3320 static HRESULT WINAPI
IFileDialogCustomize_fnAddSeparator(IFileDialogCustomize
*iface
,
3323 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3326 TRACE("%p (%d)\n", This
, dwIDCtl
);
3328 hr
= cctrl_create_new(This
, dwIDCtl
, NULL
, WC_STATICW
, SS_ETCHEDHORZ
, 0,
3329 GetSystemMetrics(SM_CYEDGE
), &ctrl
);
3331 ctrl
->type
= IDLG_CCTRL_SEPARATOR
;
3336 static HRESULT WINAPI
IFileDialogCustomize_fnAddText(IFileDialogCustomize
*iface
,
3340 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3343 TRACE("%p (%d, %p)\n", This
, dwIDCtl
, pszText
);
3345 hr
= cctrl_create_new(This
, dwIDCtl
, pszText
, WC_STATICW
, 0, 0,
3346 This
->cctrl_def_height
, &ctrl
);
3348 ctrl
->type
= IDLG_CCTRL_TEXT
;
3353 static HRESULT WINAPI
IFileDialogCustomize_fnSetControlLabel(IFileDialogCustomize
*iface
,
3357 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3358 customctrl
*ctrl
= get_cctrl(This
, dwIDCtl
);
3359 TRACE("%p (%d, %p)\n", This
, dwIDCtl
, pszLabel
);
3361 if(!ctrl
) return E_INVALIDARG
;
3365 case IDLG_CCTRL_MENU
:
3366 case IDLG_CCTRL_PUSHBUTTON
:
3367 case IDLG_CCTRL_CHECKBUTTON
:
3368 case IDLG_CCTRL_TEXT
:
3369 case IDLG_CCTRL_VISUALGROUP
:
3370 SendMessageW(ctrl
->hwnd
, WM_SETTEXT
, 0, (LPARAM
)pszLabel
);
3379 static HRESULT WINAPI
IFileDialogCustomize_fnGetControlState(IFileDialogCustomize
*iface
,
3381 CDCONTROLSTATEF
*pdwState
)
3383 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3384 customctrl
*ctrl
= get_cctrl(This
, dwIDCtl
);
3385 TRACE("%p (%d, %p)\n", This
, dwIDCtl
, pdwState
);
3387 if(!ctrl
) return E_NOTIMPL
;
3389 *pdwState
= ctrl
->cdcstate
;
3393 static HRESULT WINAPI
IFileDialogCustomize_fnSetControlState(IFileDialogCustomize
*iface
,
3395 CDCONTROLSTATEF dwState
)
3397 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3398 customctrl
*ctrl
= get_cctrl(This
,dwIDCtl
);
3399 TRACE("%p (%d, %x)\n", This
, dwIDCtl
, dwState
);
3403 LONG wndstyle
= GetWindowLongW(ctrl
->hwnd
, GWL_STYLE
);
3405 if(dwState
& CDCS_ENABLED
)
3406 wndstyle
&= ~(WS_DISABLED
);
3408 wndstyle
|= WS_DISABLED
;
3410 if(dwState
& CDCS_VISIBLE
)
3411 wndstyle
|= WS_VISIBLE
;
3413 wndstyle
&= ~(WS_VISIBLE
);
3415 SetWindowLongW(ctrl
->hwnd
, GWL_STYLE
, wndstyle
);
3417 /* We save the state separately since at least one application
3418 * relies on being able to hide a control. */
3419 ctrl
->cdcstate
= dwState
;
3425 static HRESULT WINAPI
IFileDialogCustomize_fnGetEditBoxText(IFileDialogCustomize
*iface
,
3429 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3430 customctrl
*ctrl
= get_cctrl(This
, dwIDCtl
);
3432 TRACE("%p (%d, %p)\n", This
, dwIDCtl
, ppszText
);
3434 if(!ctrl
|| !(len
= SendMessageW(ctrl
->hwnd
, WM_GETTEXTLENGTH
, 0, 0)))
3437 text
= CoTaskMemAlloc(sizeof(WCHAR
)*(len
+1));
3438 if(!text
) return E_FAIL
;
3440 SendMessageW(ctrl
->hwnd
, WM_GETTEXT
, len
+1, (LPARAM
)text
);
3445 static HRESULT WINAPI
IFileDialogCustomize_fnSetEditBoxText(IFileDialogCustomize
*iface
,
3449 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3450 customctrl
*ctrl
= get_cctrl(This
, dwIDCtl
);
3451 TRACE("%p (%d, %s)\n", This
, dwIDCtl
, debugstr_w(pszText
));
3453 if(!ctrl
|| ctrl
->type
!= IDLG_CCTRL_EDITBOX
)
3456 SendMessageW(ctrl
->hwnd
, WM_SETTEXT
, 0, (LPARAM
)pszText
);
3460 static HRESULT WINAPI
IFileDialogCustomize_fnGetCheckButtonState(IFileDialogCustomize
*iface
,
3464 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3465 customctrl
*ctrl
= get_cctrl(This
, dwIDCtl
);
3466 TRACE("%p (%d, %p)\n", This
, dwIDCtl
, pbChecked
);
3469 *pbChecked
= (SendMessageW(ctrl
->hwnd
, BM_GETCHECK
, 0, 0) == BST_CHECKED
);
3474 static HRESULT WINAPI
IFileDialogCustomize_fnSetCheckButtonState(IFileDialogCustomize
*iface
,
3478 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3479 customctrl
*ctrl
= get_cctrl(This
, dwIDCtl
);
3480 TRACE("%p (%d, %d)\n", This
, dwIDCtl
, bChecked
);
3483 SendMessageW(ctrl
->hwnd
, BM_SETCHECK
, bChecked
? BST_CHECKED
:BST_UNCHECKED
, 0);
3488 static UINT
get_combobox_index_from_id(HWND cb_hwnd
, DWORD dwIDItem
)
3490 UINT count
= SendMessageW(cb_hwnd
, CB_GETCOUNT
, 0, 0);
3492 if(!count
|| (count
== CB_ERR
))
3495 for(i
= 0; i
< count
; i
++)
3496 if(SendMessageW(cb_hwnd
, CB_GETITEMDATA
, i
, 0) == dwIDItem
)
3499 TRACE("Item with id %d not found in combobox %p (item count: %d)\n", dwIDItem
, cb_hwnd
, count
);
3503 static HRESULT WINAPI
IFileDialogCustomize_fnAddControlItem(IFileDialogCustomize
*iface
,
3508 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3509 customctrl
*ctrl
= get_cctrl(This
, dwIDCtl
);
3510 TRACE("%p (%d, %d, %s)\n", This
, dwIDCtl
, dwIDItem
, debugstr_w(pszLabel
));
3512 if(!ctrl
) return E_FAIL
;
3516 case IDLG_CCTRL_COMBOBOX
:
3520 if(get_combobox_index_from_id(ctrl
->hwnd
, dwIDItem
) != -1)
3521 return E_INVALIDARG
;
3523 index
= SendMessageW(ctrl
->hwnd
, CB_ADDSTRING
, 0, (LPARAM
)pszLabel
);
3524 SendMessageW(ctrl
->hwnd
, CB_SETITEMDATA
, index
, dwIDItem
);
3528 case IDLG_CCTRL_MENU
:
3531 SendMessageW(ctrl
->hwnd
, TB_GETBUTTON
, 0, (LPARAM
)&tbb
);
3533 if(GetMenuState((HMENU
)tbb
.dwData
, dwIDItem
, MF_BYCOMMAND
) != -1)
3534 return E_INVALIDARG
;
3536 AppendMenuW((HMENU
)tbb
.dwData
, MF_STRING
, dwIDItem
, pszLabel
);
3543 return E_NOINTERFACE
; /* win7 */
3546 static HRESULT WINAPI
IFileDialogCustomize_fnRemoveControlItem(IFileDialogCustomize
*iface
,
3550 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3551 customctrl
*ctrl
= get_cctrl(This
, dwIDCtl
);
3552 TRACE("%p (%d, %d)\n", This
, dwIDCtl
, dwIDItem
);
3554 if(!ctrl
) return E_FAIL
;
3558 case IDLG_CCTRL_COMBOBOX
:
3560 UINT i
, count
= SendMessageW(ctrl
->hwnd
, CB_GETCOUNT
, 0, 0);
3561 if(!count
|| (count
== CB_ERR
))
3564 for(i
= 0; i
< count
; i
++)
3565 if(SendMessageW(ctrl
->hwnd
, CB_GETITEMDATA
, i
, 0) == dwIDItem
)
3567 if(SendMessageW(ctrl
->hwnd
, CB_DELETESTRING
, i
, 0) == CB_ERR
)
3572 return E_UNEXPECTED
;
3574 case IDLG_CCTRL_MENU
:
3578 SendMessageW(ctrl
->hwnd
, TB_GETBUTTON
, 0, (LPARAM
)&tbb
);
3579 hmenu
= (HMENU
)tbb
.dwData
;
3581 if(!hmenu
|| !DeleteMenu(hmenu
, dwIDItem
, MF_BYCOMMAND
))
3582 return E_UNEXPECTED
;
3593 static HRESULT WINAPI
IFileDialogCustomize_fnRemoveAllControlItems(IFileDialogCustomize
*iface
,
3596 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3597 TRACE("%p (%d)\n", This
, dwIDCtl
);
3599 /* Not implemented by native */
3603 static HRESULT WINAPI
IFileDialogCustomize_fnGetControlItemState(IFileDialogCustomize
*iface
,
3606 CDCONTROLSTATEF
*pdwState
)
3608 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3609 FIXME("stub - %p\n", This
);
3613 static HRESULT WINAPI
IFileDialogCustomize_fnSetControlItemState(IFileDialogCustomize
*iface
,
3616 CDCONTROLSTATEF dwState
)
3618 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3619 FIXME("stub - %p\n", This
);
3623 static HRESULT WINAPI
IFileDialogCustomize_fnGetSelectedControlItem(IFileDialogCustomize
*iface
,
3627 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3628 customctrl
*ctrl
= get_cctrl(This
, dwIDCtl
);
3629 TRACE("%p (%d, %p)\n", This
, dwIDCtl
, pdwIDItem
);
3631 if(!ctrl
) return E_FAIL
;
3635 case IDLG_CCTRL_COMBOBOX
:
3637 UINT index
= SendMessageW(ctrl
->hwnd
, CB_GETCURSEL
, 0, 0);
3641 *pdwIDItem
= SendMessageW(ctrl
->hwnd
, CB_GETITEMDATA
, index
, 0);
3645 FIXME("Unsupported control type %d\n", ctrl
->type
);
3651 static HRESULT WINAPI
IFileDialogCustomize_fnSetSelectedControlItem(IFileDialogCustomize
*iface
,
3655 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3656 customctrl
*ctrl
= get_cctrl(This
, dwIDCtl
);
3657 TRACE("%p (%d, %d)\n", This
, dwIDCtl
, dwIDItem
);
3659 if(!ctrl
) return E_INVALIDARG
;
3663 case IDLG_CCTRL_COMBOBOX
:
3665 UINT index
= get_combobox_index_from_id(ctrl
->hwnd
, dwIDItem
);
3668 return E_INVALIDARG
;
3670 if(SendMessageW(ctrl
->hwnd
, CB_SETCURSEL
, index
, 0) == CB_ERR
)
3676 FIXME("Unsupported control type %d\n", ctrl
->type
);
3679 return E_INVALIDARG
;
3682 static HRESULT WINAPI
IFileDialogCustomize_fnStartVisualGroup(IFileDialogCustomize
*iface
,
3686 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3689 TRACE("%p (%d, %s)\n", This
, dwIDCtl
, debugstr_w(pszLabel
));
3691 if(This
->cctrl_active_vg
)
3692 return E_UNEXPECTED
;
3694 hr
= cctrl_create_new(This
, dwIDCtl
, pszLabel
, WC_STATICW
, 0, 0,
3695 This
->cctrl_def_height
, &vg
);
3698 vg
->type
= IDLG_CCTRL_VISUALGROUP
;
3699 This
->cctrl_active_vg
= vg
;
3705 static HRESULT WINAPI
IFileDialogCustomize_fnEndVisualGroup(IFileDialogCustomize
*iface
)
3707 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3708 TRACE("%p\n", This
);
3710 This
->cctrl_active_vg
= NULL
;
3715 static HRESULT WINAPI
IFileDialogCustomize_fnMakeProminent(IFileDialogCustomize
*iface
,
3718 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3719 FIXME("stub - %p (%d)\n", This
, dwIDCtl
);
3723 static HRESULT WINAPI
IFileDialogCustomize_fnSetControlItemText(IFileDialogCustomize
*iface
,
3728 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3729 FIXME("stub - %p (%d, %d, %s)\n", This
, dwIDCtl
, dwIDItem
, debugstr_w(pszLabel
));
3733 static const IFileDialogCustomizeVtbl vt_IFileDialogCustomize
= {
3734 IFileDialogCustomize_fnQueryInterface
,
3735 IFileDialogCustomize_fnAddRef
,
3736 IFileDialogCustomize_fnRelease
,
3737 IFileDialogCustomize_fnEnableOpenDropDown
,
3738 IFileDialogCustomize_fnAddMenu
,
3739 IFileDialogCustomize_fnAddPushButton
,
3740 IFileDialogCustomize_fnAddComboBox
,
3741 IFileDialogCustomize_fnAddRadioButtonList
,
3742 IFileDialogCustomize_fnAddCheckButton
,
3743 IFileDialogCustomize_fnAddEditBox
,
3744 IFileDialogCustomize_fnAddSeparator
,
3745 IFileDialogCustomize_fnAddText
,
3746 IFileDialogCustomize_fnSetControlLabel
,
3747 IFileDialogCustomize_fnGetControlState
,
3748 IFileDialogCustomize_fnSetControlState
,
3749 IFileDialogCustomize_fnGetEditBoxText
,
3750 IFileDialogCustomize_fnSetEditBoxText
,
3751 IFileDialogCustomize_fnGetCheckButtonState
,
3752 IFileDialogCustomize_fnSetCheckButtonState
,
3753 IFileDialogCustomize_fnAddControlItem
,
3754 IFileDialogCustomize_fnRemoveControlItem
,
3755 IFileDialogCustomize_fnRemoveAllControlItems
,
3756 IFileDialogCustomize_fnGetControlItemState
,
3757 IFileDialogCustomize_fnSetControlItemState
,
3758 IFileDialogCustomize_fnGetSelectedControlItem
,
3759 IFileDialogCustomize_fnSetSelectedControlItem
,
3760 IFileDialogCustomize_fnStartVisualGroup
,
3761 IFileDialogCustomize_fnEndVisualGroup
,
3762 IFileDialogCustomize_fnMakeProminent
,
3763 IFileDialogCustomize_fnSetControlItemText
3766 static HRESULT
FileDialog_constructor(IUnknown
*pUnkOuter
, REFIID riid
, void **ppv
, enum ITEMDLG_TYPE type
)
3768 FileDialogImpl
*fdimpl
;
3771 TRACE("%p, %s, %p\n", pUnkOuter
, debugstr_guid(riid
), ppv
);
3776 return CLASS_E_NOAGGREGATION
;
3778 fdimpl
= HeapAlloc(GetProcessHeap(), 0, sizeof(FileDialogImpl
));
3780 return E_OUTOFMEMORY
;
3783 fdimpl
->IFileDialog2_iface
.lpVtbl
= &vt_IFileDialog2
;
3784 fdimpl
->IExplorerBrowserEvents_iface
.lpVtbl
= &vt_IExplorerBrowserEvents
;
3785 fdimpl
->IServiceProvider_iface
.lpVtbl
= &vt_IServiceProvider
;
3786 fdimpl
->ICommDlgBrowser3_iface
.lpVtbl
= &vt_ICommDlgBrowser3
;
3787 fdimpl
->IOleWindow_iface
.lpVtbl
= &vt_IOleWindow
;
3788 fdimpl
->IFileDialogCustomize_iface
.lpVtbl
= &vt_IFileDialogCustomize
;
3790 if(type
== ITEMDLG_TYPE_OPEN
)
3792 fdimpl
->dlg_type
= ITEMDLG_TYPE_OPEN
;
3793 fdimpl
->u
.IFileOpenDialog_iface
.lpVtbl
= &vt_IFileOpenDialog
;
3794 fdimpl
->options
= FOS_PATHMUSTEXIST
| FOS_FILEMUSTEXIST
| FOS_NOCHANGEDIR
;
3795 fdimpl
->custom_title
= fdimpl
->custom_okbutton
= NULL
;
3800 fdimpl
->dlg_type
= ITEMDLG_TYPE_SAVE
;
3801 fdimpl
->u
.IFileSaveDialog_iface
.lpVtbl
= &vt_IFileSaveDialog
;
3802 fdimpl
->options
= FOS_OVERWRITEPROMPT
| FOS_NOREADONLYRETURN
| FOS_PATHMUSTEXIST
| FOS_NOCHANGEDIR
;
3804 LoadStringW(COMDLG32_hInstance
, IDS_SAVE
, buf
, sizeof(buf
)/sizeof(WCHAR
));
3805 fdimpl
->custom_title
= StrDupW(buf
);
3806 fdimpl
->custom_okbutton
= StrDupW(buf
);
3809 fdimpl
->filterspecs
= NULL
;
3810 fdimpl
->filterspec_count
= 0;
3811 fdimpl
->filetypeindex
= 0;
3813 fdimpl
->psia_selection
= fdimpl
->psia_results
= NULL
;
3814 fdimpl
->psi_setfolder
= fdimpl
->psi_folder
= NULL
;
3816 list_init(&fdimpl
->events_clients
);
3817 fdimpl
->events_next_cookie
= 0;
3819 fdimpl
->dlg_hwnd
= NULL
;
3822 fdimpl
->set_filename
= NULL
;
3823 fdimpl
->default_ext
= NULL
;
3824 fdimpl
->custom_cancelbutton
= fdimpl
->custom_filenamelabel
= NULL
;
3826 fdimpl
->client_guid
= GUID_NULL
;
3828 /* FIXME: The default folder setting should be restored for the
3829 * application if it was previously set. */
3830 SHGetDesktopFolder(&psf
);
3831 SHGetItemFromObject((IUnknown
*)psf
, &IID_IShellItem
, (void**)&fdimpl
->psi_defaultfolder
);
3832 IShellFolder_Release(psf
);
3834 hr
= init_custom_controls(fdimpl
);
3837 ERR("Failed to initialize custom controls (0x%08x).\n", hr
);
3838 IUnknown_Release((IUnknown
*)fdimpl
);
3842 hr
= IUnknown_QueryInterface((IUnknown
*)fdimpl
, riid
, ppv
);
3843 IUnknown_Release((IUnknown
*)fdimpl
);
3847 HRESULT
FileOpenDialog_Constructor(IUnknown
*pUnkOuter
, REFIID riid
, void **ppv
)
3849 return FileDialog_constructor(pUnkOuter
, riid
, ppv
, ITEMDLG_TYPE_OPEN
);
3852 HRESULT
FileSaveDialog_Constructor(IUnknown
*pUnkOuter
, REFIID riid
, void **ppv
)
3854 return FileDialog_constructor(pUnkOuter
, riid
, ppv
, ITEMDLG_TYPE_SAVE
);