annotate foosdk/sdk/foobar2000/shared/filedialogs_vista.cpp @ 1:20d02a178406 default tip

*: check in everything else yay
author Paper <paper@tflc.us>
date Mon, 05 Jan 2026 02:15:46 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1 #include "shared.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
2 #include "filedialogs.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
3 #include <shlobj.h>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
4 #include <shobjidl.h>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
5 #include <shtypes.h>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
6 #include <atlbase.h>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
7 #include <atlcom.h>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
8
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
9 #define dTEXT(X) pfc::stringcvt::string_os_from_utf8(X)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
10
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
11 class FilterSpec {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
12 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
13 void clear() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
14 m_types.set_size(0); m_strings.remove_all();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
15 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
16 void Sanity() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
17 if ( GetCount() > 200 ) SetAllFiles();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
18 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
19 void SetAllFiles() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
20 FromString( "All files|*.*" );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
21 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
22 void FromString(const char * in) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
23 clear();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
24 if (in == NULL) return;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
25 pfc::chain_list_v2_t<COMDLG_FILTERSPEC> types;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
26
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
27 for(t_size inWalk = 0; ; ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
28
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
29 t_size base1 = inWalk;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
30 t_size delta1 = ScanForSeparator(in+base1);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
31 t_size base2 = base1 + delta1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
32 if (in[base2] == 0) break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
33 ++base2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
34 t_size delta2 = ScanForSeparator(in+base2);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
35 if (delta1 > 0 && delta2 > 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
36 COMDLG_FILTERSPEC spec;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
37 spec.pszName = MakeString(in+base1,delta1);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
38 spec.pszSpec = MakeString(in+base2,delta2);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
39 types.add_item(spec);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
40 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
41 inWalk = base2 + delta2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
42 if (in[inWalk] == 0) break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
43 ++inWalk;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
44 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
45
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
46 pfc::list_to_array(m_types,types);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
47 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
48
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
49 t_size GetCount() const {return m_types.get_count();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
50 const COMDLG_FILTERSPEC * GetPtr() const {return m_types.get_ptr();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
51 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
52 static t_size ScanForSeparator(const char * in) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
53 for(t_size walk = 0; ; ++walk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
54 if (in[walk] == 0 || in[walk] == '|') return walk;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
55 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
56 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
57 WCHAR * MakeString(const char * in, t_size inLen) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
58 t_size len = pfc::stringcvt::estimate_utf8_to_wide(in,inLen);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
59 WCHAR* str = AllocString(len);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
60 pfc::stringcvt::convert_utf8_to_wide(str,len,in,inLen);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
61 return str;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
62 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
63 WCHAR * AllocString(t_size size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
64 auto iter = m_strings.insert_last();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
65 iter->set_size(size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
66 return iter->get_ptr();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
67 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
68 pfc::chain_list_v2_t<pfc::array_t<WCHAR> > m_strings;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
69 pfc::array_t<COMDLG_FILTERSPEC> m_types;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
70 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
71
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
72 static HRESULT AddOptionsHelper(pfc::com_ptr_t<IFileDialog> dlg, DWORD opts) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
73 DWORD options;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
74 HRESULT state;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
75 if (FAILED(state = dlg->GetOptions(&options))) return state;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
76 options |= opts;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
77 if (FAILED(state = dlg->SetOptions( options ))) return state;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
78 return S_OK;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
79 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
80
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
81 namespace {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
82
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
83 // SPECIAL
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
84 // Deal with slow or nonworking net shares, do not lockup the calling thread in such cases, just split away
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
85 // Particularly relevant to net shares referred by raw IP, these get us stuck for a long time
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
86 class PDNArg_t : public pfc::refcounted_object_root {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
87 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
88 CoTaskMemObject<LPITEMIDLIST> m_idList;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
89 pfc::string8 m_path;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
90 HRESULT m_result;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
91 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
92
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
93 static unsigned CALLBACK PDNProc(void * arg) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
94 pfc::refcounted_object_ptr_t<PDNArg_t> ptr; ptr.attach( reinterpret_cast<PDNArg_t*>( arg ) );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
95 CoInitialize(0);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
96
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
97 SFGAOF dummy = {};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
98 ptr->m_result = SHParseDisplayName(dTEXT(ptr->m_path),NULL,&ptr->m_idList.m_ptr,0,&dummy);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
99
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
100 CoUninitialize();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
101
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
102 return 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
103 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
104 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
105
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
106 static HRESULT SetFolderHelper(pfc::com_ptr_t<IFileDialog> dlg, const char * folderPath) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
107 CoTaskMemObject<LPITEMIDLIST> idList;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
108
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
109 // Do SHParseDisplayName() off-thread as it is known to lock up on bad net share references
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
110 pfc::refcounted_object_ptr_t<PDNArg_t> ptr = new PDNArg_t();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
111 ptr->m_path = folderPath;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
112 ptr->m_result = E_FAIL;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
113 HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, PDNProc, reinterpret_cast<void*>(ptr._duplicate_ptr()), 0, NULL);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
114 DWORD status = WaitForSingleObject( hThread, 3000 );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
115 CloseHandle(hThread);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
116 if (status != WAIT_OBJECT_0) return E_FAIL;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
117 if (FAILED(ptr->m_result)) return ptr->m_result;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
118
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
119 pfc::com_ptr_t<IShellItem> item;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
120 HRESULT state;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
121 if (FAILED(state = SHCreateShellItem(NULL,NULL,ptr->m_idList.m_ptr,item.receive_ptr()))) return state;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
122 return dlg->SetFolder(item.get_ptr());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
123 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
124
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
125 namespace {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
126 class _EH {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
127 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
128 void operator<<(HRESULT hr) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
129 if (FAILED(hr)) throw exception_com(hr);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
130 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
131 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
132 static _EH EH;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
133 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
134
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
135 BOOL Vista_GetOpenFileName(HWND parent,const char * p_ext_mask,unsigned def_ext_mask,const char * p_def_ext,const char * p_title,const char * p_directory,pfc::string_base & p_filename,BOOL b_save) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
136 modal_dialog_scope modalScope(parent);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
137
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
138 pfc::com_ptr_t<IFileDialog> dlg;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
139
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
140 if (b_save) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
141 if (FAILED(CoCreateInstance(__uuidof(FileSaveDialog), NULL, CLSCTX_ALL, IID_IFileSaveDialog, (void**) dlg.receive_ptr()))) throw pfc::exception_not_implemented();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
142 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
143 if (FAILED(CoCreateInstance(__uuidof(FileOpenDialog), NULL, CLSCTX_ALL, IID_IFileOpenDialog, (void**) dlg.receive_ptr()))) throw pfc::exception_not_implemented();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
144 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
145
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
146 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
147 FilterSpec spec; spec.FromString(p_ext_mask);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
148 spec.Sanity();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
149 if (FAILED(dlg->SetFileTypes((UINT)spec.GetCount(),spec.GetPtr()))) return FALSE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
150 if (def_ext_mask < spec.GetCount()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
151 if (FAILED(dlg->SetFileTypeIndex(def_ext_mask + 1))) return FALSE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
152 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
153 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
154 if (p_def_ext != NULL) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
155 if (FAILED(dlg->SetDefaultExtension(dTEXT(p_def_ext)))) return FALSE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
156 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
157 if (p_title != NULL) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
158 if (FAILED(dlg->SetTitle(dTEXT(p_title)))) return FALSE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
159 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
160
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
161 if (!p_filename.is_empty()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
162 pfc::string path(p_filename);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
163 pfc::string fn = pfc::io::path::getFileName(path);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
164 pfc::string parent = pfc::io::path::getParent(path);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
165 if (!parent.isEmpty()) SetFolderHelper(dlg,parent.ptr());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
166 dlg->SetFileName(dTEXT(fn.ptr()));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
167 } else if (p_directory != NULL) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
168 SetFolderHelper(dlg,p_directory);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
169 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
170
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
171 if (FAILED(AddOptionsHelper(dlg, FOS_FORCEFILESYSTEM))) return FALSE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
172
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
173 if (FAILED( dlg->Show(parent) ) ) return FALSE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
174
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
175 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
176 pfc::com_ptr_t<IShellItem> result;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
177 if (FAILED(dlg->GetResult(result.receive_ptr()))) return FALSE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
178
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
179 CoTaskMemObject<WCHAR*> nameBuf;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
180 if (FAILED(result->GetDisplayName(SIGDN_FILESYSPATH,&nameBuf.m_ptr))) return FALSE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
181
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
182 p_filename = pfc::stringcvt::string_utf8_from_os_ex( nameBuf.m_ptr );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
183 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
184 return TRUE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
185 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
186
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
187 BOOL Vista_GetOpenFileNameMulti(HWND parent,const char * p_ext_mask,unsigned def_ext_mask,const char * p_def_ext,const char * p_title,const char * p_directory,pfc::ptrholder_t<uGetOpenFileNameMultiResult> & out) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
188 modal_dialog_scope modalScope(parent);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
189
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
190 pfc::com_ptr_t<IFileOpenDialog> dlg;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
191 if (FAILED(CoCreateInstance(__uuidof(FileOpenDialog), NULL, CLSCTX_ALL, IID_IFileOpenDialog, (void**) dlg.receive_ptr()))) throw pfc::exception_not_implemented();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
192
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
193 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
194 FilterSpec spec; spec.FromString(p_ext_mask);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
195 spec.Sanity();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
196 if (FAILED(dlg->SetFileTypes((UINT)spec.GetCount(),spec.GetPtr()))) return FALSE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
197 if (def_ext_mask < spec.GetCount()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
198 if (FAILED(dlg->SetFileTypeIndex(def_ext_mask + 1))) return FALSE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
199 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
200 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
201 if (p_def_ext != NULL) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
202 if (FAILED(dlg->SetDefaultExtension(dTEXT(p_def_ext)))) return FALSE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
203 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
204 if (p_title != NULL) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
205 if (FAILED(dlg->SetTitle(dTEXT(p_title)))) return FALSE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
206 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
207
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
208 if (p_directory != NULL) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
209 SetFolderHelper(dlg,p_directory);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
210 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
211
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
212 if (FAILED(AddOptionsHelper(dlg, FOS_ALLOWMULTISELECT | FOS_FORCEFILESYSTEM))) return FALSE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
213
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
214 if (FAILED( dlg->Show(parent) ) ) return FALSE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
215
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
216 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
217 pfc::ptrholder_t<uGetOpenFileNameMultiResult_impl> result = new uGetOpenFileNameMultiResult_impl;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
218 pfc::com_ptr_t<IShellItemArray> results;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
219 if (FAILED(dlg->GetResults(results.receive_ptr()))) return FALSE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
220 DWORD total;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
221 if (FAILED(results->GetCount(&total))) return FALSE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
222 for(DWORD itemWalk = 0; itemWalk < total; ++itemWalk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
223 pfc::com_ptr_t<IShellItem> item;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
224 if (SUCCEEDED(results->GetItemAt(itemWalk,item.receive_ptr()))) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
225 CoTaskMemObject<WCHAR*> nameBuf;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
226 if (FAILED(item->GetDisplayName(SIGDN_FILESYSPATH,&nameBuf.m_ptr))) return FALSE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
227
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
228 result->AddItem(pfc::stringcvt::string_utf8_from_os_ex( nameBuf.m_ptr ) );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
229
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
230 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
231 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
232
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
233 if (result->get_count() == 0) return FALSE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
234
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
235 out = result.detach();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
236 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
237
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
238 return TRUE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
239 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
240 #if 0
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
241 namespace {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
242 class CFileDialogEvents_LocateFile : public IFileDialogEvents {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
243 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
244 CFileDialogEvents_LocateFile(pfc::stringp tofind) : m_tofind(tofind) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
245 HRESULT STDMETHODCALLTYPE OnFileOk(IFileDialog *pfd) {return S_OK;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
246
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
247 HRESULT STDMETHODCALLTYPE OnFolderChanging( IFileDialog *pfd, IShellItem *psiFolder) {return S_OK;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
248
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
249 HRESULT STDMETHODCALLTYPE OnFolderChange( IFileDialog *pfd ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
250 //pfd->GetFolder();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
251 return S_OK;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
252 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
253
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
254 HRESULT STDMETHODCALLTYPE OnSelectionChange( IFileDialog *pfd ) {return S_OK;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
255
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
256 HRESULT STDMETHODCALLTYPE OnShareViolation( IFileDialog *pfd, IShellItem *psi, FDE_SHAREVIOLATION_RESPONSE *pResponse) { return S_OK; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
257
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
258 HRESULT STDMETHODCALLTYPE OnTypeChange( IFileDialog *pfd ) {return S_OK; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
259
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
260 HRESULT STDMETHODCALLTYPE OnOverwrite( IFileDialog *pfd, IShellItem *psi, FDE_OVERWRITE_RESPONSE *pResponse) {return S_OK; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
261
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
262 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
263 const pfc::string m_tofind;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
264 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
265
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
266 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
267 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
268 BOOL Vista_BrowseForFolder(HWND parent, const char * p_title, pfc::string_base & path) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
269 modal_dialog_scope modalScope(parent);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
270 pfc::com_ptr_t<IFileOpenDialog> dlg;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
271 if (FAILED(CoCreateInstance(__uuidof(FileOpenDialog), NULL, CLSCTX_ALL, IID_IFileOpenDialog, (void**) dlg.receive_ptr()))) throw pfc::exception_not_implemented();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
272
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
273 if (p_title != NULL) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
274 if (FAILED(dlg->SetTitle(dTEXT(p_title)))) return FALSE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
275 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
276
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
277 if (FAILED(AddOptionsHelper(dlg, FOS_PICKFOLDERS | FOS_FORCEFILESYSTEM))) return FALSE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
278
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
279 if (!path.is_empty()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
280 SetFolderHelper(dlg,path);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
281 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
282
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
283 if (FAILED( dlg->Show(parent) ) ) return FALSE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
284
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
285 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
286 pfc::com_ptr_t<IShellItem> result;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
287 if (FAILED(dlg->GetResult(result.receive_ptr()))) return FALSE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
288
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
289 CoTaskMemObject<WCHAR*> nameBuf;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
290 if (FAILED(result->GetDisplayName(SIGDN_FILESYSPATH,&nameBuf.m_ptr))) return FALSE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
291
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
292 path = pfc::stringcvt::string_utf8_from_os_ex( nameBuf.m_ptr );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
293 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
294 return TRUE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
295 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
296
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
297
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
298 __inline HRESULT mySHLoadLibraryFromItem(
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
299 __in IShellItem *psiLibrary,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
300 __in DWORD grfMode,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
301 __in REFIID riid,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
302 __deref_out void **ppv
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
303 )
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
304 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
305 *ppv = NULL;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
306 IShellLibrary *plib;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
307
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
308 HRESULT hr = CoCreateInstance(
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
309 CLSID_ShellLibrary,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
310 NULL,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
311 CLSCTX_INPROC_SERVER,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
312 IID_PPV_ARGS(&plib));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
313
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
314 if (SUCCEEDED(hr))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
315 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
316 hr = plib->LoadLibraryFromItem (psiLibrary, grfMode);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
317 if (SUCCEEDED(hr))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
318 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
319 hr = plib->QueryInterface (riid, ppv);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
320 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
321 plib->Release();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
322 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
323 return hr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
324 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
325
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
326 //
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
327 // from shobjidl.h
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
328 //
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
329 __inline HRESULT mySHLoadLibraryFromKnownFolder(
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
330 __in REFKNOWNFOLDERID kfidLibrary,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
331 __in DWORD grfMode,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
332 __in REFIID riid,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
333 __deref_out void **ppv)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
334 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
335 *ppv = NULL;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
336 IShellLibrary *plib;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
337 HRESULT hr = CoCreateInstance(
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
338 CLSID_ShellLibrary,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
339 NULL,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
340 CLSCTX_INPROC_SERVER,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
341 IID_PPV_ARGS(&plib));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
342 if (SUCCEEDED(hr))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
343 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
344 hr = plib->LoadLibraryFromKnownFolder(kfidLibrary, grfMode);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
345 if (SUCCEEDED(hr))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
346 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
347 hr = plib->QueryInterface(riid, ppv);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
348 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
349 plib->Release();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
350 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
351 return hr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
352 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
353
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
354 puGetOpenFileNameMultiResult Vista_BrowseForFolderEx(HWND parent,const char * p_title, const char * initPath) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
355 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
356 modal_dialog_scope modalScope(parent);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
357 pfc::com_ptr_t<IFileOpenDialog> dlg;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
358 if (FAILED(CoCreateInstance(__uuidof(FileOpenDialog), NULL, CLSCTX_ALL, IID_IFileOpenDialog, (void**) dlg.receive_ptr()))) throw pfc::exception_not_implemented();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
359
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
360 if (p_title != NULL) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
361 EH << dlg->SetTitle(dTEXT(p_title));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
362 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
363
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
364 EH << AddOptionsHelper(dlg, FOS_ALLOWMULTISELECT | FOS_PICKFOLDERS);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
365
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
366 if (initPath && *initPath) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
367 SetFolderHelper(dlg,initPath);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
368 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
369
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
370 EH << dlg->Show(parent);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
371
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
372 pfc::ptrholder_t<uGetOpenFileNameMultiResult_impl> result = new uGetOpenFileNameMultiResult_impl;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
373 pfc::com_ptr_t<IShellItemArray> results;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
374 EH << dlg->GetResults(results.receive_ptr());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
375 DWORD total;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
376 EH << results->GetCount(&total);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
377 CoTaskMemObject<WCHAR*> nameBuf;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
378 for(DWORD itemWalk = 0; itemWalk < total; ++itemWalk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
379 pfc::com_ptr_t<IShellItem> item;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
380 EH << results->GetItemAt(itemWalk,item.receive_ptr());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
381 if (SUCCEEDED(item->GetDisplayName(SIGDN_FILESYSPATH,nameBuf.Receive()))) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
382 result->AddItem(pfc::stringcvt::string_utf8_from_os_ex( nameBuf.m_ptr ) );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
383 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
384 pfc::com_ptr_t<IShellLibrary> library;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
385 if (SUCCEEDED(mySHLoadLibraryFromItem(item.get_ptr(), STGM_READ, IID_IShellLibrary, (void**)library.receive_ptr()))) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
386 pfc::com_ptr_t<IShellItemArray> subFolders;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
387 EH << library->GetFolders(LFF_FORCEFILESYSTEM, IID_IShellItemArray, (void**)subFolders.receive_ptr());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
388 DWORD subTotal;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
389 EH << subFolders->GetCount(&subTotal);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
390 for(DWORD subWalk = 0; subWalk < subTotal; ++subWalk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
391 pfc::com_ptr_t<IShellItem> subItem;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
392 EH << subFolders->GetItemAt(subWalk,subItem.receive_ptr());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
393 EH << subItem->GetDisplayName(SIGDN_FILESYSPATH,nameBuf.Receive());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
394 result->AddItem(pfc::stringcvt::string_utf8_from_os_ex( nameBuf.m_ptr ) );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
395 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
396 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
397 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
398 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
399 if (result->GetCount() == 0) return NULL;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
400 return result.detach();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
401 } catch(exception_com const &) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
402 return NULL;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
403 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
404 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
405
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
406 static bool GetLegacyKnownFolder(int & out, REFKNOWNFOLDERID id) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
407 if (id == FOLDERID_Music) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
408 out = CSIDL_MYMUSIC;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
409 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
410 } else if (id == FOLDERID_Pictures) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
411 out = CSIDL_MYPICTURES;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
412 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
413 } else if (id == FOLDERID_Videos) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
414 out = CSIDL_MYVIDEO;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
415 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
416 } else if (id == FOLDERID_Documents) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
417 out = CSIDL_MYDOCUMENTS;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
418 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
419 } else if (id == FOLDERID_Desktop) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
420 out = CSIDL_DESKTOP;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
421 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
422 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
423 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
424 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
425 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
426
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
427 puGetOpenFileNameMultiResult SHARED_EXPORT uEvalKnownFolder(REFKNOWNFOLDERID id) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
428 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
429 pfc::com_ptr_t<IShellLibrary> library;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
430 EH << mySHLoadLibraryFromKnownFolder(id, STGM_READ, IID_IShellLibrary, (void**)library.receive_ptr());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
431
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
432 pfc::com_ptr_t<IShellItemArray> subFolders;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
433 EH << library->GetFolders(LFF_FORCEFILESYSTEM, IID_IShellItemArray, (void**)subFolders.receive_ptr());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
434
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
435 pfc::ptrholder_t<uGetOpenFileNameMultiResult_impl> result = new uGetOpenFileNameMultiResult_impl;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
436
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
437 DWORD subTotal;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
438 EH << subFolders->GetCount(&subTotal);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
439 CoTaskMemObject<WCHAR*> nameBuf;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
440 for(DWORD subWalk = 0; subWalk < subTotal; ++subWalk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
441 pfc::com_ptr_t<IShellItem> subItem;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
442 EH << subFolders->GetItemAt(subWalk,subItem.receive_ptr());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
443 EH << subItem->GetDisplayName(SIGDN_FILESYSPATH,nameBuf.Receive());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
444 result->AddItem(pfc::stringcvt::string_utf8_from_os_ex( nameBuf.m_ptr ) );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
445 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
446 if (result->get_count() == 0) return NULL;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
447 return result.detach();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
448 } catch(exception_com const &) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
449 //failed
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
450 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
451
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
452
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
453 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
454 CComPtr<IKnownFolderManager> mgr; CComPtr<IKnownFolder> folder; CoTaskMemObject<wchar_t*> path;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
455 EH << CoCreateInstance(__uuidof(KnownFolderManager), nullptr, CLSCTX_ALL, IID_IKnownFolderManager, (void**)&mgr.p);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
456 EH << mgr->GetFolder(id, &folder.p);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
457 EH << folder->GetPath(0, &path.m_ptr);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
458
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
459 pfc::ptrholder_t<uGetOpenFileNameMultiResult_impl> result = new uGetOpenFileNameMultiResult_impl;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
460 result->AddItem(pfc::stringcvt::string_utf8_from_os(path.m_ptr));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
461 return result.detach();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
462 } catch (exception_com const &) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
463
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
464 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
465
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
466 //FALLBACK
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
467
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
468
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
469
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
470 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
471 int legacyID;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
472 if (GetLegacyKnownFolder(legacyID, id)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
473 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
474 TCHAR path[MAX_PATH+16] = {};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
475 EH << SHGetFolderPath(NULL, legacyID, NULL, SHGFP_TYPE_CURRENT, path);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
476 path[_countof(path)-1] = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
477 pfc::ptrholder_t<uGetOpenFileNameMultiResult_impl> result = new uGetOpenFileNameMultiResult_impl;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
478 result->AddItem(pfc::stringcvt::string_utf8_from_os_ex( path ) );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
479 return result.detach();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
480 } catch(exception_com const &) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
481 //failed;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
482 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
483 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
484 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
485 #if 0 // Vista code path - uninteresting, XP shit still needs to be supported, SHGetKnownFolderPath() does not exist on XP
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
486 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
487 pfc::ptrholder_t<uGetOpenFileNameMultiResult_impl> result = new uGetOpenFileNameMultiResult_impl;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
488 CoTaskMemObject<WCHAR*> nameBuf;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
489 EH << SHGetKnownFolderPath(id, 0, NULL, nameBuf.Receive());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
490 result->AddItem(pfc::stringcvt::string_utf8_from_os_ex( nameBuf.m_ptr ) );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
491 return result.detach();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
492 } catch(exception_com const &) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
493 //failed
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
494 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
495 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
496 return NULL; //failure
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
497 }