Skip to content

Commit

Permalink
Move FileDialogNative code to modern interop model (#3323)
Browse files Browse the repository at this point in the history
  • Loading branch information
hughbe committed Jun 19, 2020
1 parent 0b212b1 commit 86b3b7b
Show file tree
Hide file tree
Showing 25 changed files with 1,126 additions and 407 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Runtime.InteropServices;

internal partial class Interop
{
internal static partial class Shell32
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct COMDLG_FILTERSPEC
{
public string? pszName;
public string? pszSpec;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

internal partial class Interop
{
internal static partial class Shell32
{
public enum FDAP : uint
{
BOTTOM = 0,
TOP = 1
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;

internal partial class Interop
{
internal static partial class Shell32
{
[Flags]
public enum GETPROPERTYSTOREFLAGS : uint
{
DEFAULT = 0x00000000,
HANDLERPROPERTIESONLY = 0x00000001,
READWRITE = 0x00000002,
TEMPORARY = 0x00000004,
FASTPROPERTIESONLY = 0x00000008,
OPENSLOWITEM = 0x00000010,
DELAYCREATION = 0x00000020,
BESTEFFORT = 0x00000040,
NO_OPLOCK = 0x00000080,
PREFERQUERYPROPERTIES = 0x00000100,
EXTRINSICPROPERTIES = 0x00000200,
EXTRINSICPROPERTIESONLY = 0x00000400,
VOLATILEPROPERTIES = 0x00000800,
VOLATILEPROPERTIESONLY = 0x00001000,
MASK_VALID = 0x00001FFF
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Runtime.InteropServices;

internal static partial class Interop
{
internal static partial class Shell32
{
[ComImport]
[Guid("42f85136-db7e-439c-85f1-e4075d135fc8")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IFileDialog
{
[PreserveSig]
HRESULT Show(
IntPtr parent);

[PreserveSig]
HRESULT SetFileTypes(
uint cFileTypes,
[MarshalAs(UnmanagedType.LPArray)] COMDLG_FILTERSPEC[] rgFilterSpec);

[PreserveSig]
HRESULT SetFileTypeIndex(
uint iFileType);

void GetFileTypeIndex(
out uint piFileType);

void Advise(
IFileDialogEvents pfde,
out uint pdwCookie);

void Unadvise(
uint dwCookie);

void SetOptions(
FOS fos);

void GetOptions(
out FOS pfos);

void SetDefaultFolder(
IShellItem psi);

void SetFolder(
IShellItem psi);

void GetFolder(
out IShellItem ppsi);

[PreserveSig]
HRESULT GetCurrentSelection(
out IShellItem ppsi);

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

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

void SetTitle(
[MarshalAs(UnmanagedType.LPWStr)] string pszTitle);

[PreserveSig]
HRESULT SetOkButtonLabel(
[MarshalAs(UnmanagedType.LPWStr)] string pszText);

[PreserveSig]
HRESULT SetFileNameLabel(
[MarshalAs(UnmanagedType.LPWStr)] string pszLabel);

void GetResult(
out IShellItem ppsi);

[PreserveSig]
HRESULT AddPlace(
IShellItem psi,
FDAP fdap);

void SetDefaultExtension(
[MarshalAs(UnmanagedType.LPWStr)] string pszDefaultExtension);

void Close(
[MarshalAs(UnmanagedType.Error)] int hr);

void SetClientGuid(
ref Guid guid);

[PreserveSig]
HRESULT ClearClientData();

[PreserveSig]
HRESULT SetFilter(
IntPtr pFilter);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Runtime.InteropServices;

internal static partial class Interop
{
internal static partial class Shell32
{
[ComImport]
[Guid("e6fdd21a-163f-4975-9c8c-a69f1ba37034")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IFileDialogCustomize
{
[PreserveSig]
HRESULT EnableOpenDropDown(
uint dwIDCtl);

[PreserveSig]
HRESULT AddMenu(
uint dwIDCtl,
[MarshalAs(UnmanagedType.LPWStr)] string pszLabel);

[PreserveSig]
HRESULT AddPushButton(
uint dwIDCtl,
[MarshalAs(UnmanagedType.LPWStr)] string pszLabel);

[PreserveSig]
HRESULT AddComboBox(
uint dwIDCtl);

[PreserveSig]
HRESULT AddRadioButtonList(
uint dwIDCtl);

[PreserveSig]
HRESULT AddCheckButton(
uint dwIDCtl,
[MarshalAs(UnmanagedType.LPWStr)] string pszLabel,
BOOL bChecked);

[PreserveSig]
HRESULT AddEditBox(
uint dwIDCtl,
[MarshalAs(UnmanagedType.LPWStr)] string pszText);

[PreserveSig]
HRESULT AddSeparator(
uint dwIDCtl);

void AddText(
uint dwIDCtl,
[MarshalAs(UnmanagedType.LPWStr)] string pszText);

[PreserveSig]
HRESULT SetControlLabel(
uint dwIDCtl,
[MarshalAs(UnmanagedType.LPWStr)] string pszLabel);

[PreserveSig]
HRESULT GetControlState(
uint dwIDCtl,
out CDCS pdwState);

[PreserveSig]
HRESULT SetControlState(
uint dwIDCtl,
CDCS dwState);

[PreserveSig]
HRESULT GetEditBoxText(
uint dwIDCtl,
IntPtr ppszText);

[PreserveSig]
HRESULT SetEditBoxText(
uint dwIDCtl,
[MarshalAs(UnmanagedType.LPWStr)] string pszText);

[PreserveSig]
HRESULT GetCheckButtonState(
uint dwIDCtl,
out BOOL pbChecked);

[PreserveSig]
HRESULT SetCheckButtonState(
uint dwIDCtl,
BOOL bChecked);

[PreserveSig]
HRESULT AddControlItem(
uint dwIDCtl,
uint dwIDItem,
[MarshalAs(UnmanagedType.LPWStr)] string pszLabel);

[PreserveSig]
HRESULT RemoveControlItem(
uint dwIDCtl,
uint dwIDItem);

[PreserveSig]
HRESULT RemoveAllControlItems(
uint dwIDCtl);

[PreserveSig]
HRESULT GetControlItemState(
uint dwIDCtl,
uint dwIDItem,
out CDCS pdwState);

[PreserveSig]
HRESULT SetControlItemState(
uint dwIDCtl,
uint dwIDItem,
CDCS dwState);

[PreserveSig]
HRESULT GetSelectedControlItem(
uint dwIDCtl,
out int pdwIDItem);

[PreserveSig]
HRESULT SetSelectedControlItem(
uint dwIDCtl,
uint dwIDItem);

[PreserveSig]
HRESULT StartVisualGroup(
uint dwIDCtl,
[MarshalAs(UnmanagedType.LPWStr)] string pszLabel);

[PreserveSig]
HRESULT EndVisualGroup();

[PreserveSig]
HRESULT MakeProminent(
uint dwIDCtl);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Runtime.InteropServices;

internal static partial class Interop
{
internal static partial class Shell32
{
/// <remarks>
/// Some of these callbacks are cancelable - returning S_FALSE means that the dialog should
/// not proceed (e.g. with closing, changing folder); to support this, we need to use the
/// PreserveSig attribute to enable us to return the proper HRESULT
/// </remarks>
[ComImport]
[Guid("973510DB-7D7F-452B-8975-74A85828D354")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public unsafe interface IFileDialogEvents
{
[PreserveSig]
HRESULT OnFileOk(
IFileDialog pfd);

[PreserveSig]
HRESULT OnFolderChanging(
IFileDialog pfd,
IShellItem psiFolder);

[PreserveSig]
HRESULT OnFolderChange(
IFileDialog pfd);

[PreserveSig]
HRESULT OnSelectionChange(
IFileDialog pfd);

[PreserveSig]
HRESULT OnShareViolation(
IFileDialog pfd,
IShellItem psi,
FDESVR* pResponse);

[PreserveSig]
HRESULT OnTypeChange(
IFileDialog pfd);

[PreserveSig]
HRESULT OnOverwrite(
IFileDialog pfd,
IShellItem psi,
FDEOR* pResponse);
}
}
}
Loading

0 comments on commit 86b3b7b

Please sign in to comment.