-
Notifications
You must be signed in to change notification settings - Fork 338
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Simplify using UWP file pickers from desktop apps #1063
Comments
@JaiganeshKumaran - as FYI in C#/.NET 5, we have just added support for several COM WinRT interop interfaces. Here are docs for more information: https://docs.microsoft.com/en-us/windows/apps/desktop/modernize/winrt-com-interop-csharp With these new APIs, you can add the following code in a C#/WinUI3 app which simplifies the code:
|
Right but that's still a lot of work compared to an UWP app where you just construct a picker and use it. Also these helpers must be rewritten for each supported programming language so I think it's better to have a constructor overload that does the initialization with window automatically. |
Agreed that this interop pattern is cumbersome and not discoverable. Ideally, the constructor overload would flow from a metadata attribute, as was done for FastABI support. If a class was decorated with a CanInitializeWithWindowAttribute, a constructor (or factory method) could be generated to accept an HWND source object (i.e., implementing IWindowNative), from which the given class could then call IInitializeWithWindow.Initialize. That would accrue to all language projections, rather just C#/WinRT. |
Ideally, you'd just internalize all this goop in the |
As @JaiganeshKumaran points out, it stems from HWND not being a WinRT type. Such types require a backdoor (COM interop interface) to access. But we haven't done a good job of supporting language projections there, and have effectively dropped WinRT/COM interop support on the floor. |
@Scottj1s The improved error message is good to see. I'm a big fan of help messages, instead of error messages. I had some comments here: microsoft/microsoft-ui-xaml#4167 (comment) that touched on some of this and used the pickers as an example. |
Thanks @dotMorten, and for linking the related issue. Totally agree! |
I think C++/WinRT should do something like this: template <typename T>
concept WindowLike = requires(T const& t)
{
// Function resolved with ADL, add GetWindowHandle in your type's namespace.
{ GetWindowHandle(t) } -> std::convertible_to<HWND>;
};
HWND GetWindowHandle(HWND value)
{
return value;
}
namespace winrt::Microsoft::UI::Xaml
{
HWND GetWindowHandle(Window const& window)
{
HWND result;
check_hresult(window.as<IWindowNative>()->get_WindowHandle(&result));
return result;
}
}
namespace winrt::Microsoft::UI::Windowing
{
HWND GetWindowHandle(AppWindow const& appWindow)
{
return GetWindowFromWindowId(appWindow.Id());
}
}
namespace winrt::Windows::Storage::Pickers
{
FileOpenPicker::FileOpenPicker(WindowLike auto const& windowLike)
{
check_hresult(try_as<IInitializeWithWindow>()->Initialize(GetWindowHandle(windowLike)));
}
// Repeat the same for other picker types.
} Since the number of types using IInitializeWithWindow is not large and is documented, can manually add constructor overloads taking any type that satisfies WindowLike, basically needing to have a way to get HWND. |
To use UWP file pickers such as file open picker or file save picker in desktop apps, you need to cast the object reference to IInitializeWithWindow and invoke its Initialize method. Although one can use Win32 file pickers, those lack some features like the ability to use picker contract apps. To simplify usage, I would suggest adding an overload for the constructor of FileOpenPicker and FileSavePicker to take a window handle. Since HWND can't be represented with the Windows Runtime type system, it can take an int64_t or the new WindowId structure instead.
The text was updated successfully, but these errors were encountered: