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
37 #include "filedlgbrowser.h"
39 #include "wine/debug.h"
40 #include "wine/list.h"
42 #define IDC_NAV_TOOLBAR 200
43 #define IDC_NAVBACK 201
44 #define IDC_NAVFORWARD 202
47 /* This seems to be another version of IID_IFileDialogCustomize. If
48 * there is any difference I have yet to find it. */
49 DEFINE_GUID(IID_IFileDialogCustomizeAlt
, 0x8016B7B3, 0x3D49, 0x4504, 0xA0,0xAA, 0x2A,0x37,0x49,0x4E,0x60,0x6F);
51 WINE_DEFAULT_DEBUG_CHANNEL(commdlg
);
53 static const WCHAR notifysink_childW
[] = {'n','f','s','_','c','h','i','l','d',0};
54 static const WCHAR floatnotifysinkW
[] = {'F','l','o','a','t','N','o','t','i','f','y','S','i','n','k',0};
55 static const WCHAR radiobuttonlistW
[] = {'R','a','d','i','o','B','u','t','t','o','n','L','i','s','t',0};
62 enum ITEMDLG_CCTRL_TYPE
{
64 IDLG_CCTRL_PUSHBUTTON
,
66 IDLG_CCTRL_RADIOBUTTONLIST
,
67 IDLG_CCTRL_CHECKBUTTON
,
71 IDLG_CCTRL_OPENDROPDOWN
,
72 IDLG_CCTRL_VISUALGROUP
75 typedef struct cctrl_item
{
78 CDCONTROLSTATEF cdcstate
;
84 HWND hwnd
, wrapper_hwnd
;
86 enum ITEMDLG_CCTRL_TYPE type
;
87 CDCONTROLSTATEF cdcstate
;
90 struct list sub_cctrls
;
91 struct list sub_cctrls_entry
;
92 struct list sub_items
;
97 IFileDialogEvents
*pfde
;
101 typedef struct FileDialogImpl
{
102 IFileDialog2 IFileDialog2_iface
;
104 IFileOpenDialog IFileOpenDialog_iface
;
105 IFileSaveDialog IFileSaveDialog_iface
;
107 enum ITEMDLG_TYPE dlg_type
;
108 IExplorerBrowserEvents IExplorerBrowserEvents_iface
;
109 IServiceProvider IServiceProvider_iface
;
110 ICommDlgBrowser3 ICommDlgBrowser3_iface
;
111 IOleWindow IOleWindow_iface
;
112 IFileDialogCustomize IFileDialogCustomize_iface
;
115 FILEOPENDIALOGOPTIONS options
;
116 COMDLG_FILTERSPEC
*filterspecs
;
117 UINT filterspec_count
;
120 struct list events_clients
;
121 DWORD events_next_cookie
;
123 IShellItemArray
*psia_selection
;
124 IShellItemArray
*psia_results
;
125 IShellItem
*psi_defaultfolder
;
126 IShellItem
*psi_setfolder
;
127 IShellItem
*psi_folder
;
130 IExplorerBrowser
*peb
;
131 DWORD ebevents_cookie
;
136 LPWSTR custom_okbutton
;
137 LPWSTR custom_cancelbutton
;
138 LPWSTR custom_filenamelabel
;
140 UINT cctrl_width
, cctrl_def_height
, cctrls_cols
;
144 UINT_PTR cctrl_next_dlgid
;
145 customctrl
*cctrl_active_vg
;
147 HMENU hmenu_opendropdown
;
148 customctrl cctrl_opendropdown
;
149 HFONT hfont_opendropdown
;
150 BOOL opendropdown_has_selection
;
151 DWORD opendropdown_selection
;
156 /**************************************************************************
159 static HRESULT
events_OnFileOk(FileDialogImpl
*This
)
161 events_client
*cursor
;
165 LIST_FOR_EACH_ENTRY(cursor
, &This
->events_clients
, events_client
, entry
)
167 TRACE("Notifying %p\n", cursor
);
168 hr
= IFileDialogEvents_OnFileOk(cursor
->pfde
, (IFileDialog
*)&This
->IFileDialog2_iface
);
169 if(FAILED(hr
) && hr
!= E_NOTIMPL
)
179 static HRESULT
events_OnFolderChanging(FileDialogImpl
*This
, IShellItem
*folder
)
181 events_client
*cursor
;
183 TRACE("%p (%p)\n", This
, folder
);
185 LIST_FOR_EACH_ENTRY(cursor
, &This
->events_clients
, events_client
, entry
)
187 TRACE("Notifying %p\n", cursor
);
188 hr
= IFileDialogEvents_OnFolderChanging(cursor
->pfde
, (IFileDialog
*)&This
->IFileDialog2_iface
, folder
);
189 if(FAILED(hr
) && hr
!= E_NOTIMPL
)
199 static void events_OnFolderChange(FileDialogImpl
*This
)
201 events_client
*cursor
;
204 LIST_FOR_EACH_ENTRY(cursor
, &This
->events_clients
, events_client
, entry
)
206 TRACE("Notifying %p\n", cursor
);
207 IFileDialogEvents_OnFolderChange(cursor
->pfde
, (IFileDialog
*)&This
->IFileDialog2_iface
);
211 static void events_OnSelectionChange(FileDialogImpl
*This
)
213 events_client
*cursor
;
216 LIST_FOR_EACH_ENTRY(cursor
, &This
->events_clients
, events_client
, entry
)
218 TRACE("Notifying %p\n", cursor
);
219 IFileDialogEvents_OnSelectionChange(cursor
->pfde
, (IFileDialog
*)&This
->IFileDialog2_iface
);
223 static void events_OnTypeChange(FileDialogImpl
*This
)
225 events_client
*cursor
;
228 LIST_FOR_EACH_ENTRY(cursor
, &This
->events_clients
, events_client
, entry
)
230 TRACE("Notifying %p\n", cursor
);
231 IFileDialogEvents_OnTypeChange(cursor
->pfde
, (IFileDialog
*)&This
->IFileDialog2_iface
);
235 static HRESULT
events_OnOverwrite(FileDialogImpl
*This
, IShellItem
*shellitem
)
237 events_client
*cursor
;
239 FDE_OVERWRITE_RESPONSE response
= FDEOR_DEFAULT
;
240 TRACE("%p %p\n", This
, shellitem
);
242 LIST_FOR_EACH_ENTRY(cursor
, &This
->events_clients
, events_client
, entry
)
244 TRACE("Notifying %p\n", cursor
);
245 hr
= IFileDialogEvents_OnOverwrite(cursor
->pfde
, (IFileDialog
*)&This
->IFileDialog2_iface
, shellitem
, &response
);
246 TRACE("<-- hr=%x response=%u\n", hr
, response
);
247 if(FAILED(hr
) && hr
!= E_NOTIMPL
)
256 if (response
== FDEOR_DEFAULT
)
261 LoadStringW(COMDLG32_hInstance
, IDS_OVERWRITEFILE
, buf
, 100);
262 answer
= MessageBoxW(This
->dlg_hwnd
, buf
, This
->custom_title
,
263 MB_YESNO
| MB_ICONEXCLAMATION
);
264 if (answer
== IDNO
|| answer
== IDCANCEL
)
269 else if (response
== FDEOR_REFUSE
)
276 static inline HRESULT
get_cctrl_event(IFileDialogEvents
*pfde
, IFileDialogControlEvents
**pfdce
)
278 return IFileDialogEvents_QueryInterface(pfde
, &IID_IFileDialogControlEvents
, (void**)pfdce
);
281 static HRESULT
cctrl_event_OnButtonClicked(FileDialogImpl
*This
, DWORD ctl_id
)
283 events_client
*cursor
;
286 LIST_FOR_EACH_ENTRY(cursor
, &This
->events_clients
, events_client
, entry
)
288 IFileDialogControlEvents
*pfdce
;
289 if(SUCCEEDED(get_cctrl_event(cursor
->pfde
, &pfdce
)))
291 TRACE("Notifying %p\n", cursor
);
292 IFileDialogControlEvents_OnButtonClicked(pfdce
, &This
->IFileDialogCustomize_iface
, ctl_id
);
293 IFileDialogControlEvents_Release(pfdce
);
300 static HRESULT
cctrl_event_OnItemSelected(FileDialogImpl
*This
, DWORD ctl_id
, DWORD item_id
)
302 events_client
*cursor
;
303 TRACE("%p %i %i\n", This
, ctl_id
, item_id
);
305 LIST_FOR_EACH_ENTRY(cursor
, &This
->events_clients
, events_client
, entry
)
307 IFileDialogControlEvents
*pfdce
;
308 if(SUCCEEDED(get_cctrl_event(cursor
->pfde
, &pfdce
)))
310 TRACE("Notifying %p\n", cursor
);
311 IFileDialogControlEvents_OnItemSelected(pfdce
, &This
->IFileDialogCustomize_iface
, ctl_id
, item_id
);
312 IFileDialogControlEvents_Release(pfdce
);
319 static HRESULT
cctrl_event_OnCheckButtonToggled(FileDialogImpl
*This
, DWORD ctl_id
, BOOL checked
)
321 events_client
*cursor
;
324 LIST_FOR_EACH_ENTRY(cursor
, &This
->events_clients
, events_client
, entry
)
326 IFileDialogControlEvents
*pfdce
;
327 if(SUCCEEDED(get_cctrl_event(cursor
->pfde
, &pfdce
)))
329 TRACE("Notifying %p\n", cursor
);
330 IFileDialogControlEvents_OnCheckButtonToggled(pfdce
, &This
->IFileDialogCustomize_iface
, ctl_id
, checked
);
331 IFileDialogControlEvents_Release(pfdce
);
338 static HRESULT
cctrl_event_OnControlActivating(FileDialogImpl
*This
,
341 events_client
*cursor
;
344 LIST_FOR_EACH_ENTRY(cursor
, &This
->events_clients
, events_client
, entry
)
346 IFileDialogControlEvents
*pfdce
;
347 if(SUCCEEDED(get_cctrl_event(cursor
->pfde
, &pfdce
)))
349 TRACE("Notifying %p\n", cursor
);
350 IFileDialogControlEvents_OnControlActivating(pfdce
, &This
->IFileDialogCustomize_iface
, ctl_id
);
351 IFileDialogControlEvents_Release(pfdce
);
358 /**************************************************************************
361 static UINT
get_file_name(FileDialogImpl
*This
, LPWSTR
*str
)
363 HWND hwnd_edit
= GetDlgItem(This
->dlg_hwnd
, IDC_FILENAME
);
368 if(This
->set_filename
)
370 len
= lstrlenW(This
->set_filename
);
371 *str
= CoTaskMemAlloc(sizeof(WCHAR
)*(len
+1));
372 lstrcpyW(*str
, This
->set_filename
);
378 len
= SendMessageW(hwnd_edit
, WM_GETTEXTLENGTH
, 0, 0);
379 *str
= CoTaskMemAlloc(sizeof(WCHAR
)*(len
+1));
383 SendMessageW(hwnd_edit
, WM_GETTEXT
, len
+1, (LPARAM
)*str
);
387 static BOOL
set_file_name(FileDialogImpl
*This
, LPCWSTR str
)
389 HWND hwnd_edit
= GetDlgItem(This
->dlg_hwnd
, IDC_FILENAME
);
391 if(This
->set_filename
)
392 LocalFree(This
->set_filename
);
394 This
->set_filename
= StrDupW(str
);
396 return SendMessageW(hwnd_edit
, WM_SETTEXT
, 0, (LPARAM
)str
);
399 static void fill_filename_from_selection(FileDialogImpl
*This
)
404 UINT item_count
, valid_count
;
407 if(!This
->psia_selection
)
410 hr
= IShellItemArray_GetCount(This
->psia_selection
, &item_count
);
411 if(FAILED(hr
) || !item_count
)
414 names
= HeapAlloc(GetProcessHeap(), 0, item_count
*sizeof(LPWSTR
));
416 /* Get names of the selected items */
417 valid_count
= 0; len_total
= 0;
418 for(i
= 0; i
< item_count
; i
++)
420 hr
= IShellItemArray_GetItemAt(This
->psia_selection
, i
, &psi
);
425 hr
= IShellItem_GetAttributes(psi
, SFGAO_FOLDER
, &attr
);
427 (( (This
->options
& FOS_PICKFOLDERS
) && !(attr
& SFGAO_FOLDER
)) ||
428 (!(This
->options
& FOS_PICKFOLDERS
) && (attr
& SFGAO_FOLDER
))))
431 hr
= IShellItem_GetDisplayName(psi
, SIGDN_PARENTRELATIVEPARSING
, &names
[valid_count
]);
434 len_total
+= lstrlenW(names
[valid_count
]) + 3;
437 IShellItem_Release(psi
);
443 set_file_name(This
, names
[0]);
444 CoTaskMemFree(names
[0]);
446 else if(valid_count
> 1)
448 LPWSTR string
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
)*len_total
);
449 LPWSTR cur_point
= string
;
451 for(i
= 0; i
< valid_count
; i
++)
453 LPWSTR file
= names
[i
];
455 lstrcpyW(cur_point
, file
);
456 cur_point
+= lstrlenW(file
);
461 *(cur_point
-1) = '\0';
463 set_file_name(This
, string
);
464 HeapFree(GetProcessHeap(), 0, string
);
467 HeapFree(GetProcessHeap(), 0, names
);
471 static LPWSTR
get_first_ext_from_spec(LPWSTR buf
, LPCWSTR spec
)
476 if( (endpos
= StrChrW(buf
, ';')) )
479 ext
= PathFindExtensionW(buf
);
480 if(StrChrW(ext
, '*'))
486 static BOOL
shell_item_exists(IShellItem
* shellitem
)
492 hr
= IShellItem_GetDisplayName(shellitem
, SIGDN_FILESYSPATH
, &filename
);
495 /* FIXME: Implement SFGAO_VALIDATE in Wine and use it instead. */
496 result
= (GetFileAttributesW(filename
) != INVALID_FILE_ATTRIBUTES
);
497 CoTaskMemFree(filename
);
502 result
= SUCCEEDED(IShellItem_GetAttributes(shellitem
, SFGAO_VALIDATE
, &attributes
));
508 static HRESULT
on_default_action(FileDialogImpl
*This
)
510 IShellFolder
*psf_parent
, *psf_desktop
;
512 LPITEMIDLIST current_folder
;
513 LPWSTR fn_iter
, files
= NULL
, tmp_files
;
514 UINT file_count
= 0, len
, i
;
516 HRESULT hr
, ret
= E_FAIL
;
518 len
= get_file_name(This
, &tmp_files
);
522 file_count
= COMDLG32_SplitFileNames(tmp_files
, len
, &files
, &size_used
);
523 CoTaskMemFree(tmp_files
);
525 if(!file_count
) return E_FAIL
;
527 hr
= SHGetIDListFromObject((IUnknown
*)This
->psi_folder
, ¤t_folder
);
530 ERR("Failed to get pidl for current directory.\n");
531 HeapFree(GetProcessHeap(), 0, files
);
535 TRACE("Acting on %d file(s).\n", file_count
);
537 pidla
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPITEMIDLIST
) * file_count
);
538 open_action
= ONOPEN_OPEN
;
541 for(i
= 0; i
< file_count
&& open_action
== ONOPEN_OPEN
; i
++)
543 WCHAR canon_filename
[MAX_PATH
];
546 COMDLG32_GetCanonicalPath(current_folder
, fn_iter
, canon_filename
);
548 if( (This
->options
& FOS_NOVALIDATE
) &&
549 !(This
->options
& FOS_FILEMUSTEXIST
) )
550 open_action
= ONOPEN_OPEN
;
552 open_action
= ONOPEN_BROWSE
;
554 open_action
= FILEDLG95_ValidatePathAction(canon_filename
, &psf_parent
, This
->dlg_hwnd
,
555 This
->options
& ~FOS_FILEMUSTEXIST
,
556 (This
->dlg_type
== ITEMDLG_TYPE_SAVE
),
559 /* Add the proper extension */
560 if(open_action
== ONOPEN_OPEN
)
562 static const WCHAR dotW
[] = {'.',0};
564 if(This
->dlg_type
== ITEMDLG_TYPE_SAVE
)
566 WCHAR extbuf
[MAX_PATH
], *newext
= NULL
;
568 if(This
->filterspec_count
)
570 newext
= get_first_ext_from_spec(extbuf
, This
->filterspecs
[This
->filetypeindex
].pszSpec
);
572 else if(This
->default_ext
)
574 lstrcpyW(extbuf
, dotW
);
575 lstrcatW(extbuf
, This
->default_ext
);
581 WCHAR
*ext
= PathFindExtensionW(canon_filename
);
582 if(lstrcmpW(ext
, newext
))
583 lstrcatW(canon_filename
, newext
);
588 if( !(This
->options
& FOS_NOVALIDATE
) && (This
->options
& FOS_FILEMUSTEXIST
) &&
589 !PathFileExistsW(canon_filename
))
591 if(This
->default_ext
)
593 lstrcatW(canon_filename
, dotW
);
594 lstrcatW(canon_filename
, This
->default_ext
);
596 if(!PathFileExistsW(canon_filename
))
598 FILEDLG95_OnOpenMessage(This
->dlg_hwnd
, 0, IDS_FILENOTEXISTING
);
599 open_action
= ONOPEN_BROWSE
;
604 FILEDLG95_OnOpenMessage(This
->dlg_hwnd
, 0, IDS_FILENOTEXISTING
);
605 open_action
= ONOPEN_BROWSE
;
611 pidla
[i
] = COMDLG32_SHSimpleIDListFromPathAW(canon_filename
);
613 if(psf_parent
&& !(open_action
== ONOPEN_BROWSE
))
614 IShellFolder_Release(psf_parent
);
616 fn_iter
+= (WCHAR
)lstrlenW(fn_iter
) + 1;
619 HeapFree(GetProcessHeap(), 0, files
);
620 ILFree(current_folder
);
622 if((This
->options
& FOS_PICKFOLDERS
) && open_action
== ONOPEN_BROWSE
)
623 open_action
= ONOPEN_OPEN
; /* FIXME: Multiple folders? */
628 FIXME("Filtering not implemented.\n");
632 hr
= IExplorerBrowser_BrowseToObject(This
->peb
, (IUnknown
*)psf_parent
, SBSP_DEFBROWSER
);
634 ERR("Failed to browse to directory: %08x\n", hr
);
636 IShellFolder_Release(psf_parent
);
640 hr
= SHGetDesktopFolder(&psf_desktop
);
643 if(This
->psia_results
)
645 IShellItemArray_Release(This
->psia_results
);
646 This
->psia_results
= NULL
;
649 hr
= SHCreateShellItemArray(NULL
, psf_desktop
, file_count
, (PCUITEMID_CHILD_ARRAY
)pidla
,
650 &This
->psia_results
);
652 IShellFolder_Release(psf_desktop
);
657 if(This
->options
& FOS_PICKFOLDERS
)
660 hr
= IShellItemArray_GetAttributes(This
->psia_results
, SIATTRIBFLAGS_AND
, SFGAO_FOLDER
, &attributes
);
664 LoadStringW(COMDLG32_hInstance
, IDS_INVALID_FOLDERNAME
, buf
, sizeof(buf
)/sizeof(WCHAR
));
666 MessageBoxW(This
->dlg_hwnd
, buf
, This
->custom_title
, MB_OK
| MB_ICONEXCLAMATION
);
668 IShellItemArray_Release(This
->psia_results
);
669 This
->psia_results
= NULL
;
674 if((This
->options
& FOS_OVERWRITEPROMPT
) && This
->dlg_type
== ITEMDLG_TYPE_SAVE
)
676 IShellItem
*shellitem
;
678 for (i
=0; SUCCEEDED(hr
) && i
<file_count
; i
++)
680 hr
= IShellItemArray_GetItemAt(This
->psia_results
, i
, &shellitem
);
683 if (shell_item_exists(shellitem
))
684 hr
= events_OnOverwrite(This
, shellitem
);
686 IShellItem_Release(shellitem
);
694 if(events_OnFileOk(This
) == S_OK
)
705 for(i
= 0; i
< file_count
; i
++)
707 HeapFree(GetProcessHeap(), 0, pidla
);
709 /* Success closes the dialog */
713 static void show_opendropdown(FileDialogImpl
*This
)
719 open_hwnd
= GetDlgItem(This
->dlg_hwnd
, IDOK
);
721 GetWindowRect(open_hwnd
, &open_rc
);
723 if (TrackPopupMenu(This
->hmenu_opendropdown
, 0, open_rc
.left
, open_rc
.bottom
, 0, This
->dlg_hwnd
, NULL
) &&
724 PeekMessageW(&msg
, This
->dlg_hwnd
, WM_MENUCOMMAND
, WM_MENUCOMMAND
, PM_REMOVE
))
728 This
->opendropdown_has_selection
= TRUE
;
730 mii
.cbSize
= sizeof(mii
);
732 GetMenuItemInfoW((HMENU
)msg
.lParam
, msg
.wParam
, TRUE
, &mii
);
733 This
->opendropdown_selection
= mii
.wID
;
735 if(SUCCEEDED(on_default_action(This
)))
736 EndDialog(This
->dlg_hwnd
, S_OK
);
738 This
->opendropdown_has_selection
= FALSE
;
742 /**************************************************************************
743 * Control item functions.
746 static void item_free(cctrl_item
*item
)
748 DestroyWindow(item
->hwnd
);
749 HeapFree(GetProcessHeap(), 0, item
->label
);
750 HeapFree(GetProcessHeap(), 0, item
);
753 static cctrl_item
* get_item(customctrl
* parent
, DWORD itemid
, CDCONTROLSTATEF visible_flags
, DWORD
* position
)
758 if (!position
) position
= &dummy
;
762 LIST_FOR_EACH_ENTRY(item
, &parent
->sub_items
, cctrl_item
, entry
)
764 if (item
->id
== itemid
)
767 if ((item
->cdcstate
& visible_flags
) == visible_flags
)
774 static cctrl_item
* get_first_item(customctrl
* parent
)
778 LIST_FOR_EACH_ENTRY(item
, &parent
->sub_items
, cctrl_item
, entry
)
780 if ((item
->cdcstate
& (CDCS_VISIBLE
|CDCS_ENABLED
)) == (CDCS_VISIBLE
|CDCS_ENABLED
))
787 static HRESULT
add_item(customctrl
* parent
, DWORD itemid
, LPCWSTR label
, cctrl_item
** result
)
792 if (get_item(parent
, itemid
, 0, NULL
))
795 item
= HeapAlloc(GetProcessHeap(), 0, sizeof(*item
));
796 label_copy
= HeapAlloc(GetProcessHeap(), 0, (lstrlenW(label
)+1)*sizeof(WCHAR
));
798 if (!item
|| !label_copy
)
800 HeapFree(GetProcessHeap(), 0, item
);
801 HeapFree(GetProcessHeap(), 0, label_copy
);
802 return E_OUTOFMEMORY
;
806 item
->parent_id
= parent
->id
;
807 lstrcpyW(label_copy
, label
);
808 item
->label
= label_copy
;
809 item
->cdcstate
= CDCS_VISIBLE
|CDCS_ENABLED
;
811 list_add_tail(&parent
->sub_items
, &item
->entry
);
818 /**************************************************************************
821 static inline customctrl
*get_cctrl_from_dlgid(FileDialogImpl
*This
, DWORD dlgid
)
823 customctrl
*ctrl
, *sub_ctrl
;
825 LIST_FOR_EACH_ENTRY(ctrl
, &This
->cctrls
, customctrl
, entry
)
827 if(ctrl
->dlgid
== dlgid
)
830 LIST_FOR_EACH_ENTRY(sub_ctrl
, &ctrl
->sub_cctrls
, customctrl
, sub_cctrls_entry
)
831 if(sub_ctrl
->dlgid
== dlgid
)
835 ERR("Failed to find control with dialog id %d\n", dlgid
);
839 static inline customctrl
*get_cctrl(FileDialogImpl
*This
, DWORD ctlid
)
841 customctrl
*ctrl
, *sub_ctrl
;
843 LIST_FOR_EACH_ENTRY(ctrl
, &This
->cctrls
, customctrl
, entry
)
845 if(ctrl
->id
== ctlid
)
848 LIST_FOR_EACH_ENTRY(sub_ctrl
, &ctrl
->sub_cctrls
, customctrl
, sub_cctrls_entry
)
849 if(sub_ctrl
->id
== ctlid
)
853 if (This
->hmenu_opendropdown
&& This
->cctrl_opendropdown
.id
== ctlid
)
854 return &This
->cctrl_opendropdown
;
856 TRACE("No existing control with control id %d\n", ctlid
);
860 static void ctrl_resize(HWND hctrl
, UINT min_width
, UINT max_width
, BOOL multiline
)
863 UINT len
, final_width
;
864 UINT lines
, final_height
;
872 len
= SendMessageW(hctrl
, WM_GETTEXTLENGTH
, 0, 0);
873 text
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
)*(len
+1));
875 SendMessageW(hctrl
, WM_GETTEXT
, len
+1, (LPARAM
)text
);
878 GetTextExtentPoint32W(hdc
, text
, lstrlenW(text
), &size
);
879 ReleaseDC(hctrl
, hdc
);
883 /* FIXME: line-wrap */
884 for(lines
= 1, c
= text
; *c
!= '\0'; c
++)
885 if(*c
== '\n') lines
++;
887 final_height
= size
.cy
*lines
+ 2*4;
891 GetWindowRect(hctrl
, &rc
);
892 final_height
= rc
.bottom
- rc
.top
;
895 final_width
= min(max(size
.cx
, min_width
) + 4, max_width
);
896 SetWindowPos(hctrl
, NULL
, 0, 0, final_width
, final_height
,
897 SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOACTIVATE
);
899 HeapFree(GetProcessHeap(), 0, text
);
902 static UINT
ctrl_get_height(customctrl
*ctrl
) {
904 GetWindowRect(ctrl
->wrapper_hwnd
, &rc
);
905 return rc
.bottom
- rc
.top
;
908 static void ctrl_free(customctrl
*ctrl
)
910 customctrl
*sub_cur1
, *sub_cur2
;
911 cctrl_item
*item_cur1
, *item_cur2
;
913 TRACE("Freeing control %p\n", ctrl
);
914 if(ctrl
->type
== IDLG_CCTRL_MENU
)
917 SendMessageW(ctrl
->hwnd
, TB_GETBUTTON
, 0, (LPARAM
)&tbb
);
918 DestroyMenu((HMENU
)tbb
.dwData
);
921 LIST_FOR_EACH_ENTRY_SAFE(sub_cur1
, sub_cur2
, &ctrl
->sub_cctrls
, customctrl
, sub_cctrls_entry
)
923 list_remove(&sub_cur1
->sub_cctrls_entry
);
927 LIST_FOR_EACH_ENTRY_SAFE(item_cur1
, item_cur2
, &ctrl
->sub_items
, cctrl_item
, entry
)
929 list_remove(&item_cur1
->entry
);
930 item_free(item_cur1
);
933 DestroyWindow(ctrl
->hwnd
);
934 HeapFree(GetProcessHeap(), 0, ctrl
);
937 static void customctrl_resize(FileDialogImpl
*This
, customctrl
*ctrl
)
942 customctrl
*sub_ctrl
;
946 case IDLG_CCTRL_PUSHBUTTON
:
947 case IDLG_CCTRL_COMBOBOX
:
948 case IDLG_CCTRL_CHECKBUTTON
:
949 case IDLG_CCTRL_TEXT
:
950 ctrl_resize(ctrl
->hwnd
, 160, 160, TRUE
);
951 GetWindowRect(ctrl
->hwnd
, &rc
);
952 SetWindowPos(ctrl
->wrapper_hwnd
, NULL
, 0, 0, rc
.right
-rc
.left
, rc
.bottom
-rc
.top
,
953 SWP_NOZORDER
|SWP_NOMOVE
);
955 case IDLG_CCTRL_VISUALGROUP
:
957 ctrl_resize(ctrl
->hwnd
, 0, This
->cctrl_indent
, TRUE
);
959 LIST_FOR_EACH_ENTRY(sub_ctrl
, &ctrl
->sub_cctrls
, customctrl
, sub_cctrls_entry
)
961 customctrl_resize(This
, sub_ctrl
);
962 SetWindowPos(sub_ctrl
->wrapper_hwnd
, NULL
, This
->cctrl_indent
, total_height
, 0, 0,
963 SWP_NOZORDER
|SWP_NOSIZE
);
965 total_height
+= ctrl_get_height(sub_ctrl
);
968 /* The label should be right adjusted */
972 GetWindowRect(ctrl
->hwnd
, &rc
);
973 width
= rc
.right
- rc
.left
;
974 height
= rc
.bottom
- rc
.top
;
976 SetWindowPos(ctrl
->hwnd
, NULL
, This
->cctrl_indent
- width
, 0, width
, height
, SWP_NOZORDER
);
979 /* Resize the wrapper window to fit all the sub controls */
980 SetWindowPos(ctrl
->wrapper_hwnd
, NULL
, 0, 0, This
->cctrl_width
+ This
->cctrl_indent
, total_height
,
981 SWP_NOZORDER
|SWP_NOMOVE
);
983 case IDLG_CCTRL_RADIOBUTTONLIST
:
990 LIST_FOR_EACH_ENTRY(item
, &ctrl
->sub_items
, cctrl_item
, entry
)
992 ctrl_resize(item
->hwnd
, 160, 160, TRUE
);
993 SetWindowPos(item
->hwnd
, NULL
, 0, total_height
, 0, 0,
994 SWP_NOZORDER
|SWP_NOSIZE
);
996 GetWindowRect(item
->hwnd
, &rc
);
998 total_height
+= rc
.bottom
- rc
.top
;
999 max_width
= max(rc
.right
- rc
.left
, max_width
);
1002 SetWindowPos(ctrl
->hwnd
, NULL
, 0, 0, max_width
, total_height
,
1003 SWP_NOZORDER
|SWP_NOMOVE
);
1005 SetWindowPos(ctrl
->wrapper_hwnd
, NULL
, 0, 0, max_width
, total_height
,
1006 SWP_NOZORDER
|SWP_NOMOVE
);
1010 case IDLG_CCTRL_EDITBOX
:
1011 case IDLG_CCTRL_SEPARATOR
:
1012 case IDLG_CCTRL_MENU
:
1013 case IDLG_CCTRL_OPENDROPDOWN
:
1019 static LRESULT
notifysink_on_create(HWND hwnd
, CREATESTRUCTW
*crs
)
1021 FileDialogImpl
*This
= crs
->lpCreateParams
;
1022 TRACE("%p\n", This
);
1024 SetWindowLongPtrW(hwnd
, GWLP_USERDATA
, (LPARAM
)This
);
1028 static LRESULT
notifysink_on_bn_clicked(FileDialogImpl
*This
, HWND hwnd
, WPARAM wparam
)
1030 customctrl
*ctrl
= get_cctrl_from_dlgid(This
, LOWORD(wparam
));
1032 TRACE("%p, %lx\n", This
, wparam
);
1036 if(ctrl
->type
== IDLG_CCTRL_CHECKBUTTON
)
1038 BOOL checked
= (SendMessageW(ctrl
->hwnd
, BM_GETCHECK
, 0, 0) == BST_CHECKED
);
1039 cctrl_event_OnCheckButtonToggled(This
, ctrl
->id
, checked
);
1042 cctrl_event_OnButtonClicked(This
, ctrl
->id
);
1048 static LRESULT
notifysink_on_cbn_selchange(FileDialogImpl
*This
, HWND hwnd
, WPARAM wparam
)
1050 customctrl
*ctrl
= get_cctrl_from_dlgid(This
, LOWORD(wparam
));
1051 TRACE("%p, %p (%lx)\n", This
, ctrl
, wparam
);
1055 UINT index
= SendMessageW(ctrl
->hwnd
, CB_GETCURSEL
, 0, 0);
1056 UINT selid
= SendMessageW(ctrl
->hwnd
, CB_GETITEMDATA
, index
, 0);
1058 cctrl_event_OnItemSelected(This
, ctrl
->id
, selid
);
1063 static LRESULT
notifysink_on_tvn_dropdown(FileDialogImpl
*This
, LPARAM lparam
)
1065 NMTOOLBARW
*nmtb
= (NMTOOLBARW
*)lparam
;
1066 customctrl
*ctrl
= get_cctrl_from_dlgid(This
, GetDlgCtrlID(nmtb
->hdr
.hwndFrom
));
1067 POINT pt
= { 0, nmtb
->rcButton
.bottom
};
1071 TRACE("%p, %p (%lx)\n", This
, ctrl
, lparam
);
1075 cctrl_event_OnControlActivating(This
,ctrl
->id
);
1077 SendMessageW(ctrl
->hwnd
, TB_GETBUTTON
, 0, (LPARAM
)&tbb
);
1078 ClientToScreen(ctrl
->hwnd
, &pt
);
1079 idcmd
= TrackPopupMenu((HMENU
)tbb
.dwData
, TPM_RETURNCMD
, pt
.x
, pt
.y
, 0, This
->dlg_hwnd
, NULL
);
1081 cctrl_event_OnItemSelected(This
, ctrl
->id
, idcmd
);
1084 return TBDDRET_DEFAULT
;
1087 static LRESULT
notifysink_on_wm_command(FileDialogImpl
*This
, HWND hwnd
, WPARAM wparam
, LPARAM lparam
)
1089 switch(HIWORD(wparam
))
1091 case BN_CLICKED
: return notifysink_on_bn_clicked(This
, hwnd
, wparam
);
1092 case CBN_SELCHANGE
: return notifysink_on_cbn_selchange(This
, hwnd
, wparam
);
1098 static LRESULT
notifysink_on_wm_notify(FileDialogImpl
*This
, HWND hwnd
, WPARAM wparam
, LPARAM lparam
)
1100 NMHDR
*nmhdr
= (NMHDR
*)lparam
;
1104 case TBN_DROPDOWN
: return notifysink_on_tvn_dropdown(This
, lparam
);
1110 static LRESULT CALLBACK
notifysink_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
1112 FileDialogImpl
*This
= (FileDialogImpl
*)GetWindowLongPtrW(hwnd
, GWLP_USERDATA
);
1119 case WM_NCCREATE
: return notifysink_on_create(hwnd
, (CREATESTRUCTW
*)lparam
);
1120 case WM_COMMAND
: return notifysink_on_wm_command(This
, hwnd
, wparam
, lparam
);
1121 case WM_NOTIFY
: return notifysink_on_wm_notify(This
, hwnd
, wparam
, lparam
);
1123 hwnd_child
= GetPropW(hwnd
, notifysink_childW
);
1124 ctrl
= (customctrl
*)GetWindowLongPtrW(hwnd_child
, GWLP_USERDATA
);
1125 if(ctrl
&& ctrl
->type
!= IDLG_CCTRL_VISUALGROUP
)
1127 GetClientRect(hwnd
, &rc
);
1128 SetWindowPos(hwnd_child
, NULL
, 0, 0, rc
.right
, rc
.bottom
, SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_NOZORDER
);
1133 return DefWindowProcW(hwnd
, message
, wparam
, lparam
);
1136 static HRESULT
cctrl_create_new(FileDialogImpl
*This
, DWORD id
,
1137 LPCWSTR text
, LPCWSTR wndclass
, DWORD ctrl_wsflags
,
1138 DWORD ctrl_exflags
, UINT height
, customctrl
**ppctrl
)
1140 HWND ns_hwnd
, control_hwnd
, parent_hwnd
;
1141 DWORD wsflags
= WS_CHILD
| WS_VISIBLE
| WS_CLIPSIBLINGS
;
1144 if(get_cctrl(This
, id
))
1145 return E_UNEXPECTED
; /* Duplicate id */
1147 if(This
->cctrl_active_vg
)
1148 parent_hwnd
= This
->cctrl_active_vg
->wrapper_hwnd
;
1150 parent_hwnd
= This
->cctrls_hwnd
;
1152 ns_hwnd
= CreateWindowExW(0, floatnotifysinkW
, NULL
, wsflags
,
1153 0, 0, This
->cctrl_width
, height
, parent_hwnd
,
1154 (HMENU
)This
->cctrl_next_dlgid
, COMDLG32_hInstance
, This
);
1155 control_hwnd
= CreateWindowExW(ctrl_exflags
, wndclass
, text
, wsflags
| ctrl_wsflags
,
1156 0, 0, This
->cctrl_width
, height
, ns_hwnd
,
1157 (HMENU
)This
->cctrl_next_dlgid
, COMDLG32_hInstance
, 0);
1159 if(!ns_hwnd
|| !control_hwnd
)
1161 ERR("Failed to create wrapper (%p) or control (%p)\n", ns_hwnd
, control_hwnd
);
1162 DestroyWindow(ns_hwnd
);
1163 DestroyWindow(control_hwnd
);
1168 SetPropW(ns_hwnd
, notifysink_childW
, control_hwnd
);
1170 ctrl
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(customctrl
));
1172 return E_OUTOFMEMORY
;
1174 ctrl
->hwnd
= control_hwnd
;
1175 ctrl
->wrapper_hwnd
= ns_hwnd
;
1177 ctrl
->dlgid
= This
->cctrl_next_dlgid
;
1178 ctrl
->cdcstate
= CDCS_ENABLED
| CDCS_VISIBLE
;
1179 list_init(&ctrl
->sub_cctrls
);
1180 list_init(&ctrl
->sub_items
);
1182 if(This
->cctrl_active_vg
)
1183 list_add_tail(&This
->cctrl_active_vg
->sub_cctrls
, &ctrl
->sub_cctrls_entry
);
1185 list_add_tail(&This
->cctrls
, &ctrl
->entry
);
1187 SetWindowLongPtrW(ctrl
->hwnd
, GWLP_USERDATA
, (LPARAM
)ctrl
);
1189 if(ppctrl
) *ppctrl
= ctrl
;
1191 This
->cctrl_next_dlgid
++;
1195 /**************************************************************************
1196 * Container functions.
1198 static UINT
ctrl_container_resize(FileDialogImpl
*This
, UINT container_width
)
1200 UINT container_height
;
1203 UINT max_control_height
, total_height
= 0;
1204 UINT cur_col_pos
, cur_row_pos
;
1207 static const UINT cspacing
= 90; /* Columns are spaced with 90px */
1208 static const UINT rspacing
= 4; /* Rows are spaced with 4 px. */
1210 /* Given the new width of the container, this function determines the
1211 * needed height of the container and places the controls according to
1212 * the new layout. Returns the new height.
1215 TRACE("%p\n", This
);
1217 column_width
= This
->cctrl_width
+ cspacing
;
1218 nr_of_cols
= (container_width
- This
->cctrl_indent
+ cspacing
) / column_width
;
1220 /* We don't need to do anything unless the number of visible columns has changed. */
1221 if(nr_of_cols
== This
->cctrls_cols
)
1224 GetWindowRect(This
->cctrls_hwnd
, &rc
);
1225 return rc
.bottom
- rc
.top
;
1228 This
->cctrls_cols
= nr_of_cols
;
1230 /* Get the size of the tallest control, and the total size of
1231 * all the controls to figure out the number of slots we need.
1233 max_control_height
= 0;
1234 LIST_FOR_EACH_ENTRY(ctrl
, &This
->cctrls
, customctrl
, entry
)
1236 if(ctrl
->cdcstate
& CDCS_VISIBLE
)
1238 UINT control_height
= ctrl_get_height(ctrl
);
1239 max_control_height
= max(max_control_height
, control_height
);
1241 total_height
+= control_height
+ rspacing
;
1248 container_height
= max(total_height
/ nr_of_cols
, max_control_height
+ rspacing
);
1249 TRACE("Guess: container_height: %d\n",container_height
);
1251 /* Incrementally increase container_height until all the controls
1255 UINT columns_needed
= 1;
1259 LIST_FOR_EACH_ENTRY(ctrl
, &This
->cctrls
, customctrl
, entry
)
1261 if(ctrl
->cdcstate
& CDCS_VISIBLE
)
1263 UINT control_height
= ctrl_get_height(ctrl
);
1265 if(cur_row_pos
+ control_height
> container_height
)
1267 if(++columns_needed
> nr_of_cols
)
1269 container_height
+= 1;
1270 fits_height
= FALSE
;
1276 cur_row_pos
+= control_height
+ rspacing
;
1279 } while(!fits_height
);
1281 TRACE("Final container height: %d\n", container_height
);
1283 /* Move the controls to their final destination
1285 cur_col_pos
= 0, cur_row_pos
= 0;
1286 LIST_FOR_EACH_ENTRY(ctrl
, &This
->cctrls
, customctrl
, entry
)
1288 if(ctrl
->cdcstate
& CDCS_VISIBLE
)
1291 UINT control_height
, control_indent
;
1292 GetWindowRect(ctrl
->wrapper_hwnd
, &rc
);
1293 control_height
= rc
.bottom
- rc
.top
;
1295 if(cur_row_pos
+ control_height
> container_height
)
1298 cur_col_pos
+= This
->cctrl_width
+ cspacing
;
1302 if(ctrl
->type
== IDLG_CCTRL_VISUALGROUP
)
1305 control_indent
= This
->cctrl_indent
;
1307 SetWindowPos(ctrl
->wrapper_hwnd
, NULL
, cur_col_pos
+ control_indent
, cur_row_pos
, 0, 0,
1308 SWP_NOACTIVATE
| SWP_NOSIZE
| SWP_NOZORDER
);
1310 cur_row_pos
+= control_height
+ rspacing
;
1315 if(cur_row_pos
+ This
->cctrl_width
> container_width
)
1316 ERR("-- Failed to place controls properly.\n");
1318 return container_height
;
1321 static void ctrl_container_reparent(FileDialogImpl
*This
, HWND parent
)
1327 customctrl
*ctrl
, *sub_ctrl
;
1330 wndstyle
= GetWindowLongW(This
->cctrls_hwnd
, GWL_STYLE
);
1331 wndstyle
&= ~(WS_POPUP
);
1332 wndstyle
|= WS_CHILD
;
1333 SetWindowLongW(This
->cctrls_hwnd
, GWL_STYLE
, wndstyle
);
1335 SetParent(This
->cctrls_hwnd
, parent
);
1336 ShowWindow(This
->cctrls_hwnd
, TRUE
);
1338 /* Set the fonts to match the dialog font. */
1339 font
= (HFONT
)SendMessageW(parent
, WM_GETFONT
, 0, 0);
1341 ERR("Failed to get font handle from dialog.\n");
1343 LIST_FOR_EACH_ENTRY(ctrl
, &This
->cctrls
, customctrl
, entry
)
1345 if(font
) SendMessageW(ctrl
->hwnd
, WM_SETFONT
, (WPARAM
)font
, TRUE
);
1347 /* If this is a VisualGroup */
1348 LIST_FOR_EACH_ENTRY(sub_ctrl
, &ctrl
->sub_cctrls
, customctrl
, sub_cctrls_entry
)
1350 if(font
) SendMessageW(sub_ctrl
->hwnd
, WM_SETFONT
, (WPARAM
)font
, TRUE
);
1353 if (ctrl
->type
== IDLG_CCTRL_RADIOBUTTONLIST
)
1356 LIST_FOR_EACH_ENTRY(item
, &ctrl
->sub_items
, cctrl_item
, entry
)
1358 if (font
) SendMessageW(item
->hwnd
, WM_SETFONT
, (WPARAM
)font
, TRUE
);
1362 customctrl_resize(This
, ctrl
);
1367 ShowWindow(This
->cctrls_hwnd
, FALSE
);
1369 wndstyle
= GetWindowLongW(This
->cctrls_hwnd
, GWL_STYLE
);
1370 wndstyle
&= ~(WS_CHILD
);
1371 wndstyle
|= WS_POPUP
;
1372 SetWindowLongW(This
->cctrls_hwnd
, GWL_STYLE
, wndstyle
);
1374 SetParent(This
->cctrls_hwnd
, NULL
);
1378 static LRESULT
ctrl_container_on_create(HWND hwnd
, CREATESTRUCTW
*crs
)
1380 FileDialogImpl
*This
= crs
->lpCreateParams
;
1381 TRACE("%p\n", This
);
1383 SetWindowLongPtrW(hwnd
, GWLP_USERDATA
, (LPARAM
)This
);
1387 static LRESULT
ctrl_container_on_wm_destroy(FileDialogImpl
*This
)
1389 customctrl
*cur1
, *cur2
;
1390 TRACE("%p\n", This
);
1392 LIST_FOR_EACH_ENTRY_SAFE(cur1
, cur2
, &This
->cctrls
, customctrl
, entry
)
1394 list_remove(&cur1
->entry
);
1401 static LRESULT CALLBACK
ctrl_container_wndproc(HWND hwnd
, UINT umessage
, WPARAM wparam
, LPARAM lparam
)
1403 FileDialogImpl
*This
= (FileDialogImpl
*)GetWindowLongPtrW(hwnd
, GWLP_USERDATA
);
1407 case WM_NCCREATE
: return ctrl_container_on_create(hwnd
, (CREATESTRUCTW
*)lparam
);
1408 case WM_DESTROY
: return ctrl_container_on_wm_destroy(This
);
1409 default: return DefWindowProcW(hwnd
, umessage
, wparam
, lparam
);
1415 static void radiobuttonlist_set_selected_item(FileDialogImpl
*This
, customctrl
*ctrl
, cctrl_item
*item
)
1419 LIST_FOR_EACH_ENTRY(cursor
, &ctrl
->sub_items
, cctrl_item
, entry
)
1421 SendMessageW(cursor
->hwnd
, BM_SETCHECK
, (cursor
== item
) ? BST_CHECKED
: BST_UNCHECKED
, 0);
1425 static LRESULT
radiobuttonlist_on_bn_clicked(FileDialogImpl
*This
, HWND hwnd
, HWND child
)
1427 DWORD ctrl_id
= (DWORD
)GetWindowLongPtrW(hwnd
, GWLP_ID
);
1430 BOOL found_item
=FALSE
;
1432 ctrl
= get_cctrl_from_dlgid(This
, ctrl_id
);
1436 ERR("Can't find this control\n");
1440 LIST_FOR_EACH_ENTRY(item
, &ctrl
->sub_items
, cctrl_item
, entry
)
1442 if (item
->hwnd
== child
)
1451 ERR("Can't find control item\n");
1455 radiobuttonlist_set_selected_item(This
, ctrl
, item
);
1457 cctrl_event_OnItemSelected(This
, ctrl
->id
, item
->id
);
1462 static LRESULT
radiobuttonlist_on_wm_command(FileDialogImpl
*This
, HWND hwnd
, WPARAM wparam
, LPARAM lparam
)
1464 switch(HIWORD(wparam
))
1466 case BN_CLICKED
: return radiobuttonlist_on_bn_clicked(This
, hwnd
, (HWND
)lparam
);
1472 static LRESULT CALLBACK
radiobuttonlist_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
1474 FileDialogImpl
*This
= (FileDialogImpl
*)GetWindowLongPtrW(hwnd
, GWLP_USERDATA
);
1478 case WM_COMMAND
: return radiobuttonlist_on_wm_command(This
, hwnd
, wparam
, lparam
);
1481 return DefWindowProcW(hwnd
, message
, wparam
, lparam
);
1484 static HRESULT
init_custom_controls(FileDialogImpl
*This
)
1487 static const WCHAR ctrl_container_classname
[] =
1488 {'i','d','l','g','_','c','o','n','t','a','i','n','e','r','_','p','a','n','e',0};
1490 InitCommonControlsEx(NULL
);
1492 This
->cctrl_width
= 160; /* Controls have a fixed width */
1493 This
->cctrl_indent
= 100;
1494 This
->cctrl_def_height
= 23;
1495 This
->cctrls_cols
= 0;
1497 This
->cctrl_next_dlgid
= 0x2000;
1498 list_init(&This
->cctrls
);
1499 This
->cctrl_active_vg
= NULL
;
1501 if( !GetClassInfoW(COMDLG32_hInstance
, ctrl_container_classname
, &wc
) )
1503 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
1504 wc
.lpfnWndProc
= ctrl_container_wndproc
;
1507 wc
.hInstance
= COMDLG32_hInstance
;
1509 wc
.hCursor
= LoadCursorW(0, (LPWSTR
)IDC_ARROW
);
1510 wc
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
1511 wc
.lpszMenuName
= NULL
;
1512 wc
.lpszClassName
= ctrl_container_classname
;
1514 if(!RegisterClassW(&wc
)) return E_FAIL
;
1517 This
->cctrls_hwnd
= CreateWindowExW(0, ctrl_container_classname
, NULL
,
1518 WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
,
1519 0, 0, 0, 0, NULL
, 0,
1520 COMDLG32_hInstance
, This
);
1521 if(!This
->cctrls_hwnd
)
1524 SetWindowLongW(This
->cctrls_hwnd
, GWL_STYLE
, WS_TABSTOP
);
1526 /* Register class for */
1527 if( !GetClassInfoW(COMDLG32_hInstance
, floatnotifysinkW
, &wc
) ||
1528 wc
.hInstance
!= COMDLG32_hInstance
)
1530 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
1531 wc
.lpfnWndProc
= notifysink_proc
;
1534 wc
.hInstance
= COMDLG32_hInstance
;
1536 wc
.hCursor
= LoadCursorW(0, (LPWSTR
)IDC_ARROW
);
1537 wc
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
1538 wc
.lpszMenuName
= NULL
;
1539 wc
.lpszClassName
= floatnotifysinkW
;
1541 if (!RegisterClassW(&wc
))
1542 ERR("Failed to register FloatNotifySink window class.\n");
1545 if( !GetClassInfoW(COMDLG32_hInstance
, radiobuttonlistW
, &wc
) ||
1546 wc
.hInstance
!= COMDLG32_hInstance
)
1548 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
1549 wc
.lpfnWndProc
= radiobuttonlist_proc
;
1552 wc
.hInstance
= COMDLG32_hInstance
;
1554 wc
.hCursor
= LoadCursorW(0, (LPWSTR
)IDC_ARROW
);
1555 wc
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
1556 wc
.lpszMenuName
= NULL
;
1557 wc
.lpszClassName
= radiobuttonlistW
;
1559 if (!RegisterClassW(&wc
))
1560 ERR("Failed to register RadioButtonList window class.\n");
1566 /**************************************************************************
1567 * Window related functions.
1569 static BOOL
update_open_dropdown(FileDialogImpl
*This
)
1571 /* Show or hide the open dropdown button as appropriate */
1572 BOOL show
=FALSE
, showing
;
1573 HWND open_hwnd
, dropdown_hwnd
;
1575 if (This
->hmenu_opendropdown
)
1577 INT num_visible_items
=0;
1580 LIST_FOR_EACH_ENTRY(item
, &This
->cctrl_opendropdown
.sub_items
, cctrl_item
, entry
)
1582 if (item
->cdcstate
& CDCS_VISIBLE
)
1584 num_visible_items
++;
1585 if (num_visible_items
>= 2)
1594 open_hwnd
= GetDlgItem(This
->dlg_hwnd
, IDOK
);
1595 dropdown_hwnd
= GetDlgItem(This
->dlg_hwnd
, psh1
);
1597 showing
= (GetWindowLongPtrW(dropdown_hwnd
, GWL_STYLE
) & WS_VISIBLE
) != 0;
1599 if (showing
!= show
)
1601 RECT open_rc
, dropdown_rc
;
1603 GetWindowRect(open_hwnd
, &open_rc
);
1604 GetWindowRect(dropdown_hwnd
, &dropdown_rc
);
1608 ShowWindow(dropdown_hwnd
, SW_SHOW
);
1610 SetWindowPos(open_hwnd
, NULL
, 0, 0,
1611 (open_rc
.right
- open_rc
.left
) - (dropdown_rc
.right
- dropdown_rc
.left
),
1612 open_rc
.bottom
- open_rc
.top
, SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOACTIVATE
);
1616 ShowWindow(dropdown_hwnd
, SW_HIDE
);
1618 SetWindowPos(open_hwnd
, NULL
, 0, 0,
1619 (open_rc
.right
- open_rc
.left
) + (dropdown_rc
.right
- dropdown_rc
.left
),
1620 open_rc
.bottom
- open_rc
.top
, SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOACTIVATE
);
1627 static void update_layout(FileDialogImpl
*This
)
1632 RECT cancel_rc
, dropdown_rc
, open_rc
;
1633 RECT filetype_rc
, filename_rc
, filenamelabel_rc
;
1634 RECT toolbar_rc
, ebrowser_rc
, customctrls_rc
;
1635 static const UINT vspacing
= 4, hspacing
= 4;
1636 static const UINT min_width
= 320, min_height
= 200;
1639 if (!GetClientRect(This
->dlg_hwnd
, &dialog_rc
))
1641 TRACE("Invalid dialog window, not updating layout\n");
1645 if(dialog_rc
.right
< min_width
|| dialog_rc
.bottom
< min_height
)
1647 TRACE("Dialog size (%d, %d) too small, not updating layout\n", dialog_rc
.right
, dialog_rc
.bottom
);
1652 * Calculate the size of the dialog and all the parts.
1656 hwnd
= GetDlgItem(This
->dlg_hwnd
, IDCANCEL
);
1659 int cancel_width
, cancel_height
;
1660 GetWindowRect(hwnd
, &cancel_rc
);
1661 cancel_width
= cancel_rc
.right
- cancel_rc
.left
;
1662 cancel_height
= cancel_rc
.bottom
- cancel_rc
.top
;
1664 cancel_rc
.left
= dialog_rc
.right
- cancel_width
- hspacing
;
1665 cancel_rc
.top
= dialog_rc
.bottom
- cancel_height
- vspacing
;
1666 cancel_rc
.right
= cancel_rc
.left
+ cancel_width
;
1667 cancel_rc
.bottom
= cancel_rc
.top
+ cancel_height
;
1670 /* Open/Save dropdown */
1671 show_dropdown
= update_open_dropdown(This
);
1675 int dropdown_width
, dropdown_height
;
1676 hwnd
= GetDlgItem(This
->dlg_hwnd
, psh1
);
1678 GetWindowRect(hwnd
, &dropdown_rc
);
1679 dropdown_width
= dropdown_rc
.right
- dropdown_rc
.left
;
1680 dropdown_height
= dropdown_rc
.bottom
- dropdown_rc
.top
;
1682 dropdown_rc
.left
= cancel_rc
.left
- dropdown_width
- hspacing
;
1683 dropdown_rc
.top
= cancel_rc
.top
;
1684 dropdown_rc
.right
= dropdown_rc
.left
+ dropdown_width
;
1685 dropdown_rc
.bottom
= dropdown_rc
.top
+ dropdown_height
;
1689 dropdown_rc
.left
= dropdown_rc
.right
= cancel_rc
.left
- hspacing
;
1690 dropdown_rc
.top
= cancel_rc
.top
;
1691 dropdown_rc
.bottom
= cancel_rc
.bottom
;
1694 /* Open/Save button */
1695 hwnd
= GetDlgItem(This
->dlg_hwnd
, IDOK
);
1698 int open_width
, open_height
;
1699 GetWindowRect(hwnd
, &open_rc
);
1700 open_width
= open_rc
.right
- open_rc
.left
;
1701 open_height
= open_rc
.bottom
- open_rc
.top
;
1703 open_rc
.left
= dropdown_rc
.left
- open_width
;
1704 open_rc
.top
= dropdown_rc
.top
;
1705 open_rc
.right
= open_rc
.left
+ open_width
;
1706 open_rc
.bottom
= open_rc
.top
+ open_height
;
1709 /* The filetype combobox. */
1710 hwnd
= GetDlgItem(This
->dlg_hwnd
, IDC_FILETYPE
);
1713 int filetype_width
, filetype_height
;
1714 GetWindowRect(hwnd
, &filetype_rc
);
1716 filetype_width
= filetype_rc
.right
- filetype_rc
.left
;
1717 filetype_height
= filetype_rc
.bottom
- filetype_rc
.top
;
1719 filetype_rc
.right
= cancel_rc
.right
;
1721 filetype_rc
.left
= filetype_rc
.right
- filetype_width
;
1722 filetype_rc
.top
= cancel_rc
.top
- filetype_height
- vspacing
;
1723 filetype_rc
.bottom
= filetype_rc
.top
+ filetype_height
;
1725 if(!This
->filterspec_count
)
1726 filetype_rc
.left
= filetype_rc
.right
;
1729 /* Filename label. */
1730 hwnd
= GetDlgItem(This
->dlg_hwnd
, IDC_FILENAMESTATIC
);
1733 int filetypelabel_width
, filetypelabel_height
;
1734 GetWindowRect(hwnd
, &filenamelabel_rc
);
1736 filetypelabel_width
= filenamelabel_rc
.right
- filenamelabel_rc
.left
;
1737 filetypelabel_height
= filenamelabel_rc
.bottom
- filenamelabel_rc
.top
;
1739 filenamelabel_rc
.left
= 160; /* FIXME */
1740 filenamelabel_rc
.top
= filetype_rc
.top
;
1741 filenamelabel_rc
.right
= filenamelabel_rc
.left
+ filetypelabel_width
;
1742 filenamelabel_rc
.bottom
= filenamelabel_rc
.top
+ filetypelabel_height
;
1745 /* Filename edit box. */
1746 hwnd
= GetDlgItem(This
->dlg_hwnd
, IDC_FILENAME
);
1749 int filename_width
, filename_height
;
1750 GetWindowRect(hwnd
, &filename_rc
);
1752 filename_width
= filetype_rc
.left
- filenamelabel_rc
.right
- hspacing
*2;
1753 filename_height
= filename_rc
.bottom
- filename_rc
.top
;
1755 filename_rc
.left
= filenamelabel_rc
.right
+ hspacing
;
1756 filename_rc
.top
= filetype_rc
.top
;
1757 filename_rc
.right
= filename_rc
.left
+ filename_width
;
1758 filename_rc
.bottom
= filename_rc
.top
+ filename_height
;
1761 hwnd
= GetDlgItem(This
->dlg_hwnd
, IDC_NAV_TOOLBAR
);
1764 GetWindowRect(hwnd
, &toolbar_rc
);
1765 MapWindowPoints(NULL
, This
->dlg_hwnd
, (POINT
*)&toolbar_rc
, 2);
1768 /* The custom controls */
1769 customctrls_rc
.left
= dialog_rc
.left
+ hspacing
;
1770 customctrls_rc
.right
= dialog_rc
.right
- hspacing
;
1771 customctrls_rc
.bottom
= filename_rc
.top
- vspacing
;
1772 customctrls_rc
.top
= customctrls_rc
.bottom
-
1773 ctrl_container_resize(This
, customctrls_rc
.right
- customctrls_rc
.left
);
1775 /* The ExplorerBrowser control. */
1776 ebrowser_rc
.left
= dialog_rc
.left
+ hspacing
;
1777 ebrowser_rc
.top
= toolbar_rc
.bottom
+ vspacing
;
1778 ebrowser_rc
.right
= dialog_rc
.right
- hspacing
;
1779 ebrowser_rc
.bottom
= customctrls_rc
.top
- vspacing
;
1782 * Move everything to the right place.
1785 /* FIXME: The Save Dialog uses a slightly different layout. */
1786 hdwp
= BeginDeferWindowPos(7);
1788 if(hdwp
&& This
->peb
)
1789 IExplorerBrowser_SetRect(This
->peb
, &hdwp
, ebrowser_rc
);
1791 if(hdwp
&& This
->cctrls_hwnd
)
1792 DeferWindowPos(hdwp
, This
->cctrls_hwnd
, NULL
,
1793 customctrls_rc
.left
, customctrls_rc
.top
,
1794 customctrls_rc
.right
- customctrls_rc
.left
, customctrls_rc
.bottom
- customctrls_rc
.top
,
1795 SWP_NOZORDER
| SWP_NOACTIVATE
);
1797 /* The default controls */
1798 if(hdwp
&& (hwnd
= GetDlgItem(This
->dlg_hwnd
, IDC_FILETYPE
)) )
1799 DeferWindowPos(hdwp
, hwnd
, NULL
, filetype_rc
.left
, filetype_rc
.top
, 0, 0,
1800 SWP_NOZORDER
| SWP_NOSIZE
| SWP_NOACTIVATE
);
1802 if(hdwp
&& (hwnd
= GetDlgItem(This
->dlg_hwnd
, IDC_FILENAME
)) )
1803 DeferWindowPos(hdwp
, hwnd
, NULL
, filename_rc
.left
, filename_rc
.top
,
1804 filename_rc
.right
- filename_rc
.left
, filename_rc
.bottom
- filename_rc
.top
,
1805 SWP_NOZORDER
| SWP_NOACTIVATE
);
1807 if(hdwp
&& (hwnd
= GetDlgItem(This
->dlg_hwnd
, IDC_FILENAMESTATIC
)) )
1808 DeferWindowPos(hdwp
, hwnd
, NULL
, filenamelabel_rc
.left
, filenamelabel_rc
.top
, 0, 0,
1809 SWP_NOZORDER
| SWP_NOSIZE
| SWP_NOACTIVATE
);
1811 if(hdwp
&& (hwnd
= GetDlgItem(This
->dlg_hwnd
, IDOK
)) )
1812 DeferWindowPos(hdwp
, hwnd
, NULL
, open_rc
.left
, open_rc
.top
, 0, 0,
1813 SWP_NOZORDER
| SWP_NOSIZE
| SWP_NOACTIVATE
);
1815 if(hdwp
&& This
->hmenu_opendropdown
&& (hwnd
= GetDlgItem(This
->dlg_hwnd
, psh1
)))
1816 DeferWindowPos(hdwp
, hwnd
, NULL
, dropdown_rc
.left
, dropdown_rc
.top
, 0, 0,
1817 SWP_NOZORDER
| SWP_NOSIZE
| SWP_NOACTIVATE
);
1819 if(hdwp
&& (hwnd
= GetDlgItem(This
->dlg_hwnd
, IDCANCEL
)) )
1820 DeferWindowPos(hdwp
, hwnd
, NULL
, cancel_rc
.left
, cancel_rc
.top
, 0, 0,
1821 SWP_NOZORDER
| SWP_NOSIZE
| SWP_NOACTIVATE
);
1824 EndDeferWindowPos(hdwp
);
1826 ERR("Failed to position dialog controls.\n");
1831 static HRESULT
init_explorerbrowser(FileDialogImpl
*This
)
1833 IShellItem
*psi_folder
;
1834 IObjectWithSite
*client
;
1839 /* Create ExplorerBrowser instance */
1840 OleInitialize(NULL
);
1842 hr
= CoCreateInstance(&CLSID_ExplorerBrowser
, NULL
, CLSCTX_INPROC_SERVER
,
1843 &IID_IExplorerBrowser
, (void**)&This
->peb
);
1846 ERR("Failed to instantiate ExplorerBrowser control.\n");
1850 IExplorerBrowser_SetOptions(This
->peb
, EBO_SHOWFRAMES
| EBO_NOBORDER
);
1852 hr
= IExplorerBrowser_Initialize(This
->peb
, This
->dlg_hwnd
, &rc
, NULL
);
1855 ERR("Failed to initialize the ExplorerBrowser control.\n");
1856 IExplorerBrowser_Release(This
->peb
);
1860 hr
= IExplorerBrowser_Advise(This
->peb
, &This
->IExplorerBrowserEvents_iface
, &This
->ebevents_cookie
);
1862 ERR("Advise (ExplorerBrowser) failed.\n");
1864 /* Get previous options? */
1865 fos
.ViewMode
= fos
.fFlags
= 0;
1866 if(!(This
->options
& FOS_ALLOWMULTISELECT
))
1867 fos
.fFlags
|= FWF_SINGLESEL
;
1869 IExplorerBrowser_SetFolderSettings(This
->peb
, &fos
);
1871 hr
= IExplorerBrowser_QueryInterface(This
->peb
, &IID_IObjectWithSite
, (void**)&client
);
1874 hr
= IObjectWithSite_SetSite(client
, (IUnknown
*)&This
->IFileDialog2_iface
);
1875 IObjectWithSite_Release(client
);
1877 ERR("SetSite failed, 0x%08x\n", hr
);
1880 /* Browse somewhere */
1881 psi_folder
= This
->psi_setfolder
? This
->psi_setfolder
: This
->psi_defaultfolder
;
1882 IExplorerBrowser_BrowseToObject(This
->peb
, (IUnknown
*)psi_folder
, SBSP_DEFBROWSER
);
1887 static void init_toolbar(FileDialogImpl
*This
, HWND hwnd
)
1893 htoolbar
= CreateWindowExW(0, TOOLBARCLASSNAMEW
, NULL
, TBSTYLE_FLAT
| WS_CHILD
| WS_VISIBLE
,
1895 hwnd
, (HMENU
)IDC_NAV_TOOLBAR
, NULL
, NULL
);
1897 tbab
.hInst
= HINST_COMMCTRL
;
1898 tbab
.nID
= IDB_HIST_LARGE_COLOR
;
1899 SendMessageW(htoolbar
, TB_ADDBITMAP
, 0, (LPARAM
)&tbab
);
1901 button
[0].iBitmap
= HIST_BACK
;
1902 button
[0].idCommand
= IDC_NAVBACK
;
1903 button
[0].fsState
= TBSTATE_ENABLED
;
1904 button
[0].fsStyle
= BTNS_BUTTON
;
1905 button
[0].dwData
= 0;
1906 button
[0].iString
= 0;
1908 button
[1].iBitmap
= HIST_FORWARD
;
1909 button
[1].idCommand
= IDC_NAVFORWARD
;
1910 button
[1].fsState
= TBSTATE_ENABLED
;
1911 button
[1].fsStyle
= BTNS_BUTTON
;
1912 button
[1].dwData
= 0;
1913 button
[1].iString
= 0;
1915 SendMessageW(htoolbar
, TB_ADDBUTTONSW
, 2, (LPARAM
)button
);
1916 SendMessageW(htoolbar
, TB_SETBUTTONSIZE
, 0, MAKELPARAM(24,24));
1917 SendMessageW(htoolbar
, TB_AUTOSIZE
, 0, 0);
1920 static void update_control_text(FileDialogImpl
*This
)
1923 LPCWSTR custom_okbutton
;
1926 if(This
->custom_title
)
1927 SetWindowTextW(This
->dlg_hwnd
, This
->custom_title
);
1929 if(This
->hmenu_opendropdown
&& (item
= get_first_item(&This
->cctrl_opendropdown
)))
1930 custom_okbutton
= item
->label
;
1932 custom_okbutton
= This
->custom_okbutton
;
1934 if(custom_okbutton
&&
1935 (hitem
= GetDlgItem(This
->dlg_hwnd
, IDOK
)))
1937 SetWindowTextW(hitem
, custom_okbutton
);
1938 ctrl_resize(hitem
, 50, 250, FALSE
);
1941 if(This
->custom_cancelbutton
&&
1942 (hitem
= GetDlgItem(This
->dlg_hwnd
, IDCANCEL
)))
1944 SetWindowTextW(hitem
, This
->custom_cancelbutton
);
1945 ctrl_resize(hitem
, 50, 250, FALSE
);
1948 if(This
->custom_filenamelabel
&&
1949 (hitem
= GetDlgItem(This
->dlg_hwnd
, IDC_FILENAMESTATIC
)))
1951 SetWindowTextW(hitem
, This
->custom_filenamelabel
);
1952 ctrl_resize(hitem
, 50, 250, FALSE
);
1956 static LRESULT CALLBACK
dropdown_subclass_proc(HWND hwnd
, UINT umessage
, WPARAM wparam
, LPARAM lparam
)
1958 static const WCHAR prop_this
[] = {'i','t','e','m','d','l','g','_','T','h','i','s',0};
1959 static const WCHAR prop_oldwndproc
[] = {'i','t','e','m','d','l','g','_','o','l','d','w','n','d','p','r','o','c',0};
1961 if (umessage
== WM_LBUTTONDOWN
)
1963 FileDialogImpl
*This
= (FileDialogImpl
*)GetPropW(hwnd
, prop_this
);
1965 SendMessageW(hwnd
, BM_SETCHECK
, BST_CHECKED
, 0);
1966 show_opendropdown(This
);
1967 SendMessageW(hwnd
, BM_SETCHECK
, BST_UNCHECKED
, 0);
1972 return CallWindowProcW((WNDPROC
)GetPropW(hwnd
, prop_oldwndproc
), hwnd
, umessage
, wparam
, lparam
);
1975 static LRESULT
on_wm_initdialog(HWND hwnd
, LPARAM lParam
)
1977 FileDialogImpl
*This
= (FileDialogImpl
*)lParam
;
1980 TRACE("(%p, %p)\n", This
, hwnd
);
1982 SetWindowLongPtrW(hwnd
, GWLP_USERDATA
, (LPARAM
)This
);
1983 This
->dlg_hwnd
= hwnd
;
1985 hitem
= GetDlgItem(This
->dlg_hwnd
, pshHelp
);
1986 if(hitem
) ShowWindow(hitem
, SW_HIDE
);
1988 hitem
= GetDlgItem(This
->dlg_hwnd
, IDC_FILETYPESTATIC
);
1989 if(hitem
) ShowWindow(hitem
, SW_HIDE
);
1991 /* Fill filetypes combobox, or hide it. */
1992 hitem
= GetDlgItem(This
->dlg_hwnd
, IDC_FILETYPE
);
1993 if(This
->filterspec_count
)
1998 UINT i
, maxwidth
= 0;
2001 font
= (HFONT
)SendMessageW(hitem
, WM_GETFONT
, 0, 0);
2002 SelectObject(hdc
, font
);
2004 for(i
= 0; i
< This
->filterspec_count
; i
++)
2006 SendMessageW(hitem
, CB_ADDSTRING
, 0, (LPARAM
)This
->filterspecs
[i
].pszName
);
2008 if(GetTextExtentPoint32W(hdc
, This
->filterspecs
[i
].pszName
, lstrlenW(This
->filterspecs
[i
].pszName
), &size
))
2009 maxwidth
= max(maxwidth
, size
.cx
);
2011 ReleaseDC(hitem
, hdc
);
2015 maxwidth
+= GetSystemMetrics(SM_CXVSCROLL
) + 4;
2016 SendMessageW(hitem
, CB_SETDROPPEDWIDTH
, (WPARAM
)maxwidth
, 0);
2019 ERR("Failed to calculate width of filetype dropdown\n");
2021 SendMessageW(hitem
, CB_SETCURSEL
, This
->filetypeindex
, 0);
2024 ShowWindow(hitem
, SW_HIDE
);
2026 if(This
->set_filename
&&
2027 (hitem
= GetDlgItem(This
->dlg_hwnd
, IDC_FILENAME
)) )
2028 SendMessageW(hitem
, WM_SETTEXT
, 0, (LPARAM
)This
->set_filename
);
2030 if(This
->hmenu_opendropdown
)
2033 LOGFONTW lfw
, lfw_marlett
;
2035 static const WCHAR marlett
[] = {'M','a','r','l','e','t','t',0};
2036 static const WCHAR prop_this
[] = {'i','t','e','m','d','l','g','_','T','h','i','s',0};
2037 static const WCHAR prop_oldwndproc
[] = {'i','t','e','m','d','l','g','_','o','l','d','w','n','d','p','r','o','c',0};
2039 dropdown_hwnd
= GetDlgItem(This
->dlg_hwnd
, psh1
);
2041 /* Change dropdown button font to Marlett */
2042 dialog_font
= (HFONT
)SendMessageW(dropdown_hwnd
, WM_GETFONT
, 0, 0);
2044 GetObjectW(dialog_font
, sizeof(lfw
), &lfw
);
2046 memset(&lfw_marlett
, 0, sizeof(lfw_marlett
));
2047 lstrcpyW(lfw_marlett
.lfFaceName
, marlett
);
2048 lfw_marlett
.lfHeight
= lfw
.lfHeight
;
2049 lfw_marlett
.lfCharSet
= SYMBOL_CHARSET
;
2051 This
->hfont_opendropdown
= CreateFontIndirectW(&lfw_marlett
);
2053 SendMessageW(dropdown_hwnd
, WM_SETFONT
, (LPARAM
)This
->hfont_opendropdown
, 0);
2055 /* Subclass button so we can handle LBUTTONDOWN */
2056 SetPropW(dropdown_hwnd
, prop_this
, (HANDLE
)This
);
2057 SetPropW(dropdown_hwnd
, prop_oldwndproc
,
2058 (HANDLE
)SetWindowLongPtrW(dropdown_hwnd
, GWLP_WNDPROC
, (LONG_PTR
)dropdown_subclass_proc
));
2061 ctrl_container_reparent(This
, This
->dlg_hwnd
);
2062 init_explorerbrowser(This
);
2063 init_toolbar(This
, hwnd
);
2064 update_control_text(This
);
2065 update_layout(This
);
2067 if(This
->filterspec_count
)
2068 events_OnTypeChange(This
);
2070 if ((hitem
= GetDlgItem(This
->dlg_hwnd
, IDC_FILENAME
)))
2076 static LRESULT
on_wm_size(FileDialogImpl
*This
)
2078 update_layout(This
);
2082 static LRESULT
on_wm_getminmaxinfo(FileDialogImpl
*This
, LPARAM lparam
)
2084 MINMAXINFO
*mmi
= (MINMAXINFO
*)lparam
;
2085 TRACE("%p (%p)\n", This
, mmi
);
2088 mmi
->ptMinTrackSize
.x
= 640;
2089 mmi
->ptMinTrackSize
.y
= 480;
2094 static LRESULT
on_wm_destroy(FileDialogImpl
*This
)
2096 TRACE("%p\n", This
);
2100 IExplorerBrowser_Destroy(This
->peb
);
2101 IExplorerBrowser_Release(This
->peb
);
2105 ctrl_container_reparent(This
, NULL
);
2106 This
->dlg_hwnd
= NULL
;
2108 DeleteObject(This
->hfont_opendropdown
);
2109 This
->hfont_opendropdown
= NULL
;
2114 static LRESULT
on_idok(FileDialogImpl
*This
)
2116 TRACE("%p\n", This
);
2118 if(SUCCEEDED(on_default_action(This
)))
2119 EndDialog(This
->dlg_hwnd
, S_OK
);
2124 static LRESULT
on_idcancel(FileDialogImpl
*This
)
2126 TRACE("%p\n", This
);
2128 EndDialog(This
->dlg_hwnd
, HRESULT_FROM_WIN32(ERROR_CANCELLED
));
2133 static LRESULT
on_command_opendropdown(FileDialogImpl
*This
, WPARAM wparam
, LPARAM lparam
)
2135 if(HIWORD(wparam
) == BN_CLICKED
)
2137 HWND hwnd
= (HWND
)lparam
;
2138 SendMessageW(hwnd
, BM_SETCHECK
, BST_CHECKED
, 0);
2139 show_opendropdown(This
);
2140 SendMessageW(hwnd
, BM_SETCHECK
, BST_UNCHECKED
, 0);
2146 static LRESULT
on_browse_back(FileDialogImpl
*This
)
2148 TRACE("%p\n", This
);
2149 IExplorerBrowser_BrowseToIDList(This
->peb
, NULL
, SBSP_NAVIGATEBACK
);
2153 static LRESULT
on_browse_forward(FileDialogImpl
*This
)
2155 TRACE("%p\n", This
);
2156 IExplorerBrowser_BrowseToIDList(This
->peb
, NULL
, SBSP_NAVIGATEFORWARD
);
2160 static LRESULT
on_command_filetype(FileDialogImpl
*This
, WPARAM wparam
, LPARAM lparam
)
2162 if(HIWORD(wparam
) == CBN_SELCHANGE
)
2167 UINT prev_index
= This
->filetypeindex
;
2169 This
->filetypeindex
= SendMessageW((HWND
)lparam
, CB_GETCURSEL
, 0, 0);
2170 TRACE("File type selection changed to %d.\n", This
->filetypeindex
);
2172 if(prev_index
== This
->filetypeindex
)
2175 hr
= IExplorerBrowser_GetCurrentView(This
->peb
, &IID_IShellView
, (void**)&psv
);
2178 IShellView_Refresh(psv
);
2179 IShellView_Release(psv
);
2182 if(This
->dlg_type
== ITEMDLG_TYPE_SAVE
&& get_file_name(This
, &filename
))
2184 WCHAR buf
[MAX_PATH
], extbuf
[MAX_PATH
], *ext
;
2186 ext
= get_first_ext_from_spec(extbuf
, This
->filterspecs
[This
->filetypeindex
].pszSpec
);
2189 lstrcpyW(buf
, filename
);
2191 if(PathMatchSpecW(buf
, This
->filterspecs
[prev_index
].pszSpec
))
2192 PathRemoveExtensionW(buf
);
2195 set_file_name(This
, buf
);
2197 CoTaskMemFree(filename
);
2200 /* The documentation claims that OnTypeChange is called only
2201 * when the dialog is opened, but this is obviously not the
2203 events_OnTypeChange(This
);
2209 static LRESULT
on_wm_command(FileDialogImpl
*This
, WPARAM wparam
, LPARAM lparam
)
2211 switch(LOWORD(wparam
))
2213 case IDOK
: return on_idok(This
);
2214 case IDCANCEL
: return on_idcancel(This
);
2215 case psh1
: return on_command_opendropdown(This
, wparam
, lparam
);
2216 case IDC_NAVBACK
: return on_browse_back(This
);
2217 case IDC_NAVFORWARD
: return on_browse_forward(This
);
2218 case IDC_FILETYPE
: return on_command_filetype(This
, wparam
, lparam
);
2219 default: TRACE("Unknown command.\n");
2224 static LRESULT CALLBACK
itemdlg_dlgproc(HWND hwnd
, UINT umessage
, WPARAM wparam
, LPARAM lparam
)
2226 FileDialogImpl
*This
= (FileDialogImpl
*)GetWindowLongPtrW(hwnd
, GWLP_USERDATA
);
2230 case WM_INITDIALOG
: return on_wm_initdialog(hwnd
, lparam
);
2231 case WM_COMMAND
: return on_wm_command(This
, wparam
, lparam
);
2232 case WM_SIZE
: return on_wm_size(This
);
2233 case WM_GETMINMAXINFO
: return on_wm_getminmaxinfo(This
, lparam
);
2234 case WM_DESTROY
: return on_wm_destroy(This
);
2240 static HRESULT
create_dialog(FileDialogImpl
*This
, HWND parent
)
2245 res
= DialogBoxParamW(COMDLG32_hInstance
,
2246 MAKEINTRESOURCEW(NEWFILEOPENV3ORD
),
2247 parent
, itemdlg_dlgproc
, (LPARAM
)This
);
2248 This
->dlg_hwnd
= NULL
;
2251 ERR("Failed to show dialog (LastError: %d)\n", GetLastError());
2255 TRACE("Returning 0x%08x\n", (HRESULT
)res
);
2256 return (HRESULT
)res
;
2259 /**************************************************************************
2260 * IFileDialog implementation
2262 static inline FileDialogImpl
*impl_from_IFileDialog2(IFileDialog2
*iface
)
2264 return CONTAINING_RECORD(iface
, FileDialogImpl
, IFileDialog2_iface
);
2267 static HRESULT WINAPI
IFileDialog2_fnQueryInterface(IFileDialog2
*iface
,
2271 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2272 TRACE("%p (%s, %p)\n", This
, debugstr_guid(riid
), ppvObject
);
2275 if(IsEqualGUID(riid
, &IID_IUnknown
) ||
2276 IsEqualGUID(riid
, &IID_IFileDialog
) ||
2277 IsEqualGUID(riid
, &IID_IFileDialog2
))
2281 else if(IsEqualGUID(riid
, &IID_IFileOpenDialog
) && This
->dlg_type
== ITEMDLG_TYPE_OPEN
)
2283 *ppvObject
= &This
->u
.IFileOpenDialog_iface
;
2285 else if(IsEqualGUID(riid
, &IID_IFileSaveDialog
) && This
->dlg_type
== ITEMDLG_TYPE_SAVE
)
2287 *ppvObject
= &This
->u
.IFileSaveDialog_iface
;
2289 else if(IsEqualGUID(riid
, &IID_IExplorerBrowserEvents
))
2291 *ppvObject
= &This
->IExplorerBrowserEvents_iface
;
2293 else if(IsEqualGUID(riid
, &IID_IServiceProvider
))
2295 *ppvObject
= &This
->IServiceProvider_iface
;
2297 else if(IsEqualGUID(&IID_ICommDlgBrowser3
, riid
) ||
2298 IsEqualGUID(&IID_ICommDlgBrowser2
, riid
) ||
2299 IsEqualGUID(&IID_ICommDlgBrowser
, riid
))
2301 *ppvObject
= &This
->ICommDlgBrowser3_iface
;
2303 else if(IsEqualGUID(&IID_IOleWindow
, riid
))
2305 *ppvObject
= &This
->IOleWindow_iface
;
2307 else if(IsEqualGUID(riid
, &IID_IFileDialogCustomize
) ||
2308 IsEqualGUID(riid
, &IID_IFileDialogCustomizeAlt
))
2310 *ppvObject
= &This
->IFileDialogCustomize_iface
;
2313 FIXME("Unknown interface requested: %s.\n", debugstr_guid(riid
));
2317 IUnknown_AddRef((IUnknown
*)*ppvObject
);
2321 return E_NOINTERFACE
;
2324 static ULONG WINAPI
IFileDialog2_fnAddRef(IFileDialog2
*iface
)
2326 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2327 LONG ref
= InterlockedIncrement(&This
->ref
);
2328 TRACE("%p - ref %d\n", This
, ref
);
2333 static ULONG WINAPI
IFileDialog2_fnRelease(IFileDialog2
*iface
)
2335 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2336 LONG ref
= InterlockedDecrement(&This
->ref
);
2337 TRACE("%p - ref %d\n", This
, ref
);
2342 for(i
= 0; i
< This
->filterspec_count
; i
++)
2344 LocalFree((void*)This
->filterspecs
[i
].pszName
);
2345 LocalFree((void*)This
->filterspecs
[i
].pszSpec
);
2347 HeapFree(GetProcessHeap(), 0, This
->filterspecs
);
2349 DestroyWindow(This
->cctrls_hwnd
);
2351 if(This
->psi_defaultfolder
) IShellItem_Release(This
->psi_defaultfolder
);
2352 if(This
->psi_setfolder
) IShellItem_Release(This
->psi_setfolder
);
2353 if(This
->psi_folder
) IShellItem_Release(This
->psi_folder
);
2354 if(This
->psia_selection
) IShellItemArray_Release(This
->psia_selection
);
2355 if(This
->psia_results
) IShellItemArray_Release(This
->psia_results
);
2357 LocalFree(This
->set_filename
);
2358 LocalFree(This
->default_ext
);
2359 LocalFree(This
->custom_title
);
2360 LocalFree(This
->custom_okbutton
);
2361 LocalFree(This
->custom_cancelbutton
);
2362 LocalFree(This
->custom_filenamelabel
);
2364 DestroyMenu(This
->hmenu_opendropdown
);
2365 DeleteObject(This
->hfont_opendropdown
);
2367 HeapFree(GetProcessHeap(), 0, This
);
2373 static HRESULT WINAPI
IFileDialog2_fnShow(IFileDialog2
*iface
, HWND hwndOwner
)
2375 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2376 TRACE("%p (%p)\n", iface
, hwndOwner
);
2378 This
->opendropdown_has_selection
= FALSE
;
2380 return create_dialog(This
, hwndOwner
);
2383 static HRESULT WINAPI
IFileDialog2_fnSetFileTypes(IFileDialog2
*iface
, UINT cFileTypes
,
2384 const COMDLG_FILTERSPEC
*rgFilterSpec
)
2386 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2388 TRACE("%p (%d, %p)\n", This
, cFileTypes
, rgFilterSpec
);
2390 if(This
->filterspecs
)
2391 return E_UNEXPECTED
;
2394 return E_INVALIDARG
;
2399 This
->filterspecs
= HeapAlloc(GetProcessHeap(), 0, sizeof(COMDLG_FILTERSPEC
)*cFileTypes
);
2400 for(i
= 0; i
< cFileTypes
; i
++)
2402 This
->filterspecs
[i
].pszName
= StrDupW(rgFilterSpec
[i
].pszName
);
2403 This
->filterspecs
[i
].pszSpec
= StrDupW(rgFilterSpec
[i
].pszSpec
);
2405 This
->filterspec_count
= cFileTypes
;
2410 static HRESULT WINAPI
IFileDialog2_fnSetFileTypeIndex(IFileDialog2
*iface
, UINT iFileType
)
2412 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2413 TRACE("%p (%d)\n", This
, iFileType
);
2415 if(!This
->filterspecs
)
2418 iFileType
= max(iFileType
, 1);
2419 iFileType
= min(iFileType
, This
->filterspec_count
);
2420 This
->filetypeindex
= iFileType
-1;
2425 static HRESULT WINAPI
IFileDialog2_fnGetFileTypeIndex(IFileDialog2
*iface
, UINT
*piFileType
)
2427 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2428 TRACE("%p (%p)\n", This
, piFileType
);
2431 return E_INVALIDARG
;
2433 if(This
->filterspec_count
== 0)
2436 *piFileType
= This
->filetypeindex
+ 1;
2441 static HRESULT WINAPI
IFileDialog2_fnAdvise(IFileDialog2
*iface
, IFileDialogEvents
*pfde
, DWORD
*pdwCookie
)
2443 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2444 events_client
*client
;
2445 TRACE("%p (%p, %p)\n", This
, pfde
, pdwCookie
);
2447 if(!pfde
|| !pdwCookie
)
2448 return E_INVALIDARG
;
2450 client
= HeapAlloc(GetProcessHeap(), 0, sizeof(events_client
));
2451 client
->pfde
= pfde
;
2452 client
->cookie
= ++This
->events_next_cookie
;
2454 IFileDialogEvents_AddRef(pfde
);
2455 *pdwCookie
= client
->cookie
;
2457 list_add_tail(&This
->events_clients
, &client
->entry
);
2462 static HRESULT WINAPI
IFileDialog2_fnUnadvise(IFileDialog2
*iface
, DWORD dwCookie
)
2464 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2465 events_client
*client
, *found
= NULL
;
2466 TRACE("%p (%d)\n", This
, dwCookie
);
2468 LIST_FOR_EACH_ENTRY(client
, &This
->events_clients
, events_client
, entry
)
2470 if(client
->cookie
== dwCookie
)
2479 list_remove(&found
->entry
);
2480 IFileDialogEvents_Release(found
->pfde
);
2481 HeapFree(GetProcessHeap(), 0, found
);
2485 return E_INVALIDARG
;
2488 static HRESULT WINAPI
IFileDialog2_fnSetOptions(IFileDialog2
*iface
, FILEOPENDIALOGOPTIONS fos
)
2490 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2491 TRACE("%p (0x%x)\n", This
, fos
);
2493 if( !(This
->options
& FOS_PICKFOLDERS
) && (fos
& FOS_PICKFOLDERS
) )
2496 LoadStringW(COMDLG32_hInstance
, IDS_SELECT_FOLDER
, buf
, sizeof(buf
)/sizeof(WCHAR
));
2497 IFileDialog2_SetTitle(iface
, buf
);
2500 This
->options
= fos
;
2505 static HRESULT WINAPI
IFileDialog2_fnGetOptions(IFileDialog2
*iface
, FILEOPENDIALOGOPTIONS
*pfos
)
2507 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2508 TRACE("%p (%p)\n", This
, pfos
);
2511 return E_INVALIDARG
;
2513 *pfos
= This
->options
;
2518 static HRESULT WINAPI
IFileDialog2_fnSetDefaultFolder(IFileDialog2
*iface
, IShellItem
*psi
)
2520 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2521 TRACE("%p (%p)\n", This
, psi
);
2522 if(This
->psi_defaultfolder
)
2523 IShellItem_Release(This
->psi_defaultfolder
);
2525 This
->psi_defaultfolder
= psi
;
2527 if(This
->psi_defaultfolder
)
2528 IShellItem_AddRef(This
->psi_defaultfolder
);
2533 static HRESULT WINAPI
IFileDialog2_fnSetFolder(IFileDialog2
*iface
, IShellItem
*psi
)
2535 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2536 TRACE("%p (%p)\n", This
, psi
);
2537 if(This
->psi_setfolder
)
2538 IShellItem_Release(This
->psi_setfolder
);
2540 This
->psi_setfolder
= psi
;
2542 if(This
->psi_setfolder
)
2543 IShellItem_AddRef(This
->psi_setfolder
);
2548 static HRESULT WINAPI
IFileDialog2_fnGetFolder(IFileDialog2
*iface
, IShellItem
**ppsi
)
2550 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2551 TRACE("%p (%p)\n", This
, ppsi
);
2553 return E_INVALIDARG
;
2556 If the dialog is shown, return the current(ly selected) folder. */
2559 if(This
->psi_folder
)
2560 *ppsi
= This
->psi_folder
;
2561 else if(This
->psi_setfolder
)
2562 *ppsi
= This
->psi_setfolder
;
2563 else if(This
->psi_defaultfolder
)
2564 *ppsi
= This
->psi_defaultfolder
;
2568 IShellItem_AddRef(*ppsi
);
2575 static HRESULT WINAPI
IFileDialog2_fnGetCurrentSelection(IFileDialog2
*iface
, IShellItem
**ppsi
)
2577 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2579 TRACE("%p (%p)\n", This
, ppsi
);
2582 return E_INVALIDARG
;
2584 if(This
->psia_selection
)
2586 /* FIXME: Check filename edit box */
2587 hr
= IShellItemArray_GetItemAt(This
->psia_selection
, 0, ppsi
);
2594 static HRESULT WINAPI
IFileDialog2_fnSetFileName(IFileDialog2
*iface
, LPCWSTR pszName
)
2596 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2597 TRACE("%p (%s)\n", iface
, debugstr_w(pszName
));
2599 set_file_name(This
, pszName
);
2604 static HRESULT WINAPI
IFileDialog2_fnGetFileName(IFileDialog2
*iface
, LPWSTR
*pszName
)
2606 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2607 TRACE("%p (%p)\n", iface
, pszName
);
2610 return E_INVALIDARG
;
2613 if(get_file_name(This
, pszName
))
2619 static HRESULT WINAPI
IFileDialog2_fnSetTitle(IFileDialog2
*iface
, LPCWSTR pszTitle
)
2621 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2622 TRACE("%p (%s)\n", This
, debugstr_w(pszTitle
));
2624 LocalFree(This
->custom_title
);
2625 This
->custom_title
= StrDupW(pszTitle
);
2626 update_control_text(This
);
2631 static HRESULT WINAPI
IFileDialog2_fnSetOkButtonLabel(IFileDialog2
*iface
, LPCWSTR pszText
)
2633 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2634 TRACE("%p (%s)\n", This
, debugstr_w(pszText
));
2636 LocalFree(This
->custom_okbutton
);
2637 This
->custom_okbutton
= StrDupW(pszText
);
2638 update_control_text(This
);
2639 update_layout(This
);
2644 static HRESULT WINAPI
IFileDialog2_fnSetFileNameLabel(IFileDialog2
*iface
, LPCWSTR pszLabel
)
2646 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2647 TRACE("%p (%s)\n", This
, debugstr_w(pszLabel
));
2649 LocalFree(This
->custom_filenamelabel
);
2650 This
->custom_filenamelabel
= StrDupW(pszLabel
);
2651 update_control_text(This
);
2652 update_layout(This
);
2657 static HRESULT WINAPI
IFileDialog2_fnGetResult(IFileDialog2
*iface
, IShellItem
**ppsi
)
2659 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2661 TRACE("%p (%p)\n", This
, ppsi
);
2664 return E_INVALIDARG
;
2666 if(This
->psia_results
)
2669 hr
= IShellItemArray_GetCount(This
->psia_results
, &item_count
);
2675 /* Adds a reference. */
2676 hr
= IShellItemArray_GetItemAt(This
->psia_results
, 0, ppsi
);
2682 return E_UNEXPECTED
;
2685 static HRESULT WINAPI
IFileDialog2_fnAddPlace(IFileDialog2
*iface
, IShellItem
*psi
, FDAP fdap
)
2687 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2688 FIXME("stub - %p (%p, %d)\n", This
, psi
, fdap
);
2692 static HRESULT WINAPI
IFileDialog2_fnSetDefaultExtension(IFileDialog2
*iface
, LPCWSTR pszDefaultExtension
)
2694 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2695 TRACE("%p (%s)\n", This
, debugstr_w(pszDefaultExtension
));
2697 LocalFree(This
->default_ext
);
2698 This
->default_ext
= StrDupW(pszDefaultExtension
);
2703 static HRESULT WINAPI
IFileDialog2_fnClose(IFileDialog2
*iface
, HRESULT hr
)
2705 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2706 TRACE("%p (0x%08x)\n", This
, hr
);
2709 EndDialog(This
->dlg_hwnd
, hr
);
2714 static HRESULT WINAPI
IFileDialog2_fnSetClientGuid(IFileDialog2
*iface
, REFGUID guid
)
2716 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2717 TRACE("%p (%s)\n", This
, debugstr_guid(guid
));
2718 This
->client_guid
= *guid
;
2722 static HRESULT WINAPI
IFileDialog2_fnClearClientData(IFileDialog2
*iface
)
2724 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2725 FIXME("stub - %p\n", This
);
2729 static HRESULT WINAPI
IFileDialog2_fnSetFilter(IFileDialog2
*iface
, IShellItemFilter
*pFilter
)
2731 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2732 FIXME("stub - %p (%p)\n", This
, pFilter
);
2736 static HRESULT WINAPI
IFileDialog2_fnSetCancelButtonLabel(IFileDialog2
*iface
, LPCWSTR pszLabel
)
2738 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2739 TRACE("%p (%s)\n", This
, debugstr_w(pszLabel
));
2741 LocalFree(This
->custom_cancelbutton
);
2742 This
->custom_cancelbutton
= StrDupW(pszLabel
);
2743 update_control_text(This
);
2744 update_layout(This
);
2749 static HRESULT WINAPI
IFileDialog2_fnSetNavigationRoot(IFileDialog2
*iface
, IShellItem
*psi
)
2751 FileDialogImpl
*This
= impl_from_IFileDialog2(iface
);
2752 FIXME("stub - %p (%p)\n", This
, psi
);
2756 static const IFileDialog2Vtbl vt_IFileDialog2
= {
2757 IFileDialog2_fnQueryInterface
,
2758 IFileDialog2_fnAddRef
,
2759 IFileDialog2_fnRelease
,
2760 IFileDialog2_fnShow
,
2761 IFileDialog2_fnSetFileTypes
,
2762 IFileDialog2_fnSetFileTypeIndex
,
2763 IFileDialog2_fnGetFileTypeIndex
,
2764 IFileDialog2_fnAdvise
,
2765 IFileDialog2_fnUnadvise
,
2766 IFileDialog2_fnSetOptions
,
2767 IFileDialog2_fnGetOptions
,
2768 IFileDialog2_fnSetDefaultFolder
,
2769 IFileDialog2_fnSetFolder
,
2770 IFileDialog2_fnGetFolder
,
2771 IFileDialog2_fnGetCurrentSelection
,
2772 IFileDialog2_fnSetFileName
,
2773 IFileDialog2_fnGetFileName
,
2774 IFileDialog2_fnSetTitle
,
2775 IFileDialog2_fnSetOkButtonLabel
,
2776 IFileDialog2_fnSetFileNameLabel
,
2777 IFileDialog2_fnGetResult
,
2778 IFileDialog2_fnAddPlace
,
2779 IFileDialog2_fnSetDefaultExtension
,
2780 IFileDialog2_fnClose
,
2781 IFileDialog2_fnSetClientGuid
,
2782 IFileDialog2_fnClearClientData
,
2783 IFileDialog2_fnSetFilter
,
2784 IFileDialog2_fnSetCancelButtonLabel
,
2785 IFileDialog2_fnSetNavigationRoot
2788 /**************************************************************************
2791 static inline FileDialogImpl
*impl_from_IFileOpenDialog(IFileOpenDialog
*iface
)
2793 return CONTAINING_RECORD(iface
, FileDialogImpl
, u
.IFileOpenDialog_iface
);
2796 static HRESULT WINAPI
IFileOpenDialog_fnQueryInterface(IFileOpenDialog
*iface
,
2797 REFIID riid
, void **ppvObject
)
2799 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2800 return IFileDialog2_QueryInterface(&This
->IFileDialog2_iface
, riid
, ppvObject
);
2803 static ULONG WINAPI
IFileOpenDialog_fnAddRef(IFileOpenDialog
*iface
)
2805 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2806 return IFileDialog2_AddRef(&This
->IFileDialog2_iface
);
2809 static ULONG WINAPI
IFileOpenDialog_fnRelease(IFileOpenDialog
*iface
)
2811 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2812 return IFileDialog2_Release(&This
->IFileDialog2_iface
);
2815 static HRESULT WINAPI
IFileOpenDialog_fnShow(IFileOpenDialog
*iface
, HWND hwndOwner
)
2817 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2818 return IFileDialog2_Show(&This
->IFileDialog2_iface
, hwndOwner
);
2821 static HRESULT WINAPI
IFileOpenDialog_fnSetFileTypes(IFileOpenDialog
*iface
, UINT cFileTypes
,
2822 const COMDLG_FILTERSPEC
*rgFilterSpec
)
2824 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2825 return IFileDialog2_SetFileTypes(&This
->IFileDialog2_iface
, cFileTypes
, rgFilterSpec
);
2828 static HRESULT WINAPI
IFileOpenDialog_fnSetFileTypeIndex(IFileOpenDialog
*iface
, UINT iFileType
)
2830 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2831 return IFileDialog2_SetFileTypeIndex(&This
->IFileDialog2_iface
, iFileType
);
2834 static HRESULT WINAPI
IFileOpenDialog_fnGetFileTypeIndex(IFileOpenDialog
*iface
, UINT
*piFileType
)
2836 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2837 return IFileDialog2_GetFileTypeIndex(&This
->IFileDialog2_iface
, piFileType
);
2840 static HRESULT WINAPI
IFileOpenDialog_fnAdvise(IFileOpenDialog
*iface
, IFileDialogEvents
*pfde
,
2843 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2844 return IFileDialog2_Advise(&This
->IFileDialog2_iface
, pfde
, pdwCookie
);
2847 static HRESULT WINAPI
IFileOpenDialog_fnUnadvise(IFileOpenDialog
*iface
, DWORD dwCookie
)
2849 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2850 return IFileDialog2_Unadvise(&This
->IFileDialog2_iface
, dwCookie
);
2853 static HRESULT WINAPI
IFileOpenDialog_fnSetOptions(IFileOpenDialog
*iface
, FILEOPENDIALOGOPTIONS fos
)
2855 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2856 return IFileDialog2_SetOptions(&This
->IFileDialog2_iface
, fos
);
2859 static HRESULT WINAPI
IFileOpenDialog_fnGetOptions(IFileOpenDialog
*iface
, FILEOPENDIALOGOPTIONS
*pfos
)
2861 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2862 return IFileDialog2_GetOptions(&This
->IFileDialog2_iface
, pfos
);
2865 static HRESULT WINAPI
IFileOpenDialog_fnSetDefaultFolder(IFileOpenDialog
*iface
, IShellItem
*psi
)
2867 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2868 return IFileDialog2_SetDefaultFolder(&This
->IFileDialog2_iface
, psi
);
2871 static HRESULT WINAPI
IFileOpenDialog_fnSetFolder(IFileOpenDialog
*iface
, IShellItem
*psi
)
2873 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2874 return IFileDialog2_SetFolder(&This
->IFileDialog2_iface
, psi
);
2877 static HRESULT WINAPI
IFileOpenDialog_fnGetFolder(IFileOpenDialog
*iface
, IShellItem
**ppsi
)
2879 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2880 return IFileDialog2_GetFolder(&This
->IFileDialog2_iface
, ppsi
);
2883 static HRESULT WINAPI
IFileOpenDialog_fnGetCurrentSelection(IFileOpenDialog
*iface
, IShellItem
**ppsi
)
2885 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2886 return IFileDialog2_GetCurrentSelection(&This
->IFileDialog2_iface
, ppsi
);
2889 static HRESULT WINAPI
IFileOpenDialog_fnSetFileName(IFileOpenDialog
*iface
, LPCWSTR pszName
)
2891 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2892 return IFileDialog2_SetFileName(&This
->IFileDialog2_iface
, pszName
);
2895 static HRESULT WINAPI
IFileOpenDialog_fnGetFileName(IFileOpenDialog
*iface
, LPWSTR
*pszName
)
2897 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2898 return IFileDialog2_GetFileName(&This
->IFileDialog2_iface
, pszName
);
2901 static HRESULT WINAPI
IFileOpenDialog_fnSetTitle(IFileOpenDialog
*iface
, LPCWSTR pszTitle
)
2903 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2904 return IFileDialog2_SetTitle(&This
->IFileDialog2_iface
, pszTitle
);
2907 static HRESULT WINAPI
IFileOpenDialog_fnSetOkButtonLabel(IFileOpenDialog
*iface
, LPCWSTR pszText
)
2909 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2910 return IFileDialog2_SetOkButtonLabel(&This
->IFileDialog2_iface
, pszText
);
2913 static HRESULT WINAPI
IFileOpenDialog_fnSetFileNameLabel(IFileOpenDialog
*iface
, LPCWSTR pszLabel
)
2915 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2916 return IFileDialog2_SetFileNameLabel(&This
->IFileDialog2_iface
, pszLabel
);
2919 static HRESULT WINAPI
IFileOpenDialog_fnGetResult(IFileOpenDialog
*iface
, IShellItem
**ppsi
)
2921 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2922 return IFileDialog2_GetResult(&This
->IFileDialog2_iface
, ppsi
);
2925 static HRESULT WINAPI
IFileOpenDialog_fnAddPlace(IFileOpenDialog
*iface
, IShellItem
*psi
, FDAP fdap
)
2927 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2928 return IFileDialog2_AddPlace(&This
->IFileDialog2_iface
, psi
, fdap
);
2931 static HRESULT WINAPI
IFileOpenDialog_fnSetDefaultExtension(IFileOpenDialog
*iface
,
2932 LPCWSTR pszDefaultExtension
)
2934 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2935 return IFileDialog2_SetDefaultExtension(&This
->IFileDialog2_iface
, pszDefaultExtension
);
2938 static HRESULT WINAPI
IFileOpenDialog_fnClose(IFileOpenDialog
*iface
, HRESULT hr
)
2940 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2941 return IFileDialog2_Close(&This
->IFileDialog2_iface
, hr
);
2944 static HRESULT WINAPI
IFileOpenDialog_fnSetClientGuid(IFileOpenDialog
*iface
, REFGUID guid
)
2946 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2947 return IFileDialog2_SetClientGuid(&This
->IFileDialog2_iface
, guid
);
2950 static HRESULT WINAPI
IFileOpenDialog_fnClearClientData(IFileOpenDialog
*iface
)
2952 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2953 return IFileDialog2_ClearClientData(&This
->IFileDialog2_iface
);
2956 static HRESULT WINAPI
IFileOpenDialog_fnSetFilter(IFileOpenDialog
*iface
, IShellItemFilter
*pFilter
)
2958 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2959 return IFileDialog2_SetFilter(&This
->IFileDialog2_iface
, pFilter
);
2962 static HRESULT WINAPI
IFileOpenDialog_fnGetResults(IFileOpenDialog
*iface
, IShellItemArray
**ppenum
)
2964 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2965 TRACE("%p (%p)\n", This
, ppenum
);
2967 *ppenum
= This
->psia_results
;
2971 IShellItemArray_AddRef(*ppenum
);
2978 static HRESULT WINAPI
IFileOpenDialog_fnGetSelectedItems(IFileOpenDialog
*iface
, IShellItemArray
**ppsai
)
2980 FileDialogImpl
*This
= impl_from_IFileOpenDialog(iface
);
2981 TRACE("%p (%p)\n", This
, ppsai
);
2983 if(This
->psia_selection
)
2985 *ppsai
= This
->psia_selection
;
2986 IShellItemArray_AddRef(*ppsai
);
2993 static const IFileOpenDialogVtbl vt_IFileOpenDialog
= {
2994 IFileOpenDialog_fnQueryInterface
,
2995 IFileOpenDialog_fnAddRef
,
2996 IFileOpenDialog_fnRelease
,
2997 IFileOpenDialog_fnShow
,
2998 IFileOpenDialog_fnSetFileTypes
,
2999 IFileOpenDialog_fnSetFileTypeIndex
,
3000 IFileOpenDialog_fnGetFileTypeIndex
,
3001 IFileOpenDialog_fnAdvise
,
3002 IFileOpenDialog_fnUnadvise
,
3003 IFileOpenDialog_fnSetOptions
,
3004 IFileOpenDialog_fnGetOptions
,
3005 IFileOpenDialog_fnSetDefaultFolder
,
3006 IFileOpenDialog_fnSetFolder
,
3007 IFileOpenDialog_fnGetFolder
,
3008 IFileOpenDialog_fnGetCurrentSelection
,
3009 IFileOpenDialog_fnSetFileName
,
3010 IFileOpenDialog_fnGetFileName
,
3011 IFileOpenDialog_fnSetTitle
,
3012 IFileOpenDialog_fnSetOkButtonLabel
,
3013 IFileOpenDialog_fnSetFileNameLabel
,
3014 IFileOpenDialog_fnGetResult
,
3015 IFileOpenDialog_fnAddPlace
,
3016 IFileOpenDialog_fnSetDefaultExtension
,
3017 IFileOpenDialog_fnClose
,
3018 IFileOpenDialog_fnSetClientGuid
,
3019 IFileOpenDialog_fnClearClientData
,
3020 IFileOpenDialog_fnSetFilter
,
3021 IFileOpenDialog_fnGetResults
,
3022 IFileOpenDialog_fnGetSelectedItems
3025 /**************************************************************************
3028 static inline FileDialogImpl
*impl_from_IFileSaveDialog(IFileSaveDialog
*iface
)
3030 return CONTAINING_RECORD(iface
, FileDialogImpl
, u
.IFileSaveDialog_iface
);
3033 static HRESULT WINAPI
IFileSaveDialog_fnQueryInterface(IFileSaveDialog
*iface
,
3037 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
3038 return IFileDialog2_QueryInterface(&This
->IFileDialog2_iface
, riid
, ppvObject
);
3041 static ULONG WINAPI
IFileSaveDialog_fnAddRef(IFileSaveDialog
*iface
)
3043 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
3044 return IFileDialog2_AddRef(&This
->IFileDialog2_iface
);
3047 static ULONG WINAPI
IFileSaveDialog_fnRelease(IFileSaveDialog
*iface
)
3049 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
3050 return IFileDialog2_Release(&This
->IFileDialog2_iface
);
3053 static HRESULT WINAPI
IFileSaveDialog_fnShow(IFileSaveDialog
*iface
, HWND hwndOwner
)
3055 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
3056 return IFileDialog2_Show(&This
->IFileDialog2_iface
, hwndOwner
);
3059 static HRESULT WINAPI
IFileSaveDialog_fnSetFileTypes(IFileSaveDialog
*iface
, UINT cFileTypes
,
3060 const COMDLG_FILTERSPEC
*rgFilterSpec
)
3062 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
3063 return IFileDialog2_SetFileTypes(&This
->IFileDialog2_iface
, cFileTypes
, rgFilterSpec
);
3066 static HRESULT WINAPI
IFileSaveDialog_fnSetFileTypeIndex(IFileSaveDialog
*iface
, UINT iFileType
)
3068 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
3069 return IFileDialog2_SetFileTypeIndex(&This
->IFileDialog2_iface
, iFileType
);
3072 static HRESULT WINAPI
IFileSaveDialog_fnGetFileTypeIndex(IFileSaveDialog
*iface
, UINT
*piFileType
)
3074 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
3075 return IFileDialog2_GetFileTypeIndex(&This
->IFileDialog2_iface
, piFileType
);
3078 static HRESULT WINAPI
IFileSaveDialog_fnAdvise(IFileSaveDialog
*iface
, IFileDialogEvents
*pfde
,
3081 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
3082 return IFileDialog2_Advise(&This
->IFileDialog2_iface
, pfde
, pdwCookie
);
3085 static HRESULT WINAPI
IFileSaveDialog_fnUnadvise(IFileSaveDialog
*iface
, DWORD dwCookie
)
3087 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
3088 return IFileDialog2_Unadvise(&This
->IFileDialog2_iface
, dwCookie
);
3091 static HRESULT WINAPI
IFileSaveDialog_fnSetOptions(IFileSaveDialog
*iface
, FILEOPENDIALOGOPTIONS fos
)
3093 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
3094 return IFileDialog2_SetOptions(&This
->IFileDialog2_iface
, fos
);
3097 static HRESULT WINAPI
IFileSaveDialog_fnGetOptions(IFileSaveDialog
*iface
, FILEOPENDIALOGOPTIONS
*pfos
)
3099 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
3100 return IFileDialog2_GetOptions(&This
->IFileDialog2_iface
, pfos
);
3103 static HRESULT WINAPI
IFileSaveDialog_fnSetDefaultFolder(IFileSaveDialog
*iface
, IShellItem
*psi
)
3105 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
3106 return IFileDialog2_SetDefaultFolder(&This
->IFileDialog2_iface
, psi
);
3109 static HRESULT WINAPI
IFileSaveDialog_fnSetFolder(IFileSaveDialog
*iface
, IShellItem
*psi
)
3111 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
3112 return IFileDialog2_SetFolder(&This
->IFileDialog2_iface
, psi
);
3115 static HRESULT WINAPI
IFileSaveDialog_fnGetFolder(IFileSaveDialog
*iface
, IShellItem
**ppsi
)
3117 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
3118 return IFileDialog2_GetFolder(&This
->IFileDialog2_iface
, ppsi
);
3121 static HRESULT WINAPI
IFileSaveDialog_fnGetCurrentSelection(IFileSaveDialog
*iface
, IShellItem
**ppsi
)
3123 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
3124 return IFileDialog2_GetCurrentSelection(&This
->IFileDialog2_iface
, ppsi
);
3127 static HRESULT WINAPI
IFileSaveDialog_fnSetFileName(IFileSaveDialog
*iface
, LPCWSTR pszName
)
3129 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
3130 return IFileDialog2_SetFileName(&This
->IFileDialog2_iface
, pszName
);
3133 static HRESULT WINAPI
IFileSaveDialog_fnGetFileName(IFileSaveDialog
*iface
, LPWSTR
*pszName
)
3135 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
3136 return IFileDialog2_GetFileName(&This
->IFileDialog2_iface
, pszName
);
3139 static HRESULT WINAPI
IFileSaveDialog_fnSetTitle(IFileSaveDialog
*iface
, LPCWSTR pszTitle
)
3141 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
3142 return IFileDialog2_SetTitle(&This
->IFileDialog2_iface
, pszTitle
);
3145 static HRESULT WINAPI
IFileSaveDialog_fnSetOkButtonLabel(IFileSaveDialog
*iface
, LPCWSTR pszText
)
3147 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
3148 return IFileDialog2_SetOkButtonLabel(&This
->IFileDialog2_iface
, pszText
);
3151 static HRESULT WINAPI
IFileSaveDialog_fnSetFileNameLabel(IFileSaveDialog
*iface
, LPCWSTR pszLabel
)
3153 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
3154 return IFileDialog2_SetFileNameLabel(&This
->IFileDialog2_iface
, pszLabel
);
3157 static HRESULT WINAPI
IFileSaveDialog_fnGetResult(IFileSaveDialog
*iface
, IShellItem
**ppsi
)
3159 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
3160 return IFileDialog2_GetResult(&This
->IFileDialog2_iface
, ppsi
);
3163 static HRESULT WINAPI
IFileSaveDialog_fnAddPlace(IFileSaveDialog
*iface
, IShellItem
*psi
, FDAP fdap
)
3165 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
3166 return IFileDialog2_AddPlace(&This
->IFileDialog2_iface
, psi
, fdap
);
3169 static HRESULT WINAPI
IFileSaveDialog_fnSetDefaultExtension(IFileSaveDialog
*iface
,
3170 LPCWSTR pszDefaultExtension
)
3172 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
3173 return IFileDialog2_SetDefaultExtension(&This
->IFileDialog2_iface
, pszDefaultExtension
);
3176 static HRESULT WINAPI
IFileSaveDialog_fnClose(IFileSaveDialog
*iface
, HRESULT hr
)
3178 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
3179 return IFileDialog2_Close(&This
->IFileDialog2_iface
, hr
);
3182 static HRESULT WINAPI
IFileSaveDialog_fnSetClientGuid(IFileSaveDialog
*iface
, REFGUID guid
)
3184 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
3185 return IFileDialog2_SetClientGuid(&This
->IFileDialog2_iface
, guid
);
3188 static HRESULT WINAPI
IFileSaveDialog_fnClearClientData(IFileSaveDialog
*iface
)
3190 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
3191 return IFileDialog2_ClearClientData(&This
->IFileDialog2_iface
);
3194 static HRESULT WINAPI
IFileSaveDialog_fnSetFilter(IFileSaveDialog
*iface
, IShellItemFilter
*pFilter
)
3196 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
3197 return IFileDialog2_SetFilter(&This
->IFileDialog2_iface
, pFilter
);
3200 static HRESULT WINAPI
IFileSaveDialog_fnSetSaveAsItem(IFileSaveDialog
* iface
, IShellItem
*psi
)
3202 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
3203 FIXME("stub - %p (%p)\n", This
, psi
);
3207 static HRESULT WINAPI
IFileSaveDialog_fnSetProperties(IFileSaveDialog
* iface
, IPropertyStore
*pStore
)
3209 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
3210 FIXME("stub - %p (%p)\n", This
, pStore
);
3214 static HRESULT WINAPI
IFileSaveDialog_fnSetCollectedProperties(IFileSaveDialog
* iface
,
3215 IPropertyDescriptionList
*pList
,
3216 BOOL fAppendDefault
)
3218 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
3219 FIXME("stub - %p (%p, %d)\n", This
, pList
, fAppendDefault
);
3223 static HRESULT WINAPI
IFileSaveDialog_fnGetProperties(IFileSaveDialog
* iface
, IPropertyStore
**ppStore
)
3225 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
3226 FIXME("stub - %p (%p)\n", This
, ppStore
);
3230 static HRESULT WINAPI
IFileSaveDialog_fnApplyProperties(IFileSaveDialog
* iface
,
3232 IPropertyStore
*pStore
,
3234 IFileOperationProgressSink
*pSink
)
3236 FileDialogImpl
*This
= impl_from_IFileSaveDialog(iface
);
3237 FIXME("%p (%p, %p, %p, %p)\n", This
, psi
, pStore
, hwnd
, pSink
);
3241 static const IFileSaveDialogVtbl vt_IFileSaveDialog
= {
3242 IFileSaveDialog_fnQueryInterface
,
3243 IFileSaveDialog_fnAddRef
,
3244 IFileSaveDialog_fnRelease
,
3245 IFileSaveDialog_fnShow
,
3246 IFileSaveDialog_fnSetFileTypes
,
3247 IFileSaveDialog_fnSetFileTypeIndex
,
3248 IFileSaveDialog_fnGetFileTypeIndex
,
3249 IFileSaveDialog_fnAdvise
,
3250 IFileSaveDialog_fnUnadvise
,
3251 IFileSaveDialog_fnSetOptions
,
3252 IFileSaveDialog_fnGetOptions
,
3253 IFileSaveDialog_fnSetDefaultFolder
,
3254 IFileSaveDialog_fnSetFolder
,
3255 IFileSaveDialog_fnGetFolder
,
3256 IFileSaveDialog_fnGetCurrentSelection
,
3257 IFileSaveDialog_fnSetFileName
,
3258 IFileSaveDialog_fnGetFileName
,
3259 IFileSaveDialog_fnSetTitle
,
3260 IFileSaveDialog_fnSetOkButtonLabel
,
3261 IFileSaveDialog_fnSetFileNameLabel
,
3262 IFileSaveDialog_fnGetResult
,
3263 IFileSaveDialog_fnAddPlace
,
3264 IFileSaveDialog_fnSetDefaultExtension
,
3265 IFileSaveDialog_fnClose
,
3266 IFileSaveDialog_fnSetClientGuid
,
3267 IFileSaveDialog_fnClearClientData
,
3268 IFileSaveDialog_fnSetFilter
,
3269 IFileSaveDialog_fnSetSaveAsItem
,
3270 IFileSaveDialog_fnSetProperties
,
3271 IFileSaveDialog_fnSetCollectedProperties
,
3272 IFileSaveDialog_fnGetProperties
,
3273 IFileSaveDialog_fnApplyProperties
3276 /**************************************************************************
3277 * IExplorerBrowserEvents implementation
3279 static inline FileDialogImpl
*impl_from_IExplorerBrowserEvents(IExplorerBrowserEvents
*iface
)
3281 return CONTAINING_RECORD(iface
, FileDialogImpl
, IExplorerBrowserEvents_iface
);
3284 static HRESULT WINAPI
IExplorerBrowserEvents_fnQueryInterface(IExplorerBrowserEvents
*iface
,
3285 REFIID riid
, void **ppvObject
)
3287 FileDialogImpl
*This
= impl_from_IExplorerBrowserEvents(iface
);
3288 TRACE("%p (%s, %p)\n", This
, debugstr_guid(riid
), ppvObject
);
3290 return IFileDialog2_QueryInterface(&This
->IFileDialog2_iface
, riid
, ppvObject
);
3293 static ULONG WINAPI
IExplorerBrowserEvents_fnAddRef(IExplorerBrowserEvents
*iface
)
3295 FileDialogImpl
*This
= impl_from_IExplorerBrowserEvents(iface
);
3296 TRACE("%p\n", This
);
3297 return IFileDialog2_AddRef(&This
->IFileDialog2_iface
);
3300 static ULONG WINAPI
IExplorerBrowserEvents_fnRelease(IExplorerBrowserEvents
*iface
)
3302 FileDialogImpl
*This
= impl_from_IExplorerBrowserEvents(iface
);
3303 TRACE("%p\n", This
);
3304 return IFileDialog2_Release(&This
->IFileDialog2_iface
);
3307 static HRESULT WINAPI
IExplorerBrowserEvents_fnOnNavigationPending(IExplorerBrowserEvents
*iface
,
3308 PCIDLIST_ABSOLUTE pidlFolder
)
3310 FileDialogImpl
*This
= impl_from_IExplorerBrowserEvents(iface
);
3313 TRACE("%p (%p)\n", This
, pidlFolder
);
3315 hr
= SHCreateItemFromIDList(pidlFolder
, &IID_IShellItem
, (void**)&psi
);
3318 hr
= events_OnFolderChanging(This
, psi
);
3319 IShellItem_Release(psi
);
3321 /* The ExplorerBrowser treats S_FALSE as S_OK, we don't. */
3328 ERR("Failed to convert pidl (%p) to a shellitem.\n", pidlFolder
);
3333 static HRESULT WINAPI
IExplorerBrowserEvents_fnOnViewCreated(IExplorerBrowserEvents
*iface
,
3336 FileDialogImpl
*This
= impl_from_IExplorerBrowserEvents(iface
);
3337 TRACE("%p (%p)\n", This
, psv
);
3341 static HRESULT WINAPI
IExplorerBrowserEvents_fnOnNavigationComplete(IExplorerBrowserEvents
*iface
,
3342 PCIDLIST_ABSOLUTE pidlFolder
)
3344 FileDialogImpl
*This
= impl_from_IExplorerBrowserEvents(iface
);
3346 TRACE("%p (%p)\n", This
, pidlFolder
);
3348 if(This
->psi_folder
)
3349 IShellItem_Release(This
->psi_folder
);
3351 hr
= SHCreateItemFromIDList(pidlFolder
, &IID_IShellItem
, (void**)&This
->psi_folder
);
3354 ERR("Failed to get the current folder.\n");
3355 This
->psi_folder
= NULL
;
3358 events_OnFolderChange(This
);
3363 static HRESULT WINAPI
IExplorerBrowserEvents_fnOnNavigationFailed(IExplorerBrowserEvents
*iface
,
3364 PCIDLIST_ABSOLUTE pidlFolder
)
3366 FileDialogImpl
*This
= impl_from_IExplorerBrowserEvents(iface
);
3367 TRACE("%p (%p)\n", This
, pidlFolder
);
3371 static const IExplorerBrowserEventsVtbl vt_IExplorerBrowserEvents
= {
3372 IExplorerBrowserEvents_fnQueryInterface
,
3373 IExplorerBrowserEvents_fnAddRef
,
3374 IExplorerBrowserEvents_fnRelease
,
3375 IExplorerBrowserEvents_fnOnNavigationPending
,
3376 IExplorerBrowserEvents_fnOnViewCreated
,
3377 IExplorerBrowserEvents_fnOnNavigationComplete
,
3378 IExplorerBrowserEvents_fnOnNavigationFailed
3381 /**************************************************************************
3382 * IServiceProvider implementation
3384 static inline FileDialogImpl
*impl_from_IServiceProvider(IServiceProvider
*iface
)
3386 return CONTAINING_RECORD(iface
, FileDialogImpl
, IServiceProvider_iface
);
3389 static HRESULT WINAPI
IServiceProvider_fnQueryInterface(IServiceProvider
*iface
,
3390 REFIID riid
, void **ppvObject
)
3392 FileDialogImpl
*This
= impl_from_IServiceProvider(iface
);
3393 TRACE("%p\n", This
);
3394 return IFileDialog2_QueryInterface(&This
->IFileDialog2_iface
, riid
, ppvObject
);
3397 static ULONG WINAPI
IServiceProvider_fnAddRef(IServiceProvider
*iface
)
3399 FileDialogImpl
*This
= impl_from_IServiceProvider(iface
);
3400 TRACE("%p\n", This
);
3401 return IFileDialog2_AddRef(&This
->IFileDialog2_iface
);
3404 static ULONG WINAPI
IServiceProvider_fnRelease(IServiceProvider
*iface
)
3406 FileDialogImpl
*This
= impl_from_IServiceProvider(iface
);
3407 TRACE("%p\n", This
);
3408 return IFileDialog2_Release(&This
->IFileDialog2_iface
);
3411 static HRESULT WINAPI
IServiceProvider_fnQueryService(IServiceProvider
*iface
,
3412 REFGUID guidService
,
3413 REFIID riid
, void **ppv
)
3415 FileDialogImpl
*This
= impl_from_IServiceProvider(iface
);
3416 HRESULT hr
= E_NOTIMPL
;
3417 TRACE("%p (%s, %s, %p)\n", This
, debugstr_guid(guidService
), debugstr_guid(riid
), ppv
);
3420 if(IsEqualGUID(guidService
, &SID_STopLevelBrowser
) && This
->peb
)
3421 hr
= IExplorerBrowser_QueryInterface(This
->peb
, riid
, ppv
);
3422 else if(IsEqualGUID(guidService
, &SID_SExplorerBrowserFrame
))
3423 hr
= IFileDialog2_QueryInterface(&This
->IFileDialog2_iface
, riid
, ppv
);
3425 FIXME("Interface %s requested from unknown service %s\n",
3426 debugstr_guid(riid
), debugstr_guid(guidService
));
3431 static const IServiceProviderVtbl vt_IServiceProvider
= {
3432 IServiceProvider_fnQueryInterface
,
3433 IServiceProvider_fnAddRef
,
3434 IServiceProvider_fnRelease
,
3435 IServiceProvider_fnQueryService
3438 /**************************************************************************
3439 * ICommDlgBrowser3 implementation
3441 static inline FileDialogImpl
*impl_from_ICommDlgBrowser3(ICommDlgBrowser3
*iface
)
3443 return CONTAINING_RECORD(iface
, FileDialogImpl
, ICommDlgBrowser3_iface
);
3446 static HRESULT WINAPI
ICommDlgBrowser3_fnQueryInterface(ICommDlgBrowser3
*iface
,
3447 REFIID riid
, void **ppvObject
)
3449 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
3450 TRACE("%p\n", This
);
3451 return IFileDialog2_QueryInterface(&This
->IFileDialog2_iface
, riid
, ppvObject
);
3454 static ULONG WINAPI
ICommDlgBrowser3_fnAddRef(ICommDlgBrowser3
*iface
)
3456 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
3457 TRACE("%p\n", This
);
3458 return IFileDialog2_AddRef(&This
->IFileDialog2_iface
);
3461 static ULONG WINAPI
ICommDlgBrowser3_fnRelease(ICommDlgBrowser3
*iface
)
3463 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
3464 TRACE("%p\n", This
);
3465 return IFileDialog2_Release(&This
->IFileDialog2_iface
);
3468 static HRESULT WINAPI
ICommDlgBrowser3_fnOnDefaultCommand(ICommDlgBrowser3
*iface
,
3471 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
3473 TRACE("%p (%p)\n", This
, shv
);
3475 hr
= on_default_action(This
);
3478 EndDialog(This
->dlg_hwnd
, S_OK
);
3483 static HRESULT WINAPI
ICommDlgBrowser3_fnOnStateChange(ICommDlgBrowser3
*iface
,
3484 IShellView
*shv
, ULONG uChange
)
3486 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
3487 IDataObject
*new_selection
;
3489 TRACE("%p (%p, %x)\n", This
, shv
, uChange
);
3493 case CDBOSC_SELCHANGE
:
3494 if(This
->psia_selection
)
3496 IShellItemArray_Release(This
->psia_selection
);
3497 This
->psia_selection
= NULL
;
3500 hr
= IShellView_GetItemObject(shv
, SVGIO_SELECTION
, &IID_IDataObject
, (void**)&new_selection
);
3503 hr
= SHCreateShellItemArrayFromDataObject(new_selection
, &IID_IShellItemArray
,
3504 (void**)&This
->psia_selection
);
3507 fill_filename_from_selection(This
);
3508 events_OnSelectionChange(This
);
3511 IDataObject_Release(new_selection
);
3515 TRACE("Unhandled state change\n");
3520 static HRESULT WINAPI
ICommDlgBrowser3_fnIncludeObject(ICommDlgBrowser3
*iface
,
3521 IShellView
*shv
, LPCITEMIDLIST pidl
)
3523 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
3526 LPITEMIDLIST parent_pidl
;
3529 TRACE("%p (%p, %p)\n", This
, shv
, pidl
);
3531 if(!This
->filterspec_count
&& !(This
->options
& FOS_PICKFOLDERS
))
3534 hr
= SHGetIDListFromObject((IUnknown
*)shv
, &parent_pidl
);
3537 LPITEMIDLIST full_pidl
= ILCombine(parent_pidl
, pidl
);
3538 hr
= SHCreateItemFromIDList(full_pidl
, &IID_IShellItem
, (void**)&psi
);
3539 ILFree(parent_pidl
);
3544 ERR("Failed to get shellitem (%08x).\n", hr
);
3548 hr
= IShellItem_GetAttributes(psi
, SFGAO_FOLDER
|SFGAO_LINK
, &attr
);
3549 if(FAILED(hr
) || (attr
& (SFGAO_FOLDER
| SFGAO_LINK
)))
3551 IShellItem_Release(psi
);
3555 if((This
->options
& FOS_PICKFOLDERS
) && !(attr
& (SFGAO_FOLDER
| SFGAO_LINK
)))
3557 IShellItem_Release(psi
);
3562 if(SUCCEEDED(IShellItem_GetDisplayName(psi
, SIGDN_PARENTRELATIVEPARSING
, &filename
)))
3564 if(!PathMatchSpecW(filename
, This
->filterspecs
[This
->filetypeindex
].pszSpec
))
3566 CoTaskMemFree(filename
);
3569 IShellItem_Release(psi
);
3573 static HRESULT WINAPI
ICommDlgBrowser3_fnNotify(ICommDlgBrowser3
*iface
,
3574 IShellView
*ppshv
, DWORD dwNotifyType
)
3576 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
3577 FIXME("Stub: %p (%p, 0x%x)\n", This
, ppshv
, dwNotifyType
);
3581 static HRESULT WINAPI
ICommDlgBrowser3_fnGetDefaultMenuText(ICommDlgBrowser3
*iface
,
3583 LPWSTR pszText
, int cchMax
)
3585 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
3586 FIXME("Stub: %p (%p, %p, %d)\n", This
, pshv
, pszText
, cchMax
);
3590 static HRESULT WINAPI
ICommDlgBrowser3_fnGetViewFlags(ICommDlgBrowser3
*iface
, DWORD
*pdwFlags
)
3592 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
3593 FIXME("Stub: %p (%p)\n", This
, pdwFlags
);
3597 static HRESULT WINAPI
ICommDlgBrowser3_fnOnColumnClicked(ICommDlgBrowser3
*iface
,
3598 IShellView
*pshv
, int iColumn
)
3600 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
3601 FIXME("Stub: %p (%p, %d)\n", This
, pshv
, iColumn
);
3605 static HRESULT WINAPI
ICommDlgBrowser3_fnGetCurrentFilter(ICommDlgBrowser3
*iface
,
3606 LPWSTR pszFileSpec
, int cchFileSpec
)
3608 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
3609 FIXME("Stub: %p (%p, %d)\n", This
, pszFileSpec
, cchFileSpec
);
3613 static HRESULT WINAPI
ICommDlgBrowser3_fnOnPreviewCreated(ICommDlgBrowser3
*iface
,
3616 FileDialogImpl
*This
= impl_from_ICommDlgBrowser3(iface
);
3617 FIXME("Stub: %p (%p)\n", This
, pshv
);
3621 static const ICommDlgBrowser3Vtbl vt_ICommDlgBrowser3
= {
3622 ICommDlgBrowser3_fnQueryInterface
,
3623 ICommDlgBrowser3_fnAddRef
,
3624 ICommDlgBrowser3_fnRelease
,
3625 ICommDlgBrowser3_fnOnDefaultCommand
,
3626 ICommDlgBrowser3_fnOnStateChange
,
3627 ICommDlgBrowser3_fnIncludeObject
,
3628 ICommDlgBrowser3_fnNotify
,
3629 ICommDlgBrowser3_fnGetDefaultMenuText
,
3630 ICommDlgBrowser3_fnGetViewFlags
,
3631 ICommDlgBrowser3_fnOnColumnClicked
,
3632 ICommDlgBrowser3_fnGetCurrentFilter
,
3633 ICommDlgBrowser3_fnOnPreviewCreated
3636 /**************************************************************************
3637 * IOleWindow implementation
3639 static inline FileDialogImpl
*impl_from_IOleWindow(IOleWindow
*iface
)
3641 return CONTAINING_RECORD(iface
, FileDialogImpl
, IOleWindow_iface
);
3644 static HRESULT WINAPI
IOleWindow_fnQueryInterface(IOleWindow
*iface
, REFIID riid
, void **ppvObject
)
3646 FileDialogImpl
*This
= impl_from_IOleWindow(iface
);
3647 return IFileDialog2_QueryInterface(&This
->IFileDialog2_iface
, riid
, ppvObject
);
3650 static ULONG WINAPI
IOleWindow_fnAddRef(IOleWindow
*iface
)
3652 FileDialogImpl
*This
= impl_from_IOleWindow(iface
);
3653 return IFileDialog2_AddRef(&This
->IFileDialog2_iface
);
3656 static ULONG WINAPI
IOleWindow_fnRelease(IOleWindow
*iface
)
3658 FileDialogImpl
*This
= impl_from_IOleWindow(iface
);
3659 return IFileDialog2_Release(&This
->IFileDialog2_iface
);
3662 static HRESULT WINAPI
IOleWindow_fnContextSensitiveHelp(IOleWindow
*iface
, BOOL fEnterMOde
)
3664 FileDialogImpl
*This
= impl_from_IOleWindow(iface
);
3665 FIXME("Stub: %p (%d)\n", This
, fEnterMOde
);
3669 static HRESULT WINAPI
IOleWindow_fnGetWindow(IOleWindow
*iface
, HWND
*phwnd
)
3671 FileDialogImpl
*This
= impl_from_IOleWindow(iface
);
3672 TRACE("%p (%p)\n", This
, phwnd
);
3673 *phwnd
= This
->dlg_hwnd
;
3677 static const IOleWindowVtbl vt_IOleWindow
= {
3678 IOleWindow_fnQueryInterface
,
3679 IOleWindow_fnAddRef
,
3680 IOleWindow_fnRelease
,
3681 IOleWindow_fnGetWindow
,
3682 IOleWindow_fnContextSensitiveHelp
3685 /**************************************************************************
3686 * IFileDialogCustomize implementation
3688 static inline FileDialogImpl
*impl_from_IFileDialogCustomize(IFileDialogCustomize
*iface
)
3690 return CONTAINING_RECORD(iface
, FileDialogImpl
, IFileDialogCustomize_iface
);
3693 static HRESULT WINAPI
IFileDialogCustomize_fnQueryInterface(IFileDialogCustomize
*iface
,
3694 REFIID riid
, void **ppvObject
)
3696 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3697 return IFileDialog2_QueryInterface(&This
->IFileDialog2_iface
, riid
, ppvObject
);
3700 static ULONG WINAPI
IFileDialogCustomize_fnAddRef(IFileDialogCustomize
*iface
)
3702 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3703 return IFileDialog2_AddRef(&This
->IFileDialog2_iface
);
3706 static ULONG WINAPI
IFileDialogCustomize_fnRelease(IFileDialogCustomize
*iface
)
3708 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3709 return IFileDialog2_Release(&This
->IFileDialog2_iface
);
3712 static HRESULT WINAPI
IFileDialogCustomize_fnEnableOpenDropDown(IFileDialogCustomize
*iface
,
3715 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3717 TRACE("%p (%d)\n", This
, dwIDCtl
);
3719 if (This
->hmenu_opendropdown
|| get_cctrl(This
, dwIDCtl
))
3720 return E_UNEXPECTED
;
3722 This
->hmenu_opendropdown
= CreatePopupMenu();
3724 if (!This
->hmenu_opendropdown
)
3725 return E_OUTOFMEMORY
;
3727 mi
.cbSize
= sizeof(mi
);
3728 mi
.fMask
= MIM_STYLE
;
3729 mi
.dwStyle
= MNS_NOTIFYBYPOS
;
3730 SetMenuInfo(This
->hmenu_opendropdown
, &mi
);
3732 This
->cctrl_opendropdown
.hwnd
= NULL
;
3733 This
->cctrl_opendropdown
.wrapper_hwnd
= NULL
;
3734 This
->cctrl_opendropdown
.id
= dwIDCtl
;
3735 This
->cctrl_opendropdown
.dlgid
= 0;
3736 This
->cctrl_opendropdown
.type
= IDLG_CCTRL_OPENDROPDOWN
;
3737 This
->cctrl_opendropdown
.cdcstate
= CDCS_ENABLED
| CDCS_VISIBLE
;
3738 list_init(&This
->cctrl_opendropdown
.sub_cctrls
);
3739 list_init(&This
->cctrl_opendropdown
.sub_items
);
3744 static HRESULT WINAPI
IFileDialogCustomize_fnAddMenu(IFileDialogCustomize
*iface
,
3748 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3752 TRACE("%p (%d, %p)\n", This
, dwIDCtl
, pszLabel
);
3754 hr
= cctrl_create_new(This
, dwIDCtl
, NULL
, TOOLBARCLASSNAMEW
,
3755 TBSTYLE_FLAT
| CCS_NODIVIDER
, 0,
3756 This
->cctrl_def_height
, &ctrl
);
3759 SendMessageW(ctrl
->hwnd
, TB_BUTTONSTRUCTSIZE
, sizeof(tbb
), 0);
3760 ctrl
->type
= IDLG_CCTRL_MENU
;
3762 /* Add the actual button with a popup menu. */
3763 tbb
.iBitmap
= I_IMAGENONE
;
3764 tbb
.dwData
= (DWORD_PTR
)CreatePopupMenu();
3765 tbb
.iString
= (DWORD_PTR
)pszLabel
;
3766 tbb
.fsState
= TBSTATE_ENABLED
;
3767 tbb
.fsStyle
= BTNS_WHOLEDROPDOWN
;
3770 SendMessageW(ctrl
->hwnd
, TB_ADDBUTTONSW
, 1, (LPARAM
)&tbb
);
3776 static HRESULT WINAPI
IFileDialogCustomize_fnAddPushButton(IFileDialogCustomize
*iface
,
3780 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3783 TRACE("%p (%d, %p)\n", This
, dwIDCtl
, pszLabel
);
3785 hr
= cctrl_create_new(This
, dwIDCtl
, pszLabel
, WC_BUTTONW
, BS_MULTILINE
, 0,
3786 This
->cctrl_def_height
, &ctrl
);
3788 ctrl
->type
= IDLG_CCTRL_PUSHBUTTON
;
3793 static HRESULT WINAPI
IFileDialogCustomize_fnAddComboBox(IFileDialogCustomize
*iface
,
3796 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3799 TRACE("%p (%d)\n", This
, dwIDCtl
);
3801 hr
= cctrl_create_new(This
, dwIDCtl
, NULL
, WC_COMBOBOXW
, CBS_DROPDOWNLIST
, 0,
3802 This
->cctrl_def_height
, &ctrl
);
3804 ctrl
->type
= IDLG_CCTRL_COMBOBOX
;
3809 static HRESULT WINAPI
IFileDialogCustomize_fnAddRadioButtonList(IFileDialogCustomize
*iface
,
3812 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3815 TRACE("%p (%d)\n", This
, dwIDCtl
);
3817 hr
= cctrl_create_new(This
, dwIDCtl
, NULL
, radiobuttonlistW
, 0, 0, 0, &ctrl
);
3820 ctrl
->type
= IDLG_CCTRL_RADIOBUTTONLIST
;
3821 SetWindowLongPtrW(ctrl
->hwnd
, GWLP_USERDATA
, (LPARAM
)This
);
3827 static HRESULT WINAPI
IFileDialogCustomize_fnAddCheckButton(IFileDialogCustomize
*iface
,
3832 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3835 TRACE("%p (%d, %p, %d)\n", This
, dwIDCtl
, pszLabel
, bChecked
);
3837 hr
= cctrl_create_new(This
, dwIDCtl
, pszLabel
, WC_BUTTONW
, BS_AUTOCHECKBOX
|BS_MULTILINE
, 0,
3838 This
->cctrl_def_height
, &ctrl
);
3841 ctrl
->type
= IDLG_CCTRL_CHECKBUTTON
;
3842 SendMessageW(ctrl
->hwnd
, BM_SETCHECK
, bChecked
? BST_CHECKED
: BST_UNCHECKED
, 0);
3848 static HRESULT WINAPI
IFileDialogCustomize_fnAddEditBox(IFileDialogCustomize
*iface
,
3852 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3855 TRACE("%p (%d, %p)\n", This
, dwIDCtl
, pszText
);
3857 hr
= cctrl_create_new(This
, dwIDCtl
, pszText
, WC_EDITW
, ES_AUTOHSCROLL
, WS_EX_CLIENTEDGE
,
3858 This
->cctrl_def_height
, &ctrl
);
3860 ctrl
->type
= IDLG_CCTRL_EDITBOX
;
3865 static HRESULT WINAPI
IFileDialogCustomize_fnAddSeparator(IFileDialogCustomize
*iface
,
3868 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3871 TRACE("%p (%d)\n", This
, dwIDCtl
);
3873 hr
= cctrl_create_new(This
, dwIDCtl
, NULL
, WC_STATICW
, SS_ETCHEDHORZ
, 0,
3874 GetSystemMetrics(SM_CYEDGE
), &ctrl
);
3876 ctrl
->type
= IDLG_CCTRL_SEPARATOR
;
3881 static HRESULT WINAPI
IFileDialogCustomize_fnAddText(IFileDialogCustomize
*iface
,
3885 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3888 TRACE("%p (%d, %p)\n", This
, dwIDCtl
, pszText
);
3890 hr
= cctrl_create_new(This
, dwIDCtl
, pszText
, WC_STATICW
, 0, 0,
3891 This
->cctrl_def_height
, &ctrl
);
3893 ctrl
->type
= IDLG_CCTRL_TEXT
;
3898 static HRESULT WINAPI
IFileDialogCustomize_fnSetControlLabel(IFileDialogCustomize
*iface
,
3902 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3903 customctrl
*ctrl
= get_cctrl(This
, dwIDCtl
);
3904 TRACE("%p (%d, %p)\n", This
, dwIDCtl
, pszLabel
);
3906 if(!ctrl
) return E_INVALIDARG
;
3910 case IDLG_CCTRL_MENU
:
3911 case IDLG_CCTRL_PUSHBUTTON
:
3912 case IDLG_CCTRL_CHECKBUTTON
:
3913 case IDLG_CCTRL_TEXT
:
3914 case IDLG_CCTRL_VISUALGROUP
:
3915 SendMessageW(ctrl
->hwnd
, WM_SETTEXT
, 0, (LPARAM
)pszLabel
);
3917 case IDLG_CCTRL_OPENDROPDOWN
:
3926 static HRESULT WINAPI
IFileDialogCustomize_fnGetControlState(IFileDialogCustomize
*iface
,
3928 CDCONTROLSTATEF
*pdwState
)
3930 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3931 customctrl
*ctrl
= get_cctrl(This
, dwIDCtl
);
3932 TRACE("%p (%d, %p)\n", This
, dwIDCtl
, pdwState
);
3934 if(!ctrl
|| ctrl
->type
== IDLG_CCTRL_OPENDROPDOWN
) return E_NOTIMPL
;
3936 *pdwState
= ctrl
->cdcstate
;
3940 static HRESULT WINAPI
IFileDialogCustomize_fnSetControlState(IFileDialogCustomize
*iface
,
3942 CDCONTROLSTATEF dwState
)
3944 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3945 customctrl
*ctrl
= get_cctrl(This
,dwIDCtl
);
3946 TRACE("%p (%d, %x)\n", This
, dwIDCtl
, dwState
);
3948 if(ctrl
&& ctrl
->hwnd
)
3950 LONG wndstyle
= GetWindowLongW(ctrl
->hwnd
, GWL_STYLE
);
3952 if(dwState
& CDCS_ENABLED
)
3953 wndstyle
&= ~(WS_DISABLED
);
3955 wndstyle
|= WS_DISABLED
;
3957 if(dwState
& CDCS_VISIBLE
)
3958 wndstyle
|= WS_VISIBLE
;
3960 wndstyle
&= ~(WS_VISIBLE
);
3962 SetWindowLongW(ctrl
->hwnd
, GWL_STYLE
, wndstyle
);
3964 /* We save the state separately since at least one application
3965 * relies on being able to hide a control. */
3966 ctrl
->cdcstate
= dwState
;
3972 static HRESULT WINAPI
IFileDialogCustomize_fnGetEditBoxText(IFileDialogCustomize
*iface
,
3976 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3977 customctrl
*ctrl
= get_cctrl(This
, dwIDCtl
);
3979 TRACE("%p (%d, %p)\n", This
, dwIDCtl
, ppszText
);
3981 if(!ctrl
|| !ctrl
->hwnd
|| !(len
= SendMessageW(ctrl
->hwnd
, WM_GETTEXTLENGTH
, 0, 0)))
3984 text
= CoTaskMemAlloc(sizeof(WCHAR
)*(len
+1));
3985 if(!text
) return E_FAIL
;
3987 SendMessageW(ctrl
->hwnd
, WM_GETTEXT
, len
+1, (LPARAM
)text
);
3992 static HRESULT WINAPI
IFileDialogCustomize_fnSetEditBoxText(IFileDialogCustomize
*iface
,
3996 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
3997 customctrl
*ctrl
= get_cctrl(This
, dwIDCtl
);
3998 TRACE("%p (%d, %s)\n", This
, dwIDCtl
, debugstr_w(pszText
));
4000 if(!ctrl
|| ctrl
->type
!= IDLG_CCTRL_EDITBOX
)
4003 SendMessageW(ctrl
->hwnd
, WM_SETTEXT
, 0, (LPARAM
)pszText
);
4007 static HRESULT WINAPI
IFileDialogCustomize_fnGetCheckButtonState(IFileDialogCustomize
*iface
,
4011 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
4012 customctrl
*ctrl
= get_cctrl(This
, dwIDCtl
);
4013 TRACE("%p (%d, %p)\n", This
, dwIDCtl
, pbChecked
);
4015 if(ctrl
&& ctrl
->hwnd
)
4016 *pbChecked
= (SendMessageW(ctrl
->hwnd
, BM_GETCHECK
, 0, 0) == BST_CHECKED
);
4021 static HRESULT WINAPI
IFileDialogCustomize_fnSetCheckButtonState(IFileDialogCustomize
*iface
,
4025 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
4026 customctrl
*ctrl
= get_cctrl(This
, dwIDCtl
);
4027 TRACE("%p (%d, %d)\n", This
, dwIDCtl
, bChecked
);
4029 if(ctrl
&& ctrl
->hwnd
)
4030 SendMessageW(ctrl
->hwnd
, BM_SETCHECK
, bChecked
? BST_CHECKED
:BST_UNCHECKED
, 0);
4035 static UINT
get_combobox_index_from_id(HWND cb_hwnd
, DWORD dwIDItem
)
4037 UINT count
= SendMessageW(cb_hwnd
, CB_GETCOUNT
, 0, 0);
4039 if(!count
|| (count
== CB_ERR
))
4042 for(i
= 0; i
< count
; i
++)
4043 if(SendMessageW(cb_hwnd
, CB_GETITEMDATA
, i
, 0) == dwIDItem
)
4046 TRACE("Item with id %d not found in combobox %p (item count: %d)\n", dwIDItem
, cb_hwnd
, count
);
4050 static HRESULT WINAPI
IFileDialogCustomize_fnAddControlItem(IFileDialogCustomize
*iface
,
4055 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
4056 customctrl
*ctrl
= get_cctrl(This
, dwIDCtl
);
4058 TRACE("%p (%d, %d, %s)\n", This
, dwIDCtl
, dwIDItem
, debugstr_w(pszLabel
));
4060 if(!ctrl
) return E_FAIL
;
4064 case IDLG_CCTRL_COMBOBOX
:
4069 hr
= add_item(ctrl
, dwIDItem
, pszLabel
, &item
);
4071 if (FAILED(hr
)) return hr
;
4073 index
= SendMessageW(ctrl
->hwnd
, CB_ADDSTRING
, 0, (LPARAM
)pszLabel
);
4074 SendMessageW(ctrl
->hwnd
, CB_SETITEMDATA
, index
, dwIDItem
);
4078 case IDLG_CCTRL_MENU
:
4079 case IDLG_CCTRL_OPENDROPDOWN
:
4084 hr
= add_item(ctrl
, dwIDItem
, pszLabel
, &item
);
4086 if (FAILED(hr
)) return hr
;
4088 if (ctrl
->type
== IDLG_CCTRL_MENU
)
4091 SendMessageW(ctrl
->hwnd
, TB_GETBUTTON
, 0, (LPARAM
)&tbb
);
4092 hmenu
= (HMENU
)tbb
.dwData
;
4094 else /* ctrl->type == IDLG_CCTRL_OPENDROPDOWN */
4095 hmenu
= This
->hmenu_opendropdown
;
4097 AppendMenuW(hmenu
, MF_STRING
, dwIDItem
, pszLabel
);
4100 case IDLG_CCTRL_RADIOBUTTONLIST
:
4104 hr
= add_item(ctrl
, dwIDItem
, pszLabel
, &item
);
4108 item
->hwnd
= CreateWindowExW(0, WC_BUTTONW
, pszLabel
,
4109 WS_CHILD
|WS_VISIBLE
|WS_CLIPSIBLINGS
|BS_RADIOBUTTON
|BS_MULTILINE
,
4110 0, 0, 0, 0, ctrl
->hwnd
, ULongToHandle(dwIDItem
), COMDLG32_hInstance
, 0);
4114 ERR("Failed to create radio button\n");
4115 list_remove(&item
->entry
);
4127 return E_NOINTERFACE
; /* win7 */
4130 static HRESULT WINAPI
IFileDialogCustomize_fnRemoveControlItem(IFileDialogCustomize
*iface
,
4134 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
4135 customctrl
*ctrl
= get_cctrl(This
, dwIDCtl
);
4136 TRACE("%p (%d, %d)\n", This
, dwIDCtl
, dwIDItem
);
4138 if(!ctrl
) return E_FAIL
;
4142 case IDLG_CCTRL_COMBOBOX
:
4147 item
= get_item(ctrl
, dwIDItem
, CDCS_VISIBLE
|CDCS_ENABLED
, &position
);
4149 if ((item
->cdcstate
& (CDCS_VISIBLE
|CDCS_ENABLED
)) == (CDCS_VISIBLE
|CDCS_ENABLED
))
4151 if(SendMessageW(ctrl
->hwnd
, CB_DELETESTRING
, position
, 0) == CB_ERR
)
4155 list_remove(&item
->entry
);
4160 case IDLG_CCTRL_MENU
:
4161 case IDLG_CCTRL_OPENDROPDOWN
:
4166 item
= get_item(ctrl
, dwIDItem
, 0, NULL
);
4169 return E_UNEXPECTED
;
4171 if (item
->cdcstate
& CDCS_VISIBLE
)
4173 if (ctrl
->type
== IDLG_CCTRL_MENU
)
4176 SendMessageW(ctrl
->hwnd
, TB_GETBUTTON
, 0, (LPARAM
)&tbb
);
4177 hmenu
= (HMENU
)tbb
.dwData
;
4179 else /* ctrl->type == IDLG_CCTRL_OPENDROPDOWN */
4180 hmenu
= This
->hmenu_opendropdown
;
4182 if(!hmenu
|| !DeleteMenu(hmenu
, dwIDItem
, MF_BYCOMMAND
))
4183 return E_UNEXPECTED
;
4186 list_remove(&item
->entry
);
4191 case IDLG_CCTRL_RADIOBUTTONLIST
:
4195 item
= get_item(ctrl
, dwIDItem
, 0, NULL
);
4198 return E_UNEXPECTED
;
4200 list_remove(&item
->entry
);
4212 static HRESULT WINAPI
IFileDialogCustomize_fnRemoveAllControlItems(IFileDialogCustomize
*iface
,
4215 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
4216 TRACE("%p (%d)\n", This
, dwIDCtl
);
4218 /* Not implemented by native */
4222 static HRESULT WINAPI
IFileDialogCustomize_fnGetControlItemState(IFileDialogCustomize
*iface
,
4225 CDCONTROLSTATEF
*pdwState
)
4227 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
4228 customctrl
*ctrl
= get_cctrl(This
, dwIDCtl
);
4229 TRACE("%p (%d, %d, %p)\n", This
, dwIDCtl
, dwIDItem
, pdwState
);
4231 if(!ctrl
) return E_FAIL
;
4235 case IDLG_CCTRL_COMBOBOX
:
4236 case IDLG_CCTRL_MENU
:
4237 case IDLG_CCTRL_OPENDROPDOWN
:
4238 case IDLG_CCTRL_RADIOBUTTONLIST
:
4242 item
= get_item(ctrl
, dwIDItem
, 0, NULL
);
4245 return E_UNEXPECTED
;
4247 *pdwState
= item
->cdcstate
;
4258 static HRESULT WINAPI
IFileDialogCustomize_fnSetControlItemState(IFileDialogCustomize
*iface
,
4261 CDCONTROLSTATEF dwState
)
4263 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
4264 customctrl
*ctrl
= get_cctrl(This
, dwIDCtl
);
4265 TRACE("%p (%d, %d, %x)\n", This
, dwIDCtl
, dwIDItem
, dwState
);
4267 if(!ctrl
) return E_FAIL
;
4271 case IDLG_CCTRL_COMBOBOX
:
4274 BOOL visible
, was_visible
;
4277 item
= get_item(ctrl
, dwIDItem
, CDCS_VISIBLE
|CDCS_ENABLED
, &position
);
4280 return E_UNEXPECTED
;
4282 visible
= ((dwState
& (CDCS_VISIBLE
|CDCS_ENABLED
)) == (CDCS_VISIBLE
|CDCS_ENABLED
));
4283 was_visible
= ((item
->cdcstate
& (CDCS_VISIBLE
|CDCS_ENABLED
)) == (CDCS_VISIBLE
|CDCS_ENABLED
));
4285 if (visible
&& !was_visible
)
4287 SendMessageW(ctrl
->hwnd
, CB_INSERTSTRING
, position
, (LPARAM
)item
->label
);
4288 SendMessageW(ctrl
->hwnd
, CB_SETITEMDATA
, position
, dwIDItem
);
4290 else if (!visible
&& was_visible
)
4292 SendMessageW(ctrl
->hwnd
, CB_DELETESTRING
, position
, 0);
4295 item
->cdcstate
= dwState
;
4299 case IDLG_CCTRL_MENU
:
4300 case IDLG_CCTRL_OPENDROPDOWN
:
4304 CDCONTROLSTATEF prev_state
;
4307 item
= get_item(ctrl
, dwIDItem
, CDCS_VISIBLE
, &position
);
4310 return E_UNEXPECTED
;
4312 prev_state
= item
->cdcstate
;
4314 if (ctrl
->type
== IDLG_CCTRL_MENU
)
4317 SendMessageW(ctrl
->hwnd
, TB_GETBUTTON
, 0, (LPARAM
)&tbb
);
4318 hmenu
= (HMENU
)tbb
.dwData
;
4320 else /* ctrl->type == IDLG_CCTRL_OPENDROPDOWN */
4321 hmenu
= This
->hmenu_opendropdown
;
4323 if (dwState
& CDCS_VISIBLE
)
4325 if (prev_state
& CDCS_VISIBLE
)
4328 EnableMenuItem(hmenu
, dwIDItem
,
4329 MF_BYCOMMAND
|((dwState
& CDCS_ENABLED
) ? MFS_ENABLED
: MFS_DISABLED
));
4336 mii
.cbSize
= sizeof(mii
);
4337 mii
.fMask
= MIIM_ID
|MIIM_STATE
|MIIM_STRING
;
4338 mii
.fState
= (dwState
& CDCS_ENABLED
) ? MFS_ENABLED
: MFS_DISABLED
;
4340 mii
.dwTypeData
= item
->label
;
4342 InsertMenuItemW(hmenu
, position
, TRUE
, &mii
);
4345 else if (prev_state
& CDCS_VISIBLE
)
4348 DeleteMenu(hmenu
, dwIDItem
, MF_BYCOMMAND
);
4351 item
->cdcstate
= dwState
;
4353 if (ctrl
->type
== IDLG_CCTRL_OPENDROPDOWN
)
4355 update_control_text(This
);
4356 update_layout(This
);
4361 case IDLG_CCTRL_RADIOBUTTONLIST
:
4365 item
= get_item(ctrl
, dwIDItem
, CDCS_VISIBLE
, NULL
);
4368 return E_UNEXPECTED
;
4370 /* Oddly, native allows setting this but doesn't seem to do anything with it. */
4371 item
->cdcstate
= dwState
;
4382 static HRESULT WINAPI
IFileDialogCustomize_fnGetSelectedControlItem(IFileDialogCustomize
*iface
,
4386 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
4387 customctrl
*ctrl
= get_cctrl(This
, dwIDCtl
);
4388 TRACE("%p (%d, %p)\n", This
, dwIDCtl
, pdwIDItem
);
4390 if(!ctrl
) return E_FAIL
;
4394 case IDLG_CCTRL_COMBOBOX
:
4396 UINT index
= SendMessageW(ctrl
->hwnd
, CB_GETCURSEL
, 0, 0);
4400 *pdwIDItem
= SendMessageW(ctrl
->hwnd
, CB_GETITEMDATA
, index
, 0);
4403 case IDLG_CCTRL_OPENDROPDOWN
:
4404 if (This
->opendropdown_has_selection
)
4406 *pdwIDItem
= This
->opendropdown_selection
;
4411 /* Return first enabled item. */
4412 cctrl_item
* item
= get_first_item(ctrl
);
4416 *pdwIDItem
= item
->id
;
4420 WARN("no enabled items in open dropdown\n");
4423 case IDLG_CCTRL_RADIOBUTTONLIST
:
4427 LIST_FOR_EACH_ENTRY(item
, &ctrl
->sub_items
, cctrl_item
, entry
)
4429 if (SendMessageW(item
->hwnd
, BM_GETCHECK
, 0, 0) == BST_CHECKED
)
4431 *pdwIDItem
= item
->id
;
4436 WARN("no checked items in radio button list\n");
4440 FIXME("Unsupported control type %d\n", ctrl
->type
);
4446 static HRESULT WINAPI
IFileDialogCustomize_fnSetSelectedControlItem(IFileDialogCustomize
*iface
,
4450 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
4451 customctrl
*ctrl
= get_cctrl(This
, dwIDCtl
);
4452 TRACE("%p (%d, %d)\n", This
, dwIDCtl
, dwIDItem
);
4454 if(!ctrl
) return E_INVALIDARG
;
4458 case IDLG_CCTRL_COMBOBOX
:
4460 UINT index
= get_combobox_index_from_id(ctrl
->hwnd
, dwIDItem
);
4463 return E_INVALIDARG
;
4465 if(SendMessageW(ctrl
->hwnd
, CB_SETCURSEL
, index
, 0) == CB_ERR
)
4470 case IDLG_CCTRL_RADIOBUTTONLIST
:
4474 item
= get_item(ctrl
, dwIDItem
, 0, NULL
);
4478 radiobuttonlist_set_selected_item(This
, ctrl
, item
);
4482 return E_INVALIDARG
;
4485 FIXME("Unsupported control type %d\n", ctrl
->type
);
4488 return E_INVALIDARG
;
4491 static HRESULT WINAPI
IFileDialogCustomize_fnStartVisualGroup(IFileDialogCustomize
*iface
,
4495 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
4498 TRACE("%p (%d, %s)\n", This
, dwIDCtl
, debugstr_w(pszLabel
));
4500 if(This
->cctrl_active_vg
)
4501 return E_UNEXPECTED
;
4503 hr
= cctrl_create_new(This
, dwIDCtl
, pszLabel
, WC_STATICW
, 0, 0,
4504 This
->cctrl_def_height
, &vg
);
4507 vg
->type
= IDLG_CCTRL_VISUALGROUP
;
4508 This
->cctrl_active_vg
= vg
;
4514 static HRESULT WINAPI
IFileDialogCustomize_fnEndVisualGroup(IFileDialogCustomize
*iface
)
4516 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
4517 TRACE("%p\n", This
);
4519 This
->cctrl_active_vg
= NULL
;
4524 static HRESULT WINAPI
IFileDialogCustomize_fnMakeProminent(IFileDialogCustomize
*iface
,
4527 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
4528 FIXME("stub - %p (%d)\n", This
, dwIDCtl
);
4532 static HRESULT WINAPI
IFileDialogCustomize_fnSetControlItemText(IFileDialogCustomize
*iface
,
4537 FileDialogImpl
*This
= impl_from_IFileDialogCustomize(iface
);
4538 FIXME("stub - %p (%d, %d, %s)\n", This
, dwIDCtl
, dwIDItem
, debugstr_w(pszLabel
));
4542 static const IFileDialogCustomizeVtbl vt_IFileDialogCustomize
= {
4543 IFileDialogCustomize_fnQueryInterface
,
4544 IFileDialogCustomize_fnAddRef
,
4545 IFileDialogCustomize_fnRelease
,
4546 IFileDialogCustomize_fnEnableOpenDropDown
,
4547 IFileDialogCustomize_fnAddMenu
,
4548 IFileDialogCustomize_fnAddPushButton
,
4549 IFileDialogCustomize_fnAddComboBox
,
4550 IFileDialogCustomize_fnAddRadioButtonList
,
4551 IFileDialogCustomize_fnAddCheckButton
,
4552 IFileDialogCustomize_fnAddEditBox
,
4553 IFileDialogCustomize_fnAddSeparator
,
4554 IFileDialogCustomize_fnAddText
,
4555 IFileDialogCustomize_fnSetControlLabel
,
4556 IFileDialogCustomize_fnGetControlState
,
4557 IFileDialogCustomize_fnSetControlState
,
4558 IFileDialogCustomize_fnGetEditBoxText
,
4559 IFileDialogCustomize_fnSetEditBoxText
,
4560 IFileDialogCustomize_fnGetCheckButtonState
,
4561 IFileDialogCustomize_fnSetCheckButtonState
,
4562 IFileDialogCustomize_fnAddControlItem
,
4563 IFileDialogCustomize_fnRemoveControlItem
,
4564 IFileDialogCustomize_fnRemoveAllControlItems
,
4565 IFileDialogCustomize_fnGetControlItemState
,
4566 IFileDialogCustomize_fnSetControlItemState
,
4567 IFileDialogCustomize_fnGetSelectedControlItem
,
4568 IFileDialogCustomize_fnSetSelectedControlItem
,
4569 IFileDialogCustomize_fnStartVisualGroup
,
4570 IFileDialogCustomize_fnEndVisualGroup
,
4571 IFileDialogCustomize_fnMakeProminent
,
4572 IFileDialogCustomize_fnSetControlItemText
4575 static HRESULT
FileDialog_constructor(IUnknown
*pUnkOuter
, REFIID riid
, void **ppv
, enum ITEMDLG_TYPE type
)
4577 FileDialogImpl
*fdimpl
;
4580 TRACE("%p, %s, %p\n", pUnkOuter
, debugstr_guid(riid
), ppv
);
4585 return CLASS_E_NOAGGREGATION
;
4587 fdimpl
= HeapAlloc(GetProcessHeap(), 0, sizeof(FileDialogImpl
));
4589 return E_OUTOFMEMORY
;
4592 fdimpl
->IFileDialog2_iface
.lpVtbl
= &vt_IFileDialog2
;
4593 fdimpl
->IExplorerBrowserEvents_iface
.lpVtbl
= &vt_IExplorerBrowserEvents
;
4594 fdimpl
->IServiceProvider_iface
.lpVtbl
= &vt_IServiceProvider
;
4595 fdimpl
->ICommDlgBrowser3_iface
.lpVtbl
= &vt_ICommDlgBrowser3
;
4596 fdimpl
->IOleWindow_iface
.lpVtbl
= &vt_IOleWindow
;
4597 fdimpl
->IFileDialogCustomize_iface
.lpVtbl
= &vt_IFileDialogCustomize
;
4599 if(type
== ITEMDLG_TYPE_OPEN
)
4601 fdimpl
->dlg_type
= ITEMDLG_TYPE_OPEN
;
4602 fdimpl
->u
.IFileOpenDialog_iface
.lpVtbl
= &vt_IFileOpenDialog
;
4603 fdimpl
->options
= FOS_PATHMUSTEXIST
| FOS_FILEMUSTEXIST
| FOS_NOCHANGEDIR
;
4604 fdimpl
->custom_title
= fdimpl
->custom_okbutton
= NULL
;
4609 fdimpl
->dlg_type
= ITEMDLG_TYPE_SAVE
;
4610 fdimpl
->u
.IFileSaveDialog_iface
.lpVtbl
= &vt_IFileSaveDialog
;
4611 fdimpl
->options
= FOS_OVERWRITEPROMPT
| FOS_NOREADONLYRETURN
| FOS_PATHMUSTEXIST
| FOS_NOCHANGEDIR
;
4613 LoadStringW(COMDLG32_hInstance
, IDS_SAVE
, buf
, sizeof(buf
)/sizeof(WCHAR
));
4614 fdimpl
->custom_title
= StrDupW(buf
);
4615 fdimpl
->custom_okbutton
= StrDupW(buf
);
4618 fdimpl
->filterspecs
= NULL
;
4619 fdimpl
->filterspec_count
= 0;
4620 fdimpl
->filetypeindex
= 0;
4622 fdimpl
->psia_selection
= fdimpl
->psia_results
= NULL
;
4623 fdimpl
->psi_setfolder
= fdimpl
->psi_folder
= NULL
;
4625 list_init(&fdimpl
->events_clients
);
4626 fdimpl
->events_next_cookie
= 0;
4628 fdimpl
->dlg_hwnd
= NULL
;
4631 fdimpl
->set_filename
= NULL
;
4632 fdimpl
->default_ext
= NULL
;
4633 fdimpl
->custom_cancelbutton
= fdimpl
->custom_filenamelabel
= NULL
;
4635 fdimpl
->client_guid
= GUID_NULL
;
4637 fdimpl
->hmenu_opendropdown
= NULL
;
4638 fdimpl
->hfont_opendropdown
= NULL
;
4640 /* FIXME: The default folder setting should be restored for the
4641 * application if it was previously set. */
4642 SHGetDesktopFolder(&psf
);
4643 SHGetItemFromObject((IUnknown
*)psf
, &IID_IShellItem
, (void**)&fdimpl
->psi_defaultfolder
);
4644 IShellFolder_Release(psf
);
4646 hr
= init_custom_controls(fdimpl
);
4649 ERR("Failed to initialize custom controls (0x%08x).\n", hr
);
4650 IFileDialog2_Release(&fdimpl
->IFileDialog2_iface
);
4654 hr
= IFileDialog2_QueryInterface(&fdimpl
->IFileDialog2_iface
, riid
, ppv
);
4655 IFileDialog2_Release(&fdimpl
->IFileDialog2_iface
);
4659 HRESULT
FileOpenDialog_Constructor(IUnknown
*pUnkOuter
, REFIID riid
, void **ppv
)
4661 return FileDialog_constructor(pUnkOuter
, riid
, ppv
, ITEMDLG_TYPE_OPEN
);
4664 HRESULT
FileSaveDialog_Constructor(IUnknown
*pUnkOuter
, REFIID riid
, void **ppv
)
4666 return FileDialog_constructor(pUnkOuter
, riid
, ppv
, ITEMDLG_TYPE_SAVE
);