ReactOS 0.4.17-dev-1190-g4c812f4
itemdlg.c
Go to the documentation of this file.
1/*
2 * Common Item Dialog
3 *
4 * Copyright 2010,2011 David Hedberg
5 *
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.
10 *
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.
15 *
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
19 */
20
21#if (DLL_EXPORT_VERSION >= 0x600) && defined(__REACTOS__)
22
23#include <stdarg.h>
24
25#define COBJMACROS
26#include "windef.h"
27#include "winbase.h"
28#include "winuser.h"
29#include "wingdi.h"
30#include "winreg.h"
31#include "shlwapi.h"
32
33#include "commdlg.h"
34#include "cdlg.h"
35#include "filedlgbrowser.h"
36
37#include "wine/debug.h"
38#include "wine/list.h"
39
40#define IDC_NAV_TOOLBAR 200
41#define IDC_NAVBACK 201
42#define IDC_NAVFORWARD 202
43#define IDC_NAVUP 203
44
45#include <initguid.h>
46/* This seems to be another version of IID_IFileDialogCustomize. If
47 * there is any difference I have yet to find it. */
48DEFINE_GUID(IID_IFileDialogCustomizeAlt, 0x8016B7B3, 0x3D49, 0x4504, 0xA0,0xAA, 0x2A,0x37,0x49,0x4E,0x60,0x6F);
49
51
52enum ITEMDLG_TYPE {
53 ITEMDLG_TYPE_OPEN,
54 ITEMDLG_TYPE_SAVE
55};
56
57enum ITEMDLG_CCTRL_TYPE {
58 IDLG_CCTRL_MENU,
59 IDLG_CCTRL_PUSHBUTTON,
60 IDLG_CCTRL_COMBOBOX,
61 IDLG_CCTRL_RADIOBUTTONLIST,
62 IDLG_CCTRL_CHECKBUTTON,
63 IDLG_CCTRL_EDITBOX,
64 IDLG_CCTRL_SEPARATOR,
65 IDLG_CCTRL_TEXT,
66 IDLG_CCTRL_OPENDROPDOWN,
67 IDLG_CCTRL_VISUALGROUP
68};
69
70typedef struct cctrl_item {
73 CDCONTROLSTATEF cdcstate;
74 HWND hwnd;
75 struct list entry;
76} cctrl_item;
77
78typedef struct {
79 HWND hwnd, wrapper_hwnd;
80 UINT id, dlgid;
81 enum ITEMDLG_CCTRL_TYPE type;
82 CDCONTROLSTATEF cdcstate;
83 struct list entry;
84
85 struct list sub_cctrls;
86 struct list sub_cctrls_entry;
87 struct list sub_items;
88} customctrl;
89
90typedef struct {
91 struct list entry;
94} events_client;
95
96typedef struct FileDialogImpl {
97 IFileDialog2 IFileDialog2_iface;
98 union {
99 IFileOpenDialog IFileOpenDialog_iface;
100 IFileSaveDialog IFileSaveDialog_iface;
101 } u;
102 enum ITEMDLG_TYPE dlg_type;
103 IExplorerBrowserEvents IExplorerBrowserEvents_iface;
104 IServiceProvider IServiceProvider_iface;
105 ICommDlgBrowser3 ICommDlgBrowser3_iface;
106 IOleWindow IOleWindow_iface;
107 IFileDialogCustomize IFileDialogCustomize_iface;
108 LONG ref;
109
110 FILEOPENDIALOGOPTIONS options;
111 COMDLG_FILTERSPEC *filterspecs;
112 UINT filterspec_count;
113 UINT filetypeindex;
114
115 struct list events_clients;
116 DWORD events_next_cookie;
117
118 IShellItemArray *psia_selection;
119 IShellItemArray *psia_results;
120 IShellItem *psi_defaultfolder;
121 IShellItem *psi_setfolder;
122 IShellItem *psi_folder;
123
124 HWND dlg_hwnd;
125 IExplorerBrowser *peb;
126 DWORD ebevents_cookie;
127
128 LPWSTR set_filename;
129 LPWSTR default_ext;
130 LPWSTR custom_title;
131 LPWSTR custom_okbutton;
132 LPWSTR custom_cancelbutton;
133 LPWSTR custom_filenamelabel;
134 LPWSTR current_filter;
135
136 UINT cctrl_width, cctrl_def_height, cctrls_cols;
137 UINT cctrl_indent, dpi_x, dpi_y;
138 HWND cctrls_hwnd;
139 struct list cctrls;
140 UINT_PTR cctrl_next_dlgid;
141 customctrl *cctrl_active_vg;
142
143 HMENU hmenu_opendropdown;
144 customctrl cctrl_opendropdown;
145 HFONT hfont_opendropdown;
146 BOOL opendropdown_has_selection;
147 DWORD opendropdown_selection;
148
149 GUID client_guid;
150
151 HANDLE user_actctx;
152} FileDialogImpl;
153
154/**************************************************************************
155 * Event wrappers.
156 */
157static HRESULT events_OnFileOk(FileDialogImpl *This)
158{
159 ULONG_PTR ctx_cookie = 0;
160 events_client *cursor;
161 HRESULT hr = S_OK;
162 TRACE("%p\n", This);
163
164 if (This->user_actctx != INVALID_HANDLE_VALUE)
165 ActivateActCtx(This->user_actctx, &ctx_cookie);
166
167 LIST_FOR_EACH_ENTRY(cursor, &This->events_clients, events_client, entry)
168 {
169 TRACE("Notifying %p\n", cursor);
170 hr = IFileDialogEvents_OnFileOk(cursor->pfde, (IFileDialog*)&This->IFileDialog2_iface);
171 if(FAILED(hr) && hr != E_NOTIMPL)
172 break;
173 }
174
175 if (This->user_actctx != INVALID_HANDLE_VALUE)
176 DeactivateActCtx(0, ctx_cookie);
177
178 if(hr == E_NOTIMPL)
179 hr = S_OK;
180
181 return hr;
182}
183
184static HRESULT events_OnFolderChanging(FileDialogImpl *This, IShellItem *folder)
185{
186 ULONG_PTR ctx_cookie = 0;
187 events_client *cursor;
188 HRESULT hr = S_OK;
189 TRACE("%p (%p)\n", This, folder);
190
191 if (This->user_actctx != INVALID_HANDLE_VALUE)
192 ActivateActCtx(This->user_actctx, &ctx_cookie);
193
194 LIST_FOR_EACH_ENTRY(cursor, &This->events_clients, events_client, entry)
195 {
196 TRACE("Notifying %p\n", cursor);
197 hr = IFileDialogEvents_OnFolderChanging(cursor->pfde, (IFileDialog*)&This->IFileDialog2_iface, folder);
198 if(FAILED(hr) && hr != E_NOTIMPL)
199 break;
200 }
201
202 if (This->user_actctx != INVALID_HANDLE_VALUE)
203 DeactivateActCtx(0, ctx_cookie);
204
205 if(hr == E_NOTIMPL)
206 hr = S_OK;
207
208 return hr;
209}
210
211static void events_OnFolderChange(FileDialogImpl *This)
212{
213 ULONG_PTR ctx_cookie = 0;
214 events_client *cursor;
215 TRACE("%p\n", This);
216
217 if (This->user_actctx != INVALID_HANDLE_VALUE)
218 ActivateActCtx(This->user_actctx, &ctx_cookie);
219
220 LIST_FOR_EACH_ENTRY(cursor, &This->events_clients, events_client, entry)
221 {
222 TRACE("Notifying %p\n", cursor);
223 IFileDialogEvents_OnFolderChange(cursor->pfde, (IFileDialog*)&This->IFileDialog2_iface);
224 }
225
226 if (This->user_actctx != INVALID_HANDLE_VALUE)
227 DeactivateActCtx(0, ctx_cookie);
228}
229
230static void events_OnSelectionChange(FileDialogImpl *This)
231{
232 ULONG_PTR ctx_cookie = 0;
233 events_client *cursor;
234 TRACE("%p\n", This);
235
236 if (This->user_actctx != INVALID_HANDLE_VALUE)
237 ActivateActCtx(This->user_actctx, &ctx_cookie);
238
239 LIST_FOR_EACH_ENTRY(cursor, &This->events_clients, events_client, entry)
240 {
241 TRACE("Notifying %p\n", cursor);
242 IFileDialogEvents_OnSelectionChange(cursor->pfde, (IFileDialog*)&This->IFileDialog2_iface);
243 }
244
245 if (This->user_actctx != INVALID_HANDLE_VALUE)
246 DeactivateActCtx(0, ctx_cookie);
247}
248
249static void events_OnTypeChange(FileDialogImpl *This)
250{
251 ULONG_PTR ctx_cookie = 0;
252 events_client *cursor;
253 TRACE("%p\n", This);
254
255 if (This->user_actctx != INVALID_HANDLE_VALUE)
256 ActivateActCtx(This->user_actctx, &ctx_cookie);
257
258 LIST_FOR_EACH_ENTRY(cursor, &This->events_clients, events_client, entry)
259 {
260 TRACE("Notifying %p\n", cursor);
261 IFileDialogEvents_OnTypeChange(cursor->pfde, (IFileDialog*)&This->IFileDialog2_iface);
262 }
263
264 if (This->user_actctx != INVALID_HANDLE_VALUE)
265 DeactivateActCtx(0, ctx_cookie);
266}
267
268static HRESULT events_OnOverwrite(FileDialogImpl *This, IShellItem *shellitem)
269{
270 ULONG_PTR ctx_cookie = 0;
271 events_client *cursor;
272 HRESULT hr = S_OK;
274 TRACE("%p %p\n", This, shellitem);
275
276 if (This->user_actctx != INVALID_HANDLE_VALUE)
277 ActivateActCtx(This->user_actctx, &ctx_cookie);
278
279 LIST_FOR_EACH_ENTRY(cursor, &This->events_clients, events_client, entry)
280 {
281 TRACE("Notifying %p\n", cursor);
282 hr = IFileDialogEvents_OnOverwrite(cursor->pfde, (IFileDialog*)&This->IFileDialog2_iface, shellitem, &response);
283 TRACE("<-- hr=%lx response=%u\n", hr, response);
284 if(FAILED(hr) && hr != E_NOTIMPL)
285 break;
286 }
287
288 if (This->user_actctx != INVALID_HANDLE_VALUE)
289 DeactivateActCtx(0, ctx_cookie);
290
291 if(hr == E_NOTIMPL)
292 hr = S_OK;
293
294 if(SUCCEEDED(hr))
295 {
296 if (response == FDEOR_DEFAULT)
297 {
298 WCHAR buf[100];
299 int answer;
300
302 answer = MessageBoxW(This->dlg_hwnd, buf, This->custom_title,
304 if (answer == IDNO || answer == IDCANCEL)
305 {
306 hr = E_FAIL;
307 }
308 }
309 else if (response == FDEOR_REFUSE)
310 hr = E_FAIL;
311 }
312
313 return hr;
314}
315
316static inline HRESULT get_cctrl_event(IFileDialogEvents *pfde, IFileDialogControlEvents **pfdce)
317{
318 return IFileDialogEvents_QueryInterface(pfde, &IID_IFileDialogControlEvents, (void**)pfdce);
319}
320
321static HRESULT cctrl_event_OnButtonClicked(FileDialogImpl *This, DWORD ctl_id)
322{
323 ULONG_PTR ctx_cookie = 0;
324 events_client *cursor;
325 TRACE("%p\n", This);
326
327 if (This->user_actctx != INVALID_HANDLE_VALUE)
328 ActivateActCtx(This->user_actctx, &ctx_cookie);
329
330 LIST_FOR_EACH_ENTRY(cursor, &This->events_clients, events_client, entry)
331 {
332 IFileDialogControlEvents *pfdce;
333 if(SUCCEEDED(get_cctrl_event(cursor->pfde, &pfdce)))
334 {
335 TRACE("Notifying %p\n", cursor);
336 IFileDialogControlEvents_OnButtonClicked(pfdce, &This->IFileDialogCustomize_iface, ctl_id);
337 IFileDialogControlEvents_Release(pfdce);
338 }
339 }
340
341 if (This->user_actctx != INVALID_HANDLE_VALUE)
342 DeactivateActCtx(0, ctx_cookie);
343
344 return S_OK;
345}
346
347static HRESULT cctrl_event_OnItemSelected(FileDialogImpl *This, DWORD ctl_id, DWORD item_id)
348{
349 ULONG_PTR ctx_cookie = 0;
350 events_client *cursor;
351 TRACE("%p %li %li\n", This, ctl_id, item_id);
352
353 if (This->user_actctx != INVALID_HANDLE_VALUE)
354 ActivateActCtx(This->user_actctx, &ctx_cookie);
355
356 LIST_FOR_EACH_ENTRY(cursor, &This->events_clients, events_client, entry)
357 {
358 IFileDialogControlEvents *pfdce;
359 if(SUCCEEDED(get_cctrl_event(cursor->pfde, &pfdce)))
360 {
361 TRACE("Notifying %p\n", cursor);
362 IFileDialogControlEvents_OnItemSelected(pfdce, &This->IFileDialogCustomize_iface, ctl_id, item_id);
363 IFileDialogControlEvents_Release(pfdce);
364 }
365 }
366
367 if (This->user_actctx != INVALID_HANDLE_VALUE)
368 DeactivateActCtx(0, ctx_cookie);
369
370 return S_OK;
371}
372
373static HRESULT cctrl_event_OnCheckButtonToggled(FileDialogImpl *This, DWORD ctl_id, BOOL checked)
374{
375 ULONG_PTR ctx_cookie = 0;
376 events_client *cursor;
377 TRACE("%p\n", This);
378
379 if (This->user_actctx != INVALID_HANDLE_VALUE)
380 ActivateActCtx(This->user_actctx, &ctx_cookie);
381
382 LIST_FOR_EACH_ENTRY(cursor, &This->events_clients, events_client, entry)
383 {
384 IFileDialogControlEvents *pfdce;
385 if(SUCCEEDED(get_cctrl_event(cursor->pfde, &pfdce)))
386 {
387 TRACE("Notifying %p\n", cursor);
388 IFileDialogControlEvents_OnCheckButtonToggled(pfdce, &This->IFileDialogCustomize_iface, ctl_id, checked);
389 IFileDialogControlEvents_Release(pfdce);
390 }
391 }
392
393 if (This->user_actctx != INVALID_HANDLE_VALUE)
394 DeactivateActCtx(0, ctx_cookie);
395
396 return S_OK;
397}
398
399static HRESULT cctrl_event_OnControlActivating(FileDialogImpl *This,
400 DWORD ctl_id)
401{
402 ULONG_PTR ctx_cookie = 0;
403 events_client *cursor;
404 TRACE("%p\n", This);
405
406 if (This->user_actctx != INVALID_HANDLE_VALUE)
407 ActivateActCtx(This->user_actctx, &ctx_cookie);
408
409 LIST_FOR_EACH_ENTRY(cursor, &This->events_clients, events_client, entry)
410 {
411 IFileDialogControlEvents *pfdce;
412 if(SUCCEEDED(get_cctrl_event(cursor->pfde, &pfdce)))
413 {
414 TRACE("Notifying %p\n", cursor);
415 IFileDialogControlEvents_OnControlActivating(pfdce, &This->IFileDialogCustomize_iface, ctl_id);
416 IFileDialogControlEvents_Release(pfdce);
417 }
418 }
419
420 if (This->user_actctx != INVALID_HANDLE_VALUE)
421 DeactivateActCtx(0, ctx_cookie);
422
423 return S_OK;
424}
425
426/**************************************************************************
427 * Helper functions.
428 */
429static UINT get_file_name(FileDialogImpl *This, LPWSTR *str)
430{
431 HWND hwnd_edit = GetDlgItem(This->dlg_hwnd, IDC_FILENAME);
432 UINT len;
433
434 if(!hwnd_edit)
435 {
436 if(This->set_filename)
437 {
438 len = lstrlenW(This->set_filename);
439 *str = CoTaskMemAlloc(sizeof(WCHAR)*(len+1));
440 lstrcpyW(*str, This->set_filename);
441 return len;
442 }
443 return 0;
444 }
445
446 len = SendMessageW(hwnd_edit, WM_GETTEXTLENGTH, 0, 0);
447 *str = CoTaskMemAlloc(sizeof(WCHAR)*(len+1));
448 if(!*str)
449 return 0;
450
451 SendMessageW(hwnd_edit, WM_GETTEXT, len+1, (LPARAM)*str);
452 return len;
453}
454
455static void set_current_filter(FileDialogImpl *This, LPCWSTR str)
456{
457 IShellView *psv;
458
459 if(str && !str[0])
460 return;
461
462 if(This->current_filter)
463 LocalFree(This->current_filter);
464
465 This->current_filter = str ? StrDupW(str) : NULL;
466
467 if (This->peb && SUCCEEDED(IExplorerBrowser_GetCurrentView(This->peb, &IID_IShellView, (void**)&psv)))
468 {
469 IShellView_Refresh(psv);
470 IShellView_Release(psv);
471 }
472}
473
474static BOOL set_file_name(FileDialogImpl *This, LPCWSTR str)
475{
476 if(This->set_filename)
477 LocalFree(This->set_filename);
478
479 This->set_filename = str ? StrDupW(str) : NULL;
480
481 if (str && wcspbrk(str, L"*?"))
482 set_current_filter(This, str);
483
484 return SetDlgItemTextW(This->dlg_hwnd, IDC_FILENAME, This->set_filename);
485}
486
487static void fill_filename_from_selection(FileDialogImpl *This)
488{
489 IShellItem *psi;
490 LPWSTR *names;
491 HRESULT hr;
492 DWORD item_count;
493 UINT valid_count;
494 UINT len_total, i;
495
496 if(!This->psia_selection)
497 return;
498
499 hr = IShellItemArray_GetCount(This->psia_selection, &item_count);
500 if(FAILED(hr) || !item_count)
501 return;
502
503 names = HeapAlloc(GetProcessHeap(), 0, item_count*sizeof(LPWSTR));
504
505 /* Get names of the selected items */
506 valid_count = 0; len_total = 0;
507 for(i = 0; i < item_count; i++)
508 {
509 hr = IShellItemArray_GetItemAt(This->psia_selection, i, &psi);
510 if(SUCCEEDED(hr))
511 {
512 DWORD attr;
513
514 hr = IShellItem_GetAttributes(psi, SFGAO_FOLDER, &attr);
515 if(SUCCEEDED(hr) &&
516 (( (This->options & FOS_PICKFOLDERS) && !(attr & SFGAO_FOLDER)) ||
517 (!(This->options & FOS_PICKFOLDERS) && (attr & SFGAO_FOLDER))))
518 continue;
519
520 hr = IShellItem_GetDisplayName(psi, (This->options & FOS_PICKFOLDERS) ? SIGDN_FILESYSPATH : SIGDN_PARENTRELATIVEPARSING, &names[valid_count]);
521 if(SUCCEEDED(hr))
522 {
523 len_total += lstrlenW(names[valid_count]) + 3;
524 valid_count++;
525 }
526 IShellItem_Release(psi);
527 }
528 }
529
530 if(valid_count == 1)
531 {
532 set_file_name(This, names[0]);
534 }
535 else if(valid_count > 1)
536 {
537 LPWSTR string = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*len_total);
538 LPWSTR cur_point = string;
539
540 for(i = 0; i < valid_count; i++)
541 {
542 LPWSTR file = names[i];
543 *cur_point++ = '\"';
544 lstrcpyW(cur_point, file);
545 cur_point += lstrlenW(file);
546 *cur_point++ = '\"';
547 *cur_point++ = ' ';
549 }
550 *(cur_point-1) = '\0';
551
552 set_file_name(This, string);
553 HeapFree(GetProcessHeap(), 0, string);
554 }
555
557 return;
558}
559
560static LPWSTR get_first_ext_from_spec(LPWSTR buf, LPCWSTR spec)
561{
562 WCHAR *endpos, *ext;
563 INT len;
564
565 if( (endpos = StrChrW(spec, ';')) )
566 len = endpos-spec+1;
567 else
568 len = lstrlenW(spec)+1;
569
570 if (len > MAX_PATH)
571 return NULL;
572
573 lstrcpynW(buf, spec, len);
574
576 if(StrChrW(ext, '*'))
577 return NULL;
578
579 return ext;
580}
581
582static BOOL shell_item_exists(IShellItem* shellitem)
583{
585 HRESULT hr;
586 BOOL result;
587
588 hr = IShellItem_GetDisplayName(shellitem, SIGDN_FILESYSPATH, &filename);
589 if (SUCCEEDED(hr))
590 {
591 /* FIXME: Implement SFGAO_VALIDATE in Wine and use it instead. */
594 }
595 else
596 {
598 result = SUCCEEDED(IShellItem_GetAttributes(shellitem, SFGAO_VALIDATE, &attributes));
599 }
600
601 return result;
602}
603
604static HRESULT on_default_action(FileDialogImpl *This)
605{
606 IShellFolder *psf_parent, *psf_desktop;
607 LPITEMIDLIST *pidla;
608 LPITEMIDLIST current_folder;
609 LPWSTR fn_iter, files = NULL, tmp_files, filter = NULL;
610 UINT file_count = 0, len, i;
611 int open_action;
612 HRESULT hr, ret = E_FAIL;
613
614 len = get_file_name(This, &tmp_files);
615 if(len)
616 {
617 UINT size_used;
618 file_count = COMDLG32_SplitFileNames(tmp_files, len, &files, &size_used);
619 CoTaskMemFree(tmp_files);
620 }
621 if(!file_count) return E_FAIL;
622
623 hr = SHGetIDListFromObject((IUnknown*)This->psi_folder, &current_folder);
624 if(FAILED(hr))
625 {
626 ERR("Failed to get pidl for current directory.\n");
627 HeapFree(GetProcessHeap(), 0, files);
628 return hr;
629 }
630
631 TRACE("Acting on %d file(s).\n", file_count);
632
633 pidla = HeapAlloc(GetProcessHeap(), 0, sizeof(LPITEMIDLIST) * file_count);
634 open_action = ONOPEN_OPEN;
635 fn_iter = files;
636
637 for(i = 0; i < file_count && open_action == ONOPEN_OPEN; i++)
638 {
639 WCHAR canon_filename[MAX_PATH];
640 psf_parent = NULL;
641
642 COMDLG32_GetCanonicalPath(current_folder, fn_iter, canon_filename);
643
644 if( (This->options & FOS_NOVALIDATE) &&
645 !(This->options & FOS_FILEMUSTEXIST) )
646 open_action = ONOPEN_OPEN;
647 else
648 open_action = ONOPEN_BROWSE;
649
650#ifdef __REACTOS__
651 open_action = FILEDLG95_ValidatePathAction(NULL, canon_filename, &psf_parent, This->dlg_hwnd,
652#else
653 open_action = FILEDLG95_ValidatePathAction(canon_filename, &psf_parent, This->dlg_hwnd,
654#endif
655 This->options & ~FOS_FILEMUSTEXIST,
656 (This->dlg_type == ITEMDLG_TYPE_SAVE),
657 open_action);
658
659 /* Add the proper extension */
660 if(open_action == ONOPEN_OPEN)
661 {
662 WCHAR extbuf[MAX_PATH], *newext = NULL;
663
664 if(This->current_filter)
665 {
666 newext = get_first_ext_from_spec(extbuf, This->current_filter);
667 }
668
669 if(!newext && This->default_ext)
670 {
671 lstrcpyW(extbuf, L".");
672 lstrcatW(extbuf, This->default_ext);
673 newext = extbuf;
674 }
675
676 if(This->dlg_type == ITEMDLG_TYPE_SAVE)
677 {
678 if(newext)
679 {
680 WCHAR *ext = PathFindExtensionW(canon_filename);
681 if(lstrcmpiW(ext, newext))
682 lstrcatW(canon_filename, newext);
683 }
684 }
685 else
686 {
687 if( !(This->options & FOS_NOVALIDATE) && (This->options & FOS_FILEMUSTEXIST) &&
688 !PathFileExistsW(canon_filename))
689 {
690 if(newext)
691 {
692 lstrcatW(canon_filename, newext);
693
694 if(!PathFileExistsW(canon_filename))
695 {
697 open_action = ONOPEN_BROWSE;
698 }
699 }
700 else
701 {
703 open_action = ONOPEN_BROWSE;
704 }
705 }
706 }
707 } else if (open_action == ONOPEN_SEARCH) {
708 filter = fn_iter;
709 }
710
711 pidla[i] = SHSimpleIDListFromPath(canon_filename);
712
713 if(psf_parent && !(open_action == ONOPEN_BROWSE))
714 IShellFolder_Release(psf_parent);
715
716 fn_iter += (WCHAR)lstrlenW(fn_iter) + 1;
717 }
718
719
720 if((This->options & FOS_PICKFOLDERS) && open_action == ONOPEN_BROWSE)
721 open_action = ONOPEN_OPEN; /* FIXME: Multiple folders? */
722
723 switch(open_action)
724 {
725 case ONOPEN_SEARCH:
726 set_current_filter(This, filter);
727 break;
728
729 case ONOPEN_BROWSE:
730 hr = IExplorerBrowser_BrowseToObject(This->peb, (IUnknown*)psf_parent, SBSP_DEFBROWSER);
731 if(FAILED(hr))
732 ERR("Failed to browse to directory: %08lx\n", hr);
733
734 IShellFolder_Release(psf_parent);
735 break;
736
737 case ONOPEN_OPEN:
738 hr = SHGetDesktopFolder(&psf_desktop);
739 if(SUCCEEDED(hr))
740 {
741 if(This->psia_results)
742 {
743 IShellItemArray_Release(This->psia_results);
744 This->psia_results = NULL;
745 }
746
747 hr = SHCreateShellItemArray(NULL, psf_desktop, file_count, (PCUITEMID_CHILD_ARRAY)pidla,
748 &This->psia_results);
749
750 IShellFolder_Release(psf_desktop);
751
752 if(FAILED(hr))
753 break;
754
755 if(This->options & FOS_PICKFOLDERS)
756 {
758 hr = IShellItemArray_GetAttributes(This->psia_results, SIATTRIBFLAGS_AND, SFGAO_FOLDER, &attributes);
759 if(hr != S_OK)
760 {
761 WCHAR buf[64];
763
764 MessageBoxW(This->dlg_hwnd, buf, This->custom_title, MB_OK | MB_ICONEXCLAMATION);
765
766 IShellItemArray_Release(This->psia_results);
767 This->psia_results = NULL;
768 break;
769 }
770 }
771
772 if((This->options & FOS_OVERWRITEPROMPT) && This->dlg_type == ITEMDLG_TYPE_SAVE)
773 {
774 IShellItem *shellitem;
775
776 for (i=0; SUCCEEDED(hr) && i<file_count; i++)
777 {
778 hr = IShellItemArray_GetItemAt(This->psia_results, i, &shellitem);
779 if (SUCCEEDED(hr))
780 {
781 if (shell_item_exists(shellitem))
782 hr = events_OnOverwrite(This, shellitem);
783
784 IShellItem_Release(shellitem);
785 }
786 }
787
788 if (FAILED(hr))
789 break;
790 }
791
792 if(events_OnFileOk(This) == S_OK)
793 ret = S_OK;
794 }
795 break;
796
797 default:
798 ERR("Failed.\n");
799 break;
800 }
801
802 /* Clean up */
803 HeapFree(GetProcessHeap(), 0, files);
804 ILFree(current_folder);
805 for(i = 0; i < file_count; i++)
806 ILFree(pidla[i]);
807 HeapFree(GetProcessHeap(), 0, pidla);
808
809 /* Success closes the dialog */
810 return ret;
811}
812
813static void show_opendropdown(FileDialogImpl *This)
814{
815 HWND open_hwnd;
816 RECT open_rc;
817 MSG msg;
818
819 open_hwnd = GetDlgItem(This->dlg_hwnd, IDOK);
820
821 GetWindowRect(open_hwnd, &open_rc);
822
823 if (TrackPopupMenu(This->hmenu_opendropdown, 0, open_rc.left, open_rc.bottom, 0, This->dlg_hwnd, NULL) &&
824 PeekMessageW(&msg, This->dlg_hwnd, WM_MENUCOMMAND, WM_MENUCOMMAND, PM_REMOVE))
825 {
826 MENUITEMINFOW mii;
827
828 This->opendropdown_has_selection = TRUE;
829
830 mii.cbSize = sizeof(mii);
831 mii.fMask = MIIM_ID;
832 GetMenuItemInfoW((HMENU)msg.lParam, msg.wParam, TRUE, &mii);
833 This->opendropdown_selection = mii.wID;
834
835 if(SUCCEEDED(on_default_action(This)))
836 EndDialog(This->dlg_hwnd, S_OK);
837 else
838 This->opendropdown_has_selection = FALSE;
839 }
840}
841
842/**************************************************************************
843 * Control item functions.
844 */
845
846static void item_free(cctrl_item *item)
847{
848 DestroyWindow(item->hwnd);
849 HeapFree(GetProcessHeap(), 0, item->label);
851}
852
853static cctrl_item* get_item(customctrl* parent, DWORD itemid, CDCONTROLSTATEF visible_flags, DWORD* position)
854{
855 DWORD dummy;
856 cctrl_item* item;
857
858 if (!position) position = &dummy;
859
860 *position = 0;
861
862 LIST_FOR_EACH_ENTRY(item, &parent->sub_items, cctrl_item, entry)
863 {
864 if (item->id == itemid)
865 return item;
866
867 if ((item->cdcstate & visible_flags) == visible_flags)
868 (*position)++;
869 }
870
871 return NULL;
872}
873
874static cctrl_item* get_first_item(customctrl* parent)
875{
876 cctrl_item* item;
877
878 LIST_FOR_EACH_ENTRY(item, &parent->sub_items, cctrl_item, entry)
879 {
880 if ((item->cdcstate & (CDCS_VISIBLE|CDCS_ENABLED)) == (CDCS_VISIBLE|CDCS_ENABLED))
881 return item;
882 }
883
884 return NULL;
885}
886
887static HRESULT add_item(customctrl* parent, DWORD itemid, LPCWSTR label, cctrl_item** result)
888{
889 cctrl_item* item;
890 LPWSTR label_copy;
891
892 if (get_item(parent, itemid, 0, NULL))
893 return E_INVALIDARG;
894
895 item = HeapAlloc(GetProcessHeap(), 0, sizeof(*item));
896 label_copy = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(label)+1)*sizeof(WCHAR));
897
898 if (!item || !label_copy)
899 {
901 HeapFree(GetProcessHeap(), 0, label_copy);
902 return E_OUTOFMEMORY;
903 }
904
905 item->id = itemid;
906 item->parent_id = parent->id;
907 lstrcpyW(label_copy, label);
908 item->label = label_copy;
909 item->cdcstate = CDCS_VISIBLE|CDCS_ENABLED;
910 item->hwnd = NULL;
911 list_add_tail(&parent->sub_items, &item->entry);
912
913 *result = item;
914
915 return S_OK;
916}
917
918/**************************************************************************
919 * Control functions.
920 */
921static inline customctrl *get_cctrl_from_dlgid(FileDialogImpl *This, DWORD dlgid)
922{
923 customctrl *ctrl, *sub_ctrl;
924
925 LIST_FOR_EACH_ENTRY(ctrl, &This->cctrls, customctrl, entry)
926 {
927 if(ctrl->dlgid == dlgid)
928 return ctrl;
929
930 LIST_FOR_EACH_ENTRY(sub_ctrl, &ctrl->sub_cctrls, customctrl, sub_cctrls_entry)
931 if(sub_ctrl->dlgid == dlgid)
932 return sub_ctrl;
933 }
934
935 ERR("Failed to find control with dialog id %ld\n", dlgid);
936 return NULL;
937}
938
939static inline customctrl *get_cctrl(FileDialogImpl *This, DWORD ctlid)
940{
941 customctrl *ctrl, *sub_ctrl;
942
943 LIST_FOR_EACH_ENTRY(ctrl, &This->cctrls, customctrl, entry)
944 {
945 if(ctrl->id == ctlid)
946 return ctrl;
947
948 LIST_FOR_EACH_ENTRY(sub_ctrl, &ctrl->sub_cctrls, customctrl, sub_cctrls_entry)
949 if(sub_ctrl->id == ctlid)
950 return sub_ctrl;
951 }
952
953 if (This->hmenu_opendropdown && This->cctrl_opendropdown.id == ctlid)
954 return &This->cctrl_opendropdown;
955
956 TRACE("No existing control with control id %ld\n", ctlid);
957 return NULL;
958}
959
960static void ctrl_resize(HWND hctrl, UINT min_width, UINT max_width, BOOL multiline)
961{
962 LPWSTR text;
963 UINT len, final_width;
964 UINT lines, final_height;
965 SIZE size;
966 RECT rc;
967 HDC hdc;
968 WCHAR *c;
969 HFONT font;
970
971 TRACE("\n");
972
973 len = SendMessageW(hctrl, WM_GETTEXTLENGTH, 0, 0);
974 text = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(len+1));
975 if(!text) return;
977
978 hdc = GetDC(hctrl);
979 font = (HFONT)SendMessageW(hctrl, WM_GETFONT, 0, 0);
983 ReleaseDC(hctrl, hdc);
984
985 if(len && multiline)
986 {
987 /* FIXME: line-wrap */
988 for(lines = 1, c = text; *c != '\0'; c++)
989 if(*c == '\n') lines++;
990
991 final_height = size.cy*lines + 2*4;
992 }
993 else
994 {
995 GetWindowRect(hctrl, &rc);
996 final_height = rc.bottom - rc.top;
997 }
998
999 final_width = min(max(size.cx, min_width) + 4, max_width);
1000 SetWindowPos(hctrl, NULL, 0, 0, final_width, final_height,
1002
1004}
1005
1006static UINT ctrl_get_height(customctrl *ctrl) {
1007 RECT rc;
1008 GetWindowRect(ctrl->wrapper_hwnd, &rc);
1009 return rc.bottom - rc.top;
1010}
1011
1012static void ctrl_free(customctrl *ctrl)
1013{
1014 customctrl *sub_cur1, *sub_cur2;
1015 cctrl_item *item_cur1, *item_cur2;
1016
1017 TRACE("Freeing control %p\n", ctrl);
1018 if(ctrl->type == IDLG_CCTRL_MENU)
1019 {
1020 TBBUTTON tbb;
1021 SendMessageW(ctrl->hwnd, TB_GETBUTTON, 0, (LPARAM)&tbb);
1022 DestroyMenu((HMENU)tbb.dwData);
1023 }
1024
1025 LIST_FOR_EACH_ENTRY_SAFE(sub_cur1, sub_cur2, &ctrl->sub_cctrls, customctrl, sub_cctrls_entry)
1026 {
1027 list_remove(&sub_cur1->sub_cctrls_entry);
1028 ctrl_free(sub_cur1);
1029 }
1030
1031 LIST_FOR_EACH_ENTRY_SAFE(item_cur1, item_cur2, &ctrl->sub_items, cctrl_item, entry)
1032 {
1033 list_remove(&item_cur1->entry);
1034 item_free(item_cur1);
1035 }
1036
1037 DestroyWindow(ctrl->hwnd);
1039}
1040
1041static void customctrl_resize(FileDialogImpl *This, customctrl *ctrl)
1042{
1043 RECT rc;
1044 UINT total_height;
1045 UINT max_width, size;
1046 customctrl *sub_ctrl;
1047
1048 switch(ctrl->type)
1049 {
1050 case IDLG_CCTRL_PUSHBUTTON:
1051 case IDLG_CCTRL_COMBOBOX:
1052 case IDLG_CCTRL_CHECKBUTTON:
1053 case IDLG_CCTRL_TEXT:
1054 size = MulDiv(160, This->dpi_x, USER_DEFAULT_SCREEN_DPI);
1055 ctrl_resize(ctrl->hwnd, size, size, TRUE);
1056 GetWindowRect(ctrl->hwnd, &rc);
1057 SetWindowPos(ctrl->wrapper_hwnd, NULL, 0, 0, rc.right-rc.left, rc.bottom-rc.top,
1059 break;
1060 case IDLG_CCTRL_VISUALGROUP:
1061 total_height = 0;
1062 ctrl_resize(ctrl->hwnd, 0, This->cctrl_indent, TRUE);
1063
1064 LIST_FOR_EACH_ENTRY(sub_ctrl, &ctrl->sub_cctrls, customctrl, sub_cctrls_entry)
1065 {
1066 customctrl_resize(This, sub_ctrl);
1067 SetWindowPos(sub_ctrl->wrapper_hwnd, NULL, This->cctrl_indent, total_height, 0, 0,
1069
1070 total_height += ctrl_get_height(sub_ctrl);
1071 }
1072
1073 /* The label should be right adjusted */
1074 {
1075 UINT width, height;
1076
1077 GetWindowRect(ctrl->hwnd, &rc);
1078 width = rc.right - rc.left;
1079 height = rc.bottom - rc.top;
1080
1081 SetWindowPos(ctrl->hwnd, NULL, This->cctrl_indent - width, 0, width, height, SWP_NOZORDER);
1082 }
1083
1084 /* Resize the wrapper window to fit all the sub controls */
1085 SetWindowPos(ctrl->wrapper_hwnd, NULL, 0, 0, This->cctrl_width + This->cctrl_indent, total_height,
1087 break;
1088 case IDLG_CCTRL_RADIOBUTTONLIST:
1089 {
1090 cctrl_item* item;
1091
1092 total_height = 0;
1093 max_width = 0;
1094
1095 LIST_FOR_EACH_ENTRY(item, &ctrl->sub_items, cctrl_item, entry)
1096 {
1097 size = MulDiv(160, This->dpi_x, USER_DEFAULT_SCREEN_DPI);
1098 ctrl_resize(item->hwnd, size, size, TRUE);
1099 SetWindowPos(item->hwnd, NULL, 0, total_height, 0, 0,
1101
1102 GetWindowRect(item->hwnd, &rc);
1103
1104 total_height += rc.bottom - rc.top;
1105 max_width = max(rc.right - rc.left, max_width);
1106 }
1107
1108 SetWindowPos(ctrl->hwnd, NULL, 0, 0, max_width, total_height,
1110
1111 SetWindowPos(ctrl->wrapper_hwnd, NULL, 0, 0, max_width, total_height,
1113
1114 break;
1115 }
1116 case IDLG_CCTRL_EDITBOX:
1117 case IDLG_CCTRL_SEPARATOR:
1118 case IDLG_CCTRL_MENU:
1119 case IDLG_CCTRL_OPENDROPDOWN:
1120 /* Nothing */
1121 break;
1122 }
1123}
1124
1125static LRESULT notifysink_on_create(HWND hwnd, CREATESTRUCTW *crs)
1126{
1127 FileDialogImpl *This = crs->lpCreateParams;
1128 TRACE("%p\n", This);
1129
1131 return TRUE;
1132}
1133
1134static LRESULT notifysink_on_bn_clicked(FileDialogImpl *This, HWND hwnd, WPARAM wparam)
1135{
1136 customctrl *ctrl = get_cctrl_from_dlgid(This, LOWORD(wparam));
1137
1138 TRACE("%p, %Ix\n", This, wparam);
1139
1140 if(ctrl)
1141 {
1142 if(ctrl->type == IDLG_CCTRL_CHECKBUTTON)
1143 {
1144 BOOL checked = (SendMessageW(ctrl->hwnd, BM_GETCHECK, 0, 0) == BST_CHECKED);
1145 cctrl_event_OnCheckButtonToggled(This, ctrl->id, checked);
1146 }
1147 else
1148 cctrl_event_OnButtonClicked(This, ctrl->id);
1149 }
1150
1151 return TRUE;
1152}
1153
1154static LRESULT notifysink_on_cbn_selchange(FileDialogImpl *This, HWND hwnd, WPARAM wparam)
1155{
1156 customctrl *ctrl = get_cctrl_from_dlgid(This, LOWORD(wparam));
1157 TRACE("%p, %p (%Ix)\n", This, ctrl, wparam);
1158
1159 if(ctrl)
1160 {
1161 UINT index = SendMessageW(ctrl->hwnd, CB_GETCURSEL, 0, 0);
1162 UINT selid = SendMessageW(ctrl->hwnd, CB_GETITEMDATA, index, 0);
1163
1164 cctrl_event_OnItemSelected(This, ctrl->id, selid);
1165 }
1166 return TRUE;
1167}
1168
1169static LRESULT notifysink_on_tvn_dropdown(FileDialogImpl *This, LPARAM lparam)
1170{
1171 NMTOOLBARW *nmtb = (NMTOOLBARW*)lparam;
1172 customctrl *ctrl = get_cctrl_from_dlgid(This, GetDlgCtrlID(nmtb->hdr.hwndFrom));
1173 POINT pt = { 0, nmtb->rcButton.bottom };
1174 TBBUTTON tbb;
1175 UINT idcmd;
1176
1177 TRACE("%p, %p (%Ix)\n", This, ctrl, lparam);
1178
1179 if(ctrl)
1180 {
1181 cctrl_event_OnControlActivating(This,ctrl->id);
1182
1183 SendMessageW(ctrl->hwnd, TB_GETBUTTON, 0, (LPARAM)&tbb);
1184 ClientToScreen(ctrl->hwnd, &pt);
1185 idcmd = TrackPopupMenu((HMENU)tbb.dwData, TPM_RETURNCMD, pt.x, pt.y, 0, This->dlg_hwnd, NULL);
1186 if(idcmd)
1187 cctrl_event_OnItemSelected(This, ctrl->id, idcmd);
1188 }
1189
1190 return TBDDRET_DEFAULT;
1191}
1192
1193static LRESULT notifysink_on_wm_command(FileDialogImpl *This, HWND hwnd, WPARAM wparam, LPARAM lparam)
1194{
1195 switch(HIWORD(wparam))
1196 {
1197 case BN_CLICKED: return notifysink_on_bn_clicked(This, hwnd, wparam);
1198 case CBN_SELCHANGE: return notifysink_on_cbn_selchange(This, hwnd, wparam);
1199 }
1200
1201 return FALSE;
1202}
1203
1204static LRESULT notifysink_on_wm_notify(FileDialogImpl *This, HWND hwnd, WPARAM wparam, LPARAM lparam)
1205{
1206 NMHDR *nmhdr = (NMHDR*)lparam;
1207
1208 switch(nmhdr->code)
1209 {
1210 case TBN_DROPDOWN: return notifysink_on_tvn_dropdown(This, lparam);
1211 }
1212
1213 return FALSE;
1214}
1215
1216static LRESULT CALLBACK notifysink_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
1217{
1218 FileDialogImpl *This = (FileDialogImpl*)GetWindowLongPtrW(hwnd, GWLP_USERDATA);
1219 customctrl *ctrl;
1220 HWND hwnd_child;
1221 RECT rc;
1222
1223 switch(message)
1224 {
1225 case WM_NCCREATE: return notifysink_on_create(hwnd, (CREATESTRUCTW*)lparam);
1226 case WM_COMMAND: return notifysink_on_wm_command(This, hwnd, wparam, lparam);
1227 case WM_NOTIFY: return notifysink_on_wm_notify(This, hwnd, wparam, lparam);
1228 case WM_SIZE:
1229 hwnd_child = GetPropW(hwnd, L"nfs_child");
1230 ctrl = (customctrl*)GetWindowLongPtrW(hwnd_child, GWLP_USERDATA);
1231 if(ctrl && ctrl->type != IDLG_CCTRL_VISUALGROUP)
1232 {
1233 GetClientRect(hwnd, &rc);
1235 }
1236 return TRUE;
1237 }
1238
1240}
1241
1242static HRESULT cctrl_create_new(FileDialogImpl *This, DWORD id,
1243 LPCWSTR text, LPCWSTR wndclass, DWORD ctrl_wsflags,
1244 DWORD ctrl_exflags, UINT height, customctrl **ppctrl)
1245{
1246 HWND ns_hwnd, control_hwnd, parent_hwnd;
1248 customctrl *ctrl;
1249
1250 if(get_cctrl(This, id))
1251 return E_UNEXPECTED; /* Duplicate id */
1252
1253 if(This->cctrl_active_vg)
1254 parent_hwnd = This->cctrl_active_vg->wrapper_hwnd;
1255 else
1256 parent_hwnd = This->cctrls_hwnd;
1257
1258 ns_hwnd = CreateWindowExW(0, L"FloatNotifySink", NULL, wsflags,
1259 0, 0, This->cctrl_width, height, parent_hwnd,
1260 (HMENU)This->cctrl_next_dlgid, COMDLG32_hInstance, This);
1261 control_hwnd = CreateWindowExW(ctrl_exflags, wndclass, text, wsflags | ctrl_wsflags,
1262 0, 0, This->cctrl_width, height, ns_hwnd,
1263 (HMENU)This->cctrl_next_dlgid, COMDLG32_hInstance, 0);
1264
1265 if(!ns_hwnd || !control_hwnd)
1266 {
1267 ERR("Failed to create wrapper (%p) or control (%p)\n", ns_hwnd, control_hwnd);
1268 DestroyWindow(ns_hwnd);
1269 DestroyWindow(control_hwnd);
1270
1271 return E_FAIL;
1272 }
1273
1274 SetPropW(ns_hwnd, L"nfs_child", control_hwnd);
1275
1276 ctrl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(customctrl));
1277 if(!ctrl)
1278 return E_OUTOFMEMORY;
1279
1280 ctrl->hwnd = control_hwnd;
1281 ctrl->wrapper_hwnd = ns_hwnd;
1282 ctrl->id = id;
1283 ctrl->dlgid = This->cctrl_next_dlgid;
1284 ctrl->cdcstate = CDCS_ENABLED | CDCS_VISIBLE;
1285 list_init(&ctrl->sub_cctrls);
1286 list_init(&ctrl->sub_items);
1287
1288 if(This->cctrl_active_vg)
1289 list_add_tail(&This->cctrl_active_vg->sub_cctrls, &ctrl->sub_cctrls_entry);
1290 else
1291 list_add_tail(&This->cctrls, &ctrl->entry);
1292
1294
1295 if(ppctrl) *ppctrl = ctrl;
1296
1297 This->cctrl_next_dlgid++;
1298 return S_OK;
1299}
1300
1301/**************************************************************************
1302 * Container functions.
1303 */
1304static UINT ctrl_container_resize(FileDialogImpl *This, UINT container_width)
1305{
1306 UINT container_height;
1307 UINT column_width;
1308 UINT nr_of_cols;
1309 UINT max_control_height, total_height = 0;
1310 UINT cur_col_pos, cur_row_pos;
1311 customctrl *ctrl;
1312 BOOL fits_height;
1313 UINT cspacing = MulDiv(90, This->dpi_x, USER_DEFAULT_SCREEN_DPI); /* Columns are spaced with 90px */
1314 UINT rspacing = MulDiv(4, This->dpi_y, USER_DEFAULT_SCREEN_DPI); /* Rows are spaced with 4 px. */
1315
1316 /* Given the new width of the container, this function determines the
1317 * needed height of the container and places the controls according to
1318 * the new layout. Returns the new height.
1319 */
1320
1321 TRACE("%p\n", This);
1322
1323 column_width = This->cctrl_width + cspacing;
1324 nr_of_cols = (container_width - This->cctrl_indent + cspacing) / column_width;
1325
1326 /* We don't need to do anything unless the number of visible columns has changed. */
1327 if(nr_of_cols == This->cctrls_cols)
1328 {
1329 RECT rc;
1330 GetWindowRect(This->cctrls_hwnd, &rc);
1331 return rc.bottom - rc.top;
1332 }
1333
1334 This->cctrls_cols = nr_of_cols;
1335
1336 /* Get the size of the tallest control, and the total size of
1337 * all the controls to figure out the number of slots we need.
1338 */
1339 max_control_height = 0;
1340 LIST_FOR_EACH_ENTRY(ctrl, &This->cctrls, customctrl, entry)
1341 {
1342 if(ctrl->cdcstate & CDCS_VISIBLE)
1343 {
1344 UINT control_height = ctrl_get_height(ctrl);
1345 max_control_height = max(max_control_height, control_height);
1346
1347 total_height += control_height + rspacing;
1348 }
1349 }
1350
1351 if(!total_height)
1352 return 0;
1353
1354 container_height = max(total_height / nr_of_cols, max_control_height + rspacing);
1355 TRACE("Guess: container_height: %d\n",container_height);
1356
1357 /* Incrementally increase container_height until all the controls
1358 * fit.
1359 */
1360 do {
1361 UINT columns_needed = 1;
1362 cur_row_pos = 0;
1363
1364 fits_height = TRUE;
1365 LIST_FOR_EACH_ENTRY(ctrl, &This->cctrls, customctrl, entry)
1366 {
1367 if(ctrl->cdcstate & CDCS_VISIBLE)
1368 {
1369 UINT control_height = ctrl_get_height(ctrl);
1370
1371 if(cur_row_pos + control_height > container_height)
1372 {
1373 if(++columns_needed > nr_of_cols)
1374 {
1375 container_height += 1;
1376 fits_height = FALSE;
1377 break;
1378 }
1379 cur_row_pos = 0;
1380 }
1381
1382 cur_row_pos += control_height + rspacing;
1383 }
1384 }
1385 } while(!fits_height);
1386
1387 TRACE("Final container height: %d\n", container_height);
1388
1389 /* Move the controls to their final destination
1390 */
1391 cur_col_pos = 0; cur_row_pos = 0;
1392 LIST_FOR_EACH_ENTRY(ctrl, &This->cctrls, customctrl, entry)
1393 {
1394 if(ctrl->cdcstate & CDCS_VISIBLE)
1395 {
1396 RECT rc;
1397 UINT control_height, control_indent;
1398 GetWindowRect(ctrl->wrapper_hwnd, &rc);
1399 control_height = rc.bottom - rc.top;
1400
1401 if(cur_row_pos + control_height > container_height)
1402 {
1403 cur_row_pos = 0;
1404 cur_col_pos += This->cctrl_width + cspacing;
1405 }
1406
1407
1408 if(ctrl->type == IDLG_CCTRL_VISUALGROUP)
1409 control_indent = 0;
1410 else
1411 control_indent = This->cctrl_indent;
1412
1413 SetWindowPos(ctrl->wrapper_hwnd, NULL, cur_col_pos + control_indent, cur_row_pos, 0, 0,
1415
1416 cur_row_pos += control_height + rspacing;
1417 }
1418 }
1419
1420 /* Sanity check */
1421 if(cur_row_pos + This->cctrl_width > container_width)
1422 ERR("-- Failed to place controls properly.\n");
1423
1424 return container_height;
1425}
1426
1427static void ctrl_set_font(customctrl *ctrl, HFONT font)
1428{
1429 customctrl *sub_ctrl;
1430 cctrl_item* item;
1431
1433
1434 LIST_FOR_EACH_ENTRY(sub_ctrl, &ctrl->sub_cctrls, customctrl, sub_cctrls_entry)
1435 {
1436 ctrl_set_font(sub_ctrl, font);
1437 }
1438
1439 if (ctrl->type == IDLG_CCTRL_RADIOBUTTONLIST)
1440 {
1441 LIST_FOR_EACH_ENTRY(item, &ctrl->sub_items, cctrl_item, entry)
1442 {
1444 }
1445 }
1446}
1447
1448static void ctrl_container_reparent(FileDialogImpl *This, HWND parent)
1449{
1450 LONG wndstyle;
1451
1452 if(parent)
1453 {
1454 customctrl *ctrl;
1455 HFONT font;
1456
1457 wndstyle = GetWindowLongW(This->cctrls_hwnd, GWL_STYLE);
1458 wndstyle &= ~(WS_POPUP);
1459 wndstyle |= WS_CHILD;
1460 SetWindowLongW(This->cctrls_hwnd, GWL_STYLE, wndstyle);
1461
1462 SetParent(This->cctrls_hwnd, parent);
1463 ShowWindow(This->cctrls_hwnd, TRUE);
1464
1465 /* Set the fonts to match the dialog font. */
1466 font = (HFONT)SendMessageW(parent, WM_GETFONT, 0, 0);
1467 if(!font)
1468 ERR("Failed to get font handle from dialog.\n");
1469
1470 LIST_FOR_EACH_ENTRY(ctrl, &This->cctrls, customctrl, entry)
1471 {
1472 if(font) ctrl_set_font(ctrl, font);
1473 customctrl_resize(This, ctrl);
1474 }
1475 }
1476 else
1477 {
1478 ShowWindow(This->cctrls_hwnd, FALSE);
1479
1480 wndstyle = GetWindowLongW(This->cctrls_hwnd, GWL_STYLE);
1481 wndstyle &= ~(WS_CHILD);
1482 wndstyle |= WS_POPUP;
1483 SetWindowLongW(This->cctrls_hwnd, GWL_STYLE, wndstyle);
1484
1485 SetParent(This->cctrls_hwnd, NULL);
1486 }
1487}
1488
1489static LRESULT ctrl_container_on_create(HWND hwnd, CREATESTRUCTW *crs)
1490{
1491 FileDialogImpl *This = crs->lpCreateParams;
1492 TRACE("%p\n", This);
1493
1495 return TRUE;
1496}
1497
1498static LRESULT ctrl_container_on_wm_destroy(FileDialogImpl *This)
1499{
1500 customctrl *cur1, *cur2;
1501 TRACE("%p\n", This);
1502
1503 LIST_FOR_EACH_ENTRY_SAFE(cur1, cur2, &This->cctrls, customctrl, entry)
1504 {
1505 list_remove(&cur1->entry);
1506 ctrl_free(cur1);
1507 }
1508
1509 return TRUE;
1510}
1511
1512static LRESULT CALLBACK ctrl_container_wndproc(HWND hwnd, UINT umessage, WPARAM wparam, LPARAM lparam)
1513{
1514 FileDialogImpl *This = (FileDialogImpl*)GetWindowLongPtrW(hwnd, GWLP_USERDATA);
1515
1516 switch(umessage)
1517 {
1518 case WM_NCCREATE: return ctrl_container_on_create(hwnd, (CREATESTRUCTW*)lparam);
1519 case WM_DESTROY: return ctrl_container_on_wm_destroy(This);
1520 default: return DefWindowProcW(hwnd, umessage, wparam, lparam);
1521 }
1522
1523 return FALSE;
1524}
1525
1526static void radiobuttonlist_set_selected_item(FileDialogImpl *This, customctrl *ctrl, cctrl_item *item)
1527{
1528 cctrl_item *cursor;
1529
1530 LIST_FOR_EACH_ENTRY(cursor, &ctrl->sub_items, cctrl_item, entry)
1531 {
1533 }
1534}
1535
1536static LRESULT radiobuttonlist_on_bn_clicked(FileDialogImpl *This, HWND hwnd, HWND child)
1537{
1539 customctrl *ctrl;
1540 cctrl_item *item;
1541 BOOL found_item=FALSE;
1542
1543 ctrl = get_cctrl_from_dlgid(This, ctrl_id);
1544
1545 if (!ctrl)
1546 {
1547 ERR("Can't find this control\n");
1548 return 0;
1549 }
1550
1551 LIST_FOR_EACH_ENTRY(item, &ctrl->sub_items, cctrl_item, entry)
1552 {
1553 if (item->hwnd == child)
1554 {
1555 found_item = TRUE;
1556 break;
1557 }
1558 }
1559
1560 if (!found_item)
1561 {
1562 ERR("Can't find control item\n");
1563 return 0;
1564 }
1565
1566 radiobuttonlist_set_selected_item(This, ctrl, item);
1567
1568 cctrl_event_OnItemSelected(This, ctrl->id, item->id);
1569
1570 return 0;
1571}
1572
1573static LRESULT radiobuttonlist_on_wm_command(FileDialogImpl *This, HWND hwnd, WPARAM wparam, LPARAM lparam)
1574{
1575 switch(HIWORD(wparam))
1576 {
1577 case BN_CLICKED: return radiobuttonlist_on_bn_clicked(This, hwnd, (HWND)lparam);
1578 }
1579
1580 return FALSE;
1581}
1582
1583static LRESULT CALLBACK radiobuttonlist_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
1584{
1585 FileDialogImpl *This = (FileDialogImpl*)GetWindowLongPtrW(hwnd, GWLP_USERDATA);
1586
1587 switch(message)
1588 {
1589 case WM_COMMAND: return radiobuttonlist_on_wm_command(This, hwnd, wparam, lparam);
1590 }
1591
1593}
1594
1595static HRESULT init_custom_controls(FileDialogImpl *This)
1596{
1597 WNDCLASSW wc;
1598 HDC hdc;
1599 static const WCHAR ctrl_container_classname[] = L"idlg_container_pane";
1600
1602
1603 if( !GetClassInfoW(COMDLG32_hInstance, ctrl_container_classname, &wc) )
1604 {
1606 wc.lpfnWndProc = ctrl_container_wndproc;
1607 wc.cbClsExtra = 0;
1608 wc.cbWndExtra = 0;
1610 wc.hIcon = 0;
1612 wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
1613 wc.lpszMenuName = NULL;
1614 wc.lpszClassName = ctrl_container_classname;
1615
1616 if(!RegisterClassW(&wc)) return E_FAIL;
1617 }
1618
1619 This->cctrls_hwnd = CreateWindowExW(0, ctrl_container_classname, NULL,
1621 0, 0, 0, 0, NULL, 0,
1623 if(!This->cctrls_hwnd)
1624 return E_FAIL;
1625
1626 hdc = GetDC(This->cctrls_hwnd);
1627 This->dpi_x = GetDeviceCaps(hdc, LOGPIXELSX);
1628 This->dpi_y = GetDeviceCaps(hdc, LOGPIXELSY);
1629 ReleaseDC(This->cctrls_hwnd, hdc);
1630
1631 This->cctrl_width = MulDiv(160, This->dpi_x, USER_DEFAULT_SCREEN_DPI); /* Controls have a fixed width */
1632 This->cctrl_indent = MulDiv(100, This->dpi_x, USER_DEFAULT_SCREEN_DPI);
1633 This->cctrl_def_height = MulDiv(23, This->dpi_y, USER_DEFAULT_SCREEN_DPI);
1634 This->cctrls_cols = 0;
1635
1636 This->cctrl_next_dlgid = 0x2000;
1637 list_init(&This->cctrls);
1638 This->cctrl_active_vg = NULL;
1639
1640 SetWindowLongW(This->cctrls_hwnd, GWL_STYLE, WS_TABSTOP);
1641
1642 /* Register class for */
1643 if (!GetClassInfoW(COMDLG32_hInstance, L"FloatNotifySink", &wc) ||
1645 {
1647 wc.lpfnWndProc = notifysink_proc;
1648 wc.cbClsExtra = 0;
1649 wc.cbWndExtra = 0;
1651 wc.hIcon = 0;
1653 wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
1654 wc.lpszMenuName = NULL;
1655 wc.lpszClassName = L"FloatNotifySink";
1656
1657 if (!RegisterClassW(&wc))
1658 ERR("Failed to register FloatNotifySink window class.\n");
1659 }
1660
1661 if (!GetClassInfoW(COMDLG32_hInstance, L"RadioButtonList", &wc) ||
1663 {
1665 wc.lpfnWndProc = radiobuttonlist_proc;
1666 wc.cbClsExtra = 0;
1667 wc.cbWndExtra = 0;
1669 wc.hIcon = 0;
1671 wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
1672 wc.lpszMenuName = NULL;
1673 wc.lpszClassName = L"RadioButtonList";
1674
1675 if (!RegisterClassW(&wc))
1676 ERR("Failed to register RadioButtonList window class.\n");
1677 }
1678
1679 return S_OK;
1680}
1681
1682/**************************************************************************
1683 * Window related functions.
1684 */
1685static BOOL update_open_dropdown(FileDialogImpl *This)
1686{
1687 /* Show or hide the open dropdown button as appropriate */
1688 BOOL show=FALSE, showing;
1689 HWND open_hwnd, dropdown_hwnd;
1690
1691 if (This->hmenu_opendropdown)
1692 {
1693 INT num_visible_items=0;
1694 cctrl_item* item;
1695
1696 LIST_FOR_EACH_ENTRY(item, &This->cctrl_opendropdown.sub_items, cctrl_item, entry)
1697 {
1698 if (item->cdcstate & CDCS_VISIBLE)
1699 {
1700 num_visible_items++;
1701 if (num_visible_items >= 2)
1702 {
1703 show = TRUE;
1704 break;
1705 }
1706 }
1707 }
1708 }
1709
1710 open_hwnd = GetDlgItem(This->dlg_hwnd, IDOK);
1711 dropdown_hwnd = GetDlgItem(This->dlg_hwnd, psh1);
1712
1713 showing = (GetWindowLongPtrW(dropdown_hwnd, GWL_STYLE) & WS_VISIBLE) != 0;
1714
1715 if (showing != show)
1716 {
1717 RECT open_rc, dropdown_rc;
1718
1719 GetWindowRect(open_hwnd, &open_rc);
1720 GetWindowRect(dropdown_hwnd, &dropdown_rc);
1721
1722 if (show)
1723 {
1724 ShowWindow(dropdown_hwnd, SW_SHOW);
1725
1726 SetWindowPos(open_hwnd, NULL, 0, 0,
1727 (open_rc.right - open_rc.left) - (dropdown_rc.right - dropdown_rc.left),
1728 open_rc.bottom - open_rc.top, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
1729 }
1730 else
1731 {
1732 ShowWindow(dropdown_hwnd, SW_HIDE);
1733
1734 SetWindowPos(open_hwnd, NULL, 0, 0,
1735 (open_rc.right - open_rc.left) + (dropdown_rc.right - dropdown_rc.left),
1736 open_rc.bottom - open_rc.top, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
1737 }
1738 }
1739
1740 return show;
1741}
1742
1743static void update_layout(FileDialogImpl *This)
1744{
1745 HDWP hdwp;
1746 HWND hwnd;
1747 RECT dialog_rc;
1748 RECT cancel_rc, dropdown_rc, open_rc;
1749 RECT filetype_rc, filename_rc, filenamelabel_rc;
1750 RECT toolbar_rc, ebrowser_rc, customctrls_rc;
1751 static const UINT vspacing = 4, hspacing = 4;
1752 static const UINT min_width = 320, min_height = 200;
1753 BOOL show_dropdown;
1754
1755 if (!GetClientRect(This->dlg_hwnd, &dialog_rc))
1756 {
1757 TRACE("Invalid dialog window, not updating layout\n");
1758 return;
1759 }
1760
1761 if(dialog_rc.right < min_width || dialog_rc.bottom < min_height)
1762 {
1763 TRACE("Dialog size (%ld, %ld) too small, not updating layout\n", dialog_rc.right, dialog_rc.bottom);
1764 return;
1765 }
1766
1767 /****
1768 * Calculate the size of the dialog and all the parts.
1769 */
1770
1771 /* Cancel button */
1772 hwnd = GetDlgItem(This->dlg_hwnd, IDCANCEL);
1773 if(hwnd)
1774 {
1775 int cancel_width, cancel_height;
1776 GetWindowRect(hwnd, &cancel_rc);
1777 cancel_width = cancel_rc.right - cancel_rc.left;
1778 cancel_height = cancel_rc.bottom - cancel_rc.top;
1779
1780 cancel_rc.left = dialog_rc.right - cancel_width - hspacing;
1781 cancel_rc.top = dialog_rc.bottom - cancel_height - vspacing;
1782 cancel_rc.right = cancel_rc.left + cancel_width;
1783 cancel_rc.bottom = cancel_rc.top + cancel_height;
1784 }
1785
1786 /* Open/Save dropdown */
1787 show_dropdown = update_open_dropdown(This);
1788
1789 if(show_dropdown)
1790 {
1791 int dropdown_width, dropdown_height;
1792 hwnd = GetDlgItem(This->dlg_hwnd, psh1);
1793
1794 GetWindowRect(hwnd, &dropdown_rc);
1795 dropdown_width = dropdown_rc.right - dropdown_rc.left;
1796 dropdown_height = dropdown_rc.bottom - dropdown_rc.top;
1797
1798 dropdown_rc.left = cancel_rc.left - dropdown_width - hspacing;
1799 dropdown_rc.top = cancel_rc.top;
1800 dropdown_rc.right = dropdown_rc.left + dropdown_width;
1801 dropdown_rc.bottom = dropdown_rc.top + dropdown_height;
1802 }
1803 else
1804 {
1805 dropdown_rc.left = dropdown_rc.right = cancel_rc.left - hspacing;
1806 dropdown_rc.top = cancel_rc.top;
1807 dropdown_rc.bottom = cancel_rc.bottom;
1808 }
1809
1810 /* Open/Save button */
1811 hwnd = GetDlgItem(This->dlg_hwnd, IDOK);
1812 if(hwnd)
1813 {
1814 int open_width, open_height;
1815 GetWindowRect(hwnd, &open_rc);
1816 open_width = open_rc.right - open_rc.left;
1817 open_height = open_rc.bottom - open_rc.top;
1818
1819 open_rc.left = dropdown_rc.left - open_width;
1820 open_rc.top = dropdown_rc.top;
1821 open_rc.right = open_rc.left + open_width;
1822 open_rc.bottom = open_rc.top + open_height;
1823 }
1824
1825 /* The filetype combobox. */
1826 hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILETYPE);
1827 if(hwnd)
1828 {
1829 int filetype_width, filetype_height;
1830 GetWindowRect(hwnd, &filetype_rc);
1831
1832 filetype_width = filetype_rc.right - filetype_rc.left;
1833 filetype_height = filetype_rc.bottom - filetype_rc.top;
1834
1835 filetype_rc.right = cancel_rc.right;
1836
1837 filetype_rc.left = filetype_rc.right - filetype_width;
1838 filetype_rc.top = cancel_rc.top - filetype_height - vspacing;
1839 filetype_rc.bottom = filetype_rc.top + filetype_height;
1840
1841 if(!This->filterspec_count)
1842 filetype_rc.left = filetype_rc.right;
1843 }
1844
1845 /* Filename label. */
1846 hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILENAMESTATIC);
1847 if(hwnd)
1848 {
1849 int filetypelabel_width, filetypelabel_height;
1850 GetWindowRect(hwnd, &filenamelabel_rc);
1851
1852 filetypelabel_width = filenamelabel_rc.right - filenamelabel_rc.left;
1853 filetypelabel_height = filenamelabel_rc.bottom - filenamelabel_rc.top;
1854
1855 filenamelabel_rc.left = 160; /* FIXME */
1856 filenamelabel_rc.top = filetype_rc.top;
1857 filenamelabel_rc.right = filenamelabel_rc.left + filetypelabel_width;
1858 filenamelabel_rc.bottom = filenamelabel_rc.top + filetypelabel_height;
1859 }
1860
1861 /* Filename edit box. */
1862 hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILENAME);
1863 if(hwnd)
1864 {
1865 int filename_width, filename_height;
1866 GetWindowRect(hwnd, &filename_rc);
1867
1868 filename_width = filetype_rc.left - filenamelabel_rc.right - hspacing*2;
1869 filename_height = filename_rc.bottom - filename_rc.top;
1870
1871 filename_rc.left = filenamelabel_rc.right + hspacing;
1872 filename_rc.top = filetype_rc.top;
1873 filename_rc.right = filename_rc.left + filename_width;
1874 filename_rc.bottom = filename_rc.top + filename_height;
1875 }
1876
1877 hwnd = GetDlgItem(This->dlg_hwnd, IDC_NAV_TOOLBAR);
1878 if(hwnd)
1879 {
1880 GetWindowRect(hwnd, &toolbar_rc);
1881 MapWindowPoints(NULL, This->dlg_hwnd, (POINT*)&toolbar_rc, 2);
1882 }
1883
1884 /* The custom controls */
1885 customctrls_rc.left = dialog_rc.left + hspacing;
1886 customctrls_rc.right = dialog_rc.right - hspacing;
1887 customctrls_rc.bottom = filename_rc.top - vspacing;
1888 customctrls_rc.top = customctrls_rc.bottom -
1889 ctrl_container_resize(This, customctrls_rc.right - customctrls_rc.left);
1890
1891 /* The ExplorerBrowser control. */
1892 ebrowser_rc.left = dialog_rc.left + hspacing;
1893 ebrowser_rc.top = toolbar_rc.bottom + vspacing;
1894 ebrowser_rc.right = dialog_rc.right - hspacing;
1895 ebrowser_rc.bottom = customctrls_rc.top - vspacing;
1896
1897 /****
1898 * Move everything to the right place.
1899 */
1900
1901 /* FIXME: The Save Dialog uses a slightly different layout. */
1902 hdwp = BeginDeferWindowPos(7);
1903
1904 if(hdwp && This->peb)
1905 IExplorerBrowser_SetRect(This->peb, &hdwp, ebrowser_rc);
1906
1907 if(hdwp && This->cctrls_hwnd)
1908 DeferWindowPos(hdwp, This->cctrls_hwnd, NULL,
1909 customctrls_rc.left, customctrls_rc.top,
1910 customctrls_rc.right - customctrls_rc.left, customctrls_rc.bottom - customctrls_rc.top,
1912
1913 /* The default controls */
1914 if(hdwp && (hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILETYPE)) )
1915 DeferWindowPos(hdwp, hwnd, NULL, filetype_rc.left, filetype_rc.top, 0, 0,
1917
1918 if(hdwp && (hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILENAME)) )
1919 DeferWindowPos(hdwp, hwnd, NULL, filename_rc.left, filename_rc.top,
1920 filename_rc.right - filename_rc.left, filename_rc.bottom - filename_rc.top,
1922
1923 if(hdwp && (hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILENAMESTATIC)) )
1924 DeferWindowPos(hdwp, hwnd, NULL, filenamelabel_rc.left, filenamelabel_rc.top, 0, 0,
1926
1927 if(hdwp && (hwnd = GetDlgItem(This->dlg_hwnd, IDOK)) )
1928 DeferWindowPos(hdwp, hwnd, NULL, open_rc.left, open_rc.top, 0, 0,
1930
1931 if(hdwp && This->hmenu_opendropdown && (hwnd = GetDlgItem(This->dlg_hwnd, psh1)))
1932 DeferWindowPos(hdwp, hwnd, NULL, dropdown_rc.left, dropdown_rc.top, 0, 0,
1934
1935 if(hdwp && (hwnd = GetDlgItem(This->dlg_hwnd, IDCANCEL)) )
1936 DeferWindowPos(hdwp, hwnd, NULL, cancel_rc.left, cancel_rc.top, 0, 0,
1938
1939 if(hdwp)
1940 EndDeferWindowPos(hdwp);
1941 else
1942 ERR("Failed to position dialog controls.\n");
1943
1944 return;
1945}
1946
1947static HRESULT init_explorerbrowser(FileDialogImpl *This)
1948{
1949 IShellItem *psi_folder;
1951 FOLDERSETTINGS fos;
1952 RECT rc = {0};
1953 HRESULT hr;
1954
1955 /* Create ExplorerBrowser instance */
1957
1958 hr = CoCreateInstance(&CLSID_ExplorerBrowser, NULL, CLSCTX_INPROC_SERVER,
1959 &IID_IExplorerBrowser, (void**)&This->peb);
1960 if(FAILED(hr))
1961 {
1962 ERR("Failed to instantiate ExplorerBrowser control.\n");
1963 return hr;
1964 }
1965
1966 IExplorerBrowser_SetOptions(This->peb, EBO_SHOWFRAMES | EBO_NOBORDER);
1967
1968 hr = IExplorerBrowser_Initialize(This->peb, This->dlg_hwnd, &rc, NULL);
1969 if(FAILED(hr))
1970 {
1971 ERR("Failed to initialize the ExplorerBrowser control.\n");
1972 IExplorerBrowser_Release(This->peb);
1973 This->peb = NULL;
1974 return hr;
1975 }
1976 hr = IExplorerBrowser_Advise(This->peb, &This->IExplorerBrowserEvents_iface, &This->ebevents_cookie);
1977 if(FAILED(hr))
1978 ERR("Advise (ExplorerBrowser) failed.\n");
1979
1980 /* Get previous options? */
1981 fos.ViewMode = fos.fFlags = 0;
1982 if(!(This->options & FOS_ALLOWMULTISELECT))
1983 fos.fFlags |= FWF_SINGLESEL;
1984
1985 IExplorerBrowser_SetFolderSettings(This->peb, &fos);
1986
1987 hr = IExplorerBrowser_QueryInterface(This->peb, &IID_IObjectWithSite, (void**)&client);
1988 if (hr == S_OK)
1989 {
1990 hr = IObjectWithSite_SetSite(client, (IUnknown*)&This->IFileDialog2_iface);
1991 IObjectWithSite_Release(client);
1992 if(FAILED(hr))
1993 ERR("SetSite failed, 0x%08lx\n", hr);
1994 }
1995
1996 /* Browse somewhere */
1997 psi_folder = This->psi_setfolder ? This->psi_setfolder : This->psi_defaultfolder;
1998 IExplorerBrowser_BrowseToObject(This->peb, (IUnknown*)psi_folder, SBSP_DEFBROWSER);
1999
2000 return S_OK;
2001}
2002
2003static void init_toolbar(FileDialogImpl *This, HWND hwnd)
2004{
2005 HWND htoolbar;
2006 TBADDBITMAP tbab;
2007 TBBUTTON button[3];
2008 int height;
2009 int navUpImgIndex;
2010
2012 0, 0, 0, 0,
2013 hwnd, (HMENU)IDC_NAV_TOOLBAR, NULL, NULL);
2014
2015 tbab.hInst = HINST_COMMCTRL;
2017 SendMessageW(htoolbar, TB_ADDBITMAP, 0, (LPARAM)&tbab);
2019 navUpImgIndex = SendMessageW(htoolbar, TB_ADDBITMAP, 0, (LPARAM)&tbab);
2020 navUpImgIndex += VIEW_PARENTFOLDER;
2021
2022 button[0].iBitmap = HIST_BACK;
2023 button[0].idCommand = IDC_NAVBACK;
2024 button[0].fsState = TBSTATE_ENABLED;
2025 button[0].fsStyle = BTNS_BUTTON;
2026 button[0].dwData = 0;
2027 button[0].iString = 0;
2028
2029 button[1].iBitmap = HIST_FORWARD;
2030 button[1].idCommand = IDC_NAVFORWARD;
2031 button[1].fsState = TBSTATE_ENABLED;
2032 button[1].fsStyle = BTNS_BUTTON;
2033 button[1].dwData = 0;
2034 button[1].iString = 0;
2035
2036 button[2].iBitmap = navUpImgIndex;
2037 button[2].idCommand = IDC_NAVUP;
2038 button[2].fsState = TBSTATE_ENABLED;
2039 button[2].fsStyle = BTNS_BUTTON;
2040 button[2].dwData = 0;
2041 button[2].iString = 0;
2042
2043 SendMessageW(htoolbar, TB_ADDBUTTONSW, 3, (LPARAM)button);
2046 SendMessageW(htoolbar, TB_AUTOSIZE, 0, 0);
2047}
2048
2049static void update_control_text(FileDialogImpl *This)
2050{
2051 HWND hitem;
2052 LPCWSTR custom_okbutton;
2053 cctrl_item* item;
2054 UINT min_width = MulDiv(50, This->dpi_x, USER_DEFAULT_SCREEN_DPI);
2055 UINT max_width = MulDiv(250, This->dpi_x, USER_DEFAULT_SCREEN_DPI);
2056
2057 if(This->custom_title)
2058 SetWindowTextW(This->dlg_hwnd, This->custom_title);
2059
2060 if(This->hmenu_opendropdown && (item = get_first_item(&This->cctrl_opendropdown)))
2061 custom_okbutton = item->label;
2062 else
2063 custom_okbutton = This->custom_okbutton;
2064
2065 if(custom_okbutton &&
2066 (hitem = GetDlgItem(This->dlg_hwnd, IDOK)))
2067 {
2068 SetWindowTextW(hitem, custom_okbutton);
2069 ctrl_resize(hitem, min_width, max_width, FALSE);
2070 }
2071
2072 if(This->custom_cancelbutton &&
2073 (hitem = GetDlgItem(This->dlg_hwnd, IDCANCEL)))
2074 {
2075 SetWindowTextW(hitem, This->custom_cancelbutton);
2076 ctrl_resize(hitem, min_width, max_width, FALSE);
2077 }
2078
2079 if(This->custom_filenamelabel &&
2080 (hitem = GetDlgItem(This->dlg_hwnd, IDC_FILENAMESTATIC)))
2081 {
2082 SetWindowTextW(hitem, This->custom_filenamelabel);
2083 ctrl_resize(hitem, min_width, max_width, FALSE);
2084 }
2085}
2086
2087static LRESULT CALLBACK dropdown_subclass_proc(HWND hwnd, UINT umessage, WPARAM wparam, LPARAM lparam)
2088{
2089 if (umessage == WM_LBUTTONDOWN)
2090 {
2091 FileDialogImpl *This = GetPropW(hwnd, L"itemdlg_This");
2092
2094 show_opendropdown(This);
2096
2097 return 0;
2098 }
2099
2100 return CallWindowProcW((WNDPROC)GetPropW(hwnd, L"itemdlg_oldwndproc"), hwnd, umessage, wparam, lparam);
2101}
2102
2103static LRESULT on_wm_initdialog(HWND hwnd, LPARAM lParam)
2104{
2105 FileDialogImpl *This = (FileDialogImpl*)lParam;
2106 HWND hitem;
2107
2108 TRACE("(%p, %p)\n", This, hwnd);
2109
2111 This->dlg_hwnd = hwnd;
2112
2113 hitem = GetDlgItem(This->dlg_hwnd, pshHelp);
2114 if(hitem) ShowWindow(hitem, SW_HIDE);
2115
2116 hitem = GetDlgItem(This->dlg_hwnd, IDC_FILETYPESTATIC);
2117 if(hitem) ShowWindow(hitem, SW_HIDE);
2118
2119 /* Fill filetypes combobox, or hide it. */
2120 hitem = GetDlgItem(This->dlg_hwnd, IDC_FILETYPE);
2121 if(This->filterspec_count)
2122 {
2123 HDC hdc;
2124 HFONT font;
2125 SIZE size;
2126 UINT i, maxwidth = 0;
2127
2128 hdc = GetDC(hitem);
2129 font = (HFONT)SendMessageW(hitem, WM_GETFONT, 0, 0);
2131
2132 for(i = 0; i < This->filterspec_count; i++)
2133 {
2134 SendMessageW(hitem, CB_ADDSTRING, 0, (LPARAM)This->filterspecs[i].pszName);
2135
2136 if(GetTextExtentPoint32W(hdc, This->filterspecs[i].pszName, lstrlenW(This->filterspecs[i].pszName), &size))
2137 maxwidth = max(maxwidth, size.cx);
2138 }
2139 ReleaseDC(hitem, hdc);
2140
2141 if(maxwidth > 0)
2142 {
2143 maxwidth += GetSystemMetrics(SM_CXVSCROLL) + 4;
2144 SendMessageW(hitem, CB_SETDROPPEDWIDTH, (WPARAM)maxwidth, 0);
2145 }
2146 else
2147 ERR("Failed to calculate width of filetype dropdown\n");
2148
2149 SendMessageW(hitem, CB_SETCURSEL, This->filetypeindex, 0);
2150 }
2151 else
2152 ShowWindow(hitem, SW_HIDE);
2153
2154 if(This->set_filename &&
2155 (hitem = GetDlgItem(This->dlg_hwnd, IDC_FILENAME)) )
2156 SendMessageW(hitem, WM_SETTEXT, 0, (LPARAM)This->set_filename);
2157
2158 if(This->hmenu_opendropdown)
2159 {
2160 HWND dropdown_hwnd;
2161 LOGFONTW lfw, lfw_marlett;
2162 HFONT dialog_font;
2163
2164 dropdown_hwnd = GetDlgItem(This->dlg_hwnd, psh1);
2165
2166 /* Change dropdown button font to Marlett */
2167 dialog_font = (HFONT)SendMessageW(dropdown_hwnd, WM_GETFONT, 0, 0);
2168
2169 GetObjectW(dialog_font, sizeof(lfw), &lfw);
2170
2171 memset(&lfw_marlett, 0, sizeof(lfw_marlett));
2172 lstrcpyW(lfw_marlett.lfFaceName, L"Marlett");
2173 lfw_marlett.lfHeight = lfw.lfHeight;
2174 lfw_marlett.lfCharSet = SYMBOL_CHARSET;
2175
2176 This->hfont_opendropdown = CreateFontIndirectW(&lfw_marlett);
2177
2178 SendMessageW(dropdown_hwnd, WM_SETFONT, (LPARAM)This->hfont_opendropdown, 0);
2179
2180 /* Subclass button so we can handle LBUTTONDOWN */
2181 SetPropW(dropdown_hwnd, L"itemdlg_This", This);
2182 SetPropW(dropdown_hwnd, L"itemdlg_oldwndproc",
2183 (HANDLE)SetWindowLongPtrW(dropdown_hwnd, GWLP_WNDPROC, (LONG_PTR)dropdown_subclass_proc));
2184 }
2185
2186 ctrl_container_reparent(This, This->dlg_hwnd);
2187 init_explorerbrowser(This);
2188 init_toolbar(This, hwnd);
2189 update_control_text(This);
2190 update_layout(This);
2191
2192 if(This->filterspec_count)
2193 events_OnTypeChange(This);
2194
2195 if ((hitem = GetDlgItem(This->dlg_hwnd, IDC_FILENAME)))
2196 SetFocus(hitem);
2197
2198 return FALSE;
2199}
2200
2201static LRESULT on_wm_size(FileDialogImpl *This)
2202{
2203 update_layout(This);
2204 return FALSE;
2205}
2206
2207static LRESULT on_wm_getminmaxinfo(FileDialogImpl *This, LPARAM lparam)
2208{
2209 MINMAXINFO *mmi = (MINMAXINFO*)lparam;
2210 TRACE("%p (%p)\n", This, mmi);
2211
2212 /* FIXME */
2213 mmi->ptMinTrackSize.x = 640;
2214 mmi->ptMinTrackSize.y = 480;
2215
2216 return FALSE;
2217}
2218
2219static LRESULT on_wm_destroy(FileDialogImpl *This)
2220{
2221 TRACE("%p\n", This);
2222
2223 if(This->peb)
2224 {
2225 IExplorerBrowser_Destroy(This->peb);
2226 IExplorerBrowser_Release(This->peb);
2227 This->peb = NULL;
2228 }
2229
2230 ctrl_container_reparent(This, NULL);
2231 This->dlg_hwnd = NULL;
2232
2233 DeleteObject(This->hfont_opendropdown);
2234 This->hfont_opendropdown = NULL;
2235
2236 return TRUE;
2237}
2238
2239static LRESULT on_idok(FileDialogImpl *This)
2240{
2241 TRACE("%p\n", This);
2242
2243 if(SUCCEEDED(on_default_action(This)))
2244 EndDialog(This->dlg_hwnd, S_OK);
2245
2246 return FALSE;
2247}
2248
2249static LRESULT on_idcancel(FileDialogImpl *This)
2250{
2251 TRACE("%p\n", This);
2252
2254
2255 return FALSE;
2256}
2257
2258static LRESULT on_command_opendropdown(FileDialogImpl *This, WPARAM wparam, LPARAM lparam)
2259{
2260 if(HIWORD(wparam) == BN_CLICKED)
2261 {
2262 HWND hwnd = (HWND)lparam;
2264 show_opendropdown(This);
2266 }
2267
2268 return FALSE;
2269}
2270
2271static LRESULT on_browse_back(FileDialogImpl *This)
2272{
2273 TRACE("%p\n", This);
2274 IExplorerBrowser_BrowseToIDList(This->peb, NULL, SBSP_NAVIGATEBACK);
2275 return FALSE;
2276}
2277
2278static LRESULT on_browse_forward(FileDialogImpl *This)
2279{
2280 TRACE("%p\n", This);
2281 IExplorerBrowser_BrowseToIDList(This->peb, NULL, SBSP_NAVIGATEFORWARD);
2282 return FALSE;
2283}
2284
2285static LRESULT on_command_filetype(FileDialogImpl *This, WPARAM wparam, LPARAM lparam)
2286{
2288 {
2290 UINT prev_index = This->filetypeindex;
2291
2292 This->filetypeindex = SendMessageW((HWND)lparam, CB_GETCURSEL, 0, 0);
2293 TRACE("File type selection changed to %d.\n", This->filetypeindex);
2294
2295 if(prev_index == This->filetypeindex)
2296 return FALSE;
2297
2298 set_current_filter(This, This->filterspecs[This->filetypeindex].pszSpec);
2299
2301
2302 if(filename && wcspbrk(filename, L"*?") != NULL && This->filterspecs[This->filetypeindex].pszSpec[0])
2303 {
2304 set_file_name(This, L"");
2305 }
2306 else if(filename && This->dlg_type == ITEMDLG_TYPE_SAVE)
2307 {
2308 WCHAR buf[MAX_PATH], extbuf[MAX_PATH], *ext;
2309
2310 ext = get_first_ext_from_spec(extbuf, This->filterspecs[This->filetypeindex].pszSpec);
2311 if(ext)
2312 {
2314
2315 if(PathMatchSpecW(buf, This->filterspecs[prev_index].pszSpec))
2317
2318 lstrcatW(buf, ext);
2319 set_file_name(This, buf);
2320 }
2321 }
2322
2324
2325 /* The documentation claims that OnTypeChange is called only
2326 * when the dialog is opened, but this is obviously not the
2327 * case. */
2328 events_OnTypeChange(This);
2329 }
2330
2331 return FALSE;
2332}
2333
2334static LRESULT on_browse_up(FileDialogImpl *This)
2335{
2336 TRACE("%p\n", This);
2337 IExplorerBrowser_BrowseToIDList(This->peb, NULL, SBSP_PARENT);
2338 return FALSE;
2339}
2340
2341static LRESULT on_wm_command(FileDialogImpl *This, WPARAM wparam, LPARAM lparam)
2342{
2343 switch(LOWORD(wparam))
2344 {
2345 case IDOK: return on_idok(This);
2346 case IDCANCEL: return on_idcancel(This);
2347 case psh1: return on_command_opendropdown(This, wparam, lparam);
2348 case IDC_NAVBACK: return on_browse_back(This);
2349 case IDC_NAVFORWARD: return on_browse_forward(This);
2350 case IDC_FILETYPE: return on_command_filetype(This, wparam, lparam);
2351 case IDC_NAVUP: return on_browse_up(This);
2352 default: TRACE("Unknown command.\n");
2353 }
2354 return FALSE;
2355}
2356
2357static INT_PTR CALLBACK itemdlg_dlgproc(HWND hwnd, UINT umessage, WPARAM wparam, LPARAM lparam)
2358{
2359 FileDialogImpl *This = (FileDialogImpl*)GetWindowLongPtrW(hwnd, GWLP_USERDATA);
2360
2361 switch(umessage)
2362 {
2363 case WM_INITDIALOG: return on_wm_initdialog(hwnd, lparam);
2364 case WM_COMMAND: return on_wm_command(This, wparam, lparam);
2365 case WM_SIZE: return on_wm_size(This);
2366 case WM_GETMINMAXINFO: return on_wm_getminmaxinfo(This, lparam);
2367 case WM_DESTROY: return on_wm_destroy(This);
2368 }
2369
2370 return FALSE;
2371}
2372
2373static HRESULT create_dialog(FileDialogImpl *This, HWND parent)
2374{
2375 ULONG_PTR ctx_cookie = 0;
2376 INT_PTR res;
2377
2378 if (This->dlg_hwnd)
2379 return E_UNEXPECTED;
2380
2381 if (!GetCurrentActCtx(&This->user_actctx))
2382 This->user_actctx = INVALID_HANDLE_VALUE;
2383
2385 ActivateActCtx(COMDLG32_hActCtx, &ctx_cookie);
2386
2387 SetLastError(0);
2390 parent, itemdlg_dlgproc, (LPARAM)This);
2391 This->dlg_hwnd = NULL;
2392
2394 DeactivateActCtx(0, ctx_cookie);
2395
2396 if (This->user_actctx != INVALID_HANDLE_VALUE)
2397 {
2398 ReleaseActCtx(This->user_actctx);
2399 This->user_actctx = INVALID_HANDLE_VALUE;
2400 }
2401
2402 if(res == -1)
2403 {
2404 ERR("Failed to show dialog (LastError: %ld)\n", GetLastError());
2405 return E_FAIL;
2406 }
2407
2408 TRACE("Returning 0x%08lx\n", (HRESULT)res);
2409 return (HRESULT)res;
2410}
2411
2412/**************************************************************************
2413 * IFileDialog implementation
2414 */
2415static inline FileDialogImpl *impl_from_IFileDialog2(IFileDialog2 *iface)
2416{
2417 return CONTAINING_RECORD(iface, FileDialogImpl, IFileDialog2_iface);
2418}
2419
2420static HRESULT WINAPI IFileDialog2_fnQueryInterface(IFileDialog2 *iface,
2421 REFIID riid,
2422 void **ppvObject)
2423{
2424 FileDialogImpl *This = impl_from_IFileDialog2(iface);
2425 TRACE("%p (%s, %p)\n", This, debugstr_guid(riid), ppvObject);
2426
2427 *ppvObject = NULL;
2429 IsEqualGUID(riid, &IID_IFileDialog) ||
2430 IsEqualGUID(riid, &IID_IFileDialog2))
2431 {
2432 *ppvObject = iface;
2433 }
2434 else if(IsEqualGUID(riid, &IID_IFileOpenDialog) && This->dlg_type == ITEMDLG_TYPE_OPEN)
2435 {
2436 *ppvObject = &This->u.IFileOpenDialog_iface;
2437 }
2438 else if(IsEqualGUID(riid, &IID_IFileSaveDialog) && This->dlg_type == ITEMDLG_TYPE_SAVE)
2439 {
2440 *ppvObject = &This->u.IFileSaveDialog_iface;
2441 }
2442 else if(IsEqualGUID(riid, &IID_IExplorerBrowserEvents))
2443 {
2444 *ppvObject = &This->IExplorerBrowserEvents_iface;
2445 }
2446 else if(IsEqualGUID(riid, &IID_IServiceProvider))
2447 {
2448 *ppvObject = &This->IServiceProvider_iface;
2449 }
2450 else if(IsEqualGUID(&IID_ICommDlgBrowser3, riid) ||
2451 IsEqualGUID(&IID_ICommDlgBrowser2, riid) ||
2452 IsEqualGUID(&IID_ICommDlgBrowser, riid))
2453 {
2454 *ppvObject = &This->ICommDlgBrowser3_iface;
2455 }
2456 else if(IsEqualGUID(&IID_IOleWindow, riid))
2457 {
2458 *ppvObject = &This->IOleWindow_iface;
2459 }
2460 else if(IsEqualGUID(riid, &IID_IFileDialogCustomize) ||
2461 IsEqualGUID(riid, &IID_IFileDialogCustomizeAlt))
2462 {
2463 *ppvObject = &This->IFileDialogCustomize_iface;
2464 }
2465 else
2466 FIXME("Unknown interface requested: %s.\n", debugstr_guid(riid));
2467
2468 if(*ppvObject)
2469 {
2470 IUnknown_AddRef((IUnknown*)*ppvObject);
2471 return S_OK;
2472 }
2473
2474 return E_NOINTERFACE;
2475}
2476
2477static ULONG WINAPI IFileDialog2_fnAddRef(IFileDialog2 *iface)
2478{
2479 FileDialogImpl *This = impl_from_IFileDialog2(iface);
2481 TRACE("%p - ref %ld\n", This, ref);
2482
2483 return ref;
2484}
2485
2486static ULONG WINAPI IFileDialog2_fnRelease(IFileDialog2 *iface)
2487{
2488 FileDialogImpl *This = impl_from_IFileDialog2(iface);
2490 TRACE("%p - ref %ld\n", This, ref);
2491
2492 if(!ref)
2493 {
2494 UINT i;
2495 for(i = 0; i < This->filterspec_count; i++)
2496 {
2497 LocalFree((void*)This->filterspecs[i].pszName);
2498 LocalFree((void*)This->filterspecs[i].pszSpec);
2499 }
2500 HeapFree(GetProcessHeap(), 0, This->filterspecs);
2501
2502 DestroyWindow(This->cctrls_hwnd);
2503
2504 if(This->psi_defaultfolder) IShellItem_Release(This->psi_defaultfolder);
2505 if(This->psi_setfolder) IShellItem_Release(This->psi_setfolder);
2506 if(This->psi_folder) IShellItem_Release(This->psi_folder);
2507 if(This->psia_selection) IShellItemArray_Release(This->psia_selection);
2508 if(This->psia_results) IShellItemArray_Release(This->psia_results);
2509
2510 LocalFree(This->set_filename);
2511 LocalFree(This->default_ext);
2512 LocalFree(This->custom_title);
2513 LocalFree(This->custom_okbutton);
2514 LocalFree(This->custom_cancelbutton);
2515 LocalFree(This->custom_filenamelabel);
2516 LocalFree(This->current_filter);
2517
2518 DestroyMenu(This->hmenu_opendropdown);
2519 DeleteObject(This->hfont_opendropdown);
2520
2522 }
2523
2524 return ref;
2525}
2526
2527static HRESULT WINAPI IFileDialog2_fnShow(IFileDialog2 *iface, HWND hwndOwner)
2528{
2529 FileDialogImpl *This = impl_from_IFileDialog2(iface);
2530 TRACE("%p (%p)\n", iface, hwndOwner);
2531
2532 This->opendropdown_has_selection = FALSE;
2533
2534 return create_dialog(This, hwndOwner);
2535}
2536
2537static HRESULT WINAPI IFileDialog2_fnSetFileTypes(IFileDialog2 *iface, UINT cFileTypes,
2538 const COMDLG_FILTERSPEC *rgFilterSpec)
2539{
2540 FileDialogImpl *This = impl_from_IFileDialog2(iface);
2541 UINT i;
2542 TRACE("%p (%d, %p)\n", This, cFileTypes, rgFilterSpec);
2543
2544 if(!rgFilterSpec)
2545 return E_INVALIDARG;
2546
2547 if(This->filterspecs)
2548 return E_UNEXPECTED;
2549
2550 if(!cFileTypes)
2551 return S_OK;
2552
2553 This->filterspecs = HeapAlloc(GetProcessHeap(), 0, sizeof(COMDLG_FILTERSPEC)*cFileTypes);
2554 for(i = 0; i < cFileTypes; i++)
2555 {
2556 This->filterspecs[i].pszName = StrDupW(rgFilterSpec[i].pszName);
2557 This->filterspecs[i].pszSpec = StrDupW(rgFilterSpec[i].pszSpec);
2558 }
2559 This->filterspec_count = cFileTypes;
2560
2561 set_current_filter(This, This->filterspecs[This->filetypeindex].pszSpec);
2562
2563 return S_OK;
2564}
2565
2566static HRESULT WINAPI IFileDialog2_fnSetFileTypeIndex(IFileDialog2 *iface, UINT iFileType)
2567{
2568 FileDialogImpl *This = impl_from_IFileDialog2(iface);
2569 TRACE("%p (%d)\n", This, iFileType);
2570
2571 if(!This->filterspecs)
2572 return E_FAIL;
2573
2574 iFileType = max(iFileType, 1);
2575 iFileType = min(iFileType, This->filterspec_count);
2576 This->filetypeindex = iFileType-1;
2577
2578 set_current_filter(This, This->filterspecs[This->filetypeindex].pszSpec);
2579
2580 return S_OK;
2581}
2582
2583static HRESULT WINAPI IFileDialog2_fnGetFileTypeIndex(IFileDialog2 *iface, UINT *piFileType)
2584{
2585 FileDialogImpl *This = impl_from_IFileDialog2(iface);
2586 TRACE("%p (%p)\n", This, piFileType);
2587
2588 if(!piFileType)
2589 return E_INVALIDARG;
2590
2591 if(This->filterspec_count == 0)
2592 *piFileType = 0;
2593 else
2594 *piFileType = This->filetypeindex + 1;
2595
2596 return S_OK;
2597}
2598
2599static HRESULT WINAPI IFileDialog2_fnAdvise(IFileDialog2 *iface, IFileDialogEvents *pfde, DWORD *pdwCookie)
2600{
2601 FileDialogImpl *This = impl_from_IFileDialog2(iface);
2602 events_client *client;
2603 TRACE("%p (%p, %p)\n", This, pfde, pdwCookie);
2604
2605 if(!pfde || !pdwCookie)
2606 return E_INVALIDARG;
2607
2608 client = HeapAlloc(GetProcessHeap(), 0, sizeof(events_client));
2609 client->pfde = pfde;
2610 client->cookie = ++This->events_next_cookie;
2611
2612 IFileDialogEvents_AddRef(pfde);
2613 *pdwCookie = client->cookie;
2614
2615 list_add_tail(&This->events_clients, &client->entry);
2616
2617 return S_OK;
2618}
2619
2620static HRESULT WINAPI IFileDialog2_fnUnadvise(IFileDialog2 *iface, DWORD dwCookie)
2621{
2622 FileDialogImpl *This = impl_from_IFileDialog2(iface);
2623 events_client *client, *found = NULL;
2624 TRACE("%p (%ld)\n", This, dwCookie);
2625
2626 LIST_FOR_EACH_ENTRY(client, &This->events_clients, events_client, entry)
2627 {
2628 if(client->cookie == dwCookie)
2629 {
2630 found = client;
2631 break;
2632 }
2633 }
2634
2635 if(found)
2636 {
2637 list_remove(&found->entry);
2638 IFileDialogEvents_Release(found->pfde);
2639 HeapFree(GetProcessHeap(), 0, found);
2640 return S_OK;
2641 }
2642
2643 return E_INVALIDARG;
2644}
2645
2646static HRESULT WINAPI IFileDialog2_fnSetOptions(IFileDialog2 *iface, FILEOPENDIALOGOPTIONS fos)
2647{
2648 FileDialogImpl *This = impl_from_IFileDialog2(iface);
2649 TRACE("%p (0x%lx)\n", This, fos);
2650
2651 if (fos & ~(FOS_OVERWRITEPROMPT | FOS_STRICTFILETYPES | FOS_NOCHANGEDIR | FOS_PICKFOLDERS | FOS_FORCEFILESYSTEM
2652 | FOS_ALLNONSTORAGEITEMS | FOS_NOVALIDATE | FOS_ALLOWMULTISELECT | FOS_PATHMUSTEXIST | FOS_FILEMUSTEXIST
2653 | FOS_CREATEPROMPT | FOS_SHAREAWARE | FOS_NOREADONLYRETURN | FOS_NOTESTFILECREATE | FOS_HIDEMRUPLACES
2654 | FOS_HIDEPINNEDPLACES | FOS_NODEREFERENCELINKS | FOS_DONTADDTORECENT | FOS_FORCESHOWHIDDEN
2655 | FOS_DEFAULTNOMINIMODE | FOS_FORCEPREVIEWPANEON | FOS_SUPPORTSTREAMABLEITEMS))
2656 {
2657 WARN("Invalid option %#lx\n", fos);
2658 return E_INVALIDARG;
2659 }
2660
2661 if( !(This->options & FOS_PICKFOLDERS) && (fos & FOS_PICKFOLDERS) )
2662 {
2663 WCHAR buf[30];
2665 IFileDialog2_SetTitle(iface, buf);
2666 }
2667
2668 This->options = fos;
2669
2670 return S_OK;
2671}
2672
2673static HRESULT WINAPI IFileDialog2_fnGetOptions(IFileDialog2 *iface, FILEOPENDIALOGOPTIONS *pfos)
2674{
2675 FileDialogImpl *This = impl_from_IFileDialog2(iface);
2676 TRACE("%p (%p)\n", This, pfos);
2677
2678 if(!pfos)
2679 return E_INVALIDARG;
2680
2681 *pfos = This->options;
2682
2683 return S_OK;
2684}
2685
2686static HRESULT WINAPI IFileDialog2_fnSetDefaultFolder(IFileDialog2 *iface, IShellItem *psi)
2687{
2688 FileDialogImpl *This = impl_from_IFileDialog2(iface);
2689 TRACE("%p (%p)\n", This, psi);
2690 if(This->psi_defaultfolder)
2691 IShellItem_Release(This->psi_defaultfolder);
2692
2693 This->psi_defaultfolder = psi;
2694
2695 if(This->psi_defaultfolder)
2696 IShellItem_AddRef(This->psi_defaultfolder);
2697
2698 return S_OK;
2699}
2700
2701static HRESULT WINAPI IFileDialog2_fnSetFolder(IFileDialog2 *iface, IShellItem *psi)
2702{
2703 FileDialogImpl *This = impl_from_IFileDialog2(iface);
2704 TRACE("%p (%p)\n", This, psi);
2705 if(This->psi_setfolder)
2706 IShellItem_Release(This->psi_setfolder);
2707
2708 This->psi_setfolder = psi;
2709
2710 if(This->psi_setfolder)
2711 IShellItem_AddRef(This->psi_setfolder);
2712
2713 return S_OK;
2714}
2715
2716static HRESULT WINAPI IFileDialog2_fnGetFolder(IFileDialog2 *iface, IShellItem **ppsi)
2717{
2718 FileDialogImpl *This = impl_from_IFileDialog2(iface);
2719 TRACE("%p (%p)\n", This, ppsi);
2720 if(!ppsi)
2721 return E_INVALIDARG;
2722
2723 /* FIXME:
2724 If the dialog is shown, return the current(ly selected) folder. */
2725
2726 *ppsi = NULL;
2727 if(This->psi_folder)
2728 *ppsi = This->psi_folder;
2729 else if(This->psi_setfolder)
2730 *ppsi = This->psi_setfolder;
2731 else if(This->psi_defaultfolder)
2732 *ppsi = This->psi_defaultfolder;
2733
2734 if(*ppsi)
2735 {
2736 IShellItem_AddRef(*ppsi);
2737 return S_OK;
2738 }
2739
2740 return E_FAIL;
2741}
2742
2743static HRESULT WINAPI IFileDialog2_fnGetCurrentSelection(IFileDialog2 *iface, IShellItem **ppsi)
2744{
2745 FileDialogImpl *This = impl_from_IFileDialog2(iface);
2746 HRESULT hr;
2747 TRACE("%p (%p)\n", This, ppsi);
2748
2749 if(!ppsi)
2750 return E_INVALIDARG;
2751
2752 if(This->psia_selection)
2753 {
2754 /* FIXME: Check filename edit box */
2755 hr = IShellItemArray_GetItemAt(This->psia_selection, 0, ppsi);
2756 return hr;
2757 }
2758
2759 return E_FAIL;
2760}
2761
2762static HRESULT WINAPI IFileDialog2_fnSetFileName(IFileDialog2 *iface, LPCWSTR pszName)
2763{
2764 FileDialogImpl *This = impl_from_IFileDialog2(iface);
2765 TRACE("%p (%s)\n", iface, debugstr_w(pszName));
2766
2767 set_file_name(This, pszName);
2768
2769 return S_OK;
2770}
2771
2772static HRESULT WINAPI IFileDialog2_fnGetFileName(IFileDialog2 *iface, LPWSTR *pszName)
2773{
2774 FileDialogImpl *This = impl_from_IFileDialog2(iface);
2775 TRACE("%p (%p)\n", iface, pszName);
2776
2777 if(!pszName)
2778 return E_INVALIDARG;
2779
2780 *pszName = NULL;
2781 get_file_name(This, pszName);
2782 return *pszName ? S_OK : E_FAIL;
2783}
2784
2785static HRESULT WINAPI IFileDialog2_fnSetTitle(IFileDialog2 *iface, LPCWSTR pszTitle)
2786{
2787 FileDialogImpl *This = impl_from_IFileDialog2(iface);
2788 TRACE("%p (%s)\n", This, debugstr_w(pszTitle));
2789
2790 LocalFree(This->custom_title);
2791 This->custom_title = StrDupW(pszTitle);
2792 update_control_text(This);
2793
2794 return S_OK;
2795}
2796
2797static HRESULT WINAPI IFileDialog2_fnSetOkButtonLabel(IFileDialog2 *iface, LPCWSTR pszText)
2798{
2799 FileDialogImpl *This = impl_from_IFileDialog2(iface);
2800 TRACE("%p (%s)\n", This, debugstr_w(pszText));
2801
2802 LocalFree(This->custom_okbutton);
2803 This->custom_okbutton = StrDupW(pszText);
2804 update_control_text(This);
2805 update_layout(This);
2806
2807 return S_OK;
2808}
2809
2810static HRESULT WINAPI IFileDialog2_fnSetFileNameLabel(IFileDialog2 *iface, LPCWSTR pszLabel)
2811{
2812 FileDialogImpl *This = impl_from_IFileDialog2(iface);
2813 TRACE("%p (%s)\n", This, debugstr_w(pszLabel));
2814
2815 LocalFree(This->custom_filenamelabel);
2816 This->custom_filenamelabel = StrDupW(pszLabel);
2817 update_control_text(This);
2818 update_layout(This);
2819
2820 return S_OK;
2821}
2822
2823static HRESULT WINAPI IFileDialog2_fnGetResult(IFileDialog2 *iface, IShellItem **ppsi)
2824{
2825 FileDialogImpl *This = impl_from_IFileDialog2(iface);
2826 HRESULT hr;
2827 TRACE("%p (%p)\n", This, ppsi);
2828
2829 if(!ppsi)
2830 return E_INVALIDARG;
2831
2832 if(This->psia_results)
2833 {
2834 DWORD item_count;
2835 hr = IShellItemArray_GetCount(This->psia_results, &item_count);
2836 if(SUCCEEDED(hr))
2837 {
2838 if(item_count != 1)
2839 return E_FAIL;
2840
2841 /* Adds a reference. */
2842 hr = IShellItemArray_GetItemAt(This->psia_results, 0, ppsi);
2843 }
2844
2845 return hr;
2846 }
2847
2848 return E_UNEXPECTED;
2849}
2850
2851static HRESULT WINAPI IFileDialog2_fnAddPlace(IFileDialog2 *iface, IShellItem *psi, FDAP fdap)
2852{
2853 FileDialogImpl *This = impl_from_IFileDialog2(iface);
2854 FIXME("stub - %p (%p, %d)\n", This, psi, fdap);
2855 return S_OK;
2856}
2857
2858static HRESULT WINAPI IFileDialog2_fnSetDefaultExtension(IFileDialog2 *iface, LPCWSTR pszDefaultExtension)
2859{
2860 FileDialogImpl *This = impl_from_IFileDialog2(iface);
2861 TRACE("%p (%s)\n", This, debugstr_w(pszDefaultExtension));
2862
2863 LocalFree(This->default_ext);
2864 This->default_ext = StrDupW(pszDefaultExtension);
2865
2866 return S_OK;
2867}
2868
2869static HRESULT WINAPI IFileDialog2_fnClose(IFileDialog2 *iface, HRESULT hr)
2870{
2871 FileDialogImpl *This = impl_from_IFileDialog2(iface);
2872 TRACE("%p (0x%08lx)\n", This, hr);
2873
2874 if(This->dlg_hwnd)
2875 EndDialog(This->dlg_hwnd, hr);
2876
2877 return S_OK;
2878}
2879
2880static HRESULT WINAPI IFileDialog2_fnSetClientGuid(IFileDialog2 *iface, REFGUID guid)
2881{
2882 FileDialogImpl *This = impl_from_IFileDialog2(iface);
2883 TRACE("%p (%s)\n", This, debugstr_guid(guid));
2884 This->client_guid = *guid;
2885 return S_OK;
2886}
2887
2888static HRESULT WINAPI IFileDialog2_fnClearClientData(IFileDialog2 *iface)
2889{
2890 FileDialogImpl *This = impl_from_IFileDialog2(iface);
2891 FIXME("stub - %p\n", This);
2892 return E_NOTIMPL;
2893}
2894
2895static HRESULT WINAPI IFileDialog2_fnSetFilter(IFileDialog2 *iface, IShellItemFilter *pFilter)
2896{
2897 FileDialogImpl *This = impl_from_IFileDialog2(iface);
2898 FIXME("stub - %p (%p)\n", This, pFilter);
2899 return E_NOTIMPL;
2900}
2901
2902static HRESULT WINAPI IFileDialog2_fnSetCancelButtonLabel(IFileDialog2 *iface, LPCWSTR pszLabel)
2903{
2904 FileDialogImpl *This = impl_from_IFileDialog2(iface);
2905 TRACE("%p (%s)\n", This, debugstr_w(pszLabel));
2906
2907 LocalFree(This->custom_cancelbutton);
2908 This->custom_cancelbutton = StrDupW(pszLabel);
2909 update_control_text(This);
2910 update_layout(This);
2911
2912 return S_OK;
2913}
2914
2915static HRESULT WINAPI IFileDialog2_fnSetNavigationRoot(IFileDialog2 *iface, IShellItem *psi)
2916{
2917 FileDialogImpl *This = impl_from_IFileDialog2(iface);
2918 FIXME("stub - %p (%p)\n", This, psi);
2919 return E_NOTIMPL;
2920}
2921
2922static const IFileDialog2Vtbl vt_IFileDialog2 = {
2923 IFileDialog2_fnQueryInterface,
2924 IFileDialog2_fnAddRef,
2925 IFileDialog2_fnRelease,
2926 IFileDialog2_fnShow,
2927 IFileDialog2_fnSetFileTypes,
2928 IFileDialog2_fnSetFileTypeIndex,
2929 IFileDialog2_fnGetFileTypeIndex,
2930 IFileDialog2_fnAdvise,
2931 IFileDialog2_fnUnadvise,
2932 IFileDialog2_fnSetOptions,
2933 IFileDialog2_fnGetOptions,
2934 IFileDialog2_fnSetDefaultFolder,
2935 IFileDialog2_fnSetFolder,
2936 IFileDialog2_fnGetFolder,
2937 IFileDialog2_fnGetCurrentSelection,
2938 IFileDialog2_fnSetFileName,
2939 IFileDialog2_fnGetFileName,
2940 IFileDialog2_fnSetTitle,
2941 IFileDialog2_fnSetOkButtonLabel,
2942 IFileDialog2_fnSetFileNameLabel,
2943 IFileDialog2_fnGetResult,
2944 IFileDialog2_fnAddPlace,
2945 IFileDialog2_fnSetDefaultExtension,
2946 IFileDialog2_fnClose,
2947 IFileDialog2_fnSetClientGuid,
2948 IFileDialog2_fnClearClientData,
2949 IFileDialog2_fnSetFilter,
2950 IFileDialog2_fnSetCancelButtonLabel,
2951 IFileDialog2_fnSetNavigationRoot
2952};
2953
2954/**************************************************************************
2955 * IFileOpenDialog
2956 */
2957static inline FileDialogImpl *impl_from_IFileOpenDialog(IFileOpenDialog *iface)
2958{
2959 return CONTAINING_RECORD(iface, FileDialogImpl, u.IFileOpenDialog_iface);
2960}
2961
2962static HRESULT WINAPI IFileOpenDialog_fnQueryInterface(IFileOpenDialog *iface,
2963 REFIID riid, void **ppvObject)
2964{
2965 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
2966 return IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppvObject);
2967}
2968
2969static ULONG WINAPI IFileOpenDialog_fnAddRef(IFileOpenDialog *iface)
2970{
2971 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
2972 return IFileDialog2_AddRef(&This->IFileDialog2_iface);
2973}
2974
2975static ULONG WINAPI IFileOpenDialog_fnRelease(IFileOpenDialog *iface)
2976{
2977 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
2978 return IFileDialog2_Release(&This->IFileDialog2_iface);
2979}
2980
2981static HRESULT WINAPI IFileOpenDialog_fnShow(IFileOpenDialog *iface, HWND hwndOwner)
2982{
2983 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
2984 return IFileDialog2_Show(&This->IFileDialog2_iface, hwndOwner);
2985}
2986
2987static HRESULT WINAPI IFileOpenDialog_fnSetFileTypes(IFileOpenDialog *iface, UINT cFileTypes,
2988 const COMDLG_FILTERSPEC *rgFilterSpec)
2989{
2990 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
2991 return IFileDialog2_SetFileTypes(&This->IFileDialog2_iface, cFileTypes, rgFilterSpec);
2992}
2993
2994static HRESULT WINAPI IFileOpenDialog_fnSetFileTypeIndex(IFileOpenDialog *iface, UINT iFileType)
2995{
2996 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
2997 return IFileDialog2_SetFileTypeIndex(&This->IFileDialog2_iface, iFileType);
2998}
2999
3000static HRESULT WINAPI IFileOpenDialog_fnGetFileTypeIndex(IFileOpenDialog *iface, UINT *piFileType)
3001{
3002 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
3003 return IFileDialog2_GetFileTypeIndex(&This->IFileDialog2_iface, piFileType);
3004}
3005
3006static HRESULT WINAPI IFileOpenDialog_fnAdvise(IFileOpenDialog *iface, IFileDialogEvents *pfde,
3007 DWORD *pdwCookie)
3008{
3009 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
3010 return IFileDialog2_Advise(&This->IFileDialog2_iface, pfde, pdwCookie);
3011}
3012
3013static HRESULT WINAPI IFileOpenDialog_fnUnadvise(IFileOpenDialog *iface, DWORD dwCookie)
3014{
3015 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
3016 return IFileDialog2_Unadvise(&This->IFileDialog2_iface, dwCookie);
3017}
3018
3019static HRESULT WINAPI IFileOpenDialog_fnSetOptions(IFileOpenDialog *iface, FILEOPENDIALOGOPTIONS fos)
3020{
3021 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
3022 return IFileDialog2_SetOptions(&This->IFileDialog2_iface, fos);
3023}
3024
3025static HRESULT WINAPI IFileOpenDialog_fnGetOptions(IFileOpenDialog *iface, FILEOPENDIALOGOPTIONS *pfos)
3026{
3027 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
3028 return IFileDialog2_GetOptions(&This->IFileDialog2_iface, pfos);
3029}
3030
3031static HRESULT WINAPI IFileOpenDialog_fnSetDefaultFolder(IFileOpenDialog *iface, IShellItem *psi)
3032{
3033 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
3034 return IFileDialog2_SetDefaultFolder(&This->IFileDialog2_iface, psi);
3035}
3036
3037static HRESULT WINAPI IFileOpenDialog_fnSetFolder(IFileOpenDialog *iface, IShellItem *psi)
3038{
3039 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
3040 return IFileDialog2_SetFolder(&This->IFileDialog2_iface, psi);
3041}
3042
3043static HRESULT WINAPI IFileOpenDialog_fnGetFolder(IFileOpenDialog *iface, IShellItem **ppsi)
3044{
3045 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
3046 return IFileDialog2_GetFolder(&This->IFileDialog2_iface, ppsi);
3047}
3048
3049static HRESULT WINAPI IFileOpenDialog_fnGetCurrentSelection(IFileOpenDialog *iface, IShellItem **ppsi)
3050{
3051 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
3052 return IFileDialog2_GetCurrentSelection(&This->IFileDialog2_iface, ppsi);
3053}
3054
3055static HRESULT WINAPI IFileOpenDialog_fnSetFileName(IFileOpenDialog *iface, LPCWSTR pszName)
3056{
3057 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
3058 return IFileDialog2_SetFileName(&This->IFileDialog2_iface, pszName);
3059}
3060
3061static HRESULT WINAPI IFileOpenDialog_fnGetFileName(IFileOpenDialog *iface, LPWSTR *pszName)
3062{
3063 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
3064 return IFileDialog2_GetFileName(&This->IFileDialog2_iface, pszName);
3065}
3066
3067static HRESULT WINAPI IFileOpenDialog_fnSetTitle(IFileOpenDialog *iface, LPCWSTR pszTitle)
3068{
3069 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
3070 return IFileDialog2_SetTitle(&This->IFileDialog2_iface, pszTitle);
3071}
3072
3073static HRESULT WINAPI IFileOpenDialog_fnSetOkButtonLabel(IFileOpenDialog *iface, LPCWSTR pszText)
3074{
3075 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
3076 return IFileDialog2_SetOkButtonLabel(&This->IFileDialog2_iface, pszText);
3077}
3078
3079static HRESULT WINAPI IFileOpenDialog_fnSetFileNameLabel(IFileOpenDialog *iface, LPCWSTR pszLabel)
3080{
3081 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
3082 return IFileDialog2_SetFileNameLabel(&This->IFileDialog2_iface, pszLabel);
3083}
3084
3085static HRESULT WINAPI IFileOpenDialog_fnGetResult(IFileOpenDialog *iface, IShellItem **ppsi)
3086{
3087 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
3088 return IFileDialog2_GetResult(&This->IFileDialog2_iface, ppsi);
3089}
3090
3091static HRESULT WINAPI IFileOpenDialog_fnAddPlace(IFileOpenDialog *iface, IShellItem *psi, FDAP fdap)
3092{
3093 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
3094 return IFileDialog2_AddPlace(&This->IFileDialog2_iface, psi, fdap);
3095}
3096
3097static HRESULT WINAPI IFileOpenDialog_fnSetDefaultExtension(IFileOpenDialog *iface,
3098 LPCWSTR pszDefaultExtension)
3099{
3100 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
3101 return IFileDialog2_SetDefaultExtension(&This->IFileDialog2_iface, pszDefaultExtension);
3102}
3103
3104static HRESULT WINAPI IFileOpenDialog_fnClose(IFileOpenDialog *iface, HRESULT hr)
3105{
3106 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
3107 return IFileDialog2_Close(&This->IFileDialog2_iface, hr);
3108}
3109
3110static HRESULT WINAPI IFileOpenDialog_fnSetClientGuid(IFileOpenDialog *iface, REFGUID guid)
3111{
3112 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
3113 return IFileDialog2_SetClientGuid(&This->IFileDialog2_iface, guid);
3114}
3115
3116static HRESULT WINAPI IFileOpenDialog_fnClearClientData(IFileOpenDialog *iface)
3117{
3118 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
3119 return IFileDialog2_ClearClientData(&This->IFileDialog2_iface);
3120}
3121
3122static HRESULT WINAPI IFileOpenDialog_fnSetFilter(IFileOpenDialog *iface, IShellItemFilter *pFilter)
3123{
3124 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
3125 return IFileDialog2_SetFilter(&This->IFileDialog2_iface, pFilter);
3126}
3127
3128static HRESULT WINAPI IFileOpenDialog_fnGetResults(IFileOpenDialog *iface, IShellItemArray **ppenum)
3129{
3130 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
3131 TRACE("%p (%p)\n", This, ppenum);
3132
3133 *ppenum = This->psia_results;
3134
3135 if(*ppenum)
3136 {
3137 IShellItemArray_AddRef(*ppenum);
3138 return S_OK;
3139 }
3140
3141 return E_FAIL;
3142}
3143
3144static HRESULT WINAPI IFileOpenDialog_fnGetSelectedItems(IFileOpenDialog *iface, IShellItemArray **ppsai)
3145{
3146 FileDialogImpl *This = impl_from_IFileOpenDialog(iface);
3147 TRACE("%p (%p)\n", This, ppsai);
3148
3149 if(This->psia_selection)
3150 {
3151 *ppsai = This->psia_selection;
3152 IShellItemArray_AddRef(*ppsai);
3153 return S_OK;
3154 }
3155
3156 return E_FAIL;
3157}
3158
3159static const IFileOpenDialogVtbl vt_IFileOpenDialog = {
3160 IFileOpenDialog_fnQueryInterface,
3161 IFileOpenDialog_fnAddRef,
3162 IFileOpenDialog_fnRelease,
3163 IFileOpenDialog_fnShow,
3164 IFileOpenDialog_fnSetFileTypes,
3165 IFileOpenDialog_fnSetFileTypeIndex,
3166 IFileOpenDialog_fnGetFileTypeIndex,
3167 IFileOpenDialog_fnAdvise,
3168 IFileOpenDialog_fnUnadvise,
3169 IFileOpenDialog_fnSetOptions,
3170 IFileOpenDialog_fnGetOptions,
3171 IFileOpenDialog_fnSetDefaultFolder,
3172 IFileOpenDialog_fnSetFolder,
3173 IFileOpenDialog_fnGetFolder,
3174 IFileOpenDialog_fnGetCurrentSelection,
3175 IFileOpenDialog_fnSetFileName,
3176 IFileOpenDialog_fnGetFileName,
3177 IFileOpenDialog_fnSetTitle,
3178 IFileOpenDialog_fnSetOkButtonLabel,
3179 IFileOpenDialog_fnSetFileNameLabel,
3180 IFileOpenDialog_fnGetResult,
3181 IFileOpenDialog_fnAddPlace,
3182 IFileOpenDialog_fnSetDefaultExtension,
3183 IFileOpenDialog_fnClose,
3184 IFileOpenDialog_fnSetClientGuid,
3185 IFileOpenDialog_fnClearClientData,
3186 IFileOpenDialog_fnSetFilter,
3187 IFileOpenDialog_fnGetResults,
3188 IFileOpenDialog_fnGetSelectedItems
3189};
3190
3191/**************************************************************************
3192 * IFileSaveDialog
3193 */
3194static inline FileDialogImpl *impl_from_IFileSaveDialog(IFileSaveDialog *iface)
3195{
3196 return CONTAINING_RECORD(iface, FileDialogImpl, u.IFileSaveDialog_iface);
3197}
3198
3199static HRESULT WINAPI IFileSaveDialog_fnQueryInterface(IFileSaveDialog *iface,
3200 REFIID riid,
3201 void **ppvObject)
3202{
3203 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
3204 return IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppvObject);
3205}
3206
3207static ULONG WINAPI IFileSaveDialog_fnAddRef(IFileSaveDialog *iface)
3208{
3209 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
3210 return IFileDialog2_AddRef(&This->IFileDialog2_iface);
3211}
3212
3213static ULONG WINAPI IFileSaveDialog_fnRelease(IFileSaveDialog *iface)
3214{
3215 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
3216 return IFileDialog2_Release(&This->IFileDialog2_iface);
3217}
3218
3219static HRESULT WINAPI IFileSaveDialog_fnShow(IFileSaveDialog *iface, HWND hwndOwner)
3220{
3221 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
3222 return IFileDialog2_Show(&This->IFileDialog2_iface, hwndOwner);
3223}
3224
3225static HRESULT WINAPI IFileSaveDialog_fnSetFileTypes(IFileSaveDialog *iface, UINT cFileTypes,
3226 const COMDLG_FILTERSPEC *rgFilterSpec)
3227{
3228 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
3229 return IFileDialog2_SetFileTypes(&This->IFileDialog2_iface, cFileTypes, rgFilterSpec);
3230}
3231
3232static HRESULT WINAPI IFileSaveDialog_fnSetFileTypeIndex(IFileSaveDialog *iface, UINT iFileType)
3233{
3234 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
3235 return IFileDialog2_SetFileTypeIndex(&This->IFileDialog2_iface, iFileType);
3236}
3237
3238static HRESULT WINAPI IFileSaveDialog_fnGetFileTypeIndex(IFileSaveDialog *iface, UINT *piFileType)
3239{
3240 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
3241 return IFileDialog2_GetFileTypeIndex(&This->IFileDialog2_iface, piFileType);
3242}
3243
3244static HRESULT WINAPI IFileSaveDialog_fnAdvise(IFileSaveDialog *iface, IFileDialogEvents *pfde,
3245 DWORD *pdwCookie)
3246{
3247 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
3248 return IFileDialog2_Advise(&This->IFileDialog2_iface, pfde, pdwCookie);
3249}
3250
3251static HRESULT WINAPI IFileSaveDialog_fnUnadvise(IFileSaveDialog *iface, DWORD dwCookie)
3252{
3253 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
3254 return IFileDialog2_Unadvise(&This->IFileDialog2_iface, dwCookie);
3255}
3256
3257static HRESULT WINAPI IFileSaveDialog_fnSetOptions(IFileSaveDialog *iface, FILEOPENDIALOGOPTIONS fos)
3258{
3259 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
3260 return IFileDialog2_SetOptions(&This->IFileDialog2_iface, fos);
3261}
3262
3263static HRESULT WINAPI IFileSaveDialog_fnGetOptions(IFileSaveDialog *iface, FILEOPENDIALOGOPTIONS *pfos)
3264{
3265 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
3266 return IFileDialog2_GetOptions(&This->IFileDialog2_iface, pfos);
3267}
3268
3269static HRESULT WINAPI IFileSaveDialog_fnSetDefaultFolder(IFileSaveDialog *iface, IShellItem *psi)
3270{
3271 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
3272 return IFileDialog2_SetDefaultFolder(&This->IFileDialog2_iface, psi);
3273}
3274
3275static HRESULT WINAPI IFileSaveDialog_fnSetFolder(IFileSaveDialog *iface, IShellItem *psi)
3276{
3277 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
3278 return IFileDialog2_SetFolder(&This->IFileDialog2_iface, psi);
3279}
3280
3281static HRESULT WINAPI IFileSaveDialog_fnGetFolder(IFileSaveDialog *iface, IShellItem **ppsi)
3282{
3283 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
3284 return IFileDialog2_GetFolder(&This->IFileDialog2_iface, ppsi);
3285}
3286
3287static HRESULT WINAPI IFileSaveDialog_fnGetCurrentSelection(IFileSaveDialog *iface, IShellItem **ppsi)
3288{
3289 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
3290 return IFileDialog2_GetCurrentSelection(&This->IFileDialog2_iface, ppsi);
3291}
3292
3293static HRESULT WINAPI IFileSaveDialog_fnSetFileName(IFileSaveDialog *iface, LPCWSTR pszName)
3294{
3295 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
3296 return IFileDialog2_SetFileName(&This->IFileDialog2_iface, pszName);
3297}
3298
3299static HRESULT WINAPI IFileSaveDialog_fnGetFileName(IFileSaveDialog *iface, LPWSTR *pszName)
3300{
3301 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
3302 return IFileDialog2_GetFileName(&This->IFileDialog2_iface, pszName);
3303}
3304
3305static HRESULT WINAPI IFileSaveDialog_fnSetTitle(IFileSaveDialog *iface, LPCWSTR pszTitle)
3306{
3307 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
3308 return IFileDialog2_SetTitle(&This->IFileDialog2_iface, pszTitle);
3309}
3310
3311static HRESULT WINAPI IFileSaveDialog_fnSetOkButtonLabel(IFileSaveDialog *iface, LPCWSTR pszText)
3312{
3313 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
3314 return IFileDialog2_SetOkButtonLabel(&This->IFileDialog2_iface, pszText);
3315}
3316
3317static HRESULT WINAPI IFileSaveDialog_fnSetFileNameLabel(IFileSaveDialog *iface, LPCWSTR pszLabel)
3318{
3319 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
3320 return IFileDialog2_SetFileNameLabel(&This->IFileDialog2_iface, pszLabel);
3321}
3322
3323static HRESULT WINAPI IFileSaveDialog_fnGetResult(IFileSaveDialog *iface, IShellItem **ppsi)
3324{
3325 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
3326 return IFileDialog2_GetResult(&This->IFileDialog2_iface, ppsi);
3327}
3328
3329static HRESULT WINAPI IFileSaveDialog_fnAddPlace(IFileSaveDialog *iface, IShellItem *psi, FDAP fdap)
3330{
3331 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
3332 return IFileDialog2_AddPlace(&This->IFileDialog2_iface, psi, fdap);
3333}
3334
3335static HRESULT WINAPI IFileSaveDialog_fnSetDefaultExtension(IFileSaveDialog *iface,
3336 LPCWSTR pszDefaultExtension)
3337{
3338 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
3339 return IFileDialog2_SetDefaultExtension(&This->IFileDialog2_iface, pszDefaultExtension);
3340}
3341
3342static HRESULT WINAPI IFileSaveDialog_fnClose(IFileSaveDialog *iface, HRESULT hr)
3343{
3344 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
3345 return IFileDialog2_Close(&This->IFileDialog2_iface, hr);
3346}
3347
3348static HRESULT WINAPI IFileSaveDialog_fnSetClientGuid(IFileSaveDialog *iface, REFGUID guid)
3349{
3350 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
3351 return IFileDialog2_SetClientGuid(&This->IFileDialog2_iface, guid);
3352}
3353
3354static HRESULT WINAPI IFileSaveDialog_fnClearClientData(IFileSaveDialog *iface)
3355{
3356 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
3357 return IFileDialog2_ClearClientData(&This->IFileDialog2_iface);
3358}
3359
3360static HRESULT WINAPI IFileSaveDialog_fnSetFilter(IFileSaveDialog *iface, IShellItemFilter *pFilter)
3361{
3362 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
3363 return IFileDialog2_SetFilter(&This->IFileDialog2_iface, pFilter);
3364}
3365
3366static HRESULT WINAPI IFileSaveDialog_fnSetSaveAsItem(IFileSaveDialog* iface, IShellItem *psi)
3367{
3368 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
3369 FIXME("stub - %p (%p)\n", This, psi);
3370 return E_NOTIMPL;
3371}
3372
3373static HRESULT WINAPI IFileSaveDialog_fnSetProperties(IFileSaveDialog* iface, IPropertyStore *pStore)
3374{
3375 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
3376 FIXME("stub - %p (%p)\n", This, pStore);
3377 return E_NOTIMPL;
3378}
3379
3380static HRESULT WINAPI IFileSaveDialog_fnSetCollectedProperties(IFileSaveDialog* iface,
3382 BOOL fAppendDefault)
3383{
3384 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
3385 FIXME("stub - %p (%p, %d)\n", This, pList, fAppendDefault);
3386 return E_NOTIMPL;
3387}
3388
3389static HRESULT WINAPI IFileSaveDialog_fnGetProperties(IFileSaveDialog* iface, IPropertyStore **ppStore)
3390{
3391 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
3392 FIXME("stub - %p (%p)\n", This, ppStore);
3393 return E_NOTIMPL;
3394}
3395
3396static HRESULT WINAPI IFileSaveDialog_fnApplyProperties(IFileSaveDialog* iface,
3397 IShellItem *psi,
3398 IPropertyStore *pStore,
3399 HWND hwnd,
3401{
3402 FileDialogImpl *This = impl_from_IFileSaveDialog(iface);
3403 FIXME("%p (%p, %p, %p, %p)\n", This, psi, pStore, hwnd, pSink);
3404 return E_NOTIMPL;
3405}
3406
3407static const IFileSaveDialogVtbl vt_IFileSaveDialog = {
3408 IFileSaveDialog_fnQueryInterface,
3409 IFileSaveDialog_fnAddRef,
3410 IFileSaveDialog_fnRelease,
3411 IFileSaveDialog_fnShow,
3412 IFileSaveDialog_fnSetFileTypes,
3413 IFileSaveDialog_fnSetFileTypeIndex,
3414 IFileSaveDialog_fnGetFileTypeIndex,
3415 IFileSaveDialog_fnAdvise,
3416 IFileSaveDialog_fnUnadvise,
3417 IFileSaveDialog_fnSetOptions,
3418 IFileSaveDialog_fnGetOptions,
3419 IFileSaveDialog_fnSetDefaultFolder,
3420 IFileSaveDialog_fnSetFolder,
3421 IFileSaveDialog_fnGetFolder,
3422 IFileSaveDialog_fnGetCurrentSelection,
3423 IFileSaveDialog_fnSetFileName,
3424 IFileSaveDialog_fnGetFileName,
3425 IFileSaveDialog_fnSetTitle,
3426 IFileSaveDialog_fnSetOkButtonLabel,
3427 IFileSaveDialog_fnSetFileNameLabel,
3428 IFileSaveDialog_fnGetResult,
3429 IFileSaveDialog_fnAddPlace,
3430 IFileSaveDialog_fnSetDefaultExtension,
3431 IFileSaveDialog_fnClose,
3432 IFileSaveDialog_fnSetClientGuid,
3433 IFileSaveDialog_fnClearClientData,
3434 IFileSaveDialog_fnSetFilter,
3435 IFileSaveDialog_fnSetSaveAsItem,
3436 IFileSaveDialog_fnSetProperties,
3437 IFileSaveDialog_fnSetCollectedProperties,
3438 IFileSaveDialog_fnGetProperties,
3439 IFileSaveDialog_fnApplyProperties
3440};
3441
3442/**************************************************************************
3443 * IExplorerBrowserEvents implementation
3444 */
3445static inline FileDialogImpl *impl_from_IExplorerBrowserEvents(IExplorerBrowserEvents *iface)
3446{
3447 return CONTAINING_RECORD(iface, FileDialogImpl, IExplorerBrowserEvents_iface);
3448}
3449
3450static HRESULT WINAPI IExplorerBrowserEvents_fnQueryInterface(IExplorerBrowserEvents *iface,
3451 REFIID riid, void **ppvObject)
3452{
3453 FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface);
3454 TRACE("%p (%s, %p)\n", This, debugstr_guid(riid), ppvObject);
3455
3456 return IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppvObject);
3457}
3458
3459static ULONG WINAPI IExplorerBrowserEvents_fnAddRef(IExplorerBrowserEvents *iface)
3460{
3461 FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface);
3462 TRACE("%p\n", This);
3463 return IFileDialog2_AddRef(&This->IFileDialog2_iface);
3464}
3465
3466static ULONG WINAPI IExplorerBrowserEvents_fnRelease(IExplorerBrowserEvents *iface)
3467{
3468 FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface);
3469 TRACE("%p\n", This);
3470 return IFileDialog2_Release(&This->IFileDialog2_iface);
3471}
3472
3473static HRESULT WINAPI IExplorerBrowserEvents_fnOnNavigationPending(IExplorerBrowserEvents *iface,
3474 PCIDLIST_ABSOLUTE pidlFolder)
3475{
3476 FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface);
3477 IShellItem *psi;
3478 HRESULT hr;
3479 TRACE("%p (%p)\n", This, pidlFolder);
3480
3481 hr = SHCreateItemFromIDList(pidlFolder, &IID_IShellItem, (void**)&psi);
3482 if(SUCCEEDED(hr))
3483 {
3484 hr = events_OnFolderChanging(This, psi);
3485 IShellItem_Release(psi);
3486
3487 /* The ExplorerBrowser treats S_FALSE as S_OK, we don't. */
3488 if(hr == S_FALSE)
3489 hr = E_FAIL;
3490
3491 return hr;
3492 }
3493 else
3494 ERR("Failed to convert pidl (%p) to a shellitem.\n", pidlFolder);
3495
3496 return S_OK;
3497}
3498
3499static HRESULT WINAPI IExplorerBrowserEvents_fnOnViewCreated(IExplorerBrowserEvents *iface,
3500 IShellView *psv)
3501{
3502 FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface);
3503 TRACE("%p (%p)\n", This, psv);
3504 return S_OK;
3505}
3506
3507static HRESULT WINAPI IExplorerBrowserEvents_fnOnNavigationComplete(IExplorerBrowserEvents *iface,
3508 PCIDLIST_ABSOLUTE pidlFolder)
3509{
3510 FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface);
3511 HRESULT hr;
3512 TRACE("%p (%p)\n", This, pidlFolder);
3513
3514 if(This->psi_folder)
3515 IShellItem_Release(This->psi_folder);
3516
3517 hr = SHCreateItemFromIDList(pidlFolder, &IID_IShellItem, (void**)&This->psi_folder);
3518 if(FAILED(hr))
3519 {
3520 ERR("Failed to get the current folder.\n");
3521 This->psi_folder = NULL;
3522 }
3523
3524 events_OnFolderChange(This);
3525
3526 return S_OK;
3527}
3528
3529static HRESULT WINAPI IExplorerBrowserEvents_fnOnNavigationFailed(IExplorerBrowserEvents *iface,
3530 PCIDLIST_ABSOLUTE pidlFolder)
3531{
3532 FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface);
3533 TRACE("%p (%p)\n", This, pidlFolder);
3534 return S_OK;
3535}
3536
3537static const IExplorerBrowserEventsVtbl vt_IExplorerBrowserEvents = {
3545};
3546
3547/**************************************************************************
3548 * IServiceProvider implementation
3549 */
3550static inline FileDialogImpl *impl_from_IServiceProvider(IServiceProvider *iface)
3551{
3552 return CONTAINING_RECORD(iface, FileDialogImpl, IServiceProvider_iface);
3553}
3554
3556 REFIID riid, void **ppvObject)
3557{
3558 FileDialogImpl *This = impl_from_IServiceProvider(iface);
3559 TRACE("%p\n", This);
3560 return IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppvObject);
3561}
3562
3564{
3565 FileDialogImpl *This = impl_from_IServiceProvider(iface);
3566 TRACE("%p\n", This);
3567 return IFileDialog2_AddRef(&This->IFileDialog2_iface);
3568}
3569
3571{
3572 FileDialogImpl *This = impl_from_IServiceProvider(iface);
3573 TRACE("%p\n", This);
3574 return IFileDialog2_Release(&This->IFileDialog2_iface);
3575}
3576
3578 REFGUID guidService,
3579 REFIID riid, void **ppv)
3580{
3581 FileDialogImpl *This = impl_from_IServiceProvider(iface);
3583 TRACE("%p (%s, %s, %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);
3584
3585 *ppv = NULL;
3586 if(IsEqualGUID(guidService, &SID_STopLevelBrowser) && This->peb)
3587 hr = IExplorerBrowser_QueryInterface(This->peb, riid, ppv);
3588 else if(IsEqualGUID(guidService, &SID_SExplorerBrowserFrame))
3589 hr = IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppv);
3590 else
3591 FIXME("Interface %s requested from unknown service %s\n",
3592 debugstr_guid(riid), debugstr_guid(guidService));
3593
3594 return hr;
3595}
3596
3597static const IServiceProviderVtbl vt_IServiceProvider = {
3602};
3603
3604/**************************************************************************
3605 * ICommDlgBrowser3 implementation
3606 */
3607static inline FileDialogImpl *impl_from_ICommDlgBrowser3(ICommDlgBrowser3 *iface)
3608{
3609 return CONTAINING_RECORD(iface, FileDialogImpl, ICommDlgBrowser3_iface);
3610}
3611
3613 REFIID riid, void **ppvObject)
3614{
3615 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
3616 TRACE("%p\n", This);
3617 return IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppvObject);
3618}
3619
3621{
3622 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
3623 TRACE("%p\n", This);
3624 return IFileDialog2_AddRef(&This->IFileDialog2_iface);
3625}
3626
3628{
3629 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
3630 TRACE("%p\n", This);
3631 return IFileDialog2_Release(&This->IFileDialog2_iface);
3632}
3633
3635 IShellView *shv)
3636{
3637 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
3638 HRESULT hr;
3639 TRACE("%p (%p)\n", This, shv);
3640
3641 hr = on_default_action(This);
3642
3643 if(SUCCEEDED(hr))
3644 EndDialog(This->dlg_hwnd, S_OK);
3645
3646 return S_OK;
3647}
3648
3650 IShellView *shv, ULONG uChange )
3651{
3652 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
3653 IDataObject *new_selection;
3654 HRESULT hr;
3655 TRACE("%p (%p, %lx)\n", This, shv, uChange);
3656
3657 switch(uChange)
3658 {
3659 case CDBOSC_SELCHANGE:
3660 if(This->psia_selection)
3661 {
3662 IShellItemArray_Release(This->psia_selection);
3663 This->psia_selection = NULL;
3664 }
3665
3666 hr = IShellView_GetItemObject(shv, SVGIO_SELECTION, &IID_IDataObject, (void**)&new_selection);
3667 if(SUCCEEDED(hr))
3668 {
3669 hr = SHCreateShellItemArrayFromDataObject(new_selection, &IID_IShellItemArray,
3670 (void**)&This->psia_selection);
3671 if(SUCCEEDED(hr))
3672 {
3673 fill_filename_from_selection(This);
3674 events_OnSelectionChange(This);
3675 }
3676
3677 IDataObject_Release(new_selection);
3678 }
3679 break;
3680 default:
3681 TRACE("Unhandled state change\n");
3682 }
3683 return S_OK;
3684}
3685
3687 IShellView *shv, LPCITEMIDLIST pidl)
3688{
3689 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
3690 IShellItem *psi;
3692 LPITEMIDLIST parent_pidl;
3693 HRESULT hr;
3694 ULONG attr;
3695 TRACE("%p (%p, %p)\n", This, shv, pidl);
3696
3697 if(!This->current_filter && !(This->options & FOS_PICKFOLDERS))
3698 return S_OK;
3699
3700 hr = SHGetIDListFromObject((IUnknown*)shv, &parent_pidl);
3701 if(SUCCEEDED(hr))
3702 {
3703 LPITEMIDLIST full_pidl = ILCombine(parent_pidl, pidl);
3704 hr = SHCreateItemFromIDList(full_pidl, &IID_IShellItem, (void**)&psi);
3705 ILFree(parent_pidl);
3706 ILFree(full_pidl);
3707 }
3708 if(FAILED(hr))
3709 {
3710 ERR("Failed to get shellitem (%08lx).\n", hr);
3711 return S_OK;
3712 }
3713
3714 hr = IShellItem_GetAttributes(psi, SFGAO_FOLDER|SFGAO_LINK, &attr);
3715 if(FAILED(hr) || (attr & (SFGAO_FOLDER | SFGAO_LINK)))
3716 {
3717 IShellItem_Release(psi);
3718 return S_OK;
3719 }
3720
3721 if((This->options & FOS_PICKFOLDERS) && !(attr & (SFGAO_FOLDER | SFGAO_LINK)))
3722 {
3723 IShellItem_Release(psi);
3724 return S_FALSE;
3725 }
3726
3727 hr = S_OK;
3728 if(SUCCEEDED(IShellItem_GetDisplayName(psi, SIGDN_PARENTRELATIVEPARSING, &filename)))
3729 {
3730 if(!PathMatchSpecW(filename, This->current_filter))
3731 hr = S_FALSE;
3733 }
3734
3735 IShellItem_Release(psi);
3736 return hr;
3737}
3738
3740 IShellView *ppshv, DWORD dwNotifyType)
3741{
3742 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
3743 FIXME("Stub: %p (%p, 0x%lx)\n", This, ppshv, dwNotifyType);
3744 return E_NOTIMPL;
3745}
3746
3748 IShellView *pshv,
3749 LPWSTR pszText, int cchMax)
3750{
3751 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
3752 FIXME("Stub: %p (%p, %p, %d)\n", This, pshv, pszText, cchMax);
3753 return E_NOTIMPL;
3754}
3755
3757{
3758 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
3759 FIXME("Stub: %p (%p)\n", This, pdwFlags);
3760 return E_NOTIMPL;
3761}
3762
3764 IShellView *pshv, int iColumn)
3765{
3766 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
3767 FIXME("Stub: %p (%p, %d)\n", This, pshv, iColumn);
3768 return E_NOTIMPL;
3769}
3770
3772 LPWSTR pszFileSpec, int cchFileSpec)
3773{
3774 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
3775 FIXME("Stub: %p (%p, %d)\n", This, pszFileSpec, cchFileSpec);
3776 return E_NOTIMPL;
3777}
3778
3780 IShellView *pshv)
3781{
3782 FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
3783 FIXME("Stub: %p (%p)\n", This, pshv);
3784 return E_NOTIMPL;
3785}
3786
3787static const ICommDlgBrowser3Vtbl vt_ICommDlgBrowser3 = {
3800};
3801
3802/**************************************************************************
3803 * IOleWindow implementation
3804 */
3805static inline FileDialogImpl *impl_from_IOleWindow(IOleWindow *iface)
3806{
3807 return CONTAINING_RECORD(iface, FileDialogImpl, IOleWindow_iface);
3808}
3809
3810static HRESULT WINAPI IOleWindow_fnQueryInterface(IOleWindow *iface, REFIID riid, void **ppvObject)
3811{
3812 FileDialogImpl *This = impl_from_IOleWindow(iface);
3813 return IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppvObject);
3814}
3815
3816static ULONG WINAPI IOleWindow_fnAddRef(IOleWindow *iface)
3817{
3818 FileDialogImpl *This = impl_from_IOleWindow(iface);
3819 return IFileDialog2_AddRef(&This->IFileDialog2_iface);
3820}
3821
3822static ULONG WINAPI IOleWindow_fnRelease(IOleWindow *iface)
3823{
3824 FileDialogImpl *This = impl_from_IOleWindow(iface);
3825 return IFileDialog2_Release(&This->IFileDialog2_iface);
3826}
3827
3828static HRESULT WINAPI IOleWindow_fnContextSensitiveHelp(IOleWindow *iface, BOOL fEnterMOde)
3829{
3830 FileDialogImpl *This = impl_from_IOleWindow(iface);
3831 FIXME("Stub: %p (%d)\n", This, fEnterMOde);
3832 return E_NOTIMPL;
3833}
3834
3835static HRESULT WINAPI IOleWindow_fnGetWindow(IOleWindow *iface, HWND *phwnd)
3836{
3837 FileDialogImpl *This = impl_from_IOleWindow(iface);
3838 TRACE("%p (%p)\n", This, phwnd);
3839 *phwnd = This->dlg_hwnd;
3840 return S_OK;
3841}
3842
3843static const IOleWindowVtbl vt_IOleWindow = {
3844 IOleWindow_fnQueryInterface,
3845 IOleWindow_fnAddRef,
3846 IOleWindow_fnRelease,
3847 IOleWindow_fnGetWindow,
3848 IOleWindow_fnContextSensitiveHelp
3849};
3850
3851/**************************************************************************
3852 * IFileDialogCustomize implementation
3853 */
3854static inline FileDialogImpl *impl_from_IFileDialogCustomize(IFileDialogCustomize *iface)
3855{
3856 return CONTAINING_RECORD(iface, FileDialogImpl, IFileDialogCustomize_iface);
3857}
3858
3859static HRESULT WINAPI IFileDialogCustomize_fnQueryInterface(IFileDialogCustomize *iface,
3860 REFIID riid, void **ppvObject)
3861{
3862 FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
3863 return IFileDialog2_QueryInterface(&This->IFileDialog2_iface, riid, ppvObject);
3864}
3865
3866static ULONG WINAPI IFileDialogCustomize_fnAddRef(IFileDialogCustomize *iface)
3867{
3868 FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
3869 return IFileDialog2_AddRef(&This->IFileDialog2_iface);
3870}
3871
3872static ULONG WINAPI IFileDialogCustomize_fnRelease(IFileDialogCustomize *iface)
3873{
3874 FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
3875 return IFileDialog2_Release(&This->IFileDialog2_iface);
3876}
3877
3878static HRESULT WINAPI IFileDialogCustomize_fnEnableOpenDropDown(IFileDialogCustomize *iface,
3879 DWORD dwIDCtl)
3880{
3881 FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
3882 MENUINFO mi;
3883 TRACE("%p (%ld)\n", This, dwIDCtl);
3884
3885 if (This->hmenu_opendropdown || get_cctrl(This, dwIDCtl))
3886 return E_UNEXPECTED;
3887
3888 This->hmenu_opendropdown = CreatePopupMenu();
3889
3890 if (!This->hmenu_opendropdown)
3891 return E_OUTOFMEMORY;
3892
3893 mi.cbSize = sizeof(mi);
3894 mi.fMask = MIM_STYLE;
3895 mi.dwStyle = MNS_NOTIFYBYPOS;
3896 SetMenuInfo(This->hmenu_opendropdown, &mi);
3897
3898 This->cctrl_opendropdown.hwnd = NULL;
3899 This->cctrl_opendropdown.wrapper_hwnd = NULL;
3900 This->cctrl_opendropdown.id = dwIDCtl;
3901 This->cctrl_opendropdown.dlgid = 0;
3902 This->cctrl_opendropdown.type = IDLG_CCTRL_OPENDROPDOWN;
3903 This->cctrl_opendropdown.cdcstate = CDCS_ENABLED | CDCS_VISIBLE;
3904 list_init(&This->cctrl_opendropdown.sub_cctrls);
3905 list_init(&This->cctrl_opendropdown.sub_items);
3906
3907 return S_OK;
3908}
3909
3910static HRESULT WINAPI IFileDialogCustomize_fnAddMenu(IFileDialogCustomize *iface,
3911 DWORD dwIDCtl,
3912 LPCWSTR pszLabel)
3913{
3914 FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
3915 customctrl *ctrl;
3916 TBBUTTON tbb;
3917 HRESULT hr;
3918 TRACE("%p (%ld, %p)\n", This, dwIDCtl, pszLabel);
3919
3920 hr = cctrl_create_new(This, dwIDCtl, NULL, TOOLBARCLASSNAMEW,
3922 This->cctrl_def_height, &ctrl);
3923 if(SUCCEEDED(hr))
3924 {
3925 SendMessageW(ctrl->hwnd, TB_BUTTONSTRUCTSIZE, sizeof(tbb), 0);
3926 ctrl->type = IDLG_CCTRL_MENU;
3927
3928 /* Add the actual button with a popup menu. */
3929 tbb.iBitmap = I_IMAGENONE;
3931 tbb.iString = (DWORD_PTR)pszLabel;
3934 tbb.idCommand = 1;
3935
3936 SendMessageW(ctrl->hwnd, TB_ADDBUTTONSW, 1, (LPARAM)&tbb);
3937 }
3938
3939 return hr;
3940}
3941
3942static HRESULT WINAPI IFileDialogCustomize_fnAddPushButton(IFileDialogCustomize *iface,
3943 DWORD dwIDCtl,
3944 LPCWSTR pszLabel)
3945{
3946 FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
3947 customctrl *ctrl;
3948 HRESULT hr;
3949 TRACE("%p (%ld, %p)\n", This, dwIDCtl, pszLabel);
3950
3951 hr = cctrl_create_new(This, dwIDCtl, pszLabel, WC_BUTTONW, BS_MULTILINE, 0,
3952 This->cctrl_def_height, &ctrl);
3953 if(SUCCEEDED(hr))
3954 ctrl->type = IDLG_CCTRL_PUSHBUTTON;
3955
3956 return hr;
3957}
3958
3959static HRESULT WINAPI IFileDialogCustomize_fnAddComboBox(IFileDialogCustomize *iface,
3960 DWORD dwIDCtl)
3961{
3962 FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
3963 customctrl *ctrl;
3964 HRESULT hr;
3965 TRACE("%p (%ld)\n", This, dwIDCtl);
3966
3967 hr = cctrl_create_new(This, dwIDCtl, NULL, WC_COMBOBOXW, CBS_DROPDOWNLIST, 0,
3968 This->cctrl_def_height, &ctrl);
3969 if(SUCCEEDED(hr))
3970 ctrl->type = IDLG_CCTRL_COMBOBOX;
3971
3972 return hr;
3973}
3974
3975static HRESULT WINAPI IFileDialogCustomize_fnAddRadioButtonList(IFileDialogCustomize *iface,
3976 DWORD dwIDCtl)
3977{
3978 FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
3979 customctrl *ctrl;
3980 HRESULT hr;
3981 TRACE("%p (%ld)\n", This, dwIDCtl);
3982
3983 hr = cctrl_create_new(This, dwIDCtl, NULL, L"RadioButtonList", 0, 0, 0, &ctrl);
3984 if(SUCCEEDED(hr))
3985 {
3986 ctrl->type = IDLG_CCTRL_RADIOBUTTONLIST;
3988 }
3989
3990 return hr;
3991}
3992
3993static HRESULT WINAPI IFileDialogCustomize_fnAddCheckButton(IFileDialogCustomize *iface,
3994 DWORD dwIDCtl,
3995 LPCWSTR pszLabel,
3996 BOOL bChecked)
3997{
3998 FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
3999 customctrl *ctrl;
4000 HRESULT hr;
4001 TRACE("%p (%ld, %p, %d)\n", This, dwIDCtl, pszLabel, bChecked);
4002
4003 hr = cctrl_create_new(This, dwIDCtl, pszLabel, WC_BUTTONW, BS_AUTOCHECKBOX|BS_MULTILINE, 0,
4004 This->cctrl_def_height, &ctrl);
4005 if(SUCCEEDED(hr))
4006 {
4007 ctrl->type = IDLG_CCTRL_CHECKBUTTON;
4008 SendMessageW(ctrl->hwnd, BM_SETCHECK, bChecked ? BST_CHECKED : BST_UNCHECKED, 0);
4009 }
4010
4011 return hr;
4012}
4013
4014static HRESULT WINAPI IFileDialogCustomize_fnAddEditBox(IFileDialogCustomize *iface,
4015 DWORD dwIDCtl,
4016 LPCWSTR pszText)
4017{
4018 FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
4019 customctrl *ctrl;
4020 HRESULT hr;
4021 TRACE("%p (%ld, %p)\n", This, dwIDCtl, pszText);
4022
4023 hr = cctrl_create_new(This, dwIDCtl, pszText, WC_EDITW, ES_AUTOHSCROLL, WS_EX_CLIENTEDGE,
4024 This->cctrl_def_height, &ctrl);
4025 if(SUCCEEDED(hr))
4026 ctrl->type = IDLG_CCTRL_EDITBOX;
4027
4028 return hr;
4029}
4030
4031static HRESULT WINAPI IFileDialogCustomize_fnAddSeparator(IFileDialogCustomize *iface,
4032 DWORD dwIDCtl)
4033{
4034 FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
4035 customctrl *ctrl;
4036 HRESULT hr;
4037 TRACE("%p (%ld)\n", This, dwIDCtl);
4038
4039 hr = cctrl_create_new(This, dwIDCtl, NULL, WC_STATICW, SS_ETCHEDHORZ, 0,
4041 if(SUCCEEDED(hr))
4042 ctrl->type = IDLG_CCTRL_SEPARATOR;
4043
4044 return hr;
4045}
4046
4047static HRESULT WINAPI IFileDialogCustomize_fnAddText(IFileDialogCustomize *iface,
4048 DWORD dwIDCtl,
4049 LPCWSTR pszText)
4050{
4051 FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
4052 customctrl *ctrl;
4053 HRESULT hr;
4054 TRACE("%p (%ld, %p)\n", This, dwIDCtl, pszText);
4055
4056 hr = cctrl_create_new(This, dwIDCtl, pszText, WC_STATICW, 0, 0,
4057 This->cctrl_def_height, &ctrl);
4058 if(SUCCEEDED(hr))
4059 ctrl->type = IDLG_CCTRL_TEXT;
4060
4061 return hr;
4062}
4063
4064static HRESULT WINAPI IFileDialogCustomize_fnSetControlLabel(IFileDialogCustomize *iface,
4065 DWORD dwIDCtl,
4066 LPCWSTR pszLabel)
4067{
4068 FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
4069 customctrl *ctrl = get_cctrl(This, dwIDCtl);
4070 TRACE("%p (%ld, %p)\n", This, dwIDCtl, pszLabel);
4071
4072 if(!ctrl) return E_INVALIDARG;
4073
4074 switch(ctrl->type)
4075 {
4076 case IDLG_CCTRL_MENU:
4077 case IDLG_CCTRL_PUSHBUTTON:
4078 case IDLG_CCTRL_CHECKBUTTON:
4079 case IDLG_CCTRL_TEXT:
4080 case IDLG_CCTRL_VISUALGROUP:
4081 SendMessageW(ctrl->hwnd, WM_SETTEXT, 0, (LPARAM)pszLabel);
4082 break;
4083 case IDLG_CCTRL_OPENDROPDOWN:
4084 return E_NOTIMPL;
4085 default:
4086 break;
4087 }
4088
4089 return S_OK;
4090}
4091
4092static HRESULT WINAPI IFileDialogCustomize_fnGetControlState(IFileDialogCustomize *iface,
4093 DWORD dwIDCtl,
4094 CDCONTROLSTATEF *pdwState)
4095{
4096 FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
4097 customctrl *ctrl = get_cctrl(This, dwIDCtl);
4098 TRACE("%p (%ld, %p)\n", This, dwIDCtl, pdwState);
4099
4100 if(!ctrl || ctrl->type == IDLG_CCTRL_OPENDROPDOWN) return E_NOTIMPL;
4101
4102 *pdwState = ctrl->cdcstate;
4103 return S_OK;
4104}
4105
4106static HRESULT WINAPI IFileDialogCustomize_fnSetControlState(IFileDialogCustomize *iface,
4107 DWORD dwIDCtl,
4108 CDCONTROLSTATEF dwState)
4109{
4110 FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
4111 customctrl *ctrl = get_cctrl(This,dwIDCtl);
4112 TRACE("%p (%ld, %x)\n", This, dwIDCtl, dwState);
4113
4114 if(ctrl && ctrl->hwnd)
4115 {
4116 LONG wndstyle = GetWindowLongW(ctrl->hwnd, GWL_STYLE);
4117
4118 if(dwState & CDCS_ENABLED)
4119 wndstyle &= ~(WS_DISABLED);
4120 else
4121 wndstyle |= WS_DISABLED;
4122
4123 if(dwState & CDCS_VISIBLE)
4124 wndstyle |= WS_VISIBLE;
4125 else
4126 wndstyle &= ~(WS_VISIBLE);
4127
4128 SetWindowLongW(ctrl->hwnd, GWL_STYLE, wndstyle);
4129
4130 /* We save the state separately since at least one application
4131 * relies on being able to hide a control. */
4132 ctrl->cdcstate = dwState;
4133 }
4134
4135 return S_OK;
4136}
4137
4138static HRESULT WINAPI IFileDialogCustomize_fnGetEditBoxText(IFileDialogCustomize *iface,
4139 DWORD dwIDCtl,
4140 WCHAR **ppszText)
4141{
4142 FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
4143 customctrl *ctrl = get_cctrl(This, dwIDCtl);
4144 WCHAR len, *text;
4145 TRACE("%p (%ld, %p)\n", This, dwIDCtl, ppszText);
4146
4147 if(!ctrl || !ctrl->hwnd || !(len = SendMessageW(ctrl->hwnd, WM_GETTEXTLENGTH, 0, 0)))
4148 return E_FAIL;
4149
4150 text = CoTaskMemAlloc(sizeof(WCHAR)*(len+1));
4151 if(!text) return E_FAIL;
4152
4154 *ppszText = text;
4155 return S_OK;
4156}
4157
4158static HRESULT WINAPI IFileDialogCustomize_fnSetEditBoxText(IFileDialogCustomize *iface,
4159 DWORD dwIDCtl,
4160 LPCWSTR pszText)
4161{
4162 FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
4163 customctrl *ctrl = get_cctrl(This, dwIDCtl);
4164 TRACE("%p (%ld, %s)\n", This, dwIDCtl, debugstr_w(pszText));
4165
4166 if(!ctrl || ctrl->type != IDLG_CCTRL_EDITBOX)
4167 return E_FAIL;
4168
4169 SendMessageW(ctrl->hwnd, WM_SETTEXT, 0, (LPARAM)pszText);
4170 return S_OK;
4171}
4172
4173static HRESULT WINAPI IFileDialogCustomize_fnGetCheckButtonState(IFileDialogCustomize *iface,
4174 DWORD dwIDCtl,
4175 BOOL *pbChecked)
4176{
4177 FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
4178 customctrl *ctrl = get_cctrl(This, dwIDCtl);
4179 TRACE("%p (%ld, %p)\n", This, dwIDCtl, pbChecked);
4180
4181 if(ctrl && ctrl->hwnd)
4182 *pbChecked = (SendMessageW(ctrl->hwnd, BM_GETCHECK, 0, 0) == BST_CHECKED);
4183
4184 return S_OK;
4185}
4186
4187static HRESULT WINAPI IFileDialogCustomize_fnSetCheckButtonState(IFileDialogCustomize *iface,
4188 DWORD dwIDCtl,
4189 BOOL bChecked)
4190{
4191 FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
4192 customctrl *ctrl = get_cctrl(This, dwIDCtl);
4193 TRACE("%p (%ld, %d)\n", This, dwIDCtl, bChecked);
4194
4195 if(ctrl && ctrl->hwnd)
4196 SendMessageW(ctrl->hwnd, BM_SETCHECK, bChecked ? BST_CHECKED:BST_UNCHECKED, 0);
4197
4198 return S_OK;
4199}
4200
4201static UINT get_combobox_index_from_id(HWND cb_hwnd, DWORD dwIDItem)
4202{
4203 UINT count = SendMessageW(cb_hwnd, CB_GETCOUNT, 0, 0);
4204 UINT i;
4205 if(!count || (count == CB_ERR))
4206 return -1;
4207
4208 for(i = 0; i < count; i++)
4209 if(SendMessageW(cb_hwnd, CB_GETITEMDATA, i, 0) == dwIDItem)
4210 return i;
4211
4212 TRACE("Item with id %ld not found in combobox %p (item count: %d)\n", dwIDItem, cb_hwnd, count);
4213 return -1;
4214}
4215
4216static HRESULT WINAPI IFileDialogCustomize_fnAddControlItem(IFileDialogCustomize *iface,
4217 DWORD dwIDCtl,
4218 DWORD dwIDItem,
4219 LPCWSTR pszLabel)
4220{
4221 FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
4222 customctrl *ctrl = get_cctrl(This, dwIDCtl);
4223 HRESULT hr;
4224 TRACE("%p (%ld, %ld, %s)\n", This, dwIDCtl, dwIDItem, debugstr_w(pszLabel));
4225
4226 if(!ctrl) return E_FAIL;
4227
4228 switch(ctrl->type)
4229 {
4230 case IDLG_CCTRL_COMBOBOX:
4231 {
4232 UINT index;
4233 cctrl_item* item;
4234
4235 hr = add_item(ctrl, dwIDItem, pszLabel, &item);
4236
4237 if (FAILED(hr)) return hr;
4238
4239 index = SendMessageW(ctrl->hwnd, CB_ADDSTRING, 0, (LPARAM)pszLabel);
4240 SendMessageW(ctrl->hwnd, CB_SETITEMDATA, index, dwIDItem);
4241
4242 return S_OK;
4243 }
4244 case IDLG_CCTRL_MENU:
4245 case IDLG_CCTRL_OPENDROPDOWN:
4246 {
4247 cctrl_item* item;
4248 HMENU hmenu;
4249
4250 hr = add_item(ctrl, dwIDItem, pszLabel, &item);
4251
4252 if (FAILED(hr)) return hr;
4253
4254 if (ctrl->type == IDLG_CCTRL_MENU)
4255 {
4256 TBBUTTON tbb;
4257 SendMessageW(ctrl->hwnd, TB_GETBUTTON, 0, (LPARAM)&tbb);
4258 hmenu = (HMENU)tbb.dwData;
4259 }
4260 else /* ctrl->type == IDLG_CCTRL_OPENDROPDOWN */
4261 hmenu = This->hmenu_opendropdown;
4262
4263 AppendMenuW(hmenu, MF_STRING, dwIDItem, pszLabel);
4264 return S_OK;
4265 }
4266 case IDLG_CCTRL_RADIOBUTTONLIST:
4267 {
4268 cctrl_item* item;
4269
4270 hr = add_item(ctrl, dwIDItem, pszLabel, &item);
4271
4272 if (SUCCEEDED(hr))
4273 {
4274 item->hwnd = CreateWindowExW(0, WC_BUTTONW, pszLabel,
4276 0, 0, 0, 0, ctrl->hwnd, ULongToHandle(dwIDItem), COMDLG32_hInstance, 0);
4277
4278 if (!item->hwnd)
4279 {
4280 ERR("Failed to create radio button\n");
4281 list_remove(&item->entry);
4282 item_free(item);
4283 return E_FAIL;
4284 }
4285 }
4286
4287 return hr;
4288 }
4289 default:
4290 break;
4291 }
4292
4293 return E_NOINTERFACE; /* win7 */
4294}
4295
4296static HRESULT WINAPI IFileDialogCustomize_fnRemoveControlItem(IFileDialogCustomize *iface,
4297 DWORD dwIDCtl,
4298 DWORD dwIDItem)
4299{
4300 FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
4301 customctrl *ctrl = get_cctrl(This, dwIDCtl);
4302 TRACE("%p (%ld, %ld)\n", This, dwIDCtl, dwIDItem);
4303
4304 if(!ctrl) return E_FAIL;
4305
4306 switch(ctrl->type)
4307 {
4308 case IDLG_CCTRL_COMBOBOX:
4309 {
4310 cctrl_item* item;
4311 DWORD position;
4312
4313 item = get_item(ctrl, dwIDItem, CDCS_VISIBLE|CDCS_ENABLED, &position);
4314
4315 if (!item)
4316 return E_INVALIDARG;
4317
4318 if ((item->cdcstate & (CDCS_VISIBLE|CDCS_ENABLED)) == (CDCS_VISIBLE|CDCS_ENABLED))
4319 {
4320 if(SendMessageW(ctrl->hwnd, CB_DELETESTRING, position, 0) == CB_ERR)
4321 return E_FAIL;
4322 }
4323
4324 list_remove(&item->entry);
4325 item_free(item);
4326
4327 return S_OK;
4328 }
4329 case IDLG_CCTRL_MENU:
4330 case IDLG_CCTRL_OPENDROPDOWN:
4331 {
4332 HMENU hmenu;
4333 cctrl_item* item;
4334
4335 item = get_item(ctrl, dwIDItem, 0, NULL);
4336
4337 if (!item)
4338 return E_UNEXPECTED;
4339
4340 if (item->cdcstate & CDCS_VISIBLE)
4341 {
4342 if (ctrl->type == IDLG_CCTRL_MENU)
4343 {
4344 TBBUTTON tbb;
4345 SendMessageW(ctrl->hwnd, TB_GETBUTTON, 0, (LPARAM)&tbb);
4346 hmenu = (HMENU)tbb.dwData;
4347 }
4348 else /* ctrl->type == IDLG_CCTRL_OPENDROPDOWN */
4349 hmenu = This->hmenu_opendropdown;
4350
4351 if(!hmenu || !DeleteMenu(hmenu, dwIDItem, MF_BYCOMMAND))
4352 return E_UNEXPECTED;
4353 }
4354
4355 list_remove(&item->entry);
4356 item_free(item);
4357
4358 return S_OK;
4359 }
4360 case IDLG_CCTRL_RADIOBUTTONLIST:
4361 {
4362 cctrl_item* item;
4363
4364 item = get_item(ctrl, dwIDItem, 0, NULL);
4365
4366 if (!item)
4367 return E_UNEXPECTED;
4368
4369 list_remove(&item->entry);
4370 item_free(item);
4371
4372 return S_OK;
4373 }
4374 default:
4375 break;
4376 }
4377
4378 return E_FAIL;
4379}
4380
4381static HRESULT WINAPI IFileDialogCustomize_fnRemoveAllControlItems(IFileDialogCustomize *iface,
4382 DWORD dwIDCtl)
4383{
4384 FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
4385 TRACE("%p (%ld)\n", This, dwIDCtl);
4386
4387 /* Not implemented by native */
4388 return E_NOTIMPL;
4389}
4390
4391static HRESULT WINAPI IFileDialogCustomize_fnGetControlItemState(IFileDialogCustomize *iface,
4392 DWORD dwIDCtl,
4393 DWORD dwIDItem,
4394 CDCONTROLSTATEF *pdwState)
4395{
4396 FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
4397 customctrl *ctrl = get_cctrl(This, dwIDCtl);
4398 TRACE("%p (%ld, %ld, %p)\n", This, dwIDCtl, dwIDItem, pdwState);
4399
4400 if(!ctrl) return E_FAIL;
4401
4402 switch(ctrl->type)
4403 {
4404 case IDLG_CCTRL_COMBOBOX:
4405 case IDLG_CCTRL_MENU:
4406 case IDLG_CCTRL_OPENDROPDOWN:
4407 case IDLG_CCTRL_RADIOBUTTONLIST:
4408 {
4409 cctrl_item* item;
4410
4411 item = get_item(ctrl, dwIDItem, 0, NULL);
4412
4413 if (!item)
4414 return E_UNEXPECTED;
4415
4416 *pdwState = item->cdcstate;
4417
4418 return S_OK;
4419 }
4420 default:
4421 break;
4422 }
4423
4424 return E_FAIL;
4425}
4426
4427static HRESULT WINAPI IFileDialogCustomize_fnSetControlItemState(IFileDialogCustomize *iface,
4428 DWORD dwIDCtl,
4429 DWORD dwIDItem,
4430 CDCONTROLSTATEF dwState)
4431{
4432 FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
4433 customctrl *ctrl = get_cctrl(This, dwIDCtl);
4434 TRACE("%p (%ld, %ld, %x)\n", This, dwIDCtl, dwIDItem, dwState);
4435
4436 if(!ctrl) return E_FAIL;
4437
4438 switch(ctrl->type)
4439 {
4440 case IDLG_CCTRL_COMBOBOX:
4441 {
4442 cctrl_item* item;
4443 BOOL visible, was_visible;
4444 DWORD position;
4445
4446 item = get_item(ctrl, dwIDItem, CDCS_VISIBLE|CDCS_ENABLED, &position);
4447
4448 if (!item)
4449 return E_UNEXPECTED;
4450
4451 visible = ((dwState & (CDCS_VISIBLE|CDCS_ENABLED)) == (CDCS_VISIBLE|CDCS_ENABLED));
4452 was_visible = ((item->cdcstate & (CDCS_VISIBLE|CDCS_ENABLED)) == (CDCS_VISIBLE|CDCS_ENABLED));
4453
4454 if (visible && !was_visible)
4455 {
4456 SendMessageW(ctrl->hwnd, CB_INSERTSTRING, position, (LPARAM)item->label);
4457 SendMessageW(ctrl->hwnd, CB_SETITEMDATA, position, dwIDItem);
4458 }
4459 else if (!visible && was_visible)
4460 {
4461 SendMessageW(ctrl->hwnd, CB_DELETESTRING, position, 0);
4462 }
4463
4464 item->cdcstate = dwState;
4465
4466 return S_OK;
4467 }
4468 case IDLG_CCTRL_MENU:
4469 case IDLG_CCTRL_OPENDROPDOWN:
4470 {
4471 HMENU hmenu;
4472 cctrl_item* item;
4473 CDCONTROLSTATEF prev_state;
4474 DWORD position;
4475
4476 item = get_item(ctrl, dwIDItem, CDCS_VISIBLE, &position);
4477
4478 if (!item)
4479 return E_UNEXPECTED;
4480
4481 prev_state = item->cdcstate;
4482
4483 if (ctrl->type == IDLG_CCTRL_MENU)
4484 {
4485 TBBUTTON tbb;
4486 SendMessageW(ctrl->hwnd, TB_GETBUTTON, 0, (LPARAM)&tbb);
4487 hmenu = (HMENU)tbb.dwData;
4488 }
4489 else /* ctrl->type == IDLG_CCTRL_OPENDROPDOWN */
4490 hmenu = This->hmenu_opendropdown;
4491
4492 if (dwState & CDCS_VISIBLE)
4493 {
4494 if (prev_state & CDCS_VISIBLE)
4495 {
4496 /* change state */
4497 EnableMenuItem(hmenu, dwIDItem,
4499 }
4500 else
4501 {
4502 /* show item */
4503 MENUITEMINFOW mii;
4504
4505 mii.cbSize = sizeof(mii);
4507 mii.fState = (dwState & CDCS_ENABLED) ? MFS_ENABLED : MFS_DISABLED;
4508 mii.wID = dwIDItem;
4509 mii.dwTypeData = item->label;
4510
4511 InsertMenuItemW(hmenu, position, TRUE, &mii);
4512 }
4513 }
4514 else if (prev_state & CDCS_VISIBLE)
4515 {
4516 /* hide item */
4517 DeleteMenu(hmenu, dwIDItem, MF_BYCOMMAND);
4518 }
4519
4520 item->cdcstate = dwState;
4521
4522 if (ctrl->type == IDLG_CCTRL_OPENDROPDOWN)
4523 {
4524 update_control_text(This);
4525 update_layout(This);
4526 }
4527
4528 return S_OK;
4529 }
4530 case IDLG_CCTRL_RADIOBUTTONLIST:
4531 {
4532 cctrl_item* item;
4533
4534 item = get_item(ctrl, dwIDItem, CDCS_VISIBLE, NULL);
4535
4536 if (!item)
4537 return E_UNEXPECTED;
4538
4539 /* Oddly, native allows setting this but doesn't seem to do anything with it. */
4540 item->cdcstate = dwState;
4541
4542 return S_OK;
4543 }
4544 default:
4545 break;
4546 }
4547
4548 return E_FAIL;
4549}
4550
4551static HRESULT WINAPI IFileDialogCustomize_fnGetSelectedControlItem(IFileDialogCustomize *iface,
4552 DWORD dwIDCtl,
4553 DWORD *pdwIDItem)
4554{
4555 FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
4556 customctrl *ctrl = get_cctrl(This, dwIDCtl);
4557 TRACE("%p (%ld, %p)\n", This, dwIDCtl, pdwIDItem);
4558
4559 if(!ctrl) return E_FAIL;
4560
4561 switch(ctrl->type)
4562 {
4563 case IDLG_CCTRL_COMBOBOX:
4564 {
4565 UINT index = SendMessageW(ctrl->hwnd, CB_GETCURSEL, 0, 0);
4566 if(index == CB_ERR)
4567 return E_FAIL;
4568
4569 *pdwIDItem = SendMessageW(ctrl->hwnd, CB_GETITEMDATA, index, 0);
4570 return S_OK;
4571 }
4572 case IDLG_CCTRL_OPENDROPDOWN:
4573 if (This->opendropdown_has_selection)
4574 {
4575 *pdwIDItem = This->opendropdown_selection;
4576 return S_OK;
4577 }
4578 else
4579 {
4580 /* Return first enabled item. */
4581 cctrl_item* item = get_first_item(ctrl);
4582
4583 if (item)
4584 {
4585 *pdwIDItem = item->id;
4586 return S_OK;
4587 }
4588
4589 WARN("no enabled items in open dropdown\n");
4590 return E_FAIL;
4591 }
4592 case IDLG_CCTRL_RADIOBUTTONLIST:
4593 {
4594 cctrl_item* item;
4595
4596 LIST_FOR_EACH_ENTRY(item, &ctrl->sub_items, cctrl_item, entry)
4597 {
4598 if (SendMessageW(item->hwnd, BM_GETCHECK, 0, 0) == BST_CHECKED)
4599 {
4600 *pdwIDItem = item->id;
4601 return S_OK;
4602 }
4603 }
4604
4605 WARN("no checked items in radio button list\n");
4606 return E_FAIL;
4607 }
4608 default:
4609 FIXME("Unsupported control type %d\n", ctrl->type);
4610 }
4611
4612 return E_NOTIMPL;
4613}
4614
4615static HRESULT WINAPI IFileDialogCustomize_fnSetSelectedControlItem(IFileDialogCustomize *iface,
4616 DWORD dwIDCtl,
4617 DWORD dwIDItem)
4618{
4619 FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
4620 customctrl *ctrl = get_cctrl(This, dwIDCtl);
4621 TRACE("%p (%ld, %ld)\n", This, dwIDCtl, dwIDItem);
4622
4623 if(!ctrl) return E_INVALIDARG;
4624
4625 switch(ctrl->type)
4626 {
4627 case IDLG_CCTRL_COMBOBOX:
4628 {
4629 UINT index = get_combobox_index_from_id(ctrl->hwnd, dwIDItem);
4630
4631 if(index == -1)
4632 return E_INVALIDARG;
4633
4634 if(SendMessageW(ctrl->hwnd, CB_SETCURSEL, index, 0) == CB_ERR)
4635 return E_FAIL;
4636
4637 return S_OK;
4638 }
4639 case IDLG_CCTRL_RADIOBUTTONLIST:
4640 {
4641 cctrl_item* item;
4642
4643 item = get_item(ctrl, dwIDItem, 0, NULL);
4644
4645 if (item)
4646 {
4647 radiobuttonlist_set_selected_item(This, ctrl, item);
4648 return S_OK;
4649 }
4650
4651 return E_INVALIDARG;
4652 }
4653 default:
4654 FIXME("Unsupported control type %d\n", ctrl->type);
4655 }
4656
4657 return E_INVALIDARG;
4658}
4659
4660static HRESULT WINAPI IFileDialogCustomize_fnStartVisualGroup(IFileDialogCustomize *iface,
4661 DWORD dwIDCtl,
4662 LPCWSTR pszLabel)
4663{
4664 FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
4665 customctrl *vg;
4666 HRESULT hr;
4667 TRACE("%p (%ld, %s)\n", This, dwIDCtl, debugstr_w(pszLabel));
4668
4669 if(This->cctrl_active_vg)
4670 return E_UNEXPECTED;
4671
4672 hr = cctrl_create_new(This, dwIDCtl, pszLabel, WC_STATICW, 0, 0,
4673 This->cctrl_def_height, &vg);
4674 if(SUCCEEDED(hr))
4675 {
4676 vg->type = IDLG_CCTRL_VISUALGROUP;
4677 This->cctrl_active_vg = vg;
4678 }
4679
4680 return hr;
4681}
4682
4683static HRESULT WINAPI IFileDialogCustomize_fnEndVisualGroup(IFileDialogCustomize *iface)
4684{
4685 FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
4686 TRACE("%p\n", This);
4687
4688 This->cctrl_active_vg = NULL;
4689
4690 return S_OK;
4691}
4692
4693static HRESULT WINAPI IFileDialogCustomize_fnMakeProminent(IFileDialogCustomize *iface,
4694 DWORD dwIDCtl)
4695{
4696 FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
4697 FIXME("stub - %p (%ld)\n", This, dwIDCtl);
4698 return S_OK;
4699}
4700
4701static HRESULT WINAPI IFileDialogCustomize_fnSetControlItemText(IFileDialogCustomize *iface,
4702 DWORD dwIDCtl,
4703 DWORD dwIDItem,
4704 LPCWSTR pszLabel)
4705{
4706 FileDialogImpl *This = impl_from_IFileDialogCustomize(iface);
4707 FIXME("stub - %p (%ld, %ld, %s)\n", This, dwIDCtl, dwIDItem, debugstr_w(pszLabel));
4708 return E_NOTIMPL;
4709}
4710
4711static const IFileDialogCustomizeVtbl vt_IFileDialogCustomize = {
4712 IFileDialogCustomize_fnQueryInterface,
4713 IFileDialogCustomize_fnAddRef,
4714 IFileDialogCustomize_fnRelease,
4715 IFileDialogCustomize_fnEnableOpenDropDown,
4716 IFileDialogCustomize_fnAddMenu,
4717 IFileDialogCustomize_fnAddPushButton,
4718 IFileDialogCustomize_fnAddComboBox,
4719 IFileDialogCustomize_fnAddRadioButtonList,
4720 IFileDialogCustomize_fnAddCheckButton,
4721 IFileDialogCustomize_fnAddEditBox,
4722 IFileDialogCustomize_fnAddSeparator,
4723 IFileDialogCustomize_fnAddText,
4724 IFileDialogCustomize_fnSetControlLabel,
4725 IFileDialogCustomize_fnGetControlState,
4726 IFileDialogCustomize_fnSetControlState,
4727 IFileDialogCustomize_fnGetEditBoxText,
4728 IFileDialogCustomize_fnSetEditBoxText,
4729 IFileDialogCustomize_fnGetCheckButtonState,
4730 IFileDialogCustomize_fnSetCheckButtonState,
4731 IFileDialogCustomize_fnAddControlItem,
4732 IFileDialogCustomize_fnRemoveControlItem,
4733 IFileDialogCustomize_fnRemoveAllControlItems,
4734 IFileDialogCustomize_fnGetControlItemState,
4735 IFileDialogCustomize_fnSetControlItemState,
4736 IFileDialogCustomize_fnGetSelectedControlItem,
4737 IFileDialogCustomize_fnSetSelectedControlItem,
4738 IFileDialogCustomize_fnStartVisualGroup,
4739 IFileDialogCustomize_fnEndVisualGroup,
4740 IFileDialogCustomize_fnMakeProminent,
4741 IFileDialogCustomize_fnSetControlItemText
4742};
4743
4744#if (DLL_EXPORT_VERSION <= _WIN32_WINNT_VISTA)
4747{
4748 LPITEMIDLIST pidl;
4749 HRESULT ret;
4750
4751 ret = SHGetIDListFromObject(punk, &pidl);
4752 if(SUCCEEDED(ret))
4753 {
4755 ILFree(pidl);
4756 }
4757
4758 return ret;
4759}
4760#endif
4761
4762static HRESULT FileDialog_constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv, enum ITEMDLG_TYPE type)
4763{
4764 FileDialogImpl *fdimpl;
4765 HRESULT hr;
4766 IShellFolder *psf;
4767 TRACE("%p, %s, %p\n", pUnkOuter, debugstr_guid(riid), ppv);
4768
4769 if(!ppv)
4770 return E_POINTER;
4771 if(pUnkOuter)
4772 return CLASS_E_NOAGGREGATION;
4773
4774 fdimpl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FileDialogImpl));
4775 if(!fdimpl)
4776 return E_OUTOFMEMORY;
4777
4778 fdimpl->ref = 1;
4779 fdimpl->IFileDialog2_iface.lpVtbl = &vt_IFileDialog2;
4780 fdimpl->IExplorerBrowserEvents_iface.lpVtbl = &vt_IExplorerBrowserEvents;
4781 fdimpl->IServiceProvider_iface.lpVtbl = &vt_IServiceProvider;
4782 fdimpl->ICommDlgBrowser3_iface.lpVtbl = &vt_ICommDlgBrowser3;
4783 fdimpl->IOleWindow_iface.lpVtbl = &vt_IOleWindow;
4784 fdimpl->IFileDialogCustomize_iface.lpVtbl = &vt_IFileDialogCustomize;
4785
4786 if(type == ITEMDLG_TYPE_OPEN)
4787 {
4788 fdimpl->dlg_type = ITEMDLG_TYPE_OPEN;
4789 fdimpl->u.IFileOpenDialog_iface.lpVtbl = &vt_IFileOpenDialog;
4790 fdimpl->options = FOS_PATHMUSTEXIST | FOS_FILEMUSTEXIST | FOS_NOCHANGEDIR;
4791 fdimpl->custom_title = fdimpl->custom_okbutton = NULL;
4792 }
4793 else
4794 {
4795 WCHAR buf[16];
4796 fdimpl->dlg_type = ITEMDLG_TYPE_SAVE;
4797 fdimpl->u.IFileSaveDialog_iface.lpVtbl = &vt_IFileSaveDialog;
4798 fdimpl->options = FOS_OVERWRITEPROMPT | FOS_NOREADONLYRETURN | FOS_PATHMUSTEXIST | FOS_NOCHANGEDIR;
4799
4801 fdimpl->custom_title = StrDupW(buf);
4802 fdimpl->custom_okbutton = StrDupW(buf);
4803 }
4804
4805 list_init(&fdimpl->events_clients);
4806
4807 /* FIXME: The default folder setting should be restored for the
4808 * application if it was previously set. */
4809 SHGetDesktopFolder(&psf);
4810 SHGetItemFromObject((IUnknown*)psf, &IID_IShellItem, (void**)&fdimpl->psi_defaultfolder);
4811 IShellFolder_Release(psf);
4812
4813 hr = init_custom_controls(fdimpl);
4814 if(FAILED(hr))
4815 {
4816 ERR("Failed to initialize custom controls (0x%08lx).\n", hr);
4817 IFileDialog2_Release(&fdimpl->IFileDialog2_iface);
4818 return E_FAIL;
4819 }
4820
4821 fdimpl->user_actctx = INVALID_HANDLE_VALUE;
4822
4823 hr = IFileDialog2_QueryInterface(&fdimpl->IFileDialog2_iface, riid, ppv);
4824 IFileDialog2_Release(&fdimpl->IFileDialog2_iface);
4825 return hr;
4826}
4827
4829{
4830 return FileDialog_constructor(pUnkOuter, riid, ppv, ITEMDLG_TYPE_OPEN);
4831}
4832
4834{
4835 return FileDialog_constructor(pUnkOuter, riid, ppv, ITEMDLG_TYPE_SAVE);
4836}
4837
4838#endif /* (DLL_EXPORT_VERSION >= 0x600) && defined(__REACTOS__) */
HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
EXTERN_C HRESULT WINAPI SHCreateShellItemArrayFromDataObject(_In_ IDataObject *pdo, _In_ REFIID riid, _Out_ void **ppv)
EXTERN_C HRESULT WINAPI SHCreateShellItemArray(_In_opt_ PCIDLIST_ABSOLUTE pidlParent, _In_opt_ IShellFolder *psf, _In_ UINT cidl, _In_reads_opt_(cidl) PCUITEMID_CHILD_ARRAY ppidl, _Out_ IShellItemArray **ppsiItemArray)
UINT cchMax
@ lparam
Definition: SystemMenu.c:31
@ wparam
Definition: SystemMenu.c:30
static struct local_server * impl_from_IServiceProvider(IServiceProvider *iface)
Definition: apartment.c:234
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define msg(x)
Definition: auth_time.c:54
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define index(s, c)
Definition: various.h:29
#define ARRAY_SIZE(A)
Definition: main.h:20
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
static void list_init(struct list_entry *head)
Definition: list.h:51
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
#define ULongToHandle(h)
Definition: basetsd.h:75
#define EXTERN_C
Definition: basetyps.h:12
const GUID IID_IUnknown
static void add_item(btrfs_root *r, uint64_t obj_id, uint8_t obj_type, uint64_t offset, void *data, uint16_t size)
Definition: btrfslib.c:339
int COMDLG32_SplitFileNames(LPWSTR lpstrEdit, UINT nStrLen, LPWSTR *lpstrFileList, UINT *sizeUsed)
Definition: filedlg.c:780
void COMDLG32_GetCanonicalPath(PCIDLIST_ABSOLUTE pidlAbsCurrent, LPWSTR lpstrFile, LPWSTR lpstrPathAndFile)
Definition: filedlg.c:740
HRESULT FileOpenDialog_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv)
int FILEDLG95_ValidatePathAction(LPWSTR lpstrPathAndFile, IShellFolder **ppsf, HWND hwnd, DWORD flags, BOOL isSaveDlg, int defAction)
Definition: filedlg.c:2947
#define IDS_SAVE
Definition: cdlg.h:158
#define ONOPEN_OPEN
Definition: cdlg.h:196
#define ONOPEN_BROWSE
Definition: cdlg.h:195
void FILEDLG95_OnOpenMessage(HWND hwnd, int idCaption, int idText)
Definition: filedlg.c:2846
HANDLE COMDLG32_hActCtx
Definition: cdlg32.c:46
HINSTANCE COMDLG32_hInstance
Definition: cdlg32.c:42
HRESULT FileSaveDialog_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv)
#define ONOPEN_SEARCH
Definition: cdlg.h:197
#define IDS_SELECT_FOLDER
Definition: cdlg.h:161
Definition: list.h:39
LPARAM lParam
Definition: combotst.c:139
BOOL WINAPI InitCommonControlsEx(const INITCOMMONCONTROLSEX *lpInitCtrls)
Definition: commctrl.c:904
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
HRESULT hr
Definition: delayimp.cpp:582
#define psh1
Definition: dlgs.h:117
#define pshHelp
Definition: dlgs.h:132
#define NEWFILEOPENV3ORD
Definition: dlgs.h:30
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, IUnknown *outer, DWORD cls_context, REFIID riid, void **obj)
Definition: combase.c:1685
void *WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: malloc.c:381
void WINAPI CoTaskMemFree(void *ptr)
Definition: malloc.c:389
LPWSTR WINAPI StrChrW(LPCWSTR lpszStr, WCHAR ch)
Definition: string.c:464
#define GetProcessHeap()
Definition: compat.h:736
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
HANDLE HWND
Definition: compat.h:19
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CALLBACK
Definition: compat.h:35
#define lstrcpyW
Definition: compat.h:749
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
static const WCHAR *const ext[]
Definition: module.c:53
VOID WINAPI ReleaseActCtx(IN HANDLE hActCtx)
Definition: actctx.c:208
BOOL WINAPI DeactivateActCtx(IN DWORD dwFlags, IN ULONG_PTR ulCookie)
Definition: actctx.c:268
BOOL WINAPI GetCurrentActCtx(OUT PHANDLE phActCtx)
Definition: actctx.c:298
BOOL WINAPI ActivateActCtx(IN HANDLE hActCtx, OUT PULONG_PTR ulCookie)
Definition: actctx.c:237
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:636
void WINAPI PathRemoveExtensionW(WCHAR *path)
Definition: path.c:1922
LPWSTR WINAPI PathFindExtensionW(const WCHAR *path)
Definition: path.c:1250
BOOL WINAPI PathMatchSpecW(const WCHAR *path, const WCHAR *mask)
Definition: path.c:2497
BOOL WINAPI PathFileExistsW(const WCHAR *path)
Definition: path.c:2583
WCHAR *WINAPI StrDupW(const WCHAR *str)
Definition: string.c:317
GUID guid
Definition: version.c:147
const WCHAR * text
Definition: package.c:1826
_ACRTIMP wchar_t *__cdecl wcspbrk(const wchar_t *, const wchar_t *)
Definition: wcs.c:2021
HRESULT WINAPI DECLSPEC_HOTPATCH OleInitialize(LPVOID reserved)
Definition: ole2.c:162
EXTERN_C HRESULT WINAPI SHGetItemFromObject(_In_ IUnknown *punk, _In_ REFIID riid, _Out_ void **ppv)
Definition: CShellItem.cpp:766
EXTERN_C HRESULT WINAPI SHCreateItemFromIDList(_In_ PCIDLIST_ABSOLUTE pidl, _In_ REFIID riid, _Out_ void **ppv)
Definition: CShellItem.cpp:512
#define pt(x, y)
Definition: drawing.c:79
return ret
Definition: mutex.c:147
#define L(x)
Definition: resources.c:13
r parent
Definition: btrfs.c:3010
static ULONG WINAPI IServiceProvider_fnRelease(IServiceProvider *iface)
Definition: ebrowser.c:495
static HRESULT WINAPI ICommDlgBrowser3_fnOnColumnClicked(ICommDlgBrowser3 *iface, IShellView *ppshv, int iColumn)
Definition: ebrowser.c:394
static HRESULT WINAPI IExplorerBrowserEvents_fnOnNavigationComplete(IExplorerBrowserEvents *iface, PCIDLIST_ABSOLUTE pidlFolder)
Definition: ebrowser.c:174
static HRESULT WINAPI ICommDlgBrowser3_fnGetDefaultMenuText(ICommDlgBrowser3 *iface, IShellView *ppshv, LPWSTR pszText, int cchMax)
Definition: ebrowser.c:374
static ULONG WINAPI IExplorerBrowserEvents_fnRelease(IExplorerBrowserEvents *iface)
Definition: ebrowser.c:160
static HRESULT WINAPI IServiceProvider_fnQueryService(IServiceProvider *iface, REFGUID guidService, REFIID riid, void **ppv)
Definition: ebrowser.c:506
static HRESULT WINAPI ICommDlgBrowser3_fnGetCurrentFilter(ICommDlgBrowser3 *iface, LPWSTR pszFileSpec, int cchFileSpec)
Definition: ebrowser.c:404
static ULONG WINAPI IExplorerBrowserEvents_fnAddRef(IExplorerBrowserEvents *iface)
Definition: ebrowser.c:154
static HRESULT WINAPI ICommDlgBrowser3_fnQueryInterface(ICommDlgBrowser3 *iface, REFIID riid, LPVOID *ppvObj)
Definition: ebrowser.c:313
static ULONG WINAPI ICommDlgBrowser3_fnAddRef(ICommDlgBrowser3 *iface)
Definition: ebrowser.c:320
static HRESULT WINAPI IServiceProvider_fnQueryInterface(IServiceProvider *iface, REFIID riid, LPVOID *ppvObj)
Definition: ebrowser.c:469
static HRESULT WINAPI ICommDlgBrowser3_fnOnDefaultCommand(ICommDlgBrowser3 *iface, IShellView *shv)
Definition: ebrowser.c:337
static HRESULT WINAPI ICommDlgBrowser3_fnOnPreviewCreated(ICommDlgBrowser3 *iface, IShellView *ppshv)
Definition: ebrowser.c:414
static ULONG WINAPI IServiceProvider_fnAddRef(IServiceProvider *iface)
Definition: ebrowser.c:489
static HRESULT WINAPI ICommDlgBrowser3_fnNotify(ICommDlgBrowser3 *iface, IShellView *ppshv, DWORD dwNotifyType)
Definition: ebrowser.c:364
static IShellFolder IShellItem **static IBindCtx LPITEMIDLIST SFGAOF
Definition: ebrowser.c:83
static HRESULT WINAPI IExplorerBrowserEvents_fnQueryInterface(IExplorerBrowserEvents *iface, REFIID riid, void **ppvObj)
Definition: ebrowser.c:147
static HRESULT WINAPI IExplorerBrowserEvents_fnOnNavigationPending(IExplorerBrowserEvents *iface, PCIDLIST_ABSOLUTE pidlFolder)
Definition: ebrowser.c:166
static HRESULT WINAPI IExplorerBrowserEvents_fnOnViewCreated(IExplorerBrowserEvents *iface, IShellView *psv)
Definition: ebrowser.c:188
static IExplorerBrowserEventsImpl * impl_from_IExplorerBrowserEvents(IExplorerBrowserEvents *iface)
Definition: ebrowser.c:142
static HRESULT WINAPI ICommDlgBrowser3_fnIncludeObject(ICommDlgBrowser3 *iface, IShellView *shv, LPCITEMIDLIST pidl)
Definition: ebrowser.c:354
static HRESULT WINAPI ICommDlgBrowser3_fnGetViewFlags(ICommDlgBrowser3 *iface, DWORD *pdwFlags)
Definition: ebrowser.c:385
static ICommDlgBrowser3Impl * impl_from_ICommDlgBrowser3(ICommDlgBrowser3 *iface)
Definition: ebrowser.c:308
static HRESULT WINAPI IExplorerBrowserEvents_fnOnNavigationFailed(IExplorerBrowserEvents *iface, PCIDLIST_ABSOLUTE pidlFolder)
Definition: ebrowser.c:181
static HRESULT WINAPI ICommDlgBrowser3_fnOnStateChange(ICommDlgBrowser3 *iface, IShellView *shv, ULONG uChange)
Definition: ebrowser.c:344
static ULONG WINAPI ICommDlgBrowser3_fnRelease(ICommDlgBrowser3 *iface)
Definition: ebrowser.c:326
#define IDS_FILENOTEXISTING
#define IDS_INVALID_FOLDERNAME
#define IDC_FILETYPESTATIC
#define IDC_FILENAMESTATIC
#define IDS_OVERWRITEFILE
#define IDC_FILENAME
#define IDC_FILETYPE
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
static void get_first_item(tree *t, KEY *key)
Definition: flushthread.c:2972
FxChildList * pList
pKey DeleteObject()
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLint GLsizei width
Definition: gl.h:1546
GLuint res
Definition: glext.h:9613
GLuint GLuint * names
Definition: glext.h:11545
GLsizeiptr size
Definition: glext.h:5919
const GLubyte * c
Definition: glext.h:8905
GLuint index
Definition: glext.h:6031
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint64EXT * result
Definition: glext.h:11304
GLenum GLsizei len
Definition: glext.h:6722
GLuint id
Definition: glext.h:5910
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
unsigned int UINT
Definition: sysinfo.c:13
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
const char cursor[]
Definition: icontest.c:13
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
const char * filename
Definition: ioapi.h:137
uint32_t entry
Definition: isohybrid.c:63
#define c
Definition: ke_i.h:80
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_w
Definition: kernel32.h:32
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
LONG_PTR LPARAM
Definition: minwindef.h:175
LONG_PTR LRESULT
Definition: minwindef.h:176
UINT_PTR WPARAM
Definition: minwindef.h:174
char string[160]
Definition: util.h:11
HDC hdc
Definition: main.c:9
DWORD button
Definition: button.c:166
static HDC
Definition: imagelist.c:88
static const WCHAR label[]
Definition: itemdlg.c:1608
const IID IID_IObjectWithSite
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:60
static DWORD parent_id
Definition: cursoricon.c:2424
static HWND child
Definition: cursoricon.c:298
#define ctrl
Definition: input.c:3281
static MONITORINFO mi
Definition: win.c:9400
static HMENU hmenu
Definition: win.c:78
#define min(a, b)
Definition: monoChain.cc:55
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
INT WINAPI MulDiv(INT nNumber, INT nNumerator, INT nDenominator)
Definition: muldiv.c:25
Definition: mk_font.cpp:20
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define DWORD
Definition: nt_native.h:44
const GUID IID_IOleWindow
const GUID IID_IDataObject
static HANDLE ACCESS_MASK ULONG attributes
Definition: om.c:94
#define LOWORD(l)
Definition: pedump.c:82
#define WS_CHILD
Definition: pedump.c:617
#define WS_TABSTOP
Definition: pedump.c:634
short WCHAR
Definition: pedump.c:58
#define WS_POPUP
Definition: pedump.c:616
#define ES_AUTOHSCROLL
Definition: pedump.c:672
#define WS_VISIBLE
Definition: pedump.c:620
#define BS_AUTOCHECKBOX
Definition: pedump.c:654
long LONG
Definition: pedump.c:60
#define WS_DISABLED
Definition: pedump.c:621
#define WS_CLIPSIBLINGS
Definition: pedump.c:618
#define BS_RADIOBUTTON
Definition: pedump.c:655
#define WS_CLIPCHILDREN
Definition: pedump.c:619
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:1051
HRESULT WINAPI SHGetIDListFromObject(IUnknown *punk, PIDLIST_ABSOLUTE *ppidl)
Definition: pidl.c:1682
LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
Definition: pidl.c:817
#define WC_BUTTONW
Definition: commctrl.h:4628
#define BTNS_BUTTON
Definition: commctrl.h:998
#define IDB_VIEW_LARGE_COLOR
Definition: commctrl.h:1067
#define VIEW_PARENTFOLDER
Definition: commctrl.h:1095
#define TB_AUTOSIZE
Definition: commctrl.h:1137
#define IDB_HIST_LARGE_COLOR
Definition: commctrl.h:1069
#define WC_EDITW
Definition: commctrl.h:4692
#define HINST_COMMCTRL
Definition: commctrl.h:1063
#define TBDDRET_DEFAULT
Definition: commctrl.h:1424
#define TB_BUTTONSTRUCTSIZE
Definition: commctrl.h:1134
#define TB_GETBUTTON
Definition: commctrl.h:1109
#define TB_SETBUTTONSIZE
Definition: commctrl.h:1135
#define CCS_NODIVIDER
Definition: commctrl.h:2253
#define TOOLBARCLASSNAMEW
Definition: commctrl.h:943
#define HIST_BACK
Definition: commctrl.h:1100
#define TBSTATE_ENABLED
Definition: commctrl.h:974
#define TBSTYLE_FLAT
Definition: commctrl.h:992
#define TB_ADDBUTTONSW
Definition: commctrl.h:1266
#define WC_STATICW
Definition: commctrl.h:4685
#define I_IMAGENONE
Definition: commctrl.h:2391
#define TBN_DROPDOWN
Definition: commctrl.h:1316
#define HIST_FORWARD
Definition: commctrl.h:1101
#define BTNS_WHOLEDROPDOWN
Definition: commctrl.h:1007
#define TB_ADDBITMAP
Definition: commctrl.h:1056
#define WC_COMBOBOXW
Definition: commctrl.h:4722
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8)
Definition: guiddef.h:68
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
_In_opt_ IUnknown * punk
Definition: shlwapi.h:158
_In_ LPCSTR pszSpec
Definition: shlwapi.h:354
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
#define CS_VREDRAW
Definition: winuser.h:666
#define CB_SETITEMDATA
Definition: winuser.h:1995
HMENU WINAPI CreatePopupMenu(void)
Definition: menu.c:838
#define WM_GETTEXTLENGTH
Definition: winuser.h:1647
#define SW_HIDE
Definition: winuser.h:779
#define CB_SETDROPPEDWIDTH
Definition: winuser.h:1991
#define SWP_NOACTIVATE
Definition: winuser.h:1253
#define MNS_NOTIFYBYPOS
Definition: winuser.h:770
#define MF_BYCOMMAND
Definition: winuser.h:202
#define MIIM_STRING
Definition: winuser.h:738
#define GetWindowLongPtrW
Definition: winuser.h:4983
#define SM_CYEDGE
Definition: winuser.h:1020
#define MIIM_ID
Definition: winuser.h:733
#define MAKELPARAM(l, h)
Definition: winuser.h:4116
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define CBS_DROPDOWNLIST
Definition: winuser.h:284
#define IDCANCEL
Definition: winuser.h:842
#define BST_UNCHECKED
Definition: winuser.h:199
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
BOOL WINAPI SetWindowPos(_In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
#define SM_CXVSCROLL
Definition: winuser.h:972
HWND WINAPI SetParent(_In_ HWND, _In_opt_ HWND)
#define WM_SIZE
Definition: winuser.h:1639
LONG WINAPI SetWindowLongW(_In_ HWND, _In_ int, _In_ LONG)
LONG WINAPI GetWindowLongW(_In_ HWND, _In_ int)
#define SWP_NOMOVE
Definition: winuser.h:1255
#define WM_COMMAND
Definition: winuser.h:1768
#define CS_HREDRAW
Definition: winuser.h:661
#define MF_STRING
Definition: winuser.h:138
ATOM WINAPI RegisterClassW(_In_ CONST WNDCLASSW *)
#define CB_ERR
Definition: winuser.h:2471
#define IDC_ARROW
Definition: winuser.h:695
#define CB_SETCURSEL
Definition: winuser.h:1990
#define MFS_DISABLED
Definition: winuser.h:760
BOOL WINAPI SetDlgItemTextW(_In_ HWND, _In_ int, _In_ LPCWSTR)
BOOL WINAPI DeleteMenu(_In_ HMENU, _In_ UINT, _In_ UINT)
#define SWP_NOSIZE
Definition: winuser.h:1256
#define WM_GETTEXT
Definition: winuser.h:1646
#define SS_ETCHEDHORZ
Definition: winuser.h:343
#define WM_INITDIALOG
Definition: winuser.h:1767
#define WM_LBUTTONDOWN
Definition: winuser.h:1804
#define MB_YESNO
Definition: winuser.h:828
BOOL WINAPI EndDeferWindowPos(_In_ HDWP)
#define CB_GETCOUNT
Definition: winuser.h:1971
HCURSOR WINAPI LoadCursorW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2474
int WINAPI MapWindowPoints(_In_opt_ HWND hWndFrom, _In_opt_ HWND hWndTo, _Inout_updates_(cPoints) LPPOINT lpPoints, _In_ UINT cPoints)
#define WM_GETFONT
Definition: winuser.h:1679
int WINAPI MessageBoxW(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType)
BOOL WINAPI ClientToScreen(_In_ HWND, _Inout_ LPPOINT)
HWND WINAPI GetDlgItem(_In_opt_ HWND, _In_ int)
#define IDOK
Definition: winuser.h:841
#define CBN_SELCHANGE
Definition: winuser.h:2008
#define WM_NCCREATE
Definition: winuser.h:1711
#define BM_SETCHECK
Definition: winuser.h:1950
#define MIIM_STATE
Definition: winuser.h:732
#define BS_MULTILINE
Definition: winuser.h:267
BOOL WINAPI SetWindowTextW(_In_ HWND, _In_opt_ LPCWSTR)
#define WM_SETTEXT
Definition: winuser.h:1645
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
#define WM_GETMINMAXINFO
Definition: winuser.h:1668
HWND WINAPI SetFocus(_In_opt_ HWND)
BOOL WINAPI PeekMessageW(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
#define WM_SETFONT
Definition: winuser.h:1678
HWND WINAPI CreateWindowExW(_In_ DWORD dwExStyle, _In_opt_ LPCWSTR lpClassName, _In_opt_ LPCWSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
#define PM_REMOVE
Definition: winuser.h:1207
#define IDNO
Definition: winuser.h:847
#define CB_ADDSTRING
Definition: winuser.h:1965
BOOL WINAPI SetPropW(_In_ HWND, _In_ LPCWSTR, _In_opt_ HANDLE)
BOOL WINAPI SetMenuInfo(_In_ HMENU, _In_ LPCMENUINFO)
#define CB_GETITEMDATA
Definition: winuser.h:1979
HDC WINAPI GetDC(_In_opt_ HWND)
#define MB_ICONEXCLAMATION
Definition: winuser.h:796
#define MB_OK
Definition: winuser.h:801
#define MFS_ENABLED
Definition: winuser.h:761
HANDLE WINAPI GetPropW(_In_ HWND, _In_ LPCWSTR)
BOOL WINAPI DestroyMenu(_In_ HMENU)
BOOL WINAPI GetMenuItemInfoW(_In_ HMENU, _In_ UINT, _In_ BOOL, _Inout_ LPMENUITEMINFOW)
#define GWLP_ID
Definition: winuser.h:871
int WINAPI GetDlgCtrlID(_In_ HWND)
HDWP WINAPI DeferWindowPos(_In_ HDWP, _In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
#define BN_CLICKED
Definition: winuser.h:1954
#define SW_SHOW
Definition: winuser.h:786
BOOL WINAPI TrackPopupMenu(_In_ HMENU, _In_ UINT, _In_ int, _In_ int, _Reserved_ int, _In_ HWND, _Reserved_ LPCRECT)
#define WM_DESTROY
Definition: winuser.h:1637
#define WS_EX_CLIENTEDGE
Definition: winuser.h:384
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
#define CB_INSERTSTRING
Definition: winuser.h:1986
LRESULT(CALLBACK * WNDPROC)(HWND, UINT, WPARAM, LPARAM)
Definition: winuser.h:3014
#define USER_DEFAULT_SCREEN_DPI
Definition: winuser.h:5085
#define TPM_RETURNCMD
Definition: winuser.h:2423
#define SWP_NOZORDER
Definition: winuser.h:1258
#define CB_GETCURSEL
Definition: winuser.h:1972
BOOL WINAPI GetClassInfoW(_In_opt_ HINSTANCE, _In_ LPCWSTR, _Out_ LPWNDCLASSW)
#define SetWindowLongPtrW
Definition: winuser.h:5512
#define CB_DELETESTRING
Definition: winuser.h:1966
LRESULT WINAPI CallWindowProcW(_In_ WNDPROC, _In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define GWL_STYLE
Definition: winuser.h:863
BOOL WINAPI DestroyWindow(_In_ HWND)
BOOL WINAPI EnableMenuItem(_In_ HMENU, _In_ UINT, _In_ UINT)
int WINAPI GetSystemMetrics(_In_ int)
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define BST_CHECKED
Definition: winuser.h:197
BOOL WINAPI InsertMenuItemW(_In_ HMENU, _In_ UINT, _In_ BOOL, _In_ LPCMENUITEMINFOW)
#define COLOR_BTNFACE
Definition: winuser.h:939
INT_PTR WINAPI DialogBoxParamW(_In_opt_ HINSTANCE, _In_ LPCWSTR, _In_opt_ HWND, _In_opt_ DLGPROC, _In_ LPARAM)
#define BM_GETCHECK
Definition: winuser.h:1947
HDWP WINAPI BeginDeferWindowPos(_In_ int)
BOOL WINAPI AppendMenuW(_In_ HMENU, _In_ UINT, _In_ UINT_PTR, _In_opt_ LPCWSTR)
BOOL WINAPI EndDialog(_In_ HWND, _In_ INT_PTR)
#define get_file_name
Definition: regproc.h:51
#define WM_NOTIFY
Definition: richedit.h:61
const WCHAR * str
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:236
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:242
#define LoadStringW
Definition: utils.h:64
#define memset(x, y, z)
Definition: compat.h:39
static FILE * client
Definition: client.c:37
PIDLIST_ABSOLUTE WINAPI SHSimpleIDListFromPath(PCWSTR)
@ FWF_SINGLESEL
Definition: shobjidl.idl:693
FDE_OVERWRITE_RESPONSE
Definition: shobjidl.idl:3579
@ FDEOR_DEFAULT
Definition: shobjidl.idl:3580
@ FDEOR_REFUSE
Definition: shobjidl.idl:3582
v1_enum CDCS_VISIBLE
v1_enum CDCS_ENABLED
@ EBO_NOBORDER
Definition: shobjidl.idl:3124
@ EBO_SHOWFRAMES
Definition: shobjidl.idl:3119
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
const PCUITEMID_CHILD * PCUITEMID_CHILD_ARRAY
Definition: shtypes.idl:71
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
#define TRACE(s)
Definition: solgame.cpp:4
LONG lfHeight
Definition: dimm.idl:59
WCHAR lfFaceName[LF_FACESIZE]
Definition: dimm.idl:72
BYTE lfCharSet
Definition: dimm.idl:67
long y
Definition: dcommon.idl:24
long x
Definition: dcommon.idl:24
Definition: dcommon.idl:28
long bottom
Definition: dcommon.idl:29
long right
Definition: dcommon.idl:29
long left
Definition: dcommon.idl:29
long top
Definition: dcommon.idl:29
Definition: scsiwmi.h:51
BYTE fsState
Definition: commctrl.h:951
INT_PTR iString
Definition: commctrl.h:959
int idCommand
Definition: commctrl.h:950
DWORD_PTR dwData
Definition: commctrl.h:958
int iBitmap
Definition: commctrl.h:949
BYTE fsStyle
Definition: commctrl.h:952
LPCWSTR lpszClassName
Definition: winuser.h:3293
LPCWSTR lpszMenuName
Definition: winuser.h:3292
HBRUSH hbrBackground
Definition: winuser.h:3291
HICON hIcon
Definition: winuser.h:3289
HINSTANCE hInstance
Definition: winuser.h:3288
int cbClsExtra
Definition: winuser.h:3286
UINT style
Definition: winuser.h:3284
WNDPROC lpfnWndProc
Definition: winuser.h:3285
int cbWndExtra
Definition: winuser.h:3287
HCURSOR hCursor
Definition: winuser.h:3290
Definition: cookie.c:202
Definition: cookie.c:34
struct list entry
Definition: wpp.c:51
Definition: fci.c:123
Definition: filter.c:165
Definition: fci.c:112
Definition: tftpd.h:60
Definition: send.c:48
LPVOID lpCreateParams
Definition: winuser.h:3063
LPWSTR dwTypeData
Definition: winuser.h:3377
POINT ptMinTrackSize
Definition: winuser.h:3738
DWORD cbSize
Definition: winuser.h:3892
UINT code
Definition: winuser.h:3267
HWND hwndFrom
Definition: winuser.h:3265
UINT_PTR nID
Definition: commctrl.h:1060
HINSTANCE hInst
Definition: commctrl.h:1059
#define max(a, b)
Definition: svc.c:63
#define GWLP_WNDPROC
Definition: treelist.c:66
#define GWLP_USERDATA
Definition: treelist.c:63
#define DWORD_PTR
Definition: treelist.c:76
eMaj lines
Definition: tritemp.h:206
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
int32_t INT_PTR
Definition: typedefs.h:64
const uint16_t * LPCWSTR
Definition: typedefs.h:57
uint16_t * LPWSTR
Definition: typedefs.h:56
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define HIWORD(l)
Definition: typedefs.h:247
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:3451
static HRESULT HRESULT_FROM_WIN32(unsigned int x)
Definition: winerror.h:210
#define E_NOINTERFACE
Definition: winerror.h:3479
#define ERROR_CANCELLED
Definition: winerror.h:1055
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:3771
#define E_UNEXPECTED
Definition: winerror.h:3528
#define E_POINTER
Definition: winerror.h:3480
int WINAPI GetObjectW(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
int WINAPI GetDeviceCaps(_In_opt_ HDC, _In_ int)
#define LOGPIXELSY
Definition: wingdi.h:719
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1546
#define LOGPIXELSX
Definition: wingdi.h:718
HFONT WINAPI CreateFontIndirectW(_In_ const LOGFONTW *)
#define SYMBOL_CHARSET
Definition: wingdi.h:385
BOOL WINAPI GetTextExtentPoint32W(_In_ HDC hdc, _In_reads_(c) LPCWSTR lpString, _In_ int c, _Out_ LPSIZE psizl)