From 52e09741034fed7ca09d8aa436a058c6170d1583 Mon Sep 17 00:00:00 2001
From: DinahK-2SO <116714259+DinahK-2SO@users.noreply.github.com>
Date: Tue, 30 Sep 2025 02:17:04 +0800
Subject: [PATCH 1/4] new functionalities
---
...TerminalVelocityFeatures-StoragePickers2.h | 32 ++++
...rminalVelocityFeatures-StoragePickers2.xml | 20 +++
dev/Interop/StoragePickers/FileOpenPicker.cpp | 37 ++++-
dev/Interop/StoragePickers/FileOpenPicker.h | 16 +-
dev/Interop/StoragePickers/FileSavePicker.cpp | 21 ++-
dev/Interop/StoragePickers/FileSavePicker.h | 4 +
.../StoragePickers/FileTypeChoicesMap.cpp | 8 +-
.../StoragePickers/FileTypeChoicesMap.h | 4 +-
.../StoragePickers/FileTypeFilterVector.cpp | 2 +-
dev/Interop/StoragePickers/FolderPicker.cpp | 27 +++-
dev/Interop/StoragePickers/FolderPicker.h | 8 +
.../Microsoft.Windows.Storage.Pickers.idl | 22 ++-
dev/Interop/StoragePickers/PickerCommon.cpp | 137 ++++++++++++++++--
dev/Interop/StoragePickers/PickerCommon.h | 15 +-
.../StoragePickersTests/PickerCommonTests.cpp | 65 ++++++++-
.../StoragePickersTests.cpp | 20 +++
16 files changed, 396 insertions(+), 42 deletions(-)
create mode 100644 dev/Common/TerminalVelocityFeatures-StoragePickers2.h
create mode 100644 dev/Common/TerminalVelocityFeatures-StoragePickers2.xml
diff --git a/dev/Common/TerminalVelocityFeatures-StoragePickers2.h b/dev/Common/TerminalVelocityFeatures-StoragePickers2.h
new file mode 100644
index 0000000000..e44c4cfaa5
--- /dev/null
+++ b/dev/Common/TerminalVelocityFeatures-StoragePickers2.h
@@ -0,0 +1,32 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+// THIS FILE IS AUTOMATICALLY GENERATED; DO NOT EDIT IT
+
+// INPUT FILE: dev\Common\TerminalVelocityFeatures-StoragePickers2.xml
+// OPTIONS: -Channel Experimental -Language C++ -Namespace Microsoft.Windows.Storage.Pickers -Path dev\Common\TerminalVelocityFeatures-StoragePickers2.xml -Output dev\Common\TerminalVelocityFeatures-StoragePickers2.h
+
+#if defined(__midlrt)
+namespace features
+{
+ feature_name Feature_StoragePickers2 = { DisabledByDefault, FALSE };
+}
+#endif // defined(__midlrt)
+
+// Feature constants
+#define WINDOWSAPPRUNTIME_MICROSOFT_WINDOWS_STORAGE_PICKERS_FEATURE_STORAGEPICKERS2_ENABLED 1
+
+#if defined(__cplusplus)
+
+namespace Microsoft::Windows::Storage::Pickers
+{
+
+__pragma(detect_mismatch("ODR_violation_WINDOWSAPPRUNTIME_MICROSOFT_WINDOWS_STORAGE_PICKERS_FEATURE_STORAGEPICKERS2_ENABLED_mismatch", "AlwaysEnabled"))
+struct Feature_StoragePickers2
+{
+ static constexpr bool IsEnabled() { return WINDOWSAPPRUNTIME_MICROSOFT_WINDOWS_STORAGE_PICKERS_FEATURE_STORAGEPICKERS2_ENABLED == 1; }
+};
+
+} // namespace Microsoft.Windows.Storage.Pickers
+
+#endif // defined(__cplusplus)
diff --git a/dev/Common/TerminalVelocityFeatures-StoragePickers2.xml b/dev/Common/TerminalVelocityFeatures-StoragePickers2.xml
new file mode 100644
index 0000000000..b878a8128f
--- /dev/null
+++ b/dev/Common/TerminalVelocityFeatures-StoragePickers2.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+ Feature_StoragePickers2
+ New functionalities in StoragePickers for the WindowsAppRuntime: SuggestedDefaultFolder, FileTypeChoices
+ AlwaysEnabled
+
+ Preview
+ Stable
+
+
+
diff --git a/dev/Interop/StoragePickers/FileOpenPicker.cpp b/dev/Interop/StoragePickers/FileOpenPicker.cpp
index 775e6411ab..3a8c108261 100644
--- a/dev/Interop/StoragePickers/FileOpenPicker.cpp
+++ b/dev/Interop/StoragePickers/FileOpenPicker.cpp
@@ -49,17 +49,46 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
PickerCommon::ValidateStringNoEmbeddedNulls(value);
m_commitButtonText = value;
}
- winrt::Windows::Foundation::Collections::IVector FileOpenPicker::FileTypeFilter()
+ winrt::Windows::Foundation::Collections::IMap> FileOpenPicker::FileTypeChoices()
+ {
+ THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Storage::Pickers::Feature_StoragePickers2::IsEnabled());
+ return m_fileTypeChoices;
+ }
+ winrt::Windows::Foundation::Collections::IVector FileOpenPicker::FileTypeFilter()
{
return m_fileTypeFilter;
}
+ winrt::hstring FileOpenPicker::SuggestedFolder()
+ {
+ THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Storage::Pickers::Feature_StoragePickers2::IsEnabled());
+ return m_suggestedFolder;
+ }
+ void FileOpenPicker::SuggestedFolder(winrt::hstring const& value)
+ {
+ THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Storage::Pickers::Feature_StoragePickers2::IsEnabled());
+ PickerCommon::ValidateFolderPath(value, "SuggestedFolder");
+ m_suggestedFolder = value;
+ }
+ winrt::hstring FileOpenPicker::SuggestedStartFolder()
+ {
+ THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Storage::Pickers::Feature_StoragePickers2::IsEnabled());
+ return m_suggestedStartFolder;
+ }
+ void FileOpenPicker::SuggestedStartFolder(winrt::hstring const& value)
+ {
+ THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Storage::Pickers::Feature_StoragePickers2::IsEnabled());
+ PickerCommon::ValidateFolderPath(value, "SuggestedStartFolder");
+ m_suggestedStartFolder = value;
+ }
void FileOpenPicker::CaptureParameters(PickerCommon::PickerParameters& parameters)
{
parameters.HWnd = winrt::Microsoft::UI::GetWindowFromWindowId(m_windowId);
parameters.CommitButtonText = m_commitButtonText;
- parameters.PickerLocationId = m_suggestedStartLocation;
- parameters.CaptureFilterSpec(m_fileTypeFilter.GetView());
+ parameters.SuggestedFolder = m_suggestedFolder;
+ parameters.SuggestedStartLocation = m_suggestedStartLocation;
+ parameters.SuggestedStartFolder = m_suggestedStartFolder;
+ parameters.CaptureFilterSpecData(m_fileTypeFilter.GetView(), m_fileTypeChoices.GetView());
}
winrt::Windows::Foundation::IAsyncOperation FileOpenPicker::PickSingleFileAsync()
@@ -87,7 +116,6 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
auto dialog = create_instance(CLSID_FileOpenDialog, CLSCTX_INPROC_SERVER);
parameters.ConfigureDialog(dialog);
- check_hresult(dialog->SetFileTypeIndex(parameters.FileTypeFilterPara.size()));
{
auto hr = dialog->Show(parameters.HWnd);
@@ -142,7 +170,6 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
auto dialog = create_instance(CLSID_FileOpenDialog, CLSCTX_INPROC_SERVER);
parameters.ConfigureDialog(dialog);
- check_hresult(dialog->SetFileTypeIndex(parameters.FileTypeFilterPara.size()));
FILEOPENDIALOGOPTIONS dialogOptions;
check_hresult(dialog->GetOptions(&dialogOptions));
diff --git a/dev/Interop/StoragePickers/FileOpenPicker.h b/dev/Interop/StoragePickers/FileOpenPicker.h
index 47353b6310..c8beadf316 100644
--- a/dev/Interop/StoragePickers/FileOpenPicker.h
+++ b/dev/Interop/StoragePickers/FileOpenPicker.h
@@ -6,6 +6,7 @@
#include "PickerCommon.h"
#include "StoragePickersTelemetryHelper.h"
#include
+#include "FileTypeChoicesMap.h"
#include "FileTypeFilterVector.h"
namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
@@ -23,7 +24,14 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
winrt::hstring CommitButtonText();
void CommitButtonText(winrt::hstring const& value);
- winrt::Windows::Foundation::Collections::IVector FileTypeFilter();
+ winrt::Windows::Foundation::Collections::IVector FileTypeFilter();
+ winrt::Windows::Foundation::Collections::IMap> FileTypeChoices();
+
+ winrt::hstring SuggestedFolder();
+ void SuggestedFolder(winrt::hstring const& value);
+
+ winrt::hstring SuggestedStartFolder();
+ void SuggestedStartFolder(winrt::hstring const& value);
winrt::Windows::Foundation::IAsyncOperation PickSingleFileAsync();
winrt::Windows::Foundation::IAsyncOperation> PickMultipleFilesAsync();
@@ -34,7 +42,11 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
PickerLocationId m_suggestedStartLocation{ PickerLocationId::Unspecified };
winrt::hstring m_commitButtonText{};
- winrt::Windows::Foundation::Collections::IVector m_fileTypeFilter{ make() };
+ winrt::Windows::Foundation::Collections::IVector m_fileTypeFilter{ make() };
+ winrt::Windows::Foundation::Collections::IMap> m_fileTypeChoices{ make(false) };
+
+ winrt::hstring m_suggestedFolder{};
+ winrt::hstring m_suggestedStartFolder{};
StoragePickersTelemetryHelper m_telemetryHelper{};
diff --git a/dev/Interop/StoragePickers/FileSavePicker.cpp b/dev/Interop/StoragePickers/FileSavePicker.cpp
index aa1f091b53..6fcb3e2eb0 100644
--- a/dev/Interop/StoragePickers/FileSavePicker.cpp
+++ b/dev/Interop/StoragePickers/FileSavePicker.cpp
@@ -63,10 +63,22 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
}
void FileSavePicker::SuggestedFolder(hstring const& value)
{
- PickerCommon::ValidateSuggestedFolder(value);
+ PickerCommon::ValidateFolderPath(value, "SuggestedFolder");
m_suggestedFolder = value;
}
+ hstring FileSavePicker::SuggestedStartFolder()
+ {
+ THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Storage::Pickers::Feature_StoragePickers2::IsEnabled());
+ return m_suggestedStartFolder;
+ }
+ void FileSavePicker::SuggestedStartFolder(hstring const& value)
+ {
+ THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Storage::Pickers::Feature_StoragePickers2::IsEnabled());
+ PickerCommon::ValidateFolderPath(value, "SuggestedStartFolder");
+ m_suggestedStartFolder = value;
+ }
+
hstring FileSavePicker::SuggestedFileName()
{
return m_suggestedFileName;
@@ -82,10 +94,13 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
{
parameters.HWnd = winrt::Microsoft::UI::GetWindowFromWindowId(m_windowId);
parameters.CommitButtonText = m_commitButtonText;
- parameters.PickerLocationId = m_suggestedStartLocation;
parameters.SuggestedFileName = m_suggestedFileName;
parameters.SuggestedFolder = m_suggestedFolder;
- parameters.CaptureFilterSpec(m_fileTypeChoices.GetView());
+ parameters.SuggestedStartLocation = m_suggestedStartLocation;
+ parameters.SuggestedStartFolder = m_suggestedStartFolder;
+ parameters.CaptureFilterSpecData(
+ winrt::Windows::Foundation::Collections::IVectorView{},
+ m_fileTypeChoices.GetView());
}
winrt::Windows::Foundation::IAsyncOperation FileSavePicker::PickSaveFileAsync()
diff --git a/dev/Interop/StoragePickers/FileSavePicker.h b/dev/Interop/StoragePickers/FileSavePicker.h
index 59a3eb977a..849c819819 100644
--- a/dev/Interop/StoragePickers/FileSavePicker.h
+++ b/dev/Interop/StoragePickers/FileSavePicker.h
@@ -29,6 +29,9 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
hstring SuggestedFolder();
void SuggestedFolder(hstring const& value);
+ hstring SuggestedStartFolder();
+ void SuggestedStartFolder(hstring const& value);
+
hstring SuggestedFileName();
void SuggestedFileName(hstring const& value);
@@ -41,6 +44,7 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
winrt::Windows::Foundation::Collections::IMap> m_fileTypeChoices{ make() };
hstring m_defaultFileExtension{};
hstring m_suggestedFolder{};
+ hstring m_suggestedStartFolder{};
hstring m_suggestedFileName{};
StoragePickersTelemetryHelper m_telemetryHelper{};
diff --git a/dev/Interop/StoragePickers/FileTypeChoicesMap.cpp b/dev/Interop/StoragePickers/FileTypeChoicesMap.cpp
index 3f04a4a373..5ca48d2beb 100644
--- a/dev/Interop/StoragePickers/FileTypeChoicesMap.cpp
+++ b/dev/Interop/StoragePickers/FileTypeChoicesMap.cpp
@@ -7,12 +7,18 @@
namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
{
- FileTypeChoicesMap::FileTypeChoicesMap()
+ FileTypeChoicesMap::FileTypeChoicesMap(bool forSavePicker)
+ : ForSavePicker(forSavePicker)
{
}
bool FileTypeChoicesMap::Insert(hstring const& key, winrt::Windows::Foundation::Collections::IVector const& value)
{
+ if (!ForSavePicker)
+ {
+ THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Storage::Pickers::Feature_StoragePickers2::IsEnabled());
+ }
+
// Create a new FileTypeFilterVector and copy all values from the input vector
auto validatingVector = make();
diff --git a/dev/Interop/StoragePickers/FileTypeChoicesMap.h b/dev/Interop/StoragePickers/FileTypeChoicesMap.h
index 0f1e2a1a87..794c5e20c3 100644
--- a/dev/Interop/StoragePickers/FileTypeChoicesMap.h
+++ b/dev/Interop/StoragePickers/FileTypeChoicesMap.h
@@ -11,7 +11,9 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
winrt::Windows::Foundation::Collections::IMap>,
winrt::Windows::Foundation::Collections::IIterable>>>
{
- FileTypeChoicesMap();
+ FileTypeChoicesMap(bool forSavePicker = true);
+
+ bool ForSavePicker{ forSavePicker };
// IMap>
winrt::Windows::Foundation::Collections::IVector Lookup(hstring const& key) const;
diff --git a/dev/Interop/StoragePickers/FileTypeFilterVector.cpp b/dev/Interop/StoragePickers/FileTypeFilterVector.cpp
index 5fe3d8bad5..67bb664ff9 100644
--- a/dev/Interop/StoragePickers/FileTypeFilterVector.cpp
+++ b/dev/Interop/StoragePickers/FileTypeFilterVector.cpp
@@ -7,7 +7,7 @@
namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
{
- FileTypeFilterVector::FileTypeFilterVector()
+ FileTypeFilterVector::FileTypeFilterVector(bool forSavePicker)
{
}
diff --git a/dev/Interop/StoragePickers/FolderPicker.cpp b/dev/Interop/StoragePickers/FolderPicker.cpp
index c95a581607..aeaea4a90a 100644
--- a/dev/Interop/StoragePickers/FolderPicker.cpp
+++ b/dev/Interop/StoragePickers/FolderPicker.cpp
@@ -47,15 +47,38 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
PickerCommon::ValidateStringNoEmbeddedNulls(value);
m_commitButtonText = value;
}
+ hstring FolderPicker::SuggestedFolder()
+ {
+ THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Storage::Pickers::Feature_StoragePickers2::IsEnabled());
+ return m_suggestedFolder;
+ }
+ void FolderPicker::SuggestedFolder(hstring const& value)
+ {
+ THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Storage::Pickers::Feature_StoragePickers2::IsEnabled());
+ PickerCommon::ValidateFolderPath(value, "SuggestedFolder");
+ m_suggestedFolder = value;
+ }
+ hstring FolderPicker::SuggestedStartFolder()
+ {
+ THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Storage::Pickers::Feature_StoragePickers2::IsEnabled());
+ return m_suggestedStartFolder;
+ }
+ void FolderPicker::SuggestedStartFolder(hstring const& value)
+ {
+ THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Storage::Pickers::Feature_StoragePickers2::IsEnabled());
+ PickerCommon::ValidateFolderPath(value, "SuggestedStartFolder");
+ m_suggestedStartFolder = value;
+ }
void FolderPicker::CaptureParameters(PickerCommon::PickerParameters& parameters)
{
parameters.HWnd = winrt::Microsoft::UI::GetWindowFromWindowId(m_windowId);
parameters.CommitButtonText = m_commitButtonText;
- parameters.PickerLocationId = m_suggestedStartLocation;
+ parameters.SuggestedFolder = m_suggestedFolder;
+ parameters.SuggestedStartLocation = m_suggestedStartLocation;
+ parameters.SuggestedStartFolder = m_suggestedStartFolder;
}
-
winrt::Windows::Foundation::IAsyncOperation FolderPicker::PickSingleFolderAsync()
{
// TODO: remove get strong reference when telementry is safe stop
diff --git a/dev/Interop/StoragePickers/FolderPicker.h b/dev/Interop/StoragePickers/FolderPicker.h
index f5e8f88136..49e7c4b1f7 100644
--- a/dev/Interop/StoragePickers/FolderPicker.h
+++ b/dev/Interop/StoragePickers/FolderPicker.h
@@ -21,6 +21,12 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
hstring CommitButtonText();
void CommitButtonText(hstring const& value);
+ hstring SuggestedFolder();
+ void SuggestedFolder(hstring const& value);
+
+ hstring SuggestedStartFolder();
+ void SuggestedStartFolder(hstring const& value);
+
winrt::Windows::Foundation::IAsyncOperation PickSingleFolderAsync();
private:
@@ -29,6 +35,8 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
PickerViewMode m_viewMode{ PickerViewMode::List };
PickerLocationId m_suggestedStartLocation{ PickerLocationId::Unspecified };
hstring m_commitButtonText{};
+ hstring m_suggestedFolder{};
+ hstring m_suggestedStartFolder{};
StoragePickersTelemetryHelper m_telemetryHelper{};
void CaptureParameters(PickerCommon::PickerParameters& parameters);
diff --git a/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl b/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl
index 895fb2c621..e70b9d7954 100644
--- a/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl
+++ b/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl
@@ -1,9 +1,11 @@
// Copyright (c) Microsoft Corporation and Contributors.
// Licensed under the MIT License.
+#include
+
namespace Microsoft.Windows.Storage.Pickers
{
- [contractversion(1.8)]
+ [contractversion(2.0)]
apicontract StoragePickersContract {};
[contract(StoragePickersContract, 1.8)]
@@ -41,8 +43,17 @@ namespace Microsoft.Windows.Storage.Pickers
Microsoft.Windows.Storage.Pickers.PickerViewMode ViewMode;
Microsoft.Windows.Storage.Pickers.PickerLocationId SuggestedStartLocation;
String CommitButtonText;
+ Windows.Foundation.Collections.IMap > FileTypeChoices{ get; };
Windows.Foundation.Collections.IVector FileTypeFilter{ get; };
+ [contract(StoragePickersContract, 2.0)]
+ [feature(Feature_StoragePickers2)]
+ String SuggestedFolder;
+
+ [contract(StoragePickersContract, 2.0)]
+ [feature(Feature_StoragePickers2)]
+ String SuggestedStartFolder;
+
[remote_sync] Windows.Foundation.IAsyncOperation PickSingleFileAsync();
[remote_sync] Windows.Foundation.IAsyncOperation > PickMultipleFilesAsync();
}
@@ -59,6 +70,10 @@ namespace Microsoft.Windows.Storage.Pickers
String SuggestedFileName;
String SuggestedFolder;
+ [contract(StoragePickersContract, 2.0)]
+ [feature(Feature_StoragePickers2)]
+ String SuggestedStartFolder;
+
[remote_sync] Windows.Foundation.IAsyncOperation PickSaveFileAsync();
}
@@ -76,6 +91,11 @@ namespace Microsoft.Windows.Storage.Pickers
Microsoft.Windows.Storage.Pickers.PickerViewMode ViewMode;
Microsoft.Windows.Storage.Pickers.PickerLocationId SuggestedStartLocation;
String CommitButtonText;
+ String SuggestedFolder;
+
+ [contract(StoragePickersContract, 2.0)]
+ [feature(Feature_StoragePickers2)]
+ String SuggestedStartFolder;
[remote_sync] Windows.Foundation.IAsyncOperation PickSingleFolderAsync();
}
diff --git a/dev/Interop/StoragePickers/PickerCommon.cpp b/dev/Interop/StoragePickers/PickerCommon.cpp
index dec7a50d3a..e90558e1f8 100644
--- a/dev/Interop/StoragePickers/PickerCommon.cpp
+++ b/dev/Interop/StoragePickers/PickerCommon.cpp
@@ -12,6 +12,8 @@
#include
#include
#include
+#include
+#include
namespace {
@@ -224,7 +226,7 @@ namespace PickerCommon {
ValidateStringNoEmbeddedNulls(suggestedFileName);
}
- void ValidateSuggestedFolder(winrt::hstring const& path)
+ void ValidateFolderPath(winrt::hstring const& path, std::string const& propertyName)
{
if (path.empty())
{
@@ -234,16 +236,77 @@ namespace PickerCommon {
ValidateStringNoEmbeddedNulls(path);
- auto pathObj = std::filesystem::path(path.c_str());
+ std::wstring pathString{ path };
+ auto pathObj = std::filesystem::path(pathString);
if (!pathObj.is_absolute())
{
- throw std::invalid_argument("SuggestedFolder");
+ throw std::invalid_argument(propertyName);
}
- wil::unique_cotaskmem_ptr pidl(SHSimpleIDListFromPath(path.c_str()));
- if (!pidl)
+ constexpr std::wstring_view invalidCharacters{ L"<>\"|?*" };
+
+ bool hasExtendedPrefix = false;
+ size_t startIndex = 0;
+ if (pathString.size() >= 4 && pathString[0] == L'\\' && pathString[1] == L'\\' &&
+ (pathString[2] == L'?' || pathString[2] == L'.') && pathString[3] == L'\\')
+ {
+ hasExtendedPrefix = true;
+ startIndex = 4; // Skip the extended path prefix
+ }
+
+ auto isDriveSpecifier = [&](size_t index)
+ {
+ if (!hasExtendedPrefix)
+ {
+ return index == 1 && std::iswalpha(pathString[0]);
+ }
+
+ return (index == 5 && std::iswalpha(pathString[4]));
+ };
+
+ for (size_t i = startIndex; i < pathString.size(); ++i)
+ {
+ wchar_t currentChar = pathString[i];
+
+ if (currentChar == L':')
+ {
+ if (isDriveSpecifier(i))
+ {
+ continue;
+ }
+ }
+
+ if (invalidCharacters.find(currentChar) != std::wstring_view::npos)
+ {
+ throw std::invalid_argument(propertyName);
+ }
+ }
+
+ constexpr size_t MaxComponentLength = 255;
+ bool isFirstComponent = true;
+ for (auto const& component : pathObj)
{
- throw std::invalid_argument("SuggestedFolder");
+ auto nativeComponent = component.native();
+ if (nativeComponent.empty())
+ {
+ continue;
+ }
+
+ if (isFirstComponent)
+ {
+ isFirstComponent = false;
+ continue; // Skip root name (e.g., "C:" or "\\server\share")
+ }
+
+ if (nativeComponent == L"\\" || nativeComponent == L"/")
+ {
+ continue; // Skip root directory separators
+ }
+
+ if (nativeComponent.size() > MaxComponentLength)
+ {
+ throw std::invalid_argument(propertyName);
+ }
}
}
@@ -278,6 +341,28 @@ namespace PickerCommon {
return result;
}
+ void PickerParameters::CaptureFilterSpecData(
+ winrt::Windows::Foundation::Collections::IVectorView fileTypeFilterView,
+ winrt::Windows::Foundation::Collections::IMapView> fileTypeChoicesView)
+ {
+ // The FileTypeChoices takes precedence over FileTypeFilter if both are provided.
+ if (fileTypeChoicesView && fileTypeChoicesView.Size() > 0)
+ {
+ CaptureFilterSpec(fileTypeChoicesView);
+ return;
+ }
+
+ if (fileTypeFilterView && fileTypeFilterView.Size() > 0)
+ {
+ CaptureFilterSpec(fileTypeFilterView);
+ return;
+ }
+
+ // Even if no filters provided, we still need to set filter to All Files *.*
+ auto emptyFilters = winrt::single_threaded_vector();
+ CaptureFilterSpec(emptyFilters.GetView());
+ }
+
///
/// Capture and processing pickers filter inputs and convert them into Common Item Dialog's accepting type, for FileOpenPicker
///
@@ -330,6 +415,8 @@ namespace PickerCommon {
{
FileTypeFilterPara.push_back({ FileTypeFilterData.at(i * 2).c_str(), FileTypeFilterData.at(i * 2 + 1).c_str() });
}
+
+ FocusLastFilter = true;
}
///
@@ -372,15 +459,41 @@ namespace PickerCommon {
check_hresult(dialog->SetOkButtonLabel(CommitButtonText.c_str()));
}
- auto defaultFolder = GetKnownFolderFromId(PickerLocationId);
- if (defaultFolder != nullptr)
+ winrt::com_ptr defaultFolder{};
+
+ // The SuggestedStartFolder takes precedence over SuggestedStartLocation if both are provided.
+ if (!IsHStringNullOrEmpty(SuggestedStartFolder))
+ {
+ defaultFolder = TryParseFolderItem(SuggestedStartFolder);
+ }
+
+ if (!defaultFolder)
+ {
+ defaultFolder = GetKnownFolderFromId(SuggestedStartLocation);
+ }
+
+ if (defaultFolder)
{
check_hresult(dialog->SetDefaultFolder(defaultFolder.get()));
}
+ // SuggestedFolder takes precedence over SuggestedStartFolder/SuggestedStartLocation if both are provided.
+ if (!IsHStringNullOrEmpty(SuggestedFolder))
+ {
+ if (auto folderItem = TryParseFolderItem(SuggestedFolder))
+ {
+ check_hresult(dialog->SetFolder(folderItem.get()));
+ }
+ }
+
if (FileTypeFilterPara.size() > 0)
{
check_hresult(dialog->SetFileTypes((UINT)FileTypeFilterPara.size(), FileTypeFilterPara.data()));
+
+ if (FocusLastFilter)
+ {
+ check_hresult(dialog->SetFileTypeIndex(FileTypeFilterPara.size()));
+ }
}
}
@@ -395,13 +508,5 @@ namespace PickerCommon {
check_hresult(dialog->SetFileName(SuggestedFileName.c_str()));
}
- if (!PickerCommon::IsHStringNullOrEmpty(SuggestedFolder))
- {
- winrt::com_ptr folderItem = TryParseFolderItem(SuggestedFolder);
- if (folderItem)
- {
- check_hresult(dialog->SetFolder(folderItem.get()));
- }
- }
}
}
diff --git a/dev/Interop/StoragePickers/PickerCommon.h b/dev/Interop/StoragePickers/PickerCommon.h
index 124a9eb261..f9e419bc38 100644
--- a/dev/Interop/StoragePickers/PickerCommon.h
+++ b/dev/Interop/StoragePickers/PickerCommon.h
@@ -26,26 +26,33 @@ namespace PickerCommon {
void ValidateSuggestedStartLocation(winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId const& value);
void ValidateSingleFileTypeFilterElement(winrt::hstring const& filter);
void ValidateSuggestedFileName(winrt::hstring const& suggestedFileName);
- void ValidateSuggestedFolder(winrt::hstring const& path);
+ void ValidateFolderPath(winrt::hstring const& path, std::string const& argumentName);
struct PickerParameters {
HWND HWnd{};
winrt::hstring CommitButtonText;
- winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId PickerLocationId;
+ winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId SuggestedStartLocation;
std::vector FileTypeFilterData{};
std::vector FileTypeFilterPara{};
+ bool FocusLastFilter{ false };
winrt::hstring AllFilesText{ L"All Files" }; // initialize to All Files as a default value, will be updated by localization
winrt::hstring SuggestedFileName;
winrt::hstring SuggestedFolder;
+ winrt::hstring SuggestedStartFolder;
winrt::hstring FormatExtensionWithWildcard(winrt::hstring extension);
winrt::hstring JoinExtensions(winrt::Windows::Foundation::Collections::IVectorView extensions);
- void CaptureFilterSpec(winrt::Windows::Foundation::Collections::IVectorView filters);
- void CaptureFilterSpec(winrt::Windows::Foundation::Collections::IMapView> filters);
+ void CaptureFilterSpecData(
+ winrt::Windows::Foundation::Collections::IVectorView fileTypeFilterView,
+ winrt::Windows::Foundation::Collections::IMapView> fileTypeChoicesView);
void ConfigureDialog(winrt::com_ptr dialog);
void ConfigureFileSaveDialog(winrt::com_ptr dialog);
+
+ private:
+ void CaptureFilterSpec(winrt::Windows::Foundation::Collections::IVectorView filters);
+ void CaptureFilterSpec(winrt::Windows::Foundation::Collections::IMapView> filters);
};
}
diff --git a/test/StoragePickersTests/PickerCommonTests.cpp b/test/StoragePickersTests/PickerCommonTests.cpp
index 29c870c7f8..555eec06a1 100644
--- a/test/StoragePickersTests/PickerCommonTests.cpp
+++ b/test/StoragePickersTests/PickerCommonTests.cpp
@@ -99,6 +99,7 @@ namespace Test::PickerCommonTests
// Act.
auto dialog = winrt::create_instance(CLSID_FileSaveDialog, CLSCTX_INPROC_SERVER);
+ parameters.ConfigureDialog(dialog.as());
parameters.ConfigureFileSaveDialog(dialog);
// Assert.
@@ -130,6 +131,7 @@ namespace Test::PickerCommonTests
// Act.
auto dialog = winrt::create_instance(CLSID_FileSaveDialog, CLSCTX_INPROC_SERVER);
+ parameters.ConfigureDialog(dialog.as());
parameters.ConfigureFileSaveDialog(dialog);
// Assert.
@@ -150,7 +152,7 @@ namespace Test::PickerCommonTests
// Act.
PickerParameters parameters{};
- parameters.CaptureFilterSpec(picker.FileTypeFilter().GetView());
+ parameters.CaptureFilterSpecData(picker.FileTypeFilter().GetView(), nullptr);
// Assert.
VERIFY_ARE_EQUAL(parameters.FileTypeFilterPara.size(), 3);
@@ -176,7 +178,7 @@ namespace Test::PickerCommonTests
// Act.
PickerParameters parameters{};
- parameters.CaptureFilterSpec(picker.FileTypeFilter().GetView());
+ parameters.CaptureFilterSpecData(picker.FileTypeFilter().GetView(), nullptr);
// Assert.
VERIFY_ARE_EQUAL(parameters.FileTypeFilterPara.size(), 1);
@@ -196,7 +198,7 @@ namespace Test::PickerCommonTests
// Act.
PickerParameters parameters{};
- parameters.CaptureFilterSpec(picker.FileTypeFilter().GetView());
+ parameters.CaptureFilterSpecData(picker.FileTypeFilter().GetView(), nullptr);
// Assert.
VERIFY_ARE_EQUAL(parameters.FileTypeFilterPara.size(), 1);
@@ -206,6 +208,34 @@ namespace Test::PickerCommonTests
L"*");
}
+ TEST_METHOD(VerifyFilters_FileOpenPickerWhenFileTypeChoicesDefinedExpectMatchingSpec)
+ {
+ // Arrange.
+ winrt::Microsoft::UI::WindowId windowId{};
+ winrt::Microsoft::Windows::Storage::Pickers::FileOpenPicker picker(windowId);
+
+ picker.FileTypeChoices().Insert(
+ L"Documents", winrt::single_threaded_vector({ L".txt", L".doc", L".docx" }));
+ picker.FileTypeChoices().Insert(
+ L"Pictures", winrt::single_threaded_vector({ L".png", L".jpg", L".jpeg", L".bmp" }));
+
+ // Act.
+ PickerParameters parameters{};
+ parameters.CaptureFilterSpecData(
+ winrt::Windows::Foundation::Collections::IVectorView{},
+ picker.FileTypeChoices().GetView());
+
+ // Assert.
+ VERIFY_ARE_EQUAL(parameters.FileTypeFilterPara.size(), 2);
+
+ VERIFY_ARE_EQUAL(
+ std::wstring(parameters.FileTypeFilterPara[0].pszSpec),
+ L"*.txt;*.doc;*.docx");
+ VERIFY_ARE_EQUAL(
+ std::wstring(parameters.FileTypeFilterPara[1].pszSpec),
+ L"*.png;*.jpg;*.jpeg;*.bmp");
+ }
+
TEST_METHOD(VerifyFilters_FileSavePickerWhenFileTypeChoicesDefinedExpectMatchingSpec)
{
// Arrange.
@@ -219,7 +249,9 @@ namespace Test::PickerCommonTests
// Act.
PickerParameters parameters{};
- parameters.CaptureFilterSpec(picker.FileTypeChoices().GetView());
+ parameters.CaptureFilterSpecData(
+ winrt::Windows::Foundation::Collections::IVectorView{},
+ picker.FileTypeChoices().GetView());
// Assert.
VERIFY_ARE_EQUAL(parameters.FileTypeFilterPara.size(), 2);
@@ -242,7 +274,9 @@ namespace Test::PickerCommonTests
// Act.
PickerParameters parameters{};
- parameters.CaptureFilterSpec(picker.FileTypeChoices().GetView());
+ parameters.CaptureFilterSpecData(
+ winrt::Windows::Foundation::Collections::IVectorView{},
+ picker.FileTypeChoices().GetView());
// Assert.
VERIFY_ARE_EQUAL(parameters.FileTypeFilterPara.size(), 1);
@@ -250,6 +284,9 @@ namespace Test::PickerCommonTests
VERIFY_ARE_EQUAL(
std::wstring(parameters.FileTypeFilterPara[0].pszSpec),
L"*");
+ VERIFY_ARE_EQUAL(
+ std::wstring(parameters.FileTypeFilterPara[0].pszName),
+ L"All Files");
}
TEST_METHOD(VerifyFilters_FileSavePickerWhenAsteriskFileTypeChoicesDefinedExpectAsteriskSpec)
@@ -265,7 +302,9 @@ namespace Test::PickerCommonTests
// Act.
PickerParameters parameters{};
- parameters.CaptureFilterSpec(picker.FileTypeChoices().GetView());
+ parameters.CaptureFilterSpecData(
+ winrt::Windows::Foundation::Collections::IVectorView{},
+ picker.FileTypeChoices().GetView());
// Assert.
VERIFY_ARE_EQUAL(parameters.FileTypeFilterPara.size(), 1);
@@ -628,6 +667,9 @@ namespace Test::PickerCommonTests
{
picker.SuggestedFolder(suggestedFolder);
VERIFY_ARE_EQUAL(picker.SuggestedFolder(), suggestedFolder);
+
+ picker.SuggestedStartFolder(suggestedFolder);
+ VERIFY_ARE_EQUAL(picker.SuggestedStartFolder(), suggestedFolder);
}
else
{
@@ -641,6 +683,17 @@ namespace Test::PickerCommonTests
{
// Expected exception for invalid suggested folder
}
+
+ try
+ {
+ picker.SuggestedStartFolder(suggestedFolder);
+ std::wstring errorMessage = L"Expected exception for invalid suggested start folder: " + std::wstring(suggestedFolder);
+ VERIFY_FAIL(errorMessage.c_str());
+ }
+ catch (...)
+ {
+ // Expected exception for invalid suggested start folder
+ }
}
}
}
diff --git a/test/StoragePickersTests/StoragePickersTests.cpp b/test/StoragePickersTests/StoragePickersTests.cpp
index 5c63b5a2d2..97721e7c2a 100644
--- a/test/StoragePickersTests/StoragePickersTests.cpp
+++ b/test/StoragePickersTests/StoragePickersTests.cpp
@@ -153,6 +153,17 @@ namespace Test::StoragePickersTests
picker.FileTypeFilter().Append(L"*");
VERIFY_ARE_EQUAL(picker.FileTypeFilter().GetAt(0), L"*");
+
+ auto openPickerChoices = winrt::single_threaded_vector();
+ openPickerChoices.Append(L".txt");
+ picker.FileTypeChoices().Insert(L"Documents", openPickerChoices);
+ VERIFY_ARE_EQUAL(picker.FileTypeChoices().Lookup(L"Documents").GetAt(0), L".txt");
+
+ picker.SuggestedFolder(L"C:\\temp_fileopenpicker_ut_temp");
+ VERIFY_ARE_EQUAL(picker.SuggestedFolder(), L"C:\\temp_fileopenpicker_ut_temp");
+
+ picker.SuggestedStartFolder(L"C:\\temp_fileopenpicker_ut_start");
+ VERIFY_ARE_EQUAL(picker.SuggestedStartFolder(), L"C:\\temp_fileopenpicker_ut_start");
}
TEST_METHOD(VerifyFileSavePickerOptionsAreReadCorrectly)
@@ -174,6 +185,9 @@ namespace Test::StoragePickersTests
filters.Append(L"*");
picker.FileTypeChoices().Insert(L"All Files", filters);
VERIFY_ARE_EQUAL(picker.FileTypeChoices().Lookup(L"All Files").GetAt(0), L"*");
+
+ picker.SuggestedStartFolder(L"C:\\temp_filesavepicker_start");
+ VERIFY_ARE_EQUAL(picker.SuggestedStartFolder(), L"C:\\temp_filesavepicker_start");
}
TEST_METHOD(VerifyFolderPickerOptionsAreReadCorrectly)
@@ -193,6 +207,12 @@ namespace Test::StoragePickersTests
picker.CommitButtonText(L"commit");
VERIFY_ARE_EQUAL(picker.CommitButtonText(), L"commit");
+
+ picker.SuggestedFolder(L"C:\\temp_folderpicker_ut_temp");
+ VERIFY_ARE_EQUAL(picker.SuggestedFolder(), L"C:\\temp_folderpicker_ut_temp");
+
+ picker.SuggestedStartFolder(L"C:\\temp_folderpicker_ut_start");
+ VERIFY_ARE_EQUAL(picker.SuggestedStartFolder(), L"C:\\temp_folderpicker_ut_start");
}
};
From 1534dd9a451f9fef25d3e1eda9e238521e46e58f Mon Sep 17 00:00:00 2001
From: DinahK-2SO <116714259+DinahK-2SO@users.noreply.github.com>
Date: Thu, 2 Oct 2025 10:48:36 +0800
Subject: [PATCH 2/4] fix errors
---
.../StoragePickers/FileTypeFilterVector.cpp | 2 +-
dev/Interop/StoragePickers/PickerCommon.cpp | 70 ++-----------------
2 files changed, 6 insertions(+), 66 deletions(-)
diff --git a/dev/Interop/StoragePickers/FileTypeFilterVector.cpp b/dev/Interop/StoragePickers/FileTypeFilterVector.cpp
index 67bb664ff9..5fe3d8bad5 100644
--- a/dev/Interop/StoragePickers/FileTypeFilterVector.cpp
+++ b/dev/Interop/StoragePickers/FileTypeFilterVector.cpp
@@ -7,7 +7,7 @@
namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
{
- FileTypeFilterVector::FileTypeFilterVector(bool forSavePicker)
+ FileTypeFilterVector::FileTypeFilterVector()
{
}
diff --git a/dev/Interop/StoragePickers/PickerCommon.cpp b/dev/Interop/StoragePickers/PickerCommon.cpp
index e90558e1f8..d5c003cc77 100644
--- a/dev/Interop/StoragePickers/PickerCommon.cpp
+++ b/dev/Interop/StoragePickers/PickerCommon.cpp
@@ -236,77 +236,17 @@ namespace PickerCommon {
ValidateStringNoEmbeddedNulls(path);
- std::wstring pathString{ path };
- auto pathObj = std::filesystem::path(pathString);
+ auto pathObj = std::filesystem::path(path.c_str());
if (!pathObj.is_absolute())
{
throw std::invalid_argument(propertyName);
}
- constexpr std::wstring_view invalidCharacters{ L"<>\"|?*" };
-
- bool hasExtendedPrefix = false;
- size_t startIndex = 0;
- if (pathString.size() >= 4 && pathString[0] == L'\\' && pathString[1] == L'\\' &&
- (pathString[2] == L'?' || pathString[2] == L'.') && pathString[3] == L'\\')
- {
- hasExtendedPrefix = true;
- startIndex = 4; // Skip the extended path prefix
- }
-
- auto isDriveSpecifier = [&](size_t index)
- {
- if (!hasExtendedPrefix)
- {
- return index == 1 && std::iswalpha(pathString[0]);
- }
-
- return (index == 5 && std::iswalpha(pathString[4]));
- };
-
- for (size_t i = startIndex; i < pathString.size(); ++i)
- {
- wchar_t currentChar = pathString[i];
-
- if (currentChar == L':')
- {
- if (isDriveSpecifier(i))
- {
- continue;
- }
- }
-
- if (invalidCharacters.find(currentChar) != std::wstring_view::npos)
- {
- throw std::invalid_argument(propertyName);
- }
- }
-
- constexpr size_t MaxComponentLength = 255;
- bool isFirstComponent = true;
- for (auto const& component : pathObj)
+ // The method SHSimpleIDListFromPath does syntax check on the path string.
+ wil::unique_cotaskmem_ptr pidl(SHSimpleIDListFromPath(path.c_str()));
+ if (!pidl)
{
- auto nativeComponent = component.native();
- if (nativeComponent.empty())
- {
- continue;
- }
-
- if (isFirstComponent)
- {
- isFirstComponent = false;
- continue; // Skip root name (e.g., "C:" or "\\server\share")
- }
-
- if (nativeComponent == L"\\" || nativeComponent == L"/")
- {
- continue; // Skip root directory separators
- }
-
- if (nativeComponent.size() > MaxComponentLength)
- {
- throw std::invalid_argument(propertyName);
- }
+ throw std::invalid_argument(propertyName);
}
}
From 3f0a1dd8e1d9d6975448cfd19e188b03910bc81f Mon Sep 17 00:00:00 2001
From: DinahK-2SO <116714259+DinahK-2SO@users.noreply.github.com>
Date: Thu, 2 Oct 2025 11:50:34 +0800
Subject: [PATCH 3/4] ForFeature_StoragePickers2
---
dev/Interop/StoragePickers/FileOpenPicker.h | 9 ++++++++-
dev/Interop/StoragePickers/FileTypeChoicesMap.cpp | 5 ++---
dev/Interop/StoragePickers/FileTypeChoicesMap.h | 4 ++--
3 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/dev/Interop/StoragePickers/FileOpenPicker.h b/dev/Interop/StoragePickers/FileOpenPicker.h
index c8beadf316..03319b8f4d 100644
--- a/dev/Interop/StoragePickers/FileOpenPicker.h
+++ b/dev/Interop/StoragePickers/FileOpenPicker.h
@@ -43,7 +43,14 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
winrt::hstring m_commitButtonText{};
winrt::Windows::Foundation::Collections::IVector m_fileTypeFilter{ make() };
- winrt::Windows::Foundation::Collections::IMap> m_fileTypeChoices{ make(false) };
+ winrt::Windows::Foundation::Collections::IMap> m_fileTypeChoices{
+ []()
+ {
+ auto map = make();
+ map.ForFeature_StoragePickers2 = true;
+ return map.as>>();
+ }()
+ };
winrt::hstring m_suggestedFolder{};
winrt::hstring m_suggestedStartFolder{};
diff --git a/dev/Interop/StoragePickers/FileTypeChoicesMap.cpp b/dev/Interop/StoragePickers/FileTypeChoicesMap.cpp
index 5ca48d2beb..c2f23b319f 100644
--- a/dev/Interop/StoragePickers/FileTypeChoicesMap.cpp
+++ b/dev/Interop/StoragePickers/FileTypeChoicesMap.cpp
@@ -7,14 +7,13 @@
namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
{
- FileTypeChoicesMap::FileTypeChoicesMap(bool forSavePicker)
- : ForSavePicker(forSavePicker)
+ FileTypeChoicesMap::FileTypeChoicesMap()
{
}
bool FileTypeChoicesMap::Insert(hstring const& key, winrt::Windows::Foundation::Collections::IVector const& value)
{
- if (!ForSavePicker)
+ if (ForFeature_StoragePickers2)
{
THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Storage::Pickers::Feature_StoragePickers2::IsEnabled());
}
diff --git a/dev/Interop/StoragePickers/FileTypeChoicesMap.h b/dev/Interop/StoragePickers/FileTypeChoicesMap.h
index 794c5e20c3..1dc6143667 100644
--- a/dev/Interop/StoragePickers/FileTypeChoicesMap.h
+++ b/dev/Interop/StoragePickers/FileTypeChoicesMap.h
@@ -11,9 +11,9 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
winrt::Windows::Foundation::Collections::IMap>,
winrt::Windows::Foundation::Collections::IIterable>>>
{
- FileTypeChoicesMap(bool forSavePicker = true);
+ FileTypeChoicesMap();
- bool ForSavePicker{ forSavePicker };
+ bool ForFeature_StoragePickers2{ false };
// IMap>
winrt::Windows::Foundation::Collections::IVector Lookup(hstring const& key) const;
From 0618e5b868c2ad45c433b63868d0cfa36a3b39f2 Mon Sep 17 00:00:00 2001
From: DinahK-2SO <116714259+DinahK-2SO@users.noreply.github.com>
Date: Fri, 3 Oct 2025 21:00:05 +0800
Subject: [PATCH 4/4] fix build error: fix the missing velocity head includes;
graceful
---
dev/Interop/StoragePickers/FileOpenPicker.cpp | 1 +
dev/Interop/StoragePickers/FileOpenPicker.h | 4 ++--
dev/Interop/StoragePickers/FileSavePicker.cpp | 1 +
dev/Interop/StoragePickers/FileTypeChoicesMap.cpp | 1 +
dev/Interop/StoragePickers/FolderPicker.cpp | 1 +
.../StoragePickers/Microsoft.Windows.Storage.Pickers.idl | 9 ++++++++-
dev/Interop/StoragePickers/PickerCommon.h | 2 +-
7 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/dev/Interop/StoragePickers/FileOpenPicker.cpp b/dev/Interop/StoragePickers/FileOpenPicker.cpp
index 3a8c108261..b61792f9ac 100644
--- a/dev/Interop/StoragePickers/FileOpenPicker.cpp
+++ b/dev/Interop/StoragePickers/FileOpenPicker.cpp
@@ -10,6 +10,7 @@
#include
#include
#include "TerminalVelocityFeatures-StoragePickers.h"
+#include "TerminalVelocityFeatures-StoragePickers2.h"
#include "PickerCommon.h"
#include "PickFileResult.h"
#include "PickerLocalization.h"
diff --git a/dev/Interop/StoragePickers/FileOpenPicker.h b/dev/Interop/StoragePickers/FileOpenPicker.h
index 03319b8f4d..c5ff80bc27 100644
--- a/dev/Interop/StoragePickers/FileOpenPicker.h
+++ b/dev/Interop/StoragePickers/FileOpenPicker.h
@@ -46,8 +46,8 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
winrt::Windows::Foundation::Collections::IMap> m_fileTypeChoices{
[]()
{
- auto map = make();
- map.ForFeature_StoragePickers2 = true;
+ auto map = winrt::make_self();
+ map->ForFeature_StoragePickers2 = true;
return map.as>>();
}()
};
diff --git a/dev/Interop/StoragePickers/FileSavePicker.cpp b/dev/Interop/StoragePickers/FileSavePicker.cpp
index 6fcb3e2eb0..95e965be00 100644
--- a/dev/Interop/StoragePickers/FileSavePicker.cpp
+++ b/dev/Interop/StoragePickers/FileSavePicker.cpp
@@ -15,6 +15,7 @@
#include
#include
#include "TerminalVelocityFeatures-StoragePickers.h"
+#include "TerminalVelocityFeatures-StoragePickers2.h"
#include "PickerCommon.h"
#include "PickerLocalization.h"
#include "PickFileResult.h"
diff --git a/dev/Interop/StoragePickers/FileTypeChoicesMap.cpp b/dev/Interop/StoragePickers/FileTypeChoicesMap.cpp
index c2f23b319f..0d8571ed8b 100644
--- a/dev/Interop/StoragePickers/FileTypeChoicesMap.cpp
+++ b/dev/Interop/StoragePickers/FileTypeChoicesMap.cpp
@@ -4,6 +4,7 @@
#include "pch.h"
#include "FileTypeChoicesMap.h"
#include "FileTypeFilterVector.h"
+#include "TerminalVelocityFeatures-StoragePickers2.h"
namespace winrt::Microsoft::Windows::Storage::Pickers::implementation
{
diff --git a/dev/Interop/StoragePickers/FolderPicker.cpp b/dev/Interop/StoragePickers/FolderPicker.cpp
index aeaea4a90a..5da7ab331e 100644
--- a/dev/Interop/StoragePickers/FolderPicker.cpp
+++ b/dev/Interop/StoragePickers/FolderPicker.cpp
@@ -9,6 +9,7 @@
#include
#include
#include "TerminalVelocityFeatures-StoragePickers.h"
+#include "TerminalVelocityFeatures-StoragePickers2.h"
#include "PickerCommon.h"
#include "PickFolderResult.h"
#include "PickerLocalization.h"
diff --git a/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl b/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl
index e70b9d7954..c71d622193 100644
--- a/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl
+++ b/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl
@@ -7,7 +7,7 @@ namespace Microsoft.Windows.Storage.Pickers
{
[contractversion(2.0)]
apicontract StoragePickersContract {};
-
+
[contract(StoragePickersContract, 1.8)]
enum PickerViewMode
{
@@ -43,7 +43,11 @@ namespace Microsoft.Windows.Storage.Pickers
Microsoft.Windows.Storage.Pickers.PickerViewMode ViewMode;
Microsoft.Windows.Storage.Pickers.PickerLocationId SuggestedStartLocation;
String CommitButtonText;
+
+ [contract(StoragePickersContract, 2.0)]
+ [feature(Feature_StoragePickers2)]
Windows.Foundation.Collections.IMap > FileTypeChoices{ get; };
+
Windows.Foundation.Collections.IVector FileTypeFilter{ get; };
[contract(StoragePickersContract, 2.0)]
@@ -91,6 +95,9 @@ namespace Microsoft.Windows.Storage.Pickers
Microsoft.Windows.Storage.Pickers.PickerViewMode ViewMode;
Microsoft.Windows.Storage.Pickers.PickerLocationId SuggestedStartLocation;
String CommitButtonText;
+
+ [contract(StoragePickersContract, 2.0)]
+ [feature(Feature_StoragePickers2)]
String SuggestedFolder;
[contract(StoragePickersContract, 2.0)]
diff --git a/dev/Interop/StoragePickers/PickerCommon.h b/dev/Interop/StoragePickers/PickerCommon.h
index f9e419bc38..f2bc2045ab 100644
--- a/dev/Interop/StoragePickers/PickerCommon.h
+++ b/dev/Interop/StoragePickers/PickerCommon.h
@@ -26,7 +26,7 @@ namespace PickerCommon {
void ValidateSuggestedStartLocation(winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId const& value);
void ValidateSingleFileTypeFilterElement(winrt::hstring const& filter);
void ValidateSuggestedFileName(winrt::hstring const& suggestedFileName);
- void ValidateFolderPath(winrt::hstring const& path, std::string const& argumentName);
+ void ValidateFolderPath(winrt::hstring const& path, std::string const& propertyName);
struct PickerParameters {
HWND HWnd{};