Skip to content

Commit 34556bd

Browse files
committed
feature: add COM based picker prototype basic implementation
1 parent 8ebf35b commit 34556bd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1889
-0
lines changed

prototype-workingdir/.gitignore

Whitespace-only changes.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<Project/>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<Project/>
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
#include "pch.h"
2+
#include "FileOpenPicker.h"
3+
#include "FileOpenPicker.g.cpp"
4+
#include <windows.h>
5+
#include <shobjidl.h>
6+
#include <shobjidl_core.h>
7+
#include <winrt/Microsoft.UI.Interop.h>
8+
#include "PickerCommon.h"
9+
10+
namespace winrt::Microsoft::Storage::Pickers::implementation
11+
{
12+
FileOpenPicker::FileOpenPicker(winrt::Microsoft::UI::WindowId const& windowId)
13+
: m_windowId(windowId)
14+
{
15+
}
16+
17+
winrt::Microsoft::Storage::Pickers::PickerViewMode FileOpenPicker::ViewMode()
18+
{
19+
return m_ViewMode;
20+
}
21+
void FileOpenPicker::ViewMode(winrt::Microsoft::Storage::Pickers::PickerViewMode const& value)
22+
{
23+
m_ViewMode = value;
24+
}
25+
hstring FileOpenPicker::SettingsIdentifier()
26+
{
27+
return m_SettingsIdentifier;
28+
}
29+
void FileOpenPicker::SettingsIdentifier(hstring const& value)
30+
{
31+
m_SettingsIdentifier = value;
32+
}
33+
winrt::Microsoft::Storage::Pickers::PickerLocationId FileOpenPicker::SuggestedStartLocation()
34+
{
35+
return m_PickerLocationId;
36+
}
37+
void FileOpenPicker::SuggestedStartLocation(winrt::Microsoft::Storage::Pickers::PickerLocationId const& value)
38+
{
39+
m_PickerLocationId = value;
40+
}
41+
winrt::hstring FileOpenPicker::CommitButtonText()
42+
{
43+
return m_commitButtonText;
44+
}
45+
void FileOpenPicker::CommitButtonText(winrt::hstring const& value)
46+
{
47+
m_commitButtonText = value;
48+
}
49+
winrt::Windows::Foundation::Collections::IVector<hstring> FileOpenPicker::FileTypeFilter()
50+
{
51+
return m_fileTypeFilter;
52+
}
53+
54+
struct FileOpenPickerParameters {
55+
winrt::hstring CommitButtonText;
56+
winrt::hstring SettingsIdentifierId;
57+
PickerLocationId PickerLocationId;
58+
std::vector<winrt::hstring> FileTypeFilterData{};
59+
std::vector<COMDLG_FILTERSPEC> FileTypeFilterPara{};
60+
HWND HWnd;
61+
62+
void ConfigureDialog(winrt::com_ptr<IFileOpenDialog> dialog) {
63+
PickerCommon::ConfigureDialogCommon(dialog, CommitButtonText, SettingsIdentifierId, PickerLocationId);
64+
check_hresult(dialog->SetFileTypes(FileTypeFilterPara.size(), FileTypeFilterPara.data()));
65+
}
66+
};
67+
68+
void FileOpenPicker::CaptureParameters(FileOpenPickerParameters& parameters) {
69+
parameters.CommitButtonText = m_commitButtonText;
70+
parameters.SettingsIdentifierId = m_SettingsIdentifier;
71+
parameters.PickerLocationId = m_PickerLocationId;
72+
for (size_t i = 0; i < m_fileTypeFilter.Size(); i++)
73+
{
74+
parameters.FileTypeFilterData.push_back(m_fileTypeFilter.GetAt(i));
75+
parameters.FileTypeFilterPara.push_back({ L"", parameters.FileTypeFilterData[i].c_str() });
76+
}
77+
parameters.HWnd = winrt::Microsoft::UI::GetWindowFromWindowId(m_windowId);
78+
}
79+
80+
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Storage::StorageFile> FileOpenPicker::PickSingleFileAsync()
81+
{
82+
FileOpenPickerParameters parameters{};
83+
84+
CaptureParameters(parameters);
85+
86+
co_await winrt::resume_background();
87+
88+
auto cancellationToken = co_await winrt::get_cancellation_token();
89+
if (cancellationToken())
90+
{
91+
co_return nullptr;
92+
}
93+
94+
// TODO: should we initialize COM?
95+
// wil::com_initialize_ex initializeCom{ COINIT_APARTMENTTHREADED };
96+
97+
auto dialog = create_instance<IFileOpenDialog>(CLSID_FileOpenDialog, CONTEXT_ALL);
98+
99+
parameters.ConfigureDialog(dialog);
100+
101+
auto hr = dialog->Show(parameters.HWnd);
102+
if (FAILED(hr) || cancellationToken())
103+
{
104+
co_return nullptr;
105+
}
106+
107+
winrt::com_ptr<IShellItem> shellItem{};
108+
check_hresult(dialog->GetResult(shellItem.put()));
109+
110+
auto& file = co_await PickerCommon::CreateStorageFileFromShellItem(shellItem);
111+
if (cancellationToken())
112+
{
113+
co_return nullptr;
114+
}
115+
116+
co_return file;
117+
}
118+
119+
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Foundation::Collections::IVectorView<winrt::Windows::Storage::StorageFile>> FileOpenPicker::PickMultipleFilesAsync()
120+
{
121+
FileOpenPickerParameters parameters{};
122+
123+
CaptureParameters(parameters);
124+
125+
co_await winrt::resume_background();
126+
127+
winrt::Windows::Foundation::Collections::IVector<winrt::Windows::Storage::StorageFile> results{ winrt::single_threaded_vector<winrt::Windows::Storage::StorageFile>() };
128+
129+
auto cancellationToken = co_await winrt::get_cancellation_token();
130+
if (cancellationToken())
131+
{
132+
co_return results.GetView();
133+
}
134+
135+
auto dialog = create_instance<IFileOpenDialog>(CLSID_FileOpenDialog, CONTEXT_ALL);
136+
137+
parameters.ConfigureDialog(dialog);
138+
139+
auto pickerOptions = FOS_ALLOWMULTISELECT;
140+
check_hresult(dialog->SetOptions(pickerOptions));
141+
142+
auto hr = dialog->Show(parameters.HWnd);
143+
if (FAILED(hr) || cancellationToken())
144+
{
145+
co_return results.GetView();
146+
}
147+
148+
winrt::com_ptr<IShellItemArray> shellItems{};
149+
check_hresult(dialog->GetResults(shellItems.put()));
150+
151+
DWORD itemCount = 0;
152+
check_hresult(shellItems->GetCount(&itemCount));
153+
154+
winrt::com_ptr<IShellItem> shellItem{};
155+
for (auto i = 0; i < itemCount; i++) {
156+
check_hresult(shellItems->GetItemAt(i, shellItem.put()));
157+
auto& file = co_await PickerCommon::CreateStorageFileFromShellItem(shellItem);
158+
results.Append(file);
159+
}
160+
161+
162+
if (cancellationToken())
163+
{
164+
results.Clear();
165+
co_return results.GetView();
166+
}
167+
168+
co_return results.GetView();
169+
}
170+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#pragma once
2+
#include "FileOpenPicker.g.h"
3+
4+
namespace winrt::Microsoft::Storage::Pickers::implementation
5+
{
6+
struct FileOpenPickerParameters;
7+
8+
struct FileOpenPicker : FileOpenPickerT<FileOpenPicker>
9+
{
10+
FileOpenPicker(winrt::Microsoft::UI::WindowId const& windowId);
11+
12+
winrt::Microsoft::Storage::Pickers::PickerViewMode ViewMode();
13+
void ViewMode(winrt::Microsoft::Storage::Pickers::PickerViewMode const& value);
14+
hstring SettingsIdentifier();
15+
void SettingsIdentifier(hstring const& value);
16+
winrt::Microsoft::Storage::Pickers::PickerLocationId SuggestedStartLocation();
17+
void SuggestedStartLocation(winrt::Microsoft::Storage::Pickers::PickerLocationId const& value);
18+
winrt::hstring CommitButtonText();
19+
void CommitButtonText(winrt::hstring const& value);
20+
21+
winrt::Windows::Foundation::Collections::IVector<hstring> FileTypeFilter();
22+
23+
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Storage::StorageFile> PickSingleFileAsync();
24+
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Foundation::Collections::IVectorView<winrt::Windows::Storage::StorageFile>> PickMultipleFilesAsync();
25+
26+
private:
27+
winrt::Microsoft::UI::WindowId m_windowId{};
28+
winrt::hstring m_SettingsIdentifier{};
29+
PickerLocationId m_PickerLocationId{ PickerLocationId::Unspecified };
30+
winrt::hstring m_commitButtonText{};
31+
32+
PickerViewMode m_ViewMode{ PickerViewMode::List };
33+
34+
winrt::Windows::Foundation::Collections::IVector<hstring> m_fileTypeFilter{ winrt::single_threaded_vector<hstring>() };
35+
36+
void CaptureParameters(FileOpenPickerParameters& parameters);
37+
};
38+
}
39+
namespace winrt::Microsoft::Storage::Pickers::factory_implementation
40+
{
41+
struct FileOpenPicker : FileOpenPickerT<FileOpenPicker, implementation::FileOpenPicker>
42+
{
43+
};
44+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#include "pch.h"
2+
#include "FileSavePicker.h"
3+
#include "FileSavePicker.g.cpp"
4+
#include <windows.h>
5+
#include <shobjidl.h>
6+
#include <shobjidl_core.h>
7+
#include <KnownFolders.h>
8+
#include <wil/cppwinrt.h>
9+
#include <wil/com.h>
10+
#include <wil/resource.h>
11+
#include <Microsoft.Ui.Xaml.Window.h>
12+
#include <winrt/Microsoft.UI.Interop.h>
13+
#include <winrt/Windows.Foundation.Collections.h>
14+
#include "PickerCommon.h"
15+
16+
namespace winrt::Microsoft::Storage::Pickers::implementation
17+
{
18+
19+
FileSavePicker::FileSavePicker(winrt::Microsoft::UI::WindowId const& windowId)
20+
: m_windowId(windowId)
21+
{
22+
}
23+
hstring FileSavePicker::SettingsIdentifier()
24+
{
25+
return m_SettingsIdentifier;
26+
}
27+
void FileSavePicker::SettingsIdentifier(hstring const& value)
28+
{
29+
m_SettingsIdentifier = value;
30+
}
31+
winrt::Microsoft::Storage::Pickers::PickerLocationId FileSavePicker::SuggestedStartLocation()
32+
{
33+
return m_PickerLocationId;
34+
}
35+
void FileSavePicker::SuggestedStartLocation(winrt::Microsoft::Storage::Pickers::PickerLocationId const& value)
36+
{
37+
m_PickerLocationId = value;
38+
}
39+
hstring FileSavePicker::CommitButtonText()
40+
{
41+
return m_commitButtonText;
42+
}
43+
void FileSavePicker::CommitButtonText(hstring const& value)
44+
{
45+
m_commitButtonText = value;
46+
}
47+
winrt::Windows::Foundation::Collections::IMap<hstring, winrt::Windows::Foundation::Collections::IVector<hstring>> FileSavePicker::FileTypeChoices()
48+
{
49+
return m_fileTypeChoices;
50+
}
51+
hstring FileSavePicker::DefaultFileExtension()
52+
{
53+
return m_defaultFileExtension;
54+
}
55+
void FileSavePicker::DefaultFileExtension(hstring const& value)
56+
{
57+
m_defaultFileExtension = value;
58+
}
59+
winrt::Windows::Storage::StorageFile FileSavePicker::SuggestedSaveFile()
60+
{
61+
return m_suggestedSaveFile;
62+
}
63+
void FileSavePicker::SuggestedSaveFile(winrt::Windows::Storage::StorageFile const& value)
64+
{
65+
m_suggestedSaveFile = value;
66+
}
67+
hstring FileSavePicker::SuggestedFileName()
68+
{
69+
return m_suggestedFileName;
70+
}
71+
void FileSavePicker::SuggestedFileName(hstring const& value)
72+
{
73+
m_suggestedFileName = value;
74+
}
75+
76+
struct FileOpenPickerParameters {
77+
HWND HWnd;
78+
winrt::hstring CommitButtonText;
79+
winrt::hstring SettingsIdentifierId;
80+
PickerLocationId PickerLocationId;
81+
82+
void ConfigureDialog(winrt::com_ptr<IFileOpenDialog> dialog) {
83+
PickerCommon::ConfigureDialogCommon(dialog, CommitButtonText, SettingsIdentifierId, PickerLocationId);
84+
}
85+
};
86+
87+
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Storage::StorageFile> FileSavePicker::PickSaveFileAsync()
88+
{
89+
throw hresult_not_implemented();
90+
}
91+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#pragma once
2+
#include "FileSavePicker.g.h"
3+
4+
namespace winrt::Microsoft::Storage::Pickers::implementation
5+
{
6+
struct FileSavePickerParameters;
7+
8+
struct FileSavePicker : FileSavePickerT<FileSavePicker>
9+
{
10+
FileSavePicker(winrt::Microsoft::UI::WindowId const& windowId);
11+
hstring SettingsIdentifier();
12+
void SettingsIdentifier(hstring const& value);
13+
winrt::Microsoft::Storage::Pickers::PickerLocationId SuggestedStartLocation();
14+
void SuggestedStartLocation(winrt::Microsoft::Storage::Pickers::PickerLocationId const& value);
15+
hstring CommitButtonText();
16+
void CommitButtonText(hstring const& value);
17+
winrt::Windows::Foundation::Collections::IMap<hstring, winrt::Windows::Foundation::Collections::IVector<hstring>> FileTypeChoices();
18+
hstring DefaultFileExtension();
19+
void DefaultFileExtension(hstring const& value);
20+
winrt::Windows::Storage::StorageFile SuggestedSaveFile();
21+
void SuggestedSaveFile(winrt::Windows::Storage::StorageFile const& value);
22+
hstring SuggestedFileName();
23+
void SuggestedFileName(hstring const& value);
24+
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Storage::StorageFile> PickSaveFileAsync();
25+
private:
26+
winrt::Microsoft::UI::WindowId m_windowId{};
27+
28+
hstring m_SettingsIdentifier{};
29+
PickerLocationId m_PickerLocationId{ PickerLocationId::Unspecified };
30+
hstring m_commitButtonText{};
31+
hstring m_defaultFileExtension{};
32+
winrt::Windows::Storage::StorageFile m_suggestedSaveFile{ nullptr };
33+
hstring m_suggestedFileName{};
34+
winrt::Windows::Foundation::Collections::IMap<hstring, winrt::Windows::Foundation::Collections::IVector<hstring>> m_fileTypeChoices{ winrt::single_threaded_map<hstring, winrt::Windows::Foundation::Collections::IVector<hstring>>() };
35+
36+
void CaptureParameters(FileSavePickerParameters& parameters);
37+
};
38+
}
39+
namespace winrt::Microsoft::Storage::Pickers::factory_implementation
40+
{
41+
struct FileSavePicker : FileSavePickerT<FileSavePicker, implementation::FileSavePicker>
42+
{
43+
};
44+
}

0 commit comments

Comments
 (0)