Skip to content
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

Add support for IFileOpenDialog #5319

Merged
merged 25 commits into from
Jan 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 12 additions & 3 deletions src/System.Windows.Forms.Primitives/src/Interop/Interop.IID.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,22 @@ internal static class IID
// 618736E0-3C3D-11CF-810C-00AA00389B71
public static Guid IAccessible = new Guid(0x618736E0, 0x3C3D, 0x11CF, 0x81, 0x0C, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should have a follow up issue/PR to get this one fixed. Part of the idea here with using static properties is to avoid accidentally modifying these values. :)


// D57C7288-D4AD-4768-BE02-9D969532D960
internal static Guid IFileOpenDialog { get; } = new(0xD57C7288, 0xD4AD, 0x4768, 0xBE, 0x02, 0x9D, 0x96, 0x95, 0x32, 0xD9, 0x60);

// 973510DB-7D7F-452B-8975-74A85828D354
internal static Guid IFileDialogEvents { get; } = new(0x973510DB, 0x7D7F, 0x452B, 0x89, 0x75, 0x74, 0xA8, 0x58, 0x28, 0xD3, 0x54);

// 00000109-0000-0000-C000-000000000046
public static Guid IPersistStream = new Guid(0x00000109, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
public static Guid IPersistStream { get; } = new(0x00000109, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);

// 7BF80980-BF32-101A-8BBB-00AA00300CAB
public static Guid IPicture = new Guid(0x7BF80980, 0xBF32, 0x101A, 0x8B, 0xBB, 0x00, 0xAA, 0x00, 0x30, 0x0C, 0xAB);
public static Guid IPicture { get; } = new(0x7BF80980, 0xBF32, 0x101A, 0x8B, 0xBB, 0x00, 0xAA, 0x00, 0x30, 0x0C, 0xAB);

// 43826D1E-E718-42EE-BC55-A1E261C37BFE
internal static Guid IShellItem { get; } = new(0x43826D1E, 0xE718, 0x42EE, 0xBC, 0x55, 0xA1, 0xE2, 0x61, 0xC3, 0x7B, 0xFE);

// 0000000C-0000-0000-C000-000000000046
public static Guid IStream = new Guid(0x0000000C, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
public static Guid IStream { get; } = new(0x0000000C, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,13 @@ internal static partial class Ole32
CLSCTX dwClsContext,
ref Guid riid,
[MarshalAs(UnmanagedType.Interface)] out object ppv);

[DllImport(Libraries.Ole32, ExactSpelling = true)]
public static extern HRESULT CoCreateInstance(
ref Guid rclsid,
IntPtr punkOuter,
CLSCTX dwClsContext,
ref Guid riid,
out IntPtr ppv);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ internal partial class Interop
{
internal static partial class Shell32
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
[StructLayout(LayoutKind.Sequential)]
public struct COMDLG_FILTERSPEC
{
public string? pszName;
public string? pszSpec;
public IntPtr pszName;
public IntPtr pszSpec;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,17 @@ public interface IFileDialog
IShellItem psi);

void GetFolder(
out IShellItem ppsi);
out IShellItem? ppsi);

[PreserveSig]
HRESULT GetCurrentSelection(
out IShellItem ppsi);
out IShellItem? ppsi);

void SetFileName(
[MarshalAs(UnmanagedType.LPWStr)] string pszName);

void GetFileName(
[MarshalAs(UnmanagedType.LPWStr)] out string pszName);
[MarshalAs(UnmanagedType.LPWStr)] out string? pszName);

void SetTitle(
[MarshalAs(UnmanagedType.LPWStr)] string pszTitle);
Expand All @@ -73,7 +73,7 @@ public interface IFileDialog
[MarshalAs(UnmanagedType.LPWStr)] string pszLabel);

void GetResult(
out IShellItem ppsi);
out IShellItem? ppsi);

[PreserveSig]
HRESULT AddPlace(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,17 @@ public interface IFileOpenDialog : IFileDialog
IShellItem psi);

void GetFolder(
out IShellItem ppsi);
out IShellItem? ppsi);

[PreserveSig]
HRESULT GetCurrentSelection(
out IShellItem ppsi);
out IShellItem? ppsi);

void SetFileName(
[MarshalAs(UnmanagedType.LPWStr)] string pszName);

void GetFileName(
[MarshalAs(UnmanagedType.LPWStr)] out string pszName);
[MarshalAs(UnmanagedType.LPWStr)] out string? pszName);

void SetTitle(
[MarshalAs(UnmanagedType.LPWStr)] string pszTitle);
Expand All @@ -74,7 +74,7 @@ public interface IFileOpenDialog : IFileDialog
[MarshalAs(UnmanagedType.LPWStr)] string pszLabel);

void GetResult(
out IShellItem ppsi);
out IShellItem? ppsi);

[PreserveSig]
HRESULT AddPlace(
Expand All @@ -98,11 +98,11 @@ public interface IFileOpenDialog : IFileDialog
IntPtr pFilter);

void GetResults(
out IShellItemArray ppenum);
out IShellItemArray? ppenum);

[PreserveSig]
HRESULT GetSelectedItems(
out IShellItemArray ppsai);
out IShellItemArray? ppsai);
}
#pragma warning restore CS0108
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ public interface IShellItem

[PreserveSig]
HRESULT GetParent(
out IShellItem ppsi);
out IShellItem? ppsi);

[PreserveSig]
HRESULT GetDisplayName(
SIGDN sigdnName,
[MarshalAs(UnmanagedType.LPWStr)] out string ppszName);
[MarshalAs(UnmanagedType.LPWStr)] out string? ppszName);

[PreserveSig]
HRESULT GetAttributes(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ internal static partial class Shell32
[DllImport(Libraries.Shell32, ExactSpelling = true)]
public static extern HRESULT SHCreateShellItem(IntPtr pidlParent, IntPtr psfParent, IntPtr pidl, out IShellItem ppsi);

[DllImport(Libraries.Shell32, EntryPoint = "SHCreateShellItem", ExactSpelling = true)]
public static extern HRESULT SHCreateShellItemViaComWrappers(IntPtr pidlParent, IntPtr psfParent, IntPtr pidl, out IntPtr ppsi);

public static IShellItem GetShellItemForPath(string path)
{
if (SHParseDisplayName(path, IntPtr.Zero, out IntPtr pidl, 0, out uint _).Succeeded())
Expand All @@ -24,5 +27,21 @@ public static IShellItem GetShellItemForPath(string path)

throw new FileNotFoundException();
}

public static IShellItem GetShellItemForPathViaComWrappers(string path)
{
if (SHParseDisplayName(path, IntPtr.Zero, out IntPtr pidl, 0, out uint _).Succeeded())
{
// No parent specified
if (SHCreateShellItemViaComWrappers(IntPtr.Zero, IntPtr.Zero, pidl, out IntPtr ret).Succeeded())
{
var obj = WinFormsComWrappers.Instance
.GetOrCreateObjectForComInstance(ret, CreateObjectFlags.None);
return (IShellItem)obj;
}
}

throw new FileNotFoundException();
}
}
}