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
,
74 HWND hwnd
, wrapper_hwnd
;
76 enum ITEMDLG_CCTRL_TYPE type
;
77 CDCONTROLSTATEF cdcstate
;
83 IFileDialogEvents
*pfde
;
87 typedef struct FileDialogImpl
{
88 IFileDialog2 IFileDialog2_iface
;
90 IFileOpenDialog IFileOpenDialog_iface
;
91 IFileSaveDialog IFileSaveDialog_iface
;
93 enum ITEMDLG_TYPE dlg_type
;
94 IExplorerBrowserEvents IExplorerBrowserEvents_iface
;
95 IServiceProvider IServiceProvider_iface
;
96 ICommDlgBrowser3 ICommDlgBrowser3_iface
;
97 IOleWindow IOleWindow_iface
;
98 IFileDialogCustomize IFileDialogCustomize_iface
;
101 FILEOPENDIALOGOPTIONS options
;
102 COMDLG_FILTERSPEC
*filterspecs
;
103 UINT filterspec_count
;
106 struct list events_clients
;
107 DWORD events_next_cookie
;
109 IShellItemArray
*psia_selection
;
110 IShellItemArray
*psia_results
;
111 IShellItem
*psi_defaultfolder
;
112 IShellItem
*psi_setfolder
;
113 IShellItem
*psi_folder
;
116 IExplorerBrowser
*peb
;
117 DWORD ebevents_cookie
;
122 LPWSTR custom_okbutton
;
123 LPWSTR custom_cancelbutton
;
124 LPWSTR custom_filenamelabel
;
126 UINT cctrl_width
, cctrl_def_height
, cctrls_cols
;
129 UINT_PTR cctrl_next_dlgid
;
134 /**************************************************************************
137 static HRESULT
events_OnFileOk(FileDialogImpl
*This
)
139 events_client
*cursor
;
143 LIST_FOR_EACH_ENTRY(cursor
, &This
->events_clients
, events_client
, entry
)
145 TRACE("Notifying %p\n", cursor
);
146 hr
= IFileDialogEvents_OnFileOk(cursor
->pfde
, (IFileDialog
*)&This
->IFileDialog2_iface
);
147 if(FAILED(hr
) && hr
!= E_NOTIMPL
)
157 static HRESULT
events_OnFolderChanging(FileDialogImpl
*This
, IShellItem
*folder
)
159 events_client
*cursor
;
161 TRACE("%p (%p)\n", This
, folder
);
163 LIST_FOR_EACH_ENTRY(cursor
, &This
->events_clients
, events_client
, entry
)
165 TRACE("Notifying %p\n", cursor
);
166 hr
= IFileDialogEvents_OnFolderChanging(cursor
->pfde
, (IFileDialog
*)&This
->IFileDialog2_iface
, folder
);
167 if(FAILED(hr
) && hr
!= E_NOTIMPL
)
177 static void events_OnFolderChange(FileDialogImpl
*This
)
179 events_client
*cursor
;
182 LIST_FOR_EACH_ENTRY(cursor
, &This
->events_clients
, events_client
, entry
)
184 TRACE("Notifying %p\n", cursor
);
185 IFileDialogEvents_OnFolderChange(cursor
->pfde
, (IFileDialog
*)&This
->IFileDialog2_iface
);
189 static void events_OnSelectionChange(FileDialogImpl
*This
)
191 events_client
*cursor
;
194 LIST_FOR_EACH_ENTRY(cursor
, &This
->events_clients
, events_client
, entry
)
196 TRACE("Notifying %p\n", cursor
);
197 IFileDialogEvents_OnSelectionChange(cursor
->pfde
, (IFileDialog
*)&This
->IFileDialog2_iface
);
201 static inline HRESULT
get_cctrl_event(IFileDialogEvents
*pfde
, IFileDialogControlEvents
**pfdce
)
203 return IFileDialogEvents_QueryInterface(pfde
, &IID_IFileDialogControlEvents
, (void**)pfdce
);
206 static HRESULT
cctrl_event_OnButtonClicked(FileDialogImpl
*This
, DWORD ctl_id
)
208 events_client
*cursor
;
211 LIST_FOR_EACH_ENTRY(cursor
, &This
->events_clients
, events_client
, entry
)
213 IFileDialogControlEvents
*pfdce
;
214 if(SUCCEEDED(get_cctrl_event(cursor
->pfde
, &pfdce
)))
216 TRACE("Notifying %p\n", cursor
);
217 IFileDialogControlEvents_OnButtonClicked(pfdce
, &This
->IFileDialogCustomize_iface
, ctl_id
);
218 IFileDialogControlEvents_Release(pfdce
);
225 static HRESULT
cctrl_event_OnItemSelected(FileDialogImpl
*This
, DWORD ctl_id
, DWORD item_id
)
227 events_client
*cursor
;
230 LIST_FOR_EACH_ENTRY(cursor
, &This
->events_clients
, events_client
, entry
)
232 IFileDialogControlEvents
*pfdce
;
233 if(SUCCEEDED(get_cctrl_event(cursor
->pfde
, &pfdce
)))
235 TRACE("Notifying %p\n", cursor
);
236 IFileDialogControlEvents_OnItemSelected(pfdce
, &This
->IFileDialogCustomize_iface
, ctl_id
, item_id
);
237 IFileDialogControlEvents_Release(pfdce
);
244 static HRESULT
cctrl_event_OnCheckButtonToggled(FileDialogImpl
*This
, DWORD ctl_id
, BOOL checked
)
246 events_client
*cursor
;
249 LIST_FOR_EACH_ENTRY(cursor
, &This
->events_clients
, events_client
, entry
)
251 IFileDialogControlEvents
*pfdce
;
252 if(SUCCEEDED(get_cctrl_event(cursor
->pfde
, &pfdce
)))
254 TRACE("Notifying %p\n", cursor
);
255 IFileDialogControlEvents_OnCheckButtonToggled(pfdce
, &This
->IFileDialogCustomize_iface
, ctl_id
, checked
);
256 IFileDialogControlEvents_Release(pfdce
);
263 static HRESULT
cctrl_event_OnControlActivating(FileDialogImpl
*This
,
266 events_client
*cursor
;
269 LIST_FOR_EACH_ENTRY(cursor
, &This
->events_clients
, events_client
, entry
)
271 IFileDialogControlEvents
*pfdce
;
272 if(SUCCEEDED(get_cctrl_event(cursor
->pfde
, &pfdce
)))
274 TRACE("Notifying %p\n", cursor
);
275 IFileDialogControlEvents_OnControlActivating(pfdce
, &This
->IFileDialogCustomize_iface
, ctl_id
);
276 IFileDialogControlEvents_Release(pfdce
);
283 /**************************************************************************
286 static UINT
get_file_name(FileDialogImpl
*This
, LPWSTR
*str
)
288 HWND hwnd_edit
= GetDlgItem(This
->dlg_hwnd
, IDC_FILENAME
);
293 if(This
->set_filename
)
295 len
= lstrlenW(This
->set_filename
);
296 *str
= CoTaskMemAlloc(sizeof(WCHAR
)*(len
+1));
297 lstrcpyW(*str
, This
->set_filename
);
303 len
= SendMessageW(hwnd_edit
, WM_GETTEXTLENGTH
, 0, 0);
304 *str
= CoTaskMemAlloc(sizeof(WCHAR
)*(len
+1));
308 SendMessageW(hwnd_edit
, WM_GETTEXT
, len
+1, (LPARAM
)*str
);
312 static BOOL
set_file_name(FileDialogImpl
*This
, LPCWSTR str
)
314 HWND hwnd_edit
= GetDlgItem(This
->dlg_hwnd
, IDC_FILENAME
);
316 if(This
->set_filename
)
317 LocalFree(This
->set_filename
);
319 This
->set_filename
= StrDupW(str
);
321 return SendMessageW(hwnd_edit
, WM_SETTEXT
, 0, (LPARAM
)str
);
324 static void fill_filename_from_selection(FileDialogImpl
*This
)
329 UINT item_count
, valid_count
;
332 if(!This
->psia_selection
)
335 hr
= IShellItemArray_GetCount(This
->psia_selection
, &item_count
);
336 if(FAILED(hr
) || !item_count
)
339 names
= HeapAlloc(GetProcessHeap(), 0, item_count
*sizeof(LPWSTR
));
341 /* Get names of the selected items */
342 valid_count
= 0; len_total
= 0;
343 for(i
= 0; i
< item_count
; i
++)
345 hr
= IShellItemArray_GetItemAt(This
->psia_selection
, i
, &psi
);
350 hr
= IShellItem_GetAttributes(psi
, SFGAO_FOLDER
, &attr
);
351 if(SUCCEEDED(hr
) && (attr
& SFGAO_FOLDER
))
352 continue; /* FIXME: FOS_PICKFOLDERS */
354 hr
= IShellItem_GetDisplayName(psi
, SIGDN_PARENTRELATIVEPARSING
, &names
[valid_count
]);
357 len_total
+= lstrlenW(names
[valid_count
]) + 3;
360 IShellItem_Release(psi
);
366 set_file_name(This
, names
[0]);
367 CoTaskMemFree(names
[0]);
369 else if(valid_count
> 1)
371 LPWSTR string
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
)*len_total
);
372 LPWSTR cur_point
= string
;
374 for(i
= 0; i
< valid_count
; i
++)
376 LPWSTR file
= names
[i
];
378 lstrcpyW(cur_point
, file
);
379 cur_point
+= lstrlenW(file
);
384 *(cur_point
-1) = '\0';
386 set_file_name(This
, string
);
387 HeapFree(GetProcessHeap(), 0, string
);
390 HeapFree(GetProcessHeap(), 0, names
);
394 static LPWSTR
get_first_ext_from_spec(LPWSTR buf
, LPCWSTR spec
)
399 if( (endpos
= StrChrW(buf
, ';')) )
402 ext
= PathFindExtensionW(buf
);
403 if(StrChrW(ext
, '*'))
409 static HRESULT
on_default_action(FileDialogImpl
*This
)
411 IShellFolder
*psf_parent
, *psf_desktop
;
413 LPITEMIDLIST current_folder
;
414 LPWSTR fn_iter
, files
= NULL
, tmp_files
;
415 UINT file_count
= 0, len
, i
;
417 HRESULT hr
, ret
= E_FAIL
;
419 len
= get_file_name(This
, &tmp_files
);
423 file_count
= COMDLG32_SplitFileNames(tmp_files
, len
, &files
, &size_used
);
424 CoTaskMemFree(tmp_files
);
426 if(!file_count
) return E_FAIL
;
428 hr
= SHGetIDListFromObject((IUnknown
*)This
->psi_folder
, ¤t_folder
);
431 ERR("Failed to get pidl for current directory.\n");
432 HeapFree(GetProcessHeap(), 0, files
);
436 TRACE("Acting on %d file(s).\n", file_count
);
438 pidla
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPITEMIDLIST
) * file_count
);
439 open_action
= ONOPEN_OPEN
;
442 for(i
= 0; i
< file_count
&& open_action
== ONOPEN_OPEN
; i
++)
444 WCHAR canon_filename
[MAX_PATH
];
447 COMDLG32_GetCanonicalPath(current_folder
, fn_iter
, canon_filename
);
449 if( (This
->options
& FOS_NOVALIDATE
) &&
450 !(This
->options
& FOS_FILEMUSTEXIST
) )
451 open_action
= ONOPEN_OPEN
;
453 open_action
= ONOPEN_BROWSE
;
455 open_action
= FILEDLG95_ValidatePathAction(canon_filename
, &psf_parent
, This
->dlg_hwnd
,
456 This
->options
& ~FOS_FILEMUSTEXIST
,
457 (This
->dlg_type
== ITEMDLG_TYPE_SAVE
),
460 /* Add the proper extension */
461 if(open_action
== ONOPEN_OPEN
)
463 static const WCHAR dotW
[] = {'.',0};
465 if(This
->dlg_type
== ITEMDLG_TYPE_SAVE
)
467 WCHAR extbuf
[MAX_PATH
], *newext
= NULL
;
469 if(This
->filterspec_count
)
471 newext
= get_first_ext_from_spec(extbuf
, This
->filterspecs
[This
->filetypeindex
].pszSpec
);
473 else if(This
->default_ext
)
475 lstrcpyW(extbuf
, dotW
);
476 lstrcatW(extbuf
, This
->default_ext
);
482 WCHAR
*ext
= PathFindExtensionW(canon_filename
);
483 if(lstrcmpW(ext
, newext
))
484 lstrcatW(canon_filename
, newext
);
489 if( !(This
->options
& FOS_NOVALIDATE
) && (This
->options
& FOS_FILEMUSTEXIST
) &&
490 !PathFileExistsW(canon_filename
))
492 if(This
->default_ext
)
494 lstrcatW(canon_filename
, dotW
);
495 lstrcatW(canon_filename
, This
->default_ext
);
497 if(!PathFileExistsW(canon_filename
))
499 FILEDLG95_OnOpenMessage(This
->dlg_hwnd
, 0, IDS_FILENOTEXISTING
);
500 open_action
= ONOPEN_BROWSE
;
505 FILEDLG95_OnOpenMessage(This
->dlg_hwnd
, 0, IDS_FILENOTEXISTING
);
506 open_action
= ONOPEN_BROWSE
;
512 pidla
[i
] = COMDLG32_SHSimpleIDListFromPathAW(canon_filename
);
514 if(psf_parent
&& !(open_action
== ONOPEN_BROWSE
))
515 IShellFolder_Release(psf_parent
);
517 fn_iter
+= (WCHAR
)lstrlenW(fn_iter
) + 1;
520 HeapFree(GetProcessHeap(), 0, files
);
521 ILFree(current_folder
);
523 if((This
->options
& FOS_PICKFOLDERS
) && open_action
== ONOPEN_BROWSE
)
524 open_action
= ONOPEN_OPEN
; /* FIXME: Multiple folders? */
529 FIXME("Filtering not implemented.\n");
533 hr
= IExplorerBrowser_BrowseToObject(This
->peb
, (IUnknown
*)psf_parent
, SBSP_DEFBROWSER
);
535 ERR("Failed to browse to directory: %08x\n", hr
);
537 IShellFolder_Release(psf_parent
);
541 if(events_OnFileOk(This
) != S_OK
)
544 hr
= SHGetDesktopFolder(&psf_desktop
);
547 if(This
->psia_results
)
548 IShellItemArray_Release(This
->psia_results
);
550 hr
= SHCreateShellItemArray(NULL
, psf_desktop
, file_count
, (PCUITEMID_CHILD_ARRAY
)pidla
,
551 &This
->psia_results
);
555 IShellFolder_Release(psf_desktop
);
565 for(i
= 0; i
< file_count
; i
++)
567 HeapFree(GetProcessHeap(), 0, pidla
);
569 /* Success closes the dialog */
573 /**************************************************************************
576 static inline customctrl
*get_cctrl_from_dlgid(FileDialogImpl
*This
, DWORD dlgid
)
580 LIST_FOR_EACH_ENTRY(ctrl
, &This
->cctrls
, customctrl
, entry
)
581 if(ctrl
->dlgid
== dlgid
)
584 ERR("Failed to find control with dialog id %d\n", dlgid
);
588 static inline customctrl
*get_cctrl(FileDialogImpl
*This
, DWORD ctlid
)
592 LIST_FOR_EACH_ENTRY(ctrl
, &This
->cctrls
, customctrl
, entry
)
593 if(ctrl
->id
== ctlid
)
596 ERR("Failed to find control with control id %d\n", ctlid
);
600 static void ctrl_resize(HWND hctrl
, UINT min_width
, UINT max_width
, BOOL multiline
)
603 UINT len
, final_width
;
604 UINT lines
, final_height
;
612 len
= SendMessageW(hctrl
, WM_GETTEXTLENGTH
, 0, 0);
613 text
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
)*(len
+1));
615 SendMessageW(hctrl
, WM_GETTEXT
, len
+1, (LPARAM
)text
);
618 GetTextExtentPoint32W(hdc
, text
, lstrlenW(text
), &size
);
619 ReleaseDC(hctrl
, hdc
);
623 /* FIXME: line-wrap */
624 for(lines
= 1, c
= text
; *c
!= '\0'; c
++)
625 if(*c
== '\n') lines
++;
627 final_height
= size
.cy
*lines
+ 2*4;
631 GetWindowRect(hctrl
, &rc
);
632 final_height
= rc
.bottom
- rc
.top
;
635 final_width
= min(max(size
.cx
, min_width
) + 4, max_width
);
636 SetWindowPos(hctrl
, NULL
, 0, 0, final_width
, final_height
,
637 SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOACTIVATE
);
639 HeapFree(GetProcessHeap(), 0, text
);
642 static void customctrl_resize(FileDialogImpl
*This
, customctrl
*ctrl
)
648 case IDLG_CCTRL_PUSHBUTTON
:
649 case IDLG_CCTRL_COMBOBOX
:
650 case IDLG_CCTRL_CHECKBUTTON
:
651 case IDLG_CCTRL_TEXT
:
652 ctrl_resize(ctrl
->hwnd
, 160, 160, TRUE
);
653 GetWindowRect(ctrl
->hwnd
, &rc
);
654 SetWindowPos(ctrl
->wrapper_hwnd
, NULL
, 0, 0, rc
.right
-rc
.left
, rc
.bottom
-rc
.top
,
655 SWP_NOZORDER
|SWP_NOMOVE
|SWP_NOZORDER
);
657 case IDLG_CCTRL_RADIOBUTTONLIST
:
658 case IDLG_CCTRL_EDITBOX
:
659 case IDLG_CCTRL_SEPARATOR
:
660 case IDLG_CCTRL_MENU
:
666 static LRESULT
notifysink_on_create(HWND hwnd
, CREATESTRUCTW
*crs
)
668 FileDialogImpl
*This
= crs
->lpCreateParams
;
671 SetWindowLongPtrW(hwnd
, GWLP_USERDATA
, (LPARAM
)This
);
675 static LRESULT
notifysink_on_bn_clicked(FileDialogImpl
*This
, HWND hwnd
, WPARAM wparam
)
677 customctrl
*ctrl
= get_cctrl_from_dlgid(This
, LOWORD(wparam
));
679 TRACE("%p, %lx\n", This
, wparam
);
683 if(ctrl
->type
== IDLG_CCTRL_CHECKBUTTON
)
685 BOOL checked
= (SendMessageW(ctrl
->hwnd
, BM_GETCHECK
, 0, 0) == BST_CHECKED
);
686 cctrl_event_OnCheckButtonToggled(This
, ctrl
->id
, checked
);
689 cctrl_event_OnButtonClicked(This
, ctrl
->id
);
695 static LRESULT
notifysink_on_cbn_selchange(FileDialogImpl
*This
, HWND hwnd
, WPARAM wparam
)
697 customctrl
*ctrl
= get_cctrl_from_dlgid(This
, LOWORD(wparam
));
698 TRACE("%p, %p (%lx)\n", This
, ctrl
, wparam
);
702 UINT index
= SendMessageW(ctrl
->hwnd
, CB_GETCURSEL
, 0, 0);
703 UINT selid
= SendMessageW(ctrl
->hwnd
, CB_GETITEMDATA
, index
, 0);
705 cctrl_event_OnItemSelected(This
, ctrl
->id
, selid
);
710 static LRESULT
notifysink_on_tvn_dropdown(FileDialogImpl
*This
, LPARAM lparam
)
712 NMTOOLBARW
*nmtb
= (NMTOOLBARW
*)lparam
;
713 customctrl
*ctrl
= get_cctrl_from_dlgid(This
, GetDlgCtrlID(nmtb
->hdr
.hwndFrom
));
714 POINT pt
= { 0, nmtb
->rcButton
.bottom
};
718 TRACE("%p, %p (%lx)\n", This
, ctrl
, lparam
);
722 cctrl_event_OnControlActivating(This
,ctrl
->id
);
724 SendMessageW(ctrl
->hwnd
, TB_GETBUTTON
, 0, (LPARAM
)&tbb
);
725 ClientToScreen(ctrl
->hwnd
, &pt
);
726 idcmd
= TrackPopupMenu((HMENU
)tbb
.dwData
, TPM_RETURNCMD
, pt
.x
, pt
.y
, 0, This
->dlg_hwnd
, NULL
);
728 cctrl_event_OnItemSelected(This
, ctrl
->id
, idcmd
);
731 return TBDDRET_DEFAULT
;
734 static LRESULT
notifysink_on_wm_command(FileDialogImpl
*This
, HWND hwnd
, WPARAM wparam
, LPARAM lparam
)
736 switch(HIWORD(wparam
))
738 case BN_CLICKED
: return notifysink_on_bn_clicked(This
, hwnd
, wparam
);
739 case CBN_SELCHANGE
: return notifysink_on_cbn_selchange(This
, hwnd
, wparam
);
745 static LRESULT
notifysink_on_wm_notify(FileDialogImpl
*This
, HWND hwnd
, WPARAM wparam
, LPARAM lparam
)
747 NMHDR
*nmhdr
= (NMHDR
*)lparam
;
751 case TBN_DROPDOWN
: return notifysink_on_tvn_dropdown(This
, lparam
);
757 static LRESULT CALLBACK
notifysink_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
759 FileDialogImpl
*This
= (FileDialogImpl
*)GetWindowLongPtrW(hwnd
, GWLP_USERDATA
);
765 case WM_NCCREATE
: return notifysink_on_create(hwnd
, (CREATESTRUCTW
*)lparam
);
766 case WM_COMMAND
: return notifysink_on_wm_command(This
, hwnd
, wparam
, lparam
);
767 case WM_NOTIFY
: return notifysink_on_wm_notify(This
, hwnd
, wparam
, lparam
);
769 hwnd_child
= GetPropW(hwnd
, notifysink_childW
);
770 GetClientRect(hwnd
, &rc
);
771 SetWindowPos(hwnd_child
, NULL
, 0, 0, rc
.right
, rc
.bottom
, SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_NOZORDER
);
775 return DefWindowProcW(hwnd
, message
, wparam
, lparam
);
778 static HRESULT
cctrl_create_new(FileDialogImpl
*This
, DWORD id
,
779 LPCWSTR text
, LPCWSTR wndclass
, DWORD ctrl_wsflags
,
780 DWORD ctrl_exflags
, UINT height
, customctrl
**ppctrl
)
782 HWND ns_hwnd
, control_hwnd
;
783 DWORD wsflags
= WS_CHILD
| WS_VISIBLE
| WS_CLIPSIBLINGS
;
786 if(get_cctrl(This
, id
))
787 return E_UNEXPECTED
; /* Duplicate id */
789 ns_hwnd
= CreateWindowExW(0, floatnotifysinkW
, NULL
, wsflags
,
790 0, 0, This
->cctrl_width
, height
, This
->cctrls_hwnd
,
791 (HMENU
)This
->cctrl_next_dlgid
, COMDLG32_hInstance
, This
);
792 control_hwnd
= CreateWindowExW(ctrl_exflags
, wndclass
, text
, wsflags
| ctrl_wsflags
,
793 0, 0, This
->cctrl_width
, height
, ns_hwnd
,
794 (HMENU
)This
->cctrl_next_dlgid
, COMDLG32_hInstance
, 0);
796 if(!ns_hwnd
|| !control_hwnd
)
798 ERR("Failed to create wrapper (%p) or control (%p)\n", ns_hwnd
, control_hwnd
);
799 DestroyWindow(ns_hwnd
);
800 DestroyWindow(control_hwnd
);
805 SetPropW(ns_hwnd
, notifysink_childW
, control_hwnd
);
807 ctrl
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(customctrl
));
809 return E_OUTOFMEMORY
;
811 ctrl
->hwnd
= control_hwnd
;
812 ctrl
->wrapper_hwnd
= ns_hwnd
;
814 ctrl
->dlgid
= This
->cctrl_next_dlgid
;
815 ctrl
->cdcstate
= CDCS_ENABLED
| CDCS_VISIBLE
;
816 list_add_tail(&This
->cctrls
, &ctrl
->entry
);
817 if(ppctrl
) *ppctrl
= ctrl
;
819 This
->cctrl_next_dlgid
++;
823 /**************************************************************************
824 * Container functions.
826 static UINT
ctrl_container_resize(FileDialogImpl
*This
, UINT container_width
)
828 UINT container_height
;
831 UINT max_control_height
, total_height
= 0;
832 UINT cur_col_pos
, cur_row_pos
;
835 static const UINT col_indent
= 100; /* The first column is indented 100px */
836 static const UINT cspacing
= 90; /* Columns are spaced with 90px */
837 static const UINT rspacing
= 4; /* Rows are spaced with 4 px. */
839 /* Given the new width of the container, this function determines the
840 * needed height of the container and places the controls according to
841 * the new layout. Returns the new height.
846 column_width
= This
->cctrl_width
+ cspacing
;
847 nr_of_cols
= (container_width
- col_indent
+ cspacing
) / column_width
;
849 /* We don't need to do anything unless the number of visible columns has changed. */
850 if(nr_of_cols
== This
->cctrls_cols
)
853 GetWindowRect(This
->cctrls_hwnd
, &rc
);
854 return rc
.bottom
- rc
.top
;
857 This
->cctrls_cols
= nr_of_cols
;
859 /* Get the size of the tallest control, and the total size of
860 * all the controls to figure out the number of slots we need.
862 max_control_height
= 0;
863 LIST_FOR_EACH_ENTRY(ctrl
, &This
->cctrls
, customctrl
, entry
)
865 if(ctrl
->cdcstate
& CDCS_VISIBLE
)
869 GetWindowRect(ctrl
->wrapper_hwnd
, &rc
);
870 control_height
= rc
.bottom
- rc
.top
;
871 max_control_height
= max(max_control_height
, control_height
);
873 total_height
+= control_height
+ rspacing
;
880 container_height
= max(total_height
/ nr_of_cols
, max_control_height
+ rspacing
);
881 TRACE("Guess: container_height: %d\n",container_height
);
883 /* Incrementally increase container_height until all the controls
887 UINT columns_needed
= 1;
891 LIST_FOR_EACH_ENTRY(ctrl
, &This
->cctrls
, customctrl
, entry
)
893 if(ctrl
->cdcstate
& CDCS_VISIBLE
)
897 GetWindowRect(ctrl
->wrapper_hwnd
, &rc
);
898 control_height
= rc
.bottom
- rc
.top
;
900 if(cur_row_pos
+ control_height
> container_height
)
902 if(++columns_needed
> nr_of_cols
)
904 container_height
+= 1;
911 cur_row_pos
+= control_height
+ rspacing
;
914 } while(!fits_height
);
916 TRACE("Final container height: %d\n", container_height
);
918 /* Move the controls to their final destination
920 cur_col_pos
= col_indent
, cur_row_pos
= 0;
921 LIST_FOR_EACH_ENTRY(ctrl
, &This
->cctrls
, customctrl
, entry
)
923 if(ctrl
->cdcstate
& CDCS_VISIBLE
)
927 GetWindowRect(ctrl
->wrapper_hwnd
, &rc
);
928 control_height
= rc
.bottom
- rc
.top
;
930 if(cur_row_pos
+ control_height
> container_height
)
933 cur_col_pos
+= This
->cctrl_width
+ cspacing
;
936 SetWindowPos(ctrl
->wrapper_hwnd
, NULL
, cur_col_pos
, cur_row_pos
, 0, 0,
937 SWP_NOACTIVATE
| SWP_NOSIZE
| SWP_NOZORDER
);
939 cur_row_pos
+= control_height
+ rspacing
;
944 if(cur_row_pos
+ This
->cctrl_width
> container_width
)
945 ERR("-- Failed to place controls properly.\n");
947 return container_height
;
950 static void ctrl_container_reparent(FileDialogImpl
*This
, HWND parent
)
959 wndstyle
= GetWindowLongW(This
->cctrls_hwnd
, GWL_STYLE
);
960 wndstyle
&= ~(WS_POPUP
);
961 wndstyle
|= WS_CHILD
;
962 SetWindowLongW(This
->cctrls_hwnd
, GWL_STYLE
, wndstyle
);
964 SetParent(This
->cctrls_hwnd
, parent
);
965 ShowWindow(This
->cctrls_hwnd
, TRUE
);
967 /* Set the fonts to match the dialog font. */
968 font
= (HFONT
)SendMessageW(parent
, WM_GETFONT
, 0, 0);
970 ERR("Failed to get font handle from dialog.\n");
972 LIST_FOR_EACH_ENTRY(ctrl
, &This
->cctrls
, customctrl
, entry
)
974 if(font
) SendMessageW(ctrl
->hwnd
, WM_SETFONT
, (WPARAM
)font
, TRUE
);
975 customctrl_resize(This
, ctrl
);
980 ShowWindow(This
->cctrls_hwnd
, FALSE
);
982 wndstyle
= GetWindowLongW(This
->cctrls_hwnd
, GWL_STYLE
);
983 wndstyle
&= ~(WS_CHILD
);
984 wndstyle
|= WS_POPUP
;
985 SetWindowLongW(This
->cctrls_hwnd
, GWL_STYLE
, wndstyle
);
987 SetParent(This
->cctrls_hwnd
, NULL
);
991 static LRESULT
ctrl_container_on_create(HWND hwnd
, CREATESTRUCTW
*crs
)
993 FileDialogImpl
*This
= crs
->lpCreateParams
;
996 SetWindowLongPtrW(hwnd
, GWLP_USERDATA
, (LPARAM
)This
);
1000 static LRESULT
ctrl_container_on_wm_destroy(FileDialogImpl
*This
)
1002 customctrl
*cur1
, *cur2
;
1003 TRACE("%p\n", This
);
1005 LIST_FOR_EACH_ENTRY_SAFE(cur1
, cur2
, &This
->cctrls
, customctrl
, entry
)
1007 TRACE("Freeing control %p\n", cur1
);
1008 list_remove(&cur1
->entry
);
1010 if(cur1
->type
== IDLG_CCTRL_MENU
)
1013 SendMessageW(cur1
->hwnd
, TB_GETBUTTON
, 0, (LPARAM
)&tbb
);
1014 DestroyMenu((HMENU
)tbb
.dwData
);
1017 DestroyWindow(cur1
->hwnd
);
1018 HeapFree(GetProcessHeap(), 0, cur1
);
1024 static LRESULT CALLBACK
ctrl_container_wndproc(HWND hwnd
, UINT umessage
, WPARAM wparam
, LPARAM lparam
)
1026 FileDialogImpl
*This
= (FileDialogImpl
*)GetWindowLongPtrW(hwnd
, GWLP_USERDATA
);
1030 case WM_NCCREATE
: return ctrl_container_on_create(hwnd
, (CREATESTRUCTW
*)lparam
);
1031 case WM_DESTROY
: return ctrl_container_on_wm_destroy(This
);
1032 default: return DefWindowProcW(hwnd
, umessage
, wparam
, lparam
);
1038 static HRESULT
init_custom_controls(FileDialogImpl
*This
)
1041 static const WCHAR ctrl_container_classname
[] =
1042 {'i','d','l','g','_','c','o','n','t','a','i','n','e','r','_','p','a','n','e',0};
1044 InitCommonControlsEx(NULL
);
1046 This
->cctrl_width
= 160; /* Controls have a fixed width */
1047 This
->cctrl_def_height
= 23;
1048 This
->cctrls_cols
= 0;
1050 This
->cctrl_next_dlgid
= 0x2000;
1051 list_init(&This
->cctrls
);
1053 if( !GetClassInfoW(COMDLG32_hInstance
, ctrl_container_classname
, &wc
) )
1055 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
1056 wc
.lpfnWndProc
= ctrl_container_wndproc
;
1059 wc
.hInstance
= COMDLG32_hInstance
;
1061 wc
.hCursor
= LoadCursorW(0, (LPWSTR
)IDC_ARROW
);
1062 wc
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
1063 wc
.lpszMenuName
= NULL
;
1064 wc
.lpszClassName
= ctrl_container_classname
;
1066 if(!RegisterClassW(&wc
)) return E_FAIL
;
1069 This
->cctrls_hwnd
= CreateWindowExW(0, ctrl_container_classname
, NULL
,
1070 WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
,
1071 0, 0, 0, 0, NULL
, 0,
1072 COMDLG32_hInstance
, (void*)This
);
1073 if(!This
->cctrls_hwnd
)
1076 SetWindowLongW(This
->cctrls_hwnd
, GWL_STYLE
, WS_TABSTOP
);
1078 /* Register class for */
1079 if( !GetClassInfoW(COMDLG32_hInstance
, floatnotifysinkW
, &wc
) ||
1080 wc
.hInstance
!= COMDLG32_hInstance
)
1082 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
1083 wc
.lpfnWndProc
= notifysink_proc
;
1086 wc
.hInstance
= COMDLG32_hInstance
;
1088 wc
.hCursor
= LoadCursorW(0, (LPWSTR
)IDC_ARROW
);
1089 wc
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
1090 wc
.lpszMenuName
= NULL
;
1091 wc
.lpszClassName
= floatnotifysinkW
;
1093 if (!RegisterClassW(&wc
))
1094 ERR("Failed to register FloatNotifySink window class.\n");
1100 /**************************************************************************
1101 * Window related functions.
1103 static SIZE
update_layout(FileDialogImpl
*This
)
1108 RECT cancel_rc
, open_rc
;
1109 RECT filetype_rc
, filename_rc
, filenamelabel_rc
;
1110 RECT toolbar_rc
, ebrowser_rc
, customctrls_rc
;
1111 int missing_width
, missing_height
;
1112 static const UINT vspacing
= 4, hspacing
= 4;
1115 GetClientRect(This
->dlg_hwnd
, &dialog_rc
);
1117 missing_width
= max(0, 320 - dialog_rc
.right
);
1118 missing_height
= max(0, 200 - dialog_rc
.bottom
);
1120 if(missing_width
|| missing_height
)
1122 TRACE("Missing (%d, %d)\n", missing_width
, missing_height
);
1123 ret
.cx
= missing_width
;
1124 ret
.cy
= missing_height
;
1129 * Calculate the size of the dialog and all the parts.
1133 hwnd
= GetDlgItem(This
->dlg_hwnd
, IDCANCEL
);
1136 int cancel_width
, cancel_height
;
1137 GetWindowRect(hwnd
, &cancel_rc
);
1138 cancel_width
= cancel_rc
.right
- cancel_rc
.left
;
1139 cancel_height
= cancel_rc
.bottom
- cancel_rc
.top
;
1141 cancel_rc
.left
= dialog_rc
.right
- cancel_width
- hspacing
;
1142 cancel_rc
.top
= dialog_rc
.bottom
- cancel_height
- vspacing
;
1143 cancel_rc
.right
= cancel_rc
.left
+ cancel_width
;
1144 cancel_rc
.bottom
= cancel_rc
.top
+ cancel_height
;
1147 /* Open/Save button */
1148 hwnd
= GetDlgItem(This
->dlg_hwnd
, IDOK
);
1151 int open_width
, open_height
;
1152 GetWindowRect(hwnd
, &open_rc
);
1153 open_width
= open_rc
.right
- open_rc
.left
;
1154 open_height
= open_rc
.bottom
- open_rc
.top
;
1156 open_rc
.left
= cancel_rc
.left
- open_width
- hspacing
;
1157 open_rc
.top
= cancel_rc
.top
;
1158 open_rc
.right
= open_rc
.left
+ open_width
;
1159 open_rc
.bottom
= open_rc
.top
+ open_height
;
1162 /* The filetype combobox. */
1163 hwnd
= GetDlgItem(This
->dlg_hwnd
, IDC_FILETYPE
);
1166 int filetype_width
, filetype_height
;
1167 GetWindowRect(hwnd
, &filetype_rc
);
1169 filetype_width
= filetype_rc
.right
- filetype_rc
.left
;
1170 filetype_height
= filetype_rc
.bottom
- filetype_rc
.top
;
1172 filetype_rc
.right
= cancel_rc
.right
;
1174 filetype_rc
.left
= filetype_rc
.right
- filetype_width
;
1175 filetype_rc
.top
= cancel_rc
.top
- filetype_height
- vspacing
;
1176 filetype_rc
.bottom
= filetype_rc
.top
+ filetype_height
;
1178 if(!This
->filterspec_count
)
1179 filetype_rc
.left
= filetype_rc
.right
;
1182 /* Filename label. */
1183 hwnd
= GetDlgItem(This
->dlg_hwnd
, IDC_FILENAMESTATIC
);
1186 int filetypelabel_width
, filetypelabel_height
;
1187 GetWindowRect(hwnd
, &filenamelabel_rc
);
1189 filetypelabel_width
= filenamelabel_rc
.right
- filenamelabel_rc
.left
;
1190 filetypelabel_height
= filenamelabel_rc
.bottom
- filenamelabel_rc
.top
;
1192 filenamelabel_rc
.left
= 160; /* FIXME */
1193 filenamelabel_rc
.top
= filetype_rc
.top
;
1194 filenamelabel_rc
.right
= filenamelabel_rc
.left
+ filetypelabel_width
;
1195 filenamelabel_rc
.bottom
= filenamelabel_rc
.top
+ filetypelabel_height
;
1198 /* Filename edit box. */
1199 hwnd
= GetDlgItem(This
->dlg_hwnd
, IDC_FILENAME
);
1202 int filename_width
, filename_height
;
1203 GetWindowRect(hwnd
, &filename_rc
);
1205 filename_width
= filetype_rc
.left
- filenamelabel_rc
.right
- hspacing
*2;
1206 filename_height
= filename_rc
.bottom
- filename_rc
.top
;
1208 filename_rc
.left
= filenamelabel_rc
.right
+ hspacing
;
1209 filename_rc
.top
= filetype_rc
.top
;
1210 filename_rc
.right
= filename_rc
.left
+ filename_width
;
1211 filename_rc
.bottom
= filename_rc
.top
+ filename_height
;
1214 hwnd
= GetDlgItem(This
->dlg_hwnd
, IDC_NAV_TOOLBAR
);
1217 GetWindowRect(hwnd
, &toolbar_rc
);
1218 MapWindowPoints(NULL
, This
->dlg_hwnd
, (POINT
*)&toolbar_rc
, 2);
1221 /* The custom controls */
1222 customctrls_rc
.left
= dialog_rc
.left
+ hspacing
;
1223 customctrls_rc
.right
= dialog_rc
.right
- hspacing
;
1224 customctrls_rc
.bottom
= filename_rc
.top
- vspacing
;
1225 customctrls_rc
.top
= customctrls_rc
.bottom
-
1226 ctrl_container_resize(This
, customctrls_rc
.right
- customctrls_rc
.left
);
1228 /* The ExplorerBrowser control. */
1229 ebrowser_rc
.left
= dialog_rc
.left
+ hspacing
;
1230 ebrowser_rc
.top
= toolbar_rc
.bottom
+ vspacing
;
1231 ebrowser_rc
.right
= dialog_rc
.right
- hspacing
;
1232 ebrowser_rc
.bottom
= customctrls_rc
.top
- vspacing
;
1235 * Move everything to the right place.
1238 /* FIXME: The Save Dialog uses a slightly different layout. */
1239 hdwp
= BeginDeferWindowPos(7);
1241 if(hdwp
&& This
->peb
)
1242 IExplorerBrowser_SetRect(This
->peb
, &hdwp
, ebrowser_rc
);
1244 if(hdwp
&& This
->cctrls_hwnd
)
1245 DeferWindowPos(hdwp
, This
->cctrls_hwnd
, NULL
,
1246 customctrls_rc
.left
, customctrls_rc
.top
,
1247 customctrls_rc
.right
- customctrls_rc
.left
, customctrls_rc
.bottom
- customctrls_rc
.top
,
1248 SWP_NOZORDER
| SWP_NOACTIVATE
);
1250 /* The default controls */
1251 if(hdwp
&& (hwnd
= GetDlgItem(This
->dlg_hwnd
, IDC_FILETYPE
)) )
1252 DeferWindowPos(hdwp
, hwnd
, NULL
, filetype_rc
.left
, filetype_rc
.top
, 0, 0,
1253 SWP_NOZORDER
| SWP_NOSIZE
| SWP_NOACTIVATE
);
1255 if(hdwp
&& (hwnd
= GetDlgItem(This
->dlg_hwnd
, IDC_FILENAME
)) )
1256 DeferWindowPos(hdwp
, hwnd
, NULL
, filename_rc
.left
, filename_rc
.top
,
1257 filename_rc
.right
- filename_rc
.left
, filename_rc
.bottom
- filename_rc
.top
,
1258 SWP_NOZORDER
| SWP_NOACTIVATE
);
1260 if(hdwp
&& (hwnd
= GetDlgItem(This
->dlg_hwnd
, IDC_FILENAMESTATIC
)) )
1261 DeferWindowPos(hdwp
, hwnd
, NULL
, filenamelabel_rc
.left
, filenamelabel_rc
.top
, 0, 0,
1262 SWP_NOZORDER
| SWP_NOSIZE
| SWP_NOACTIVATE
);
1264 if(hdwp
&& (hwnd
= GetDlgItem(This
->dlg_hwnd
, IDOK
)) )
1265 DeferWindowPos(hdwp
, hwnd
, NULL
, open_rc
.left
, open_rc
.top
, 0, 0,
1266 SWP_NOZORDER
| SWP_NOSIZE
| SWP_NOACTIVATE
);
1268 if(hdwp
&& (hwnd
= GetDlgItem(This
->dlg_hwnd
, IDCANCEL
)) )
1269 DeferWindowPos(hdwp
, hwnd
, NULL
, cancel_rc
.left
, cancel_rc
.top
, 0, 0,
1270 SWP_NOZORDER
| SWP_NOSIZE
| SWP_NOACTIVATE
);
1273 EndDeferWindowPos(hdwp
);
1275 ERR("Failed to position dialog controls.\n");
1277 ret
.cx
= 0; ret
.cy
= 0;
1281 static HRESULT
init_explorerbrowser(FileDialogImpl
*This
)
1283 IShellItem
*psi_folder
;
1288 /* Create ExplorerBrowser instance */
1289 OleInitialize(NULL
);
1291 hr
= CoCreateInstance(&CLSID_ExplorerBrowser
, NULL
, CLSCTX_INPROC_SERVER
,
1292 &IID_IExplorerBrowser
, (void**)&This
->peb
);
1295 ERR("Failed to instantiate ExplorerBrowser control.\n");
1299 IExplorerBrowser_SetOptions(This
->peb
, EBO_SHOWFRAMES
);
1301 hr
= IExplorerBrowser_Initialize(This
->peb
, This
->dlg_hwnd
, &rc
, NULL
);
1304 ERR("Failed to initialize the ExplorerBrowser control.\n");
1305 IExplorerBrowser_Release(This
->peb
);
1309 hr
= IExplorerBrowser_Advise(This
->peb
, &This
->IExplorerBrowserEvents_iface
, &This
->ebevents_cookie
);
1311 ERR("Advise (ExplorerBrowser) failed.\n");
1313 /* Get previous options? */
1314 fos
.ViewMode
= fos
.fFlags
= 0;
1315 if(!(This
->options
& FOS_ALLOWMULTISELECT
))
1316 fos
.fFlags
|= FWF_SINGLESEL
;
1318 IExplorerBrowser_SetFolderSettings(This
->peb
, &fos
);
1320 hr
= IUnknown_SetSite((IUnknown
*)This
->peb
, (IUnknown
*)This
);
1322 ERR("SetSite (ExplorerBrowser) failed.\n");
1324 /* Browse somewhere */
1325 psi_folder
= This
->psi_setfolder
? This
->psi_setfolder
: This
->psi_defaultfolder
;
1326 IExplorerBrowser_BrowseToObject(This
->peb
, (IUnknown
*)psi_folder
, SBSP_DEFBROWSER
);
1331 static void init_toolbar(FileDialogImpl
*This
, HWND hwnd
)
1337 htoolbar
= CreateWindowExW(0, TOOLBARCLASSNAMEW
, NULL
, TBSTYLE_FLAT
| WS_CHILD
| WS_VISIBLE
,
1339 hwnd
, (HMENU
)IDC_NAV_TOOLBAR
, NULL
, NULL
);
1341 tbab
.hInst
= HINST_COMMCTRL
;
1342 tbab
.nID
= IDB_HIST_LARGE_COLOR
;
1343 SendMessageW(htoolbar
, TB_ADDBITMAP
, 0, (LPARAM
)&tbab
);
1345 button
[0].iBitmap
= HIST_BACK
;
1346 button
[0].idCommand
= IDC_NAVBACK
;
1347 button
[0].fsState
= TBSTATE_ENABLED
;
1348 button
[0].fsStyle
= BTNS_BUTTON
;
1349 button
[0].dwData
= 0;
1350 button
[0].iString
= 0;
1352 button
[1].iBitmap
= HIST_FORWARD
;
1353 button
[1].idCommand
= IDC_NAVFORWARD
;
1354 button
[1].fsState
= TBSTATE_ENABLED
;
1355 button
[1].fsStyle
= BTNS_BUTTON
;
1356 button
[1].dwData
= 0;
1357 button
[1].iString
= 0;
1359 SendMessageW(htoolbar
, TB_ADDBUTTONSW
, 2, (LPARAM
)button
);
1360 SendMessageW(htoolbar
, TB_SETBUTTONSIZE
, 0, MAKELPARAM(24,24));
1361 SendMessageW(htoolbar
, TB_AUTOSIZE
, 0, 0);
1364 static void update_control_text(FileDialogImpl
*This
)
1367 if(This
->custom_title
)
1368 SetWindowTextW(This
->dlg_hwnd
, This
->custom_title
);
1370 if(This
->custom_okbutton
&&
1371 (hitem
= GetDlgItem(This
->dlg_hwnd
, IDOK
)))
1373 SetWindowTextW(hitem
, This
->custom_okbutton
);
1374 ctrl_resize(hitem
, 50, 250, FALSE
);
1377 if(This
->custom_cancelbutton
&&
1378 (hitem
= GetDlgItem(This
->dlg_hwnd
, IDCANCEL
)))
1380 SetWindowTextW(hitem
, This
->custom_cancelbutton
);
1381 ctrl_resize(hitem
, 50, 250, FALSE
);
1384 if(This
->custom_filenamelabel
&&
1385 (hitem
= GetDlgItem(This
->dlg_hwnd
, IDC_FILENAMESTATIC
)))
1387 SetWindowTextW(hitem
, This
->custom_filenamelabel
);
1388 ctrl_resize(hitem
, 50, 250, FALSE
);
1392 static LRESULT
on_wm_initdialog(HWND hwnd
, LPARAM lParam
)
1394 FileDialogImpl
*This
= (FileDialogImpl
*)lParam
;
1397 TRACE("(%p, %p)\n", This
, hwnd
);
1399 SetWindowLongPtrW(hwnd
, GWLP_USERDATA
, (LPARAM
)This
);
1400 This
->dlg_hwnd
= hwnd
;
1402 hitem
= GetDlgItem(This
->dlg_hwnd
, pshHelp
);
1403 if(hitem
) ShowWindow(hitem
, SW_HIDE
);
1405 hitem
= GetDlgItem(This
->dlg_hwnd
, IDC_FILETYPESTATIC
);
1406 if(hitem
) ShowWindow(hitem
, SW_HIDE
);
1408 /* Fill filetypes combobox, or hide it. */
1409 hitem
= GetDlgItem(This
->dlg_hwnd
, IDC_FILETYPE
);
1410 if(This
->filterspec_count
)
1413 for(i
= 0; i
< This
->filterspec_count
; i
++)
1414 SendMessageW(hitem
, CB_ADDSTRING
, 0, (LPARAM
)This
->filterspecs
[i
].pszName
);
1416 SendMessageW(hitem
, CB_SETCURSEL
, This
->filetypeindex
, 0);
1419 ShowWindow(hitem
, SW_HIDE
);
1421 if(This
->set_filename
&&
1422 (hitem
= GetDlgItem(This
->dlg_hwnd
, IDC_FILENAME
)) )
1423 SendMessageW(hitem
, WM_SETTEXT
, 0, (LPARAM
)This
->set_filename
);
1425 ctrl_container_reparent(This
, This
->dlg_hwnd
);
1426 init_explorerbrowser(This
);
1427 init_toolbar(This
, hwnd
);
1428 update_control_text(This
);
1429 update_layout(This
);
1434 static LRESULT
on_wm_size(FileDialogImpl
*This
)
1436 update_layout(This
);
1440 static LRESULT
on_wm_getminmaxinfo(FileDialogImpl
*This
, LPARAM lparam
)
1442 MINMAXINFO
*mmi
= (MINMAXINFO
*)lparam
;
1443 TRACE("%p (%p)\n", This
, mmi
);
1446 mmi
->ptMinTrackSize
.x
= 640;
1447 mmi
->ptMinTrackSize
.y
= 480;
1452 static LRESULT
on_wm_destroy(FileDialogImpl
*This
)
1454 TRACE("%p\n", This
);
1458 IExplorerBrowser_Destroy(This
->peb
);
1459 IExplorerBrowser_Release(This
->peb
);
1463 ctrl_container_reparent(This
, NULL
);
1464 This
->dlg_hwnd
= NULL
;
1469 static LRESULT
on_idok(FileDialogImpl
*This
)
1471 TRACE("%p\n", This
);
1473 if(SUCCEEDED(on_default_action(This
)))
1474 EndDialog(This
->dlg_hwnd
, S_OK
);
1479 static LRESULT
on_idcancel(FileDialogImpl
*This
)
1481 TRACE("%p\n", This
);
1483 EndDialog(This
->dlg_hwnd
, HRESULT_FROM_WIN32(ERROR_CANCELLED
));
1488 static LRESULT
on_browse_back(FileDialogImpl
*This
)
1490 TRACE("%p\n", This
);
1491 IExplorerBrowser_BrowseToIDList(This
->peb
, NULL
, SBSP_NAVIGATEBACK
);
1495 static LRESULT
on_browse_forward(FileDialogImpl
*This
)
1497 TRACE("%p\n", This
);
1498 IExplorerBrowser_BrowseToIDList(This
->peb
, NULL
, SBSP_NAVIGATEFORWARD
);
1502 static LRESULT
on_command_filetype(FileDialogImpl
*This
, WPARAM wparam
, LPARAM lparam
)
1504 if(HIWORD(wparam
) == CBN_SELCHANGE
)
1509 UINT prev_index
= This
->filetypeindex
;
1511 This
->filetypeindex
= SendMessageW((HWND
)lparam
, CB_GETCURSEL
, 0, 0);
1512 TRACE("File type selection changed to %d.\n", This
->filetypeindex
);
1514 if(prev_index
== This
->filetypeindex
)
1517 hr
= IExplorerBrowser_GetCurrentView(This
->peb
, &IID_IShellView
, (void**)&psv
);
1520 IShellView_Refresh(psv
);
1521 IShellView_Release(psv
);
1524 if(This
->dlg_type
== ITEMDLG_TYPE_SAVE
&& get_file_name(This
, &filename
))
1526 WCHAR buf
[MAX_PATH
], extbuf
[MAX_PATH
], *ext
;
1528 ext
= get_first_ext_from_spec(extbuf
, This
->filterspecs
[This
->filetypeindex
].pszSpec
);
1531 lstrcpyW(buf
, filename
);
1533 if(PathMatchSpecW(buf
, This
->filterspecs
[prev_index
].pszSpec
))
1534 PathRemoveExtensionW(buf
);
1537 set_file_name(This
, buf
);
1539 CoTaskMemFree(filename
);
1546 static LRESULT
on_wm_command(FileDialogImpl
*This
, WPARAM wparam
, LPARAM lparam
)
1548 switch(LOWORD(wparam
))
1550 case IDOK
: return on_idok(This
);
1551 case IDCANCEL
: return on_idcancel(This
);
1552 case IDC_NAVBACK
: return on_browse_back(This
);
1553 case IDC_NAVFORWARD
: return on_browse_forward(This
);
1554 case IDC_FILETYPE
: return on_command_filetype(This
, wparam
, lparam
);
1555 default: TRACE("Unknown command.\n");
1560 static LRESULT CALLBACK
itemdlg_dlgproc(HWND hwnd
, UINT umessage
, WPARAM wparam
, LPARAM lparam
)
1562 FileDialogImpl
*This
= (FileDialogImpl
*)GetWindowLongPtrW(hwnd
, GWLP_USERDATA
);
1566 case WM_INITDIALOG
: return on_wm_initdialog(hwnd
, lparam
);
1567 case WM_COMMAND
: return on_wm_command(This
, wparam
, lparam
);
1568 case WM_SIZE
: return on_wm_size(This
);
1569 case WM_GETMINMAXINFO
: return on_wm_getminmaxinfo(This
, lparam
);
1570 case WM_DESTROY
: return on_wm_destroy(This
);
1576 static HRESULT
create_dialog(FileDialogImpl
*This
, HWND parent
)
1581 res
= DialogBoxParamW(COMDLG32_hInstance
,
1582 MAKEINTRESOURCEW(NEWFILEOPENV3ORD
),
1583 parent
, itemdlg_dlgproc
, (LPARAM
)This
);
1584 This
->dlg_hwnd
= NULL
;
1587 ERR("Failed to show dialog (LastError: %d)\n", GetLastError());
1591 TRACE("Returning 0x%08x\n", (HRESULT
)res
);
1592 return (HRESULT
)res
;
1595 /**************************************************************************
1596 * IFileDialog implementation
1598 static inline FileDialogImpl
*impl_from_IFileDialog2(IFileDialog2
*iface
)
1600 return CONTAINING_RECORD(iface
, FileDialogImpl
, IFileDialog2_iface
);
1603 static HRESULT WINAPI
IFileDialog2_fnQueryInterface(IFileDialog2
*iface
,
1607 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1608 TRACE("%p (%s, %p)\n", This
, debugstr_guid(riid
), ppvObject
);
1611 if(IsEqualGUID(riid
, &IID_IUnknown
) ||
1612 IsEqualGUID(riid
, &IID_IFileDialog
) ||
1613 IsEqualGUID(riid
, &IID_IFileDialog2
))
1617 else if(IsEqualGUID(riid
, &IID_IFileOpenDialog
) && This
->dlg_type
== ITEMDLG_TYPE_OPEN
)
1619 *ppvObject
= &This
->u
.IFileOpenDialog_iface
;
1621 else if(IsEqualGUID(riid
, &IID_IFileSaveDialog
) && This
->dlg_type
== ITEMDLG_TYPE_SAVE
)
1623 *ppvObject
= &This
->u
.IFileSaveDialog_iface
;
1625 else if(IsEqualGUID(riid
, &IID_IExplorerBrowserEvents
))
1627 *ppvObject
= &This
->IExplorerBrowserEvents_iface
;
1629 else if(IsEqualGUID(riid
, &IID_IServiceProvider
))
1631 *ppvObject
= &This
->IServiceProvider_iface
;
1633 else if(IsEqualGUID(&IID_ICommDlgBrowser3
, riid
) ||
1634 IsEqualGUID(&IID_ICommDlgBrowser2
, riid
) ||
1635 IsEqualGUID(&IID_ICommDlgBrowser
, riid
))
1637 *ppvObject
= &This
->ICommDlgBrowser3_iface
;
1639 else if(IsEqualGUID(&IID_IOleWindow
, riid
))
1641 *ppvObject
= &This
->IOleWindow_iface
;
1643 else if(IsEqualGUID(riid
, &IID_IFileDialogCustomize
) ||
1644 IsEqualGUID(riid
, &IID_IFileDialogCustomizeAlt
))
1646 *ppvObject
= &This
->IFileDialogCustomize_iface
;
1649 FIXME("Unknown interface requested: %s.\n", debugstr_guid(riid
));
1653 IUnknown_AddRef((IUnknown
*)*ppvObject
);
1657 return E_NOINTERFACE
;
1660 static ULONG WINAPI
IFileDialog2_fnAddRef(IFileDialog2
*iface
)
1662 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1663 LONG ref
= InterlockedIncrement(&This
->ref
);
1664 TRACE("%p - ref %d\n", This
, ref
);
1669 static ULONG WINAPI
IFileDialog2_fnRelease(IFileDialog2
*iface
)
1671 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1672 LONG ref
= InterlockedDecrement(&This
->ref
);
1673 TRACE("%p - ref %d\n", This
, ref
);
1678 for(i
= 0; i
< This
->filterspec_count
; i
++)
1680 LocalFree((void*)This
->filterspecs
[i
].pszName
);
1681 LocalFree((void*)This
->filterspecs
[i
].pszSpec
);
1683 HeapFree(GetProcessHeap(), 0, This
->filterspecs
);
1685 DestroyWindow(This
->cctrls_hwnd
);
1687 if(This
->psi_defaultfolder
) IShellItem_Release(This
->psi_defaultfolder
);
1688 if(This
->psi_setfolder
) IShellItem_Release(This
->psi_setfolder
);
1689 if(This
->psi_folder
) IShellItem_Release(This
->psi_folder
);
1690 if(This
->psia_selection
) IShellItemArray_Release(This
->psia_selection
);
1691 if(This
->psia_results
) IShellItemArray_Release(This
->psia_results
);
1693 LocalFree(This
->set_filename
);
1694 LocalFree(This
->default_ext
);
1695 LocalFree(This
->custom_title
);
1696 LocalFree(This
->custom_okbutton
);
1697 LocalFree(This
->custom_cancelbutton
);
1698 LocalFree(This
->custom_filenamelabel
);
1700 HeapFree(GetProcessHeap(), 0, This
);
1706 static HRESULT WINAPI
IFileDialog2_fnShow(IFileDialog2
*iface
, HWND hwndOwner
)
1708 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1709 TRACE("%p (%p)\n", iface
, hwndOwner
);
1711 return create_dialog(This
, hwndOwner
);
1714 static HRESULT WINAPI
IFileDialog2_fnSetFileTypes(IFileDialog2
*iface
, UINT cFileTypes
,
1715 const COMDLG_FILTERSPEC
*rgFilterSpec
)
1717 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1719 TRACE("%p (%d, %p)\n", This
, cFileTypes
, rgFilterSpec
);
1721 if(This
->filterspecs
)
1722 return E_UNEXPECTED
;
1725 return E_INVALIDARG
;
1730 This
->filterspecs
= HeapAlloc(GetProcessHeap(), 0, sizeof(COMDLG_FILTERSPEC
)*cFileTypes
);
1731 for(i
= 0; i
< cFileTypes
; i
++)
1733 This
->filterspecs
[i
].pszName
= StrDupW(rgFilterSpec
[i
].pszName
);
1734 This
->filterspecs
[i
].pszSpec
= StrDupW(rgFilterSpec
[i
].pszSpec
);
1736 This
->filterspec_count
= cFileTypes
;
1741 static HRESULT WINAPI
IFileDialog2_fnSetFileTypeIndex(IFileDialog2
*iface
, UINT iFileType
)
1743 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1744 TRACE("%p (%d)\n", This
, iFileType
);
1746 if(!This
->filterspecs
)
1749 if(iFileType
>= This
->filterspec_count
)
1750 This
->filetypeindex
= This
->filterspec_count
- 1;
1752 This
->filetypeindex
= iFileType
;
1757 static HRESULT WINAPI
IFileDialog2_fnGetFileTypeIndex(IFileDialog2
*iface
, UINT
*piFileType
)
1759 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1760 TRACE("%p (%p)\n", This
, piFileType
);
1763 return E_INVALIDARG
;
1765 *piFileType
= This
->filetypeindex
;
1770 static HRESULT WINAPI
IFileDialog2_fnAdvise(IFileDialog2
*iface
, IFileDialogEvents
*pfde
, DWORD
*pdwCookie
)
1772 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1773 events_client
*client
;
1774 TRACE("%p (%p, %p)\n", This
, pfde
, pdwCookie
);
1776 if(!pfde
|| !pdwCookie
)
1777 return E_INVALIDARG
;
1779 client
= HeapAlloc(GetProcessHeap(), 0, sizeof(events_client
));
1780 client
->pfde
= pfde
;
1781 client
->cookie
= ++This
->events_next_cookie
;
1783 IFileDialogEvents_AddRef(pfde
);
1784 *pdwCookie
= client
->cookie
;
1786 list_add_tail(&This
->events_clients
, &client
->entry
);
1791 static HRESULT WINAPI
IFileDialog2_fnUnadvise(IFileDialog2
*iface
, DWORD dwCookie
)
1793 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1794 events_client
*client
, *found
= NULL
;
1795 TRACE("%p (%d)\n", This
, dwCookie
);
1797 LIST_FOR_EACH_ENTRY(client
, &This
->events_clients
, events_client
, entry
)
1799 if(client
->cookie
== dwCookie
)
1808 list_remove(&found
->entry
);
1809 IFileDialogEvents_Release(found
->pfde
);
1810 HeapFree(GetProcessHeap(), 0, found
);
1814 return E_INVALIDARG
;
1817 static HRESULT WINAPI
IFileDialog2_fnSetOptions(IFileDialog2
*iface
, FILEOPENDIALOGOPTIONS fos
)
1819 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1820 TRACE("%p (0x%x)\n", This
, fos
);
1822 This
->options
= fos
;
1827 static HRESULT WINAPI
IFileDialog2_fnGetOptions(IFileDialog2
*iface
, FILEOPENDIALOGOPTIONS
*pfos
)
1829 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1830 TRACE("%p (%p)\n", This
, pfos
);
1833 return E_INVALIDARG
;
1835 *pfos
= This
->options
;
1840 static HRESULT WINAPI
IFileDialog2_fnSetDefaultFolder(IFileDialog2
*iface
, IShellItem
*psi
)
1842 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1843 TRACE("%p (%p)\n", This
, psi
);
1844 if(This
->psi_defaultfolder
)
1845 IShellItem_Release(This
->psi_defaultfolder
);
1847 This
->psi_defaultfolder
= psi
;
1849 if(This
->psi_defaultfolder
)
1850 IShellItem_AddRef(This
->psi_defaultfolder
);
1855 static HRESULT WINAPI
IFileDialog2_fnSetFolder(IFileDialog2
*iface
, IShellItem
*psi
)
1857 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1858 TRACE("%p (%p)\n", This
, psi
);
1859 if(This
->psi_setfolder
)
1860 IShellItem_Release(This
->psi_setfolder
);
1862 This
->psi_setfolder
= psi
;
1864 if(This
->psi_setfolder
)
1865 IShellItem_AddRef(This
->psi_setfolder
);
1870 static HRESULT WINAPI
IFileDialog2_fnGetFolder(IFileDialog2
*iface
, IShellItem
**ppsi
)
1872 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1873 TRACE("%p (%p)\n", This
, ppsi
);
1875 return E_INVALIDARG
;
1878 If the dialog is shown, return the current(ly selected) folder. */
1881 if(This
->psi_folder
)
1882 *ppsi
= This
->psi_folder
;
1883 else if(This
->psi_setfolder
)
1884 *ppsi
= This
->psi_setfolder
;
1885 else if(This
->psi_defaultfolder
)
1886 *ppsi
= This
->psi_defaultfolder
;
1890 IShellItem_AddRef(*ppsi
);
1897 static HRESULT WINAPI
IFileDialog2_fnGetCurrentSelection(IFileDialog2
*iface
, IShellItem
**ppsi
)
1899 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1901 TRACE("%p (%p)\n", This
, ppsi
);
1904 return E_INVALIDARG
;
1906 if(This
->psia_selection
)
1908 /* FIXME: Check filename edit box */
1909 hr
= IShellItemArray_GetItemAt(This
->psia_selection
, 0, ppsi
);
1916 static HRESULT WINAPI
IFileDialog2_fnSetFileName(IFileDialog2
*iface
, LPCWSTR pszName
)
1918 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1919 TRACE("%p (%s)\n", iface
, debugstr_w(pszName
));
1921 set_file_name(This
, pszName
);
1926 static HRESULT WINAPI
IFileDialog2_fnGetFileName(IFileDialog2
*iface
, LPWSTR
*pszName
)
1928 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1929 TRACE("%p (%p)\n", iface
, pszName
);
1932 return E_INVALIDARG
;
1935 if(get_file_name(This
, pszName
))
1941 static HRESULT WINAPI
IFileDialog2_fnSetTitle(IFileDialog2
*iface
, LPCWSTR pszTitle
)
1943 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1944 TRACE("%p (%s)\n", This
, debugstr_w(pszTitle
));
1946 LocalFree(This
->custom_title
);
1947 This
->custom_title
= StrDupW(pszTitle
);
1948 update_control_text(This
);
1953 static HRESULT WINAPI
IFileDialog2_fnSetOkButtonLabel(IFileDialog2
*iface
, LPCWSTR pszText
)
1955 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1956 TRACE("%p (%s)\n", This
, debugstr_w(pszText
));
1958 LocalFree(This
->custom_okbutton
);
1959 This
->custom_okbutton
= StrDupW(pszText
);
1960 update_control_text(This
);
1961 update_layout(This
);
1966 static HRESULT WINAPI
IFileDialog2_fnSetFileNameLabel(IFileDialog2
*iface
, LPCWSTR pszLabel
)
1968 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1969 TRACE("%p (%s)\n", This
, debugstr_w(pszLabel
));
1971 LocalFree(This
->custom_filenamelabel
);
1972 This
->custom_filenamelabel
= StrDupW(pszLabel
);
1973 update_control_text(This
);
1974 update_layout(This
);
1979 static HRESULT WINAPI
IFileDialog2_fnGetResult(IFileDialog2
*iface
, IShellItem
**ppsi
)
1981 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
1983 TRACE("%p (%p)\n", This
, ppsi
);
1986 return E_INVALIDARG
;
1988 if(This
->psia_results
)
1991 hr
= IShellItemArray_GetCount(This
->psia_results
, &item_count
);
1997 /* Adds a reference. */
1998 hr
= IShellItemArray_GetItemAt(This
->psia_results
, 0, ppsi
);
2004 return E_UNEXPECTED
;
2007 static HRESULT WINAPI
IFileDialog2_fnAddPlace(IFileDialog2
*iface
, IShellItem
*psi
, FDAP fdap
)
2009 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2010 FIXME("stub - %p (%p, %d)\n", This
, psi
, fdap
);
2014 static HRESULT WINAPI
IFileDialog2_fnSetDefaultExtension(IFileDialog2
*iface
, LPCWSTR pszDefaultExtension
)
2016 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2017 TRACE("%p (%s)\n", This
, debugstr_w(pszDefaultExtension
));
2019 LocalFree(This
->default_ext
);
2020 This
->default_ext
= StrDupW(pszDefaultExtension
);
2025 static HRESULT WINAPI
IFileDialog2_fnClose(IFileDialog2
*iface
, HRESULT hr
)
2027 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2028 TRACE("%p (0x%08x)\n", This
, hr
);
2031 EndDialog(This
->dlg_hwnd
, hr
);
2036 static HRESULT WINAPI
IFileDialog2_fnSetClientGuid(IFileDialog2
*iface
, REFGUID guid
)
2038 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2039 TRACE("%p (%s)\n", This
, debugstr_guid(guid
));
2040 This
->client_guid
= *guid
;
2044 static HRESULT WINAPI
IFileDialog2_fnClearClientData(IFileDialog2
*iface
)
2046 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2047 FIXME("stub - %p\n", This
);
2051 static HRESULT WINAPI
IFileDialog2_fnSetFilter(IFileDialog2
*iface
, IShellItemFilter
*pFilter
)
2053 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2054 FIXME("stub - %p (%p)\n", This
, pFilter
);
2058 static HRESULT WINAPI
IFileDialog2_fnSetCancelButtonLabel(IFileDialog2
*iface
, LPCWSTR pszLabel
)
2060 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2061 TRACE("%p (%s)\n", This
, debugstr_w(pszLabel
));
2063 LocalFree(This
->custom_cancelbutton
);
2064 This
->custom_cancelbutton
= StrDupW(pszLabel
);
2065 update_control_text(This
);
2066 update_layout(This
);
2071 static HRESULT WINAPI
IFileDialog2_fnSetNavigationRoot(IFileDialog2
*iface
, IShellItem
*psi
)
2073 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2074 FIXME("stub - %p (%p)\n", This
, psi
);
2078 static const IFileDialog2Vtbl vt_IFileDialog2
= {
2079 IFileDialog2_fnQueryInterface
,
2080 IFileDialog2_fnAddRef
,
2081 IFileDialog2_fnRelease
,
2082 IFileDialog2_fnShow
,
2083 IFileDialog2_fnSetFileTypes
,
2084 IFileDialog2_fnSetFileTypeIndex
,
2085 IFileDialog2_fnGetFileTypeIndex
,
2086 IFileDialog2_fnAdvise
,
2087 IFileDialog2_fnUnadvise
,
2088 IFileDialog2_fnSetOptions
,
2089 IFileDialog2_fnGetOptions
,
2090 IFileDialog2_fnSetDefaultFolder
,
2091 IFileDialog2_fnSetFolder
,
2092 IFileDialog2_fnGetFolder
,
2093 IFileDialog2_fnGetCurrentSelection
,
2094 IFileDialog2_fnSetFileName
,
2095 IFileDialog2_fnGetFileName
,
2096 IFileDialog2_fnSetTitle
,
2097 IFileDialog2_fnSetOkButtonLabel
,
2098 IFileDialog2_fnSetFileNameLabel
,
2099 IFileDialog2_fnGetResult
,
2100 IFileDialog2_fnAddPlace
,
2101 IFileDialog2_fnSetDefaultExtension
,
2102 IFileDialog2_fnClose
,
2103 IFileDialog2_fnSetClientGuid
,
2104 IFileDialog2_fnClearClientData
,
2105 IFileDialog2_fnSetFilter
,
2106 IFileDialog2_fnSetCancelButtonLabel
,
2107 IFileDialog2_fnSetNavigationRoot
2110 /**************************************************************************
2113 static inline FileDialogImpl
*impl_from_IFileOpenDialog(IFileOpenDialog
*iface
)
2115 return CONTAINING_RECORD(iface
, FileDialogImpl
, u
.IFileOpenDialog_iface
);
2118 static HRESULT WINAPI
IFileOpenDialog_fnQueryInterface(IFileOpenDialog
*iface
,
2119 REFIID riid
, void **ppvObject
)
2121 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2122 return IFileDialog2_QueryInterface(&This
->IFileDialog2_iface
, riid
, ppvObject
);
2125 static ULONG WINAPI
IFileOpenDialog_fnAddRef(IFileOpenDialog
*iface
)
2127 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2128 return IFileDialog2_AddRef(&This
->IFileDialog2_iface
);
2131 static ULONG WINAPI
IFileOpenDialog_fnRelease(IFileOpenDialog
*iface
)
2133 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2134 return IFileDialog2_Release(&This
->IFileDialog2_iface
);
2137 static HRESULT WINAPI
IFileOpenDialog_fnShow(IFileOpenDialog
*iface
, HWND hwndOwner
)
2139 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2140 return IFileDialog2_Show(&This
->IFileDialog2_iface
, hwndOwner
);
2143 static HRESULT WINAPI
IFileOpenDialog_fnSetFileTypes(IFileOpenDialog
*iface
, UINT cFileTypes
,
2144 const COMDLG_FILTERSPEC
*rgFilterSpec
)
2146 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2147 return IFileDialog2_SetFileTypes(&This
->IFileDialog2_iface
, cFileTypes
, rgFilterSpec
);
2150 static HRESULT WINAPI
IFileOpenDialog_fnSetFileTypeIndex(IFileOpenDialog
*iface
, UINT iFileType
)
2152 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2153 return IFileDialog2_SetFileTypeIndex(&This
->IFileDialog2_iface
, iFileType
);
2156 static HRESULT WINAPI
IFileOpenDialog_fnGetFileTypeIndex(IFileOpenDialog
*iface
, UINT
*piFileType
)
2158 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2159 return IFileDialog2_GetFileTypeIndex(&This
->IFileDialog2_iface
, piFileType
);
2162 static HRESULT WINAPI
IFileOpenDialog_fnAdvise(IFileOpenDialog
*iface
, IFileDialogEvents
*pfde
,
2165 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2166 return IFileDialog2_Advise(&This
->IFileDialog2_iface
, pfde
, pdwCookie
);
2169 static HRESULT WINAPI
IFileOpenDialog_fnUnadvise(IFileOpenDialog
*iface
, DWORD dwCookie
)
2171 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2172 return IFileDialog2_Unadvise(&This
->IFileDialog2_iface
, dwCookie
);
2175 static HRESULT WINAPI
IFileOpenDialog_fnSetOptions(IFileOpenDialog
*iface
, FILEOPENDIALOGOPTIONS fos
)
2177 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2178 return IFileDialog2_SetOptions(&This
->IFileDialog2_iface
, fos
);
2181 static HRESULT WINAPI
IFileOpenDialog_fnGetOptions(IFileOpenDialog
*iface
, FILEOPENDIALOGOPTIONS
*pfos
)
2183 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2184 return IFileDialog2_GetOptions(&This
->IFileDialog2_iface
, pfos
);
2187 static HRESULT WINAPI
IFileOpenDialog_fnSetDefaultFolder(IFileOpenDialog
*iface
, IShellItem
*psi
)
2189 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2190 return IFileDialog2_SetDefaultFolder(&This
->IFileDialog2_iface
, psi
);
2193 static HRESULT WINAPI
IFileOpenDialog_fnSetFolder(IFileOpenDialog
*iface
, IShellItem
*psi
)
2195 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2196 return IFileDialog2_SetFolder(&This
->IFileDialog2_iface
, psi
);
2199 static HRESULT WINAPI
IFileOpenDialog_fnGetFolder(IFileOpenDialog
*iface
, IShellItem
**ppsi
)
2201 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2202 return IFileDialog2_GetFolder(&This
->IFileDialog2_iface
, ppsi
);
2205 static HRESULT WINAPI
IFileOpenDialog_fnGetCurrentSelection(IFileOpenDialog
*iface
, IShellItem
**ppsi
)
2207 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2208 return IFileDialog2_GetCurrentSelection(&This
->IFileDialog2_iface
, ppsi
);
2211 static HRESULT WINAPI
IFileOpenDialog_fnSetFileName(IFileOpenDialog
*iface
, LPCWSTR pszName
)
2213 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2214 return IFileDialog2_SetFileName(&This
->IFileDialog2_iface
, pszName
);
2217 static HRESULT WINAPI
IFileOpenDialog_fnGetFileName(IFileOpenDialog
*iface
, LPWSTR
*pszName
)
2219 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2220 return IFileDialog2_GetFileName(&This
->IFileDialog2_iface
, pszName
);
2223 static HRESULT WINAPI
IFileOpenDialog_fnSetTitle(IFileOpenDialog
*iface
, LPCWSTR pszTitle
)
2225 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2226 return IFileDialog2_SetTitle(&This
->IFileDialog2_iface
, pszTitle
);
2229 static HRESULT WINAPI
IFileOpenDialog_fnSetOkButtonLabel(IFileOpenDialog
*iface
, LPCWSTR pszText
)
2231 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2232 return IFileDialog2_SetOkButtonLabel(&This
->IFileDialog2_iface
, pszText
);
2235 static HRESULT WINAPI
IFileOpenDialog_fnSetFileNameLabel(IFileOpenDialog
*iface
, LPCWSTR pszLabel
)
2237 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2238 return IFileDialog2_SetFileNameLabel(&This
->IFileDialog2_iface
, pszLabel
);
2241 static HRESULT WINAPI
IFileOpenDialog_fnGetResult(IFileOpenDialog
*iface
, IShellItem
**ppsi
)
2243 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2244 return IFileDialog2_GetResult(&This
->IFileDialog2_iface
, ppsi
);
2247 static HRESULT WINAPI
IFileOpenDialog_fnAddPlace(IFileOpenDialog
*iface
, IShellItem
*psi
, FDAP fdap
)
2249 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2250 return IFileDialog2_AddPlace(&This
->IFileDialog2_iface
, psi
, fdap
);
2253 static HRESULT WINAPI
IFileOpenDialog_fnSetDefaultExtension(IFileOpenDialog
*iface
,
2254 LPCWSTR pszDefaultExtension
)
2256 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2257 return IFileDialog2_SetDefaultExtension(&This
->IFileDialog2_iface
, pszDefaultExtension
);
2260 static HRESULT WINAPI
IFileOpenDialog_fnClose(IFileOpenDialog
*iface
, HRESULT hr
)
2262 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2263 return IFileDialog2_Close(&This
->IFileDialog2_iface
, hr
);
2266 static HRESULT WINAPI
IFileOpenDialog_fnSetClientGuid(IFileOpenDialog
*iface
, REFGUID guid
)
2268 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2269 return IFileDialog2_SetClientGuid(&This
->IFileDialog2_iface
, guid
);
2272 static HRESULT WINAPI
IFileOpenDialog_fnClearClientData(IFileOpenDialog
*iface
)
2274 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2275 return IFileDialog2_ClearClientData(&This
->IFileDialog2_iface
);
2278 static HRESULT WINAPI
IFileOpenDialog_fnSetFilter(IFileOpenDialog
*iface
, IShellItemFilter
*pFilter
)
2280 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2281 return IFileDialog2_SetFilter(&This
->IFileDialog2_iface
, pFilter
);
2284 static HRESULT WINAPI
IFileOpenDialog_fnGetResults(IFileOpenDialog
*iface
, IShellItemArray
**ppenum
)
2286 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2287 TRACE("%p (%p)\n", This
, ppenum
);
2289 *ppenum
= This
->psia_results
;
2293 IShellItemArray_AddRef(*ppenum
);
2300 static HRESULT WINAPI
IFileOpenDialog_fnGetSelectedItems(IFileOpenDialog
*iface
, IShellItemArray
**ppsai
)
2302 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2303 TRACE("%p (%p)\n", This
, ppsai
);
2305 if(This
->psia_selection
)
2307 *ppsai
= This
->psia_selection
;
2308 IShellItemArray_AddRef(*ppsai
);
2315 static const IFileOpenDialogVtbl vt_IFileOpenDialog
= {
2316 IFileOpenDialog_fnQueryInterface
,
2317 IFileOpenDialog_fnAddRef
,
2318 IFileOpenDialog_fnRelease
,
2319 IFileOpenDialog_fnShow
,
2320 IFileOpenDialog_fnSetFileTypes
,
2321 IFileOpenDialog_fnSetFileTypeIndex
,
2322 IFileOpenDialog_fnGetFileTypeIndex
,
2323 IFileOpenDialog_fnAdvise
,
2324 IFileOpenDialog_fnUnadvise
,
2325 IFileOpenDialog_fnSetOptions
,
2326 IFileOpenDialog_fnGetOptions
,
2327 IFileOpenDialog_fnSetDefaultFolder
,
2328 IFileOpenDialog_fnSetFolder
,
2329 IFileOpenDialog_fnGetFolder
,
2330 IFileOpenDialog_fnGetCurrentSelection
,
2331 IFileOpenDialog_fnSetFileName
,
2332 IFileOpenDialog_fnGetFileName
,
2333 IFileOpenDialog_fnSetTitle
,
2334 IFileOpenDialog_fnSetOkButtonLabel
,
2335 IFileOpenDialog_fnSetFileNameLabel
,
2336 IFileOpenDialog_fnGetResult
,
2337 IFileOpenDialog_fnAddPlace
,
2338 IFileOpenDialog_fnSetDefaultExtension
,
2339 IFileOpenDialog_fnClose
,
2340 IFileOpenDialog_fnSetClientGuid
,
2341 IFileOpenDialog_fnClearClientData
,
2342 IFileOpenDialog_fnSetFilter
,
2343 IFileOpenDialog_fnGetResults
,
2344 IFileOpenDialog_fnGetSelectedItems
2347 /**************************************************************************
2350 static inline FileDialogImpl
*impl_from_IFileSaveDialog(IFileSaveDialog
*iface
)
2352 return CONTAINING_RECORD(iface
, FileDialogImpl
, u
.IFileSaveDialog_iface
);
2355 static HRESULT WINAPI
IFileSaveDialog_fnQueryInterface(IFileSaveDialog
*iface
,
2359 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2360 return IFileDialog2_QueryInterface(&This
->IFileDialog2_iface
, riid
, ppvObject
);
2363 static ULONG WINAPI
IFileSaveDialog_fnAddRef(IFileSaveDialog
*iface
)
2365 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2366 return IFileDialog2_AddRef(&This
->IFileDialog2_iface
);
2369 static ULONG WINAPI
IFileSaveDialog_fnRelease(IFileSaveDialog
*iface
)
2371 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2372 return IFileDialog2_Release(&This
->IFileDialog2_iface
);
2375 static HRESULT WINAPI
IFileSaveDialog_fnShow(IFileSaveDialog
*iface
, HWND hwndOwner
)
2377 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2378 return IFileDialog2_Show(&This
->IFileDialog2_iface
, hwndOwner
);
2381 static HRESULT WINAPI
IFileSaveDialog_fnSetFileTypes(IFileSaveDialog
*iface
, UINT cFileTypes
,
2382 const COMDLG_FILTERSPEC
*rgFilterSpec
)
2384 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2385 return IFileDialog2_SetFileTypes(&This
->IFileDialog2_iface
, cFileTypes
, rgFilterSpec
);
2388 static HRESULT WINAPI
IFileSaveDialog_fnSetFileTypeIndex(IFileSaveDialog
*iface
, UINT iFileType
)
2390 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2391 return IFileDialog2_SetFileTypeIndex(&This
->IFileDialog2_iface
, iFileType
);
2394 static HRESULT WINAPI
IFileSaveDialog_fnGetFileTypeIndex(IFileSaveDialog
*iface
, UINT
*piFileType
)
2396 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2397 return IFileDialog2_GetFileTypeIndex(&This
->IFileDialog2_iface
, piFileType
);
2400 static HRESULT WINAPI
IFileSaveDialog_fnAdvise(IFileSaveDialog
*iface
, IFileDialogEvents
*pfde
,
2403 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2404 return IFileDialog2_Advise(&This
->IFileDialog2_iface
, pfde
, pdwCookie
);
2407 static HRESULT WINAPI
IFileSaveDialog_fnUnadvise(IFileSaveDialog
*iface
, DWORD dwCookie
)
2409 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2410 return IFileDialog2_Unadvise(&This
->IFileDialog2_iface
, dwCookie
);
2413 static HRESULT WINAPI
IFileSaveDialog_fnSetOptions(IFileSaveDialog
*iface
, FILEOPENDIALOGOPTIONS fos
)
2415 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2416 return IFileDialog2_SetOptions(&This
->IFileDialog2_iface
, fos
);
2419 static HRESULT WINAPI
IFileSaveDialog_fnGetOptions(IFileSaveDialog
*iface
, FILEOPENDIALOGOPTIONS
*pfos
)
2421 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2422 return IFileDialog2_GetOptions(&This
->IFileDialog2_iface
, pfos
);
2425 static HRESULT WINAPI
IFileSaveDialog_fnSetDefaultFolder(IFileSaveDialog
*iface
, IShellItem
*psi
)
2427 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2428 return IFileDialog2_SetDefaultFolder(&This
->IFileDialog2_iface
, psi
);
2431 static HRESULT WINAPI
IFileSaveDialog_fnSetFolder(IFileSaveDialog
*iface
, IShellItem
*psi
)
2433 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2434 return IFileDialog2_SetFolder(&This
->IFileDialog2_iface
, psi
);
2437 static HRESULT WINAPI
IFileSaveDialog_fnGetFolder(IFileSaveDialog
*iface
, IShellItem
**ppsi
)
2439 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2440 return IFileDialog2_GetFolder(&This
->IFileDialog2_iface
, ppsi
);
2443 static HRESULT WINAPI
IFileSaveDialog_fnGetCurrentSelection(IFileSaveDialog
*iface
, IShellItem
**ppsi
)
2445 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2446 return IFileDialog2_GetCurrentSelection(&This
->IFileDialog2_iface
, ppsi
);
2449 static HRESULT WINAPI
IFileSaveDialog_fnSetFileName(IFileSaveDialog
*iface
, LPCWSTR pszName
)
2451 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2452 return IFileDialog2_SetFileName(&This
->IFileDialog2_iface
, pszName
);
2455 static HRESULT WINAPI
IFileSaveDialog_fnGetFileName(IFileSaveDialog
*iface
, LPWSTR
*pszName
)
2457 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2458 return IFileDialog2_GetFileName(&This
->IFileDialog2_iface
, pszName
);
2461 static HRESULT WINAPI
IFileSaveDialog_fnSetTitle(IFileSaveDialog
*iface
, LPCWSTR pszTitle
)
2463 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2464 return IFileDialog2_SetTitle(&This
->IFileDialog2_iface
, pszTitle
);
2467 static HRESULT WINAPI
IFileSaveDialog_fnSetOkButtonLabel(IFileSaveDialog
*iface
, LPCWSTR pszText
)
2469 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2470 return IFileDialog2_SetOkButtonLabel(&This
->IFileDialog2_iface
, pszText
);
2473 static HRESULT WINAPI
IFileSaveDialog_fnSetFileNameLabel(IFileSaveDialog
*iface
, LPCWSTR pszLabel
)
2475 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2476 return IFileDialog2_SetFileNameLabel(&This
->IFileDialog2_iface
, pszLabel
);
2479 static HRESULT WINAPI
IFileSaveDialog_fnGetResult(IFileSaveDialog
*iface
, IShellItem
**ppsi
)
2481 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2482 return IFileDialog2_GetResult(&This
->IFileDialog2_iface
, ppsi
);
2485 static HRESULT WINAPI
IFileSaveDialog_fnAddPlace(IFileSaveDialog
*iface
, IShellItem
*psi
, FDAP fdap
)
2487 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2488 return IFileDialog2_AddPlace(&This
->IFileDialog2_iface
, psi
, fdap
);
2491 static HRESULT WINAPI
IFileSaveDialog_fnSetDefaultExtension(IFileSaveDialog
*iface
,
2492 LPCWSTR pszDefaultExtension
)
2494 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2495 return IFileDialog2_SetDefaultExtension(&This
->IFileDialog2_iface
, pszDefaultExtension
);
2498 static HRESULT WINAPI
IFileSaveDialog_fnClose(IFileSaveDialog
*iface
, HRESULT hr
)
2500 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2501 return IFileDialog2_Close(&This
->IFileDialog2_iface
, hr
);
2504 static HRESULT WINAPI
IFileSaveDialog_fnSetClientGuid(IFileSaveDialog
*iface
, REFGUID guid
)
2506 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2507 return IFileDialog2_SetClientGuid(&This
->IFileDialog2_iface
, guid
);
2510 static HRESULT WINAPI
IFileSaveDialog_fnClearClientData(IFileSaveDialog
*iface
)
2512 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2513 return IFileDialog2_ClearClientData(&This
->IFileDialog2_iface
);
2516 static HRESULT WINAPI
IFileSaveDialog_fnSetFilter(IFileSaveDialog
*iface
, IShellItemFilter
*pFilter
)
2518 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2519 return IFileDialog2_SetFilter(&This
->IFileDialog2_iface
, pFilter
);
2522 static HRESULT WINAPI
IFileSaveDialog_fnSetSaveAsItem(IFileSaveDialog
* iface
, IShellItem
*psi
)
2524 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2525 FIXME("stub - %p (%p)\n", This
, psi
);
2529 static HRESULT WINAPI
IFileSaveDialog_fnSetProperties(IFileSaveDialog
* iface
, IPropertyStore
*pStore
)
2531 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2532 FIXME("stub - %p (%p)\n", This
, pStore
);
2536 static HRESULT WINAPI
IFileSaveDialog_fnSetCollectedProperties(IFileSaveDialog
* iface
,
2537 IPropertyDescriptionList
*pList
,
2538 BOOL fAppendDefault
)
2540 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2541 FIXME("stub - %p (%p, %d)\n", This
, pList
, fAppendDefault
);
2545 static HRESULT WINAPI
IFileSaveDialog_fnGetProperties(IFileSaveDialog
* iface
, IPropertyStore
**ppStore
)
2547 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2548 FIXME("stub - %p (%p)\n", This
, ppStore
);
2552 static HRESULT WINAPI
IFileSaveDialog_fnApplyProperties(IFileSaveDialog
* iface
,
2554 IPropertyStore
*pStore
,
2556 IFileOperationProgressSink
*pSink
)
2558 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
2559 FIXME("%p (%p, %p, %p, %p)\n", This
, psi
, pStore
, hwnd
, pSink
);
2563 static const IFileSaveDialogVtbl vt_IFileSaveDialog
= {
2564 IFileSaveDialog_fnQueryInterface
,
2565 IFileSaveDialog_fnAddRef
,
2566 IFileSaveDialog_fnRelease
,
2567 IFileSaveDialog_fnShow
,
2568 IFileSaveDialog_fnSetFileTypes
,
2569 IFileSaveDialog_fnSetFileTypeIndex
,
2570 IFileSaveDialog_fnGetFileTypeIndex
,
2571 IFileSaveDialog_fnAdvise
,
2572 IFileSaveDialog_fnUnadvise
,
2573 IFileSaveDialog_fnSetOptions
,
2574 IFileSaveDialog_fnGetOptions
,
2575 IFileSaveDialog_fnSetDefaultFolder
,
2576 IFileSaveDialog_fnSetFolder
,
2577 IFileSaveDialog_fnGetFolder
,
2578 IFileSaveDialog_fnGetCurrentSelection
,
2579 IFileSaveDialog_fnSetFileName
,
2580 IFileSaveDialog_fnGetFileName
,
2581 IFileSaveDialog_fnSetTitle
,
2582 IFileSaveDialog_fnSetOkButtonLabel
,
2583 IFileSaveDialog_fnSetFileNameLabel
,
2584 IFileSaveDialog_fnGetResult
,
2585 IFileSaveDialog_fnAddPlace
,
2586 IFileSaveDialog_fnSetDefaultExtension
,
2587 IFileSaveDialog_fnClose
,
2588 IFileSaveDialog_fnSetClientGuid
,
2589 IFileSaveDialog_fnClearClientData
,
2590 IFileSaveDialog_fnSetFilter
,
2591 IFileSaveDialog_fnSetSaveAsItem
,
2592 IFileSaveDialog_fnSetProperties
,
2593 IFileSaveDialog_fnSetCollectedProperties
,
2594 IFileSaveDialog_fnGetProperties
,
2595 IFileSaveDialog_fnApplyProperties
2598 /**************************************************************************
2599 * IExplorerBrowserEvents implementation
2601 static inline FileDialogImpl
*impl_from_IExplorerBrowserEvents(IExplorerBrowserEvents
*iface
)
2603 return CONTAINING_RECORD(iface
, FileDialogImpl
, IExplorerBrowserEvents_iface
);
2606 static HRESULT WINAPI
IExplorerBrowserEvents_fnQueryInterface(IExplorerBrowserEvents
*iface
,
2607 REFIID riid
, void **ppvObject
)
2609 FileDialogImpl
*This
= impl_from_IExplorerBrowserEvents(iface
);
2610 TRACE("%p (%s, %p)\n", This
, debugstr_guid(riid
), ppvObject
);
2612 return IFileDialog2_QueryInterface(&This
->IFileDialog2_iface
, riid
, ppvObject
);
2615 static ULONG WINAPI
IExplorerBrowserEvents_fnAddRef(IExplorerBrowserEvents
*iface
)
2617 FileDialogImpl
*This
= impl_from_IExplorerBrowserEvents(iface
);
2618 TRACE("%p\n", This
);
2619 return IFileDialog2_AddRef(&This
->IFileDialog2_iface
);
2622 static ULONG WINAPI
IExplorerBrowserEvents_fnRelease(IExplorerBrowserEvents
*iface
)
2624 FileDialogImpl
*This
= impl_from_IExplorerBrowserEvents(iface
);
2625 TRACE("%p\n", This
);
2626 return IFileDialog2_Release(&This
->IFileDialog2_iface
);
2629 static HRESULT WINAPI
IExplorerBrowserEvents_fnOnNavigationPending(IExplorerBrowserEvents
*iface
,
2630 PCIDLIST_ABSOLUTE pidlFolder
)
2632 FileDialogImpl
*This
= impl_from_IExplorerBrowserEvents(iface
);
2635 TRACE("%p (%p)\n", This
, pidlFolder
);
2637 hr
= SHCreateItemFromIDList(pidlFolder
, &IID_IShellItem
, (void**)&psi
);
2640 hr
= events_OnFolderChanging(This
, psi
);
2641 IShellItem_Release(psi
);
2643 /* The ExplorerBrowser treats S_FALSE as S_OK, we don't. */
2650 ERR("Failed to convert pidl (%p) to a shellitem.\n", pidlFolder
);
2655 static HRESULT WINAPI
IExplorerBrowserEvents_fnOnViewCreated(IExplorerBrowserEvents
*iface
,
2658 FileDialogImpl
*This
= impl_from_IExplorerBrowserEvents(iface
);
2659 TRACE("%p (%p)\n", This
, psv
);
2663 static HRESULT WINAPI
IExplorerBrowserEvents_fnOnNavigationComplete(IExplorerBrowserEvents
*iface
,
2664 PCIDLIST_ABSOLUTE pidlFolder
)
2666 FileDialogImpl
*This
= impl_from_IExplorerBrowserEvents(iface
);
2668 TRACE("%p (%p)\n", This
, pidlFolder
);
2670 if(This
->psi_folder
)
2671 IShellItem_Release(This
->psi_folder
);
2673 hr
= SHCreateItemFromIDList(pidlFolder
, &IID_IShellItem
, (void**)&This
->psi_folder
);
2676 ERR("Failed to get the current folder.\n");
2677 This
->psi_folder
= NULL
;
2680 events_OnFolderChange(This
);
2685 static HRESULT WINAPI
IExplorerBrowserEvents_fnOnNavigationFailed(IExplorerBrowserEvents
*iface
,
2686 PCIDLIST_ABSOLUTE pidlFolder
)
2688 FileDialogImpl
*This
= impl_from_IExplorerBrowserEvents(iface
);
2689 TRACE("%p (%p)\n", This
, pidlFolder
);
2693 static const IExplorerBrowserEventsVtbl vt_IExplorerBrowserEvents
= {
2694 IExplorerBrowserEvents_fnQueryInterface
,
2695 IExplorerBrowserEvents_fnAddRef
,
2696 IExplorerBrowserEvents_fnRelease
,
2697 IExplorerBrowserEvents_fnOnNavigationPending
,
2698 IExplorerBrowserEvents_fnOnViewCreated
,
2699 IExplorerBrowserEvents_fnOnNavigationComplete
,
2700 IExplorerBrowserEvents_fnOnNavigationFailed
2703 /**************************************************************************
2704 * IServiceProvider implementation
2706 static inline FileDialogImpl
*impl_from_IServiceProvider(IServiceProvider
*iface
)
2708 return CONTAINING_RECORD(iface
, FileDialogImpl
, IServiceProvider_iface
);
2711 static HRESULT WINAPI
IServiceProvider_fnQueryInterface(IServiceProvider
*iface
,
2712 REFIID riid
, void **ppvObject
)
2714 FileDialogImpl
*This
= impl_from_IServiceProvider(iface
);
2715 TRACE("%p\n", This
);
2716 return IFileDialog2_QueryInterface(&This
->IFileDialog2_iface
, riid
, ppvObject
);
2719 static ULONG WINAPI
IServiceProvider_fnAddRef(IServiceProvider
*iface
)
2721 FileDialogImpl
*This
= impl_from_IServiceProvider(iface
);
2722 TRACE("%p\n", This
);
2723 return IFileDialog2_AddRef(&This
->IFileDialog2_iface
);
2726 static ULONG WINAPI
IServiceProvider_fnRelease(IServiceProvider
*iface
)
2728 FileDialogImpl
*This
= impl_from_IServiceProvider(iface
);
2729 TRACE("%p\n", This
);
2730 return IFileDialog2_Release(&This
->IFileDialog2_iface
);
2733 static HRESULT WINAPI
IServiceProvider_fnQueryService(IServiceProvider
*iface
,
2734 REFGUID guidService
,
2735 REFIID riid
, void **ppv
)
2737 FileDialogImpl
*This
= impl_from_IServiceProvider(iface
);
2738 HRESULT hr
= E_NOTIMPL
;
2739 TRACE("%p (%s, %s, %p)\n", This
, debugstr_guid(guidService
), debugstr_guid(riid
), ppv
);
2742 if(IsEqualGUID(guidService
, &SID_STopLevelBrowser
) && This
->peb
)
2743 hr
= IExplorerBrowser_QueryInterface(This
->peb
, riid
, ppv
);
2744 else if(IsEqualGUID(guidService
, &SID_SExplorerBrowserFrame
))
2745 hr
= IFileDialog2_QueryInterface(&This
->IFileDialog2_iface
, riid
, ppv
);
2747 FIXME("Interface %s requested from unknown service %s\n",
2748 debugstr_guid(riid
), debugstr_guid(guidService
));
2753 static const IServiceProviderVtbl vt_IServiceProvider
= {
2754 IServiceProvider_fnQueryInterface
,
2755 IServiceProvider_fnAddRef
,
2756 IServiceProvider_fnRelease
,
2757 IServiceProvider_fnQueryService
2760 /**************************************************************************
2761 * ICommDlgBrowser3 implementation
2763 static inline FileDialogImpl
*impl_from_ICommDlgBrowser3(ICommDlgBrowser3
*iface
)
2765 return CONTAINING_RECORD(iface
, FileDialogImpl
, ICommDlgBrowser3_iface
);
2768 static HRESULT WINAPI
ICommDlgBrowser3_fnQueryInterface(ICommDlgBrowser3
*iface
,
2769 REFIID riid
, void **ppvObject
)
2771 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
2772 TRACE("%p\n", This
);
2773 return IFileDialog2_QueryInterface(&This
->IFileDialog2_iface
, riid
, ppvObject
);
2776 static ULONG WINAPI
ICommDlgBrowser3_fnAddRef(ICommDlgBrowser3
*iface
)
2778 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
2779 TRACE("%p\n", This
);
2780 return IFileDialog2_AddRef(&This
->IFileDialog2_iface
);
2783 static ULONG WINAPI
ICommDlgBrowser3_fnRelease(ICommDlgBrowser3
*iface
)
2785 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
2786 TRACE("%p\n", This
);
2787 return IFileDialog2_Release(&This
->IFileDialog2_iface
);
2790 static HRESULT WINAPI
ICommDlgBrowser3_fnOnDefaultCommand(ICommDlgBrowser3
*iface
,
2793 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
2795 TRACE("%p (%p)\n", This
, shv
);
2797 hr
= on_default_action(This
);
2800 EndDialog(This
->dlg_hwnd
, S_OK
);
2805 static HRESULT WINAPI
ICommDlgBrowser3_fnOnStateChange(ICommDlgBrowser3
*iface
,
2806 IShellView
*shv
, ULONG uChange
)
2808 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
2809 IDataObject
*new_selection
;
2811 TRACE("%p (%p, %x)\n", This
, shv
, uChange
);
2815 case CDBOSC_SELCHANGE
:
2816 if(This
->psia_selection
)
2818 IShellItemArray_Release(This
->psia_selection
);
2819 This
->psia_selection
= NULL
;
2822 hr
= IShellView_GetItemObject(shv
, SVGIO_SELECTION
, &IID_IDataObject
, (void**)&new_selection
);
2825 hr
= SHCreateShellItemArrayFromDataObject(new_selection
, &IID_IShellItemArray
,
2826 (void**)&This
->psia_selection
);
2829 fill_filename_from_selection(This
);
2830 events_OnSelectionChange(This
);
2833 IDataObject_Release(new_selection
);
2837 TRACE("Unhandled state change\n");
2842 static HRESULT WINAPI
ICommDlgBrowser3_fnIncludeObject(ICommDlgBrowser3
*iface
,
2843 IShellView
*shv
, LPCITEMIDLIST pidl
)
2845 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
2848 LPITEMIDLIST parent_pidl
;
2851 TRACE("%p (%p, %p)\n", This
, shv
, pidl
);
2853 if(!This
->filterspec_count
)
2856 hr
= SHGetIDListFromObject((IUnknown
*)shv
, &parent_pidl
);
2859 LPITEMIDLIST full_pidl
= ILCombine(parent_pidl
, pidl
);
2860 hr
= SHCreateItemFromIDList(full_pidl
, &IID_IShellItem
, (void**)&psi
);
2861 ILFree(parent_pidl
);
2866 ERR("Failed to get shellitem (%08x).\n", hr
);
2870 hr
= IShellItem_GetAttributes(psi
, SFGAO_FOLDER
|SFGAO_LINK
, &attr
);
2871 if(FAILED(hr
) || (attr
& (SFGAO_FOLDER
| SFGAO_LINK
)))
2873 IShellItem_Release(psi
);
2878 if(SUCCEEDED(IShellItem_GetDisplayName(psi
, SIGDN_PARENTRELATIVEPARSING
, &filename
)))
2880 if(!PathMatchSpecW(filename
, This
->filterspecs
[This
->filetypeindex
].pszSpec
))
2882 CoTaskMemFree(filename
);
2885 IShellItem_Release(psi
);
2889 static HRESULT WINAPI
ICommDlgBrowser3_fnNotify(ICommDlgBrowser3
*iface
,
2890 IShellView
*ppshv
, DWORD dwNotifyType
)
2892 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
2893 FIXME("Stub: %p (%p, 0x%x)\n", This
, ppshv
, dwNotifyType
);
2897 static HRESULT WINAPI
ICommDlgBrowser3_fnGetDefaultMenuText(ICommDlgBrowser3
*iface
,
2899 LPWSTR pszText
, int cchMax
)
2901 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
2902 FIXME("Stub: %p (%p, %p, %d)\n", This
, pshv
, pszText
, cchMax
);
2906 static HRESULT WINAPI
ICommDlgBrowser3_fnGetViewFlags(ICommDlgBrowser3
*iface
, DWORD
*pdwFlags
)
2908 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
2909 FIXME("Stub: %p (%p)\n", This
, pdwFlags
);
2913 static HRESULT WINAPI
ICommDlgBrowser3_fnOnColumnClicked(ICommDlgBrowser3
*iface
,
2914 IShellView
*pshv
, int iColumn
)
2916 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
2917 FIXME("Stub: %p (%p, %d)\n", This
, pshv
, iColumn
);
2921 static HRESULT WINAPI
ICommDlgBrowser3_fnGetCurrentFilter(ICommDlgBrowser3
*iface
,
2922 LPWSTR pszFileSpec
, int cchFileSpec
)
2924 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
2925 FIXME("Stub: %p (%p, %d)\n", This
, pszFileSpec
, cchFileSpec
);
2929 static HRESULT WINAPI
ICommDlgBrowser3_fnOnPreviewCreated(ICommDlgBrowser3
*iface
,
2932 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
2933 FIXME("Stub: %p (%p)\n", This
, pshv
);
2937 static const ICommDlgBrowser3Vtbl vt_ICommDlgBrowser3
= {
2938 ICommDlgBrowser3_fnQueryInterface
,
2939 ICommDlgBrowser3_fnAddRef
,
2940 ICommDlgBrowser3_fnRelease
,
2941 ICommDlgBrowser3_fnOnDefaultCommand
,
2942 ICommDlgBrowser3_fnOnStateChange
,
2943 ICommDlgBrowser3_fnIncludeObject
,
2944 ICommDlgBrowser3_fnNotify
,
2945 ICommDlgBrowser3_fnGetDefaultMenuText
,
2946 ICommDlgBrowser3_fnGetViewFlags
,
2947 ICommDlgBrowser3_fnOnColumnClicked
,
2948 ICommDlgBrowser3_fnGetCurrentFilter
,
2949 ICommDlgBrowser3_fnOnPreviewCreated
2952 /**************************************************************************
2953 * IOleWindow implementation
2955 static inline FileDialogImpl
*impl_from_IOleWindow(IOleWindow
*iface
)
2957 return CONTAINING_RECORD(iface
, FileDialogImpl
, IOleWindow_iface
);
2960 static HRESULT WINAPI
IOleWindow_fnQueryInterface(IOleWindow
*iface
, REFIID riid
, void **ppvObject
)
2962 FileDialogImpl
*This
= impl_from_IOleWindow(iface
);
2963 return IFileDialog2_QueryInterface(&This
->IFileDialog2_iface
, riid
, ppvObject
);
2966 static ULONG WINAPI
IOleWindow_fnAddRef(IOleWindow
*iface
)
2968 FileDialogImpl
*This
= impl_from_IOleWindow(iface
);
2969 return IFileDialog2_AddRef(&This
->IFileDialog2_iface
);
2972 static ULONG WINAPI
IOleWindow_fnRelease(IOleWindow
*iface
)
2974 FileDialogImpl
*This
= impl_from_IOleWindow(iface
);
2975 return IFileDialog2_Release(&This
->IFileDialog2_iface
);
2978 static HRESULT WINAPI
IOleWindow_fnContextSensitiveHelp(IOleWindow
*iface
, BOOL fEnterMOde
)
2980 FileDialogImpl
*This
= impl_from_IOleWindow(iface
);
2981 FIXME("Stub: %p (%d)\n", This
, fEnterMOde
);
2985 static HRESULT WINAPI
IOleWindow_fnGetWindow(IOleWindow
*iface
, HWND
*phwnd
)
2987 FileDialogImpl
*This
= impl_from_IOleWindow(iface
);
2988 TRACE("%p (%p)\n", This
, phwnd
);
2989 *phwnd
= This
->dlg_hwnd
;
2993 static const IOleWindowVtbl vt_IOleWindow
= {
2994 IOleWindow_fnQueryInterface
,
2995 IOleWindow_fnAddRef
,
2996 IOleWindow_fnRelease
,
2997 IOleWindow_fnGetWindow
,
2998 IOleWindow_fnContextSensitiveHelp
3001 /**************************************************************************
3002 * IFileDialogCustomize implementation
3004 static inline FileDialogImpl
*impl_from_IFileDialogCustomize(IFileDialogCustomize
*iface
)
3006 return CONTAINING_RECORD(iface
, FileDialogImpl
, IFileDialogCustomize_iface
);
3009 static HRESULT WINAPI
IFileDialogCustomize_fnQueryInterface(IFileDialogCustomize
*iface
,
3010 REFIID riid
, void **ppvObject
)
3012 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3013 return IFileDialog2_QueryInterface(&This
->IFileDialog2_iface
, riid
, ppvObject
);
3016 static ULONG WINAPI
IFileDialogCustomize_fnAddRef(IFileDialogCustomize
*iface
)
3018 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3019 return IFileDialog2_AddRef(&This
->IFileDialog2_iface
);
3022 static ULONG WINAPI
IFileDialogCustomize_fnRelease(IFileDialogCustomize
*iface
)
3024 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3025 return IFileDialog2_Release(&This
->IFileDialog2_iface
);
3028 static HRESULT WINAPI
IFileDialogCustomize_fnEnableOpenDropDown(IFileDialogCustomize
*iface
,
3031 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3032 FIXME("stub - %p (%d)\n", This
, dwIDCtl
);
3036 static HRESULT WINAPI
IFileDialogCustomize_fnAddMenu(IFileDialogCustomize
*iface
,
3040 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3044 TRACE("%p (%d, %p)\n", This
, dwIDCtl
, pszLabel
);
3046 hr
= cctrl_create_new(This
, dwIDCtl
, NULL
, TOOLBARCLASSNAMEW
,
3047 TBSTYLE_FLAT
| CCS_NODIVIDER
, 0,
3048 This
->cctrl_def_height
, &ctrl
);
3051 SendMessageW(ctrl
->hwnd
, TB_BUTTONSTRUCTSIZE
, sizeof(tbb
), 0);
3052 ctrl
->type
= IDLG_CCTRL_MENU
;
3054 /* Add the actual button with a popup menu. */
3055 tbb
.iBitmap
= I_IMAGENONE
;
3056 tbb
.dwData
= (DWORD_PTR
)CreatePopupMenu();
3057 tbb
.iString
= (DWORD_PTR
)pszLabel
;
3058 tbb
.fsState
= TBSTATE_ENABLED
;
3059 tbb
.fsStyle
= BTNS_WHOLEDROPDOWN
;
3062 SendMessageW(ctrl
->hwnd
, TB_ADDBUTTONSW
, 1, (LPARAM
)&tbb
);
3068 static HRESULT WINAPI
IFileDialogCustomize_fnAddPushButton(IFileDialogCustomize
*iface
,
3072 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3075 TRACE("%p (%d, %p)\n", This
, dwIDCtl
, pszLabel
);
3077 hr
= cctrl_create_new(This
, dwIDCtl
, pszLabel
, WC_BUTTONW
, BS_MULTILINE
, 0,
3078 This
->cctrl_def_height
, &ctrl
);
3080 ctrl
->type
= IDLG_CCTRL_PUSHBUTTON
;
3085 static HRESULT WINAPI
IFileDialogCustomize_fnAddComboBox(IFileDialogCustomize
*iface
,
3088 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3091 TRACE("%p (%d)\n", This
, dwIDCtl
);
3093 hr
= cctrl_create_new(This
, dwIDCtl
, NULL
, WC_COMBOBOXW
, CBS_DROPDOWNLIST
, 0,
3094 This
->cctrl_def_height
, &ctrl
);
3096 ctrl
->type
= IDLG_CCTRL_COMBOBOX
;
3101 static HRESULT WINAPI
IFileDialogCustomize_fnAddRadioButtonList(IFileDialogCustomize
*iface
,
3104 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3105 FIXME("stub - %p (%d)\n", This
, dwIDCtl
);
3109 static HRESULT WINAPI
IFileDialogCustomize_fnAddCheckButton(IFileDialogCustomize
*iface
,
3114 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3117 TRACE("%p (%d, %p, %d)\n", This
, dwIDCtl
, pszLabel
, bChecked
);
3119 hr
= cctrl_create_new(This
, dwIDCtl
, pszLabel
, WC_BUTTONW
, BS_AUTOCHECKBOX
, 0,
3120 This
->cctrl_def_height
, &ctrl
);
3123 ctrl
->type
= IDLG_CCTRL_CHECKBUTTON
;
3124 SendMessageW(ctrl
->hwnd
, BM_SETCHECK
, bChecked
? BST_CHECKED
: BST_UNCHECKED
, 0);
3130 static HRESULT WINAPI
IFileDialogCustomize_fnAddEditBox(IFileDialogCustomize
*iface
,
3134 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3137 TRACE("%p (%d, %p)\n", This
, dwIDCtl
, pszText
);
3139 hr
= cctrl_create_new(This
, dwIDCtl
, pszText
, WC_EDITW
, ES_AUTOHSCROLL
, WS_EX_CLIENTEDGE
,
3140 This
->cctrl_def_height
, &ctrl
);
3142 ctrl
->type
= IDLG_CCTRL_EDITBOX
;
3147 static HRESULT WINAPI
IFileDialogCustomize_fnAddSeparator(IFileDialogCustomize
*iface
,
3150 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3153 TRACE("%p (%d)\n", This
, dwIDCtl
);
3155 hr
= cctrl_create_new(This
, dwIDCtl
, NULL
, WC_STATICW
, SS_ETCHEDHORZ
, 0,
3156 GetSystemMetrics(SM_CYEDGE
), &ctrl
);
3158 ctrl
->type
= IDLG_CCTRL_SEPARATOR
;
3163 static HRESULT WINAPI
IFileDialogCustomize_fnAddText(IFileDialogCustomize
*iface
,
3167 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3170 TRACE("%p (%d, %p)\n", This
, dwIDCtl
, pszText
);
3172 hr
= cctrl_create_new(This
, dwIDCtl
, pszText
, WC_STATICW
, 0, 0,
3173 This
->cctrl_def_height
, &ctrl
);
3175 ctrl
->type
= IDLG_CCTRL_TEXT
;
3180 static HRESULT WINAPI
IFileDialogCustomize_fnSetControlLabel(IFileDialogCustomize
*iface
,
3184 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3185 customctrl
*ctrl
= get_cctrl(This
, dwIDCtl
);
3186 TRACE("%p (%d, %p)\n", This
, dwIDCtl
, pszLabel
);
3188 if(!ctrl
) return E_INVALIDARG
;
3192 case IDLG_CCTRL_MENU
:
3193 case IDLG_CCTRL_PUSHBUTTON
:
3194 case IDLG_CCTRL_CHECKBUTTON
:
3195 case IDLG_CCTRL_TEXT
:
3196 SendMessageW(ctrl
->hwnd
, WM_SETTEXT
, 0, (LPARAM
)pszLabel
);
3205 static HRESULT WINAPI
IFileDialogCustomize_fnGetControlState(IFileDialogCustomize
*iface
,
3207 CDCONTROLSTATEF
*pdwState
)
3209 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3210 customctrl
*ctrl
= get_cctrl(This
, dwIDCtl
);
3211 TRACE("%p (%d, %p)\n", This
, dwIDCtl
, pdwState
);
3213 if(!ctrl
) return E_NOTIMPL
;
3215 *pdwState
= ctrl
->cdcstate
;
3219 static HRESULT WINAPI
IFileDialogCustomize_fnSetControlState(IFileDialogCustomize
*iface
,
3221 CDCONTROLSTATEF dwState
)
3223 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3224 customctrl
*ctrl
= get_cctrl(This
,dwIDCtl
);
3225 TRACE("%p (%d, %x)\n", This
, dwIDCtl
, dwState
);
3229 LONG wndstyle
= GetWindowLongW(ctrl
->hwnd
, GWL_STYLE
);
3231 if(dwState
& CDCS_ENABLED
)
3232 wndstyle
&= ~(WS_DISABLED
);
3234 wndstyle
|= WS_DISABLED
;
3236 if(dwState
& CDCS_VISIBLE
)
3237 wndstyle
|= WS_VISIBLE
;
3239 wndstyle
&= ~(WS_VISIBLE
);
3241 SetWindowLongW(ctrl
->hwnd
, GWL_STYLE
, wndstyle
);
3243 /* We save the state separately since at least one application
3244 * relies on being able to hide a control. */
3245 ctrl
->cdcstate
= dwState
;
3251 static HRESULT WINAPI
IFileDialogCustomize_fnGetEditBoxText(IFileDialogCustomize
*iface
,
3255 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3256 customctrl
*ctrl
= get_cctrl(This
, dwIDCtl
);
3258 TRACE("%p (%d, %p)\n", This
, dwIDCtl
, ppszText
);
3260 if(!ctrl
|| !(len
= SendMessageW(ctrl
->hwnd
, WM_GETTEXTLENGTH
, 0, 0)))
3263 text
= CoTaskMemAlloc(sizeof(WCHAR
)*(len
+1));
3264 if(!text
) return E_FAIL
;
3266 SendMessageW(ctrl
->hwnd
, WM_GETTEXT
, len
+1, (LPARAM
)text
);
3271 static HRESULT WINAPI
IFileDialogCustomize_fnSetEditBoxText(IFileDialogCustomize
*iface
,
3275 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3276 customctrl
*ctrl
= get_cctrl(This
, dwIDCtl
);
3277 TRACE("%p (%d, %s)\n", This
, dwIDCtl
, debugstr_w(pszText
));
3279 if(!ctrl
|| ctrl
->type
!= IDLG_CCTRL_EDITBOX
)
3282 SendMessageW(ctrl
->hwnd
, WM_SETTEXT
, 0, (LPARAM
)pszText
);
3286 static HRESULT WINAPI
IFileDialogCustomize_fnGetCheckButtonState(IFileDialogCustomize
*iface
,
3290 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3291 customctrl
*ctrl
= get_cctrl(This
, dwIDCtl
);
3292 TRACE("%p (%d, %p)\n", This
, dwIDCtl
, pbChecked
);
3295 *pbChecked
= (SendMessageW(ctrl
->hwnd
, BM_GETCHECK
, 0, 0) == BST_CHECKED
);
3300 static HRESULT WINAPI
IFileDialogCustomize_fnSetCheckButtonState(IFileDialogCustomize
*iface
,
3304 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3305 customctrl
*ctrl
= get_cctrl(This
, dwIDCtl
);
3306 TRACE("%p (%d, %d)\n", This
, dwIDCtl
, bChecked
);
3309 SendMessageW(ctrl
->hwnd
, BM_SETCHECK
, bChecked
? BST_CHECKED
:BST_UNCHECKED
, 0);
3314 static UINT
get_combobox_index_from_id(HWND cb_hwnd
, DWORD dwIDItem
)
3316 UINT count
= SendMessageW(cb_hwnd
, CB_GETCOUNT
, 0, 0);
3318 if(!count
|| (count
== CB_ERR
))
3321 for(i
= 0; i
< count
; i
++)
3322 if(SendMessageW(cb_hwnd
, CB_GETITEMDATA
, i
, 0) == dwIDItem
)
3325 TRACE("Item with id %d not found in combobox %p (item count: %d)\n", dwIDItem
, cb_hwnd
, count
);
3329 static HRESULT WINAPI
IFileDialogCustomize_fnAddControlItem(IFileDialogCustomize
*iface
,
3334 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3335 customctrl
*ctrl
= get_cctrl(This
, dwIDCtl
);
3336 TRACE("%p (%d, %d, %s)\n", This
, dwIDCtl
, dwIDItem
, debugstr_w(pszLabel
));
3338 if(!ctrl
) return E_FAIL
;
3342 case IDLG_CCTRL_COMBOBOX
:
3346 if(get_combobox_index_from_id(ctrl
->hwnd
, dwIDItem
) != -1)
3347 return E_INVALIDARG
;
3349 index
= SendMessageW(ctrl
->hwnd
, CB_ADDSTRING
, 0, (LPARAM
)pszLabel
);
3350 SendMessageW(ctrl
->hwnd
, CB_SETITEMDATA
, index
, dwIDItem
);
3354 case IDLG_CCTRL_MENU
:
3357 SendMessageW(ctrl
->hwnd
, TB_GETBUTTON
, 0, (LPARAM
)&tbb
);
3359 if(GetMenuState((HMENU
)tbb
.dwData
, dwIDItem
, MF_BYCOMMAND
) != -1)
3360 return E_INVALIDARG
;
3362 AppendMenuW((HMENU
)tbb
.dwData
, MF_STRING
, dwIDItem
, pszLabel
);
3369 return E_NOINTERFACE
; /* win7 */
3372 static HRESULT WINAPI
IFileDialogCustomize_fnRemoveControlItem(IFileDialogCustomize
*iface
,
3376 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3377 customctrl
*ctrl
= get_cctrl(This
, dwIDCtl
);
3378 TRACE("%p (%d, %d)\n", This
, dwIDCtl
, dwIDItem
);
3380 if(!ctrl
) return E_FAIL
;
3384 case IDLG_CCTRL_COMBOBOX
:
3386 UINT i
, count
= SendMessageW(ctrl
->hwnd
, CB_GETCOUNT
, 0, 0);
3387 if(!count
|| (count
== CB_ERR
))
3390 for(i
= 0; i
< count
; i
++)
3391 if(SendMessageW(ctrl
->hwnd
, CB_GETITEMDATA
, i
, 0) == dwIDItem
)
3393 if(SendMessageW(ctrl
->hwnd
, CB_DELETESTRING
, i
, 0) == CB_ERR
)
3398 return E_UNEXPECTED
;
3400 case IDLG_CCTRL_MENU
:
3404 SendMessageW(ctrl
->hwnd
, TB_GETBUTTON
, 0, (LPARAM
)&tbb
);
3405 hmenu
= (HMENU
)tbb
.dwData
;
3407 if(!hmenu
|| !DeleteMenu(hmenu
, dwIDItem
, MF_BYCOMMAND
))
3408 return E_UNEXPECTED
;
3419 static HRESULT WINAPI
IFileDialogCustomize_fnRemoveAllControlItems(IFileDialogCustomize
*iface
,
3422 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3423 TRACE("%p (%d)\n", This
, dwIDCtl
);
3425 /* Not implemented by native */
3429 static HRESULT WINAPI
IFileDialogCustomize_fnGetControlItemState(IFileDialogCustomize
*iface
,
3432 CDCONTROLSTATEF
*pdwState
)
3434 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3435 FIXME("stub - %p\n", This
);
3439 static HRESULT WINAPI
IFileDialogCustomize_fnSetControlItemState(IFileDialogCustomize
*iface
,
3442 CDCONTROLSTATEF dwState
)
3444 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3445 FIXME("stub - %p\n", This
);
3449 static HRESULT WINAPI
IFileDialogCustomize_fnGetSelectedControlItem(IFileDialogCustomize
*iface
,
3453 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3454 customctrl
*ctrl
= get_cctrl(This
, dwIDCtl
);
3455 TRACE("%p (%d, %p)\n", This
, dwIDCtl
, pdwIDItem
);
3457 if(!ctrl
) return E_FAIL
;
3461 case IDLG_CCTRL_COMBOBOX
:
3463 UINT index
= SendMessageW(ctrl
->hwnd
, CB_GETCURSEL
, 0, 0);
3467 *pdwIDItem
= SendMessageW(ctrl
->hwnd
, CB_GETITEMDATA
, index
, 0);
3471 FIXME("Unsupported control type %d\n", ctrl
->type
);
3477 static HRESULT WINAPI
IFileDialogCustomize_fnSetSelectedControlItem(IFileDialogCustomize
*iface
,
3481 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3482 customctrl
*ctrl
= get_cctrl(This
, dwIDCtl
);
3483 TRACE("%p (%d, %d)\n", This
, dwIDCtl
, dwIDItem
);
3485 if(!ctrl
) return E_INVALIDARG
;
3489 case IDLG_CCTRL_COMBOBOX
:
3491 UINT index
= get_combobox_index_from_id(ctrl
->hwnd
, dwIDItem
);
3494 return E_INVALIDARG
;
3496 if(SendMessageW(ctrl
->hwnd
, CB_SETCURSEL
, index
, 0) == CB_ERR
)
3502 FIXME("Unsupported control type %d\n", ctrl
->type
);
3505 return E_INVALIDARG
;
3508 static HRESULT WINAPI
IFileDialogCustomize_fnStartVisualGroup(IFileDialogCustomize
*iface
,
3512 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3513 FIXME("stub - %p (%d, %s)\n", This
, dwIDCtl
, debugstr_w(pszLabel
));
3517 static HRESULT WINAPI
IFileDialogCustomize_fnEndVisualGroup(IFileDialogCustomize
*iface
)
3519 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3520 FIXME("stub - %p\n", This
);
3524 static HRESULT WINAPI
IFileDialogCustomize_fnMakeProminent(IFileDialogCustomize
*iface
,
3527 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3528 FIXME("stub - %p (%d)\n", This
, dwIDCtl
);
3532 static HRESULT WINAPI
IFileDialogCustomize_fnSetControlItemText(IFileDialogCustomize
*iface
,
3537 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3538 FIXME("stub - %p (%d, %d, %s)\n", This
, dwIDCtl
, dwIDItem
, debugstr_w(pszLabel
));
3542 static const IFileDialogCustomizeVtbl vt_IFileDialogCustomize
= {
3543 IFileDialogCustomize_fnQueryInterface
,
3544 IFileDialogCustomize_fnAddRef
,
3545 IFileDialogCustomize_fnRelease
,
3546 IFileDialogCustomize_fnEnableOpenDropDown
,
3547 IFileDialogCustomize_fnAddMenu
,
3548 IFileDialogCustomize_fnAddPushButton
,
3549 IFileDialogCustomize_fnAddComboBox
,
3550 IFileDialogCustomize_fnAddRadioButtonList
,
3551 IFileDialogCustomize_fnAddCheckButton
,
3552 IFileDialogCustomize_fnAddEditBox
,
3553 IFileDialogCustomize_fnAddSeparator
,
3554 IFileDialogCustomize_fnAddText
,
3555 IFileDialogCustomize_fnSetControlLabel
,
3556 IFileDialogCustomize_fnGetControlState
,
3557 IFileDialogCustomize_fnSetControlState
,
3558 IFileDialogCustomize_fnGetEditBoxText
,
3559 IFileDialogCustomize_fnSetEditBoxText
,
3560 IFileDialogCustomize_fnGetCheckButtonState
,
3561 IFileDialogCustomize_fnSetCheckButtonState
,
3562 IFileDialogCustomize_fnAddControlItem
,
3563 IFileDialogCustomize_fnRemoveControlItem
,
3564 IFileDialogCustomize_fnRemoveAllControlItems
,
3565 IFileDialogCustomize_fnGetControlItemState
,
3566 IFileDialogCustomize_fnSetControlItemState
,
3567 IFileDialogCustomize_fnGetSelectedControlItem
,
3568 IFileDialogCustomize_fnSetSelectedControlItem
,
3569 IFileDialogCustomize_fnStartVisualGroup
,
3570 IFileDialogCustomize_fnEndVisualGroup
,
3571 IFileDialogCustomize_fnMakeProminent
,
3572 IFileDialogCustomize_fnSetControlItemText
3575 static HRESULT
FileDialog_constructor(IUnknown
*pUnkOuter
, REFIID riid
, void **ppv
, enum ITEMDLG_TYPE type
)
3577 FileDialogImpl
*fdimpl
;
3580 TRACE("%p, %s, %p\n", pUnkOuter
, debugstr_guid(riid
), ppv
);
3585 return CLASS_E_NOAGGREGATION
;
3587 fdimpl
= HeapAlloc(GetProcessHeap(), 0, sizeof(FileDialogImpl
));
3589 return E_OUTOFMEMORY
;
3592 fdimpl
->IFileDialog2_iface
.lpVtbl
= &vt_IFileDialog2
;
3593 fdimpl
->IExplorerBrowserEvents_iface
.lpVtbl
= &vt_IExplorerBrowserEvents
;
3594 fdimpl
->IServiceProvider_iface
.lpVtbl
= &vt_IServiceProvider
;
3595 fdimpl
->ICommDlgBrowser3_iface
.lpVtbl
= &vt_ICommDlgBrowser3
;
3596 fdimpl
->IOleWindow_iface
.lpVtbl
= &vt_IOleWindow
;
3597 fdimpl
->IFileDialogCustomize_iface
.lpVtbl
= &vt_IFileDialogCustomize
;
3599 if(type
== ITEMDLG_TYPE_OPEN
)
3601 fdimpl
->dlg_type
= ITEMDLG_TYPE_OPEN
;
3602 fdimpl
->u
.IFileOpenDialog_iface
.lpVtbl
= &vt_IFileOpenDialog
;
3603 fdimpl
->options
= FOS_PATHMUSTEXIST
| FOS_FILEMUSTEXIST
| FOS_NOCHANGEDIR
;
3604 fdimpl
->custom_title
= fdimpl
->custom_okbutton
= NULL
;
3609 fdimpl
->dlg_type
= ITEMDLG_TYPE_SAVE
;
3610 fdimpl
->u
.IFileSaveDialog_iface
.lpVtbl
= &vt_IFileSaveDialog
;
3611 fdimpl
->options
= FOS_OVERWRITEPROMPT
| FOS_NOREADONLYRETURN
| FOS_PATHMUSTEXIST
| FOS_NOCHANGEDIR
;
3613 LoadStringW(COMDLG32_hInstance
, IDS_SAVE
, buf
, sizeof(buf
)/sizeof(WCHAR
));
3614 fdimpl
->custom_title
= StrDupW(buf
);
3615 fdimpl
->custom_okbutton
= StrDupW(buf
);
3618 fdimpl
->filterspecs
= NULL
;
3619 fdimpl
->filterspec_count
= 0;
3620 fdimpl
->filetypeindex
= 0;
3622 fdimpl
->psia_selection
= fdimpl
->psia_results
= NULL
;
3623 fdimpl
->psi_setfolder
= fdimpl
->psi_folder
= NULL
;
3625 list_init(&fdimpl
->events_clients
);
3626 fdimpl
->events_next_cookie
= 0;
3628 fdimpl
->dlg_hwnd
= NULL
;
3631 fdimpl
->set_filename
= NULL
;
3632 fdimpl
->default_ext
= NULL
;
3633 fdimpl
->custom_cancelbutton
= fdimpl
->custom_filenamelabel
= NULL
;
3635 fdimpl
->client_guid
= GUID_NULL
;
3637 /* FIXME: The default folder setting should be restored for the
3638 * application if it was previously set. */
3639 SHGetDesktopFolder(&psf
);
3640 SHGetItemFromObject((IUnknown
*)psf
, &IID_IShellItem
, (void**)&fdimpl
->psi_defaultfolder
);
3641 IShellFolder_Release(psf
);
3643 hr
= init_custom_controls(fdimpl
);
3646 ERR("Failed to initialize custom controls (0x%08x).\n", hr
);
3647 IUnknown_Release((IUnknown
*)fdimpl
);
3651 hr
= IUnknown_QueryInterface((IUnknown
*)fdimpl
, riid
, ppv
);
3652 IUnknown_Release((IUnknown
*)fdimpl
);
3656 HRESULT
FileOpenDialog_Constructor(IUnknown
*pUnkOuter
, REFIID riid
, void **ppv
)
3658 return FileDialog_constructor(pUnkOuter
, riid
, ppv
, ITEMDLG_TYPE_OPEN
);
3661 HRESULT
FileSaveDialog_Constructor(IUnknown
*pUnkOuter
, REFIID riid
, void **ppv
)
3663 return FileDialog_constructor(pUnkOuter
, riid
, ppv
, ITEMDLG_TYPE_SAVE
);