using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Vanara.Extensions;
using Vanara.InteropServices;
using static Vanara.PInvoke.Mpr;
namespace Vanara.Windows.Forms
{
///
/// A dialog box that allows the user to browse and connect to network resources.
///
///
public class NetworkConnectionDialog : CommonDialog
{
private NETRESOURCE nres = new NETRESOURCE();
private CONNECTDLGSTRUCT opts;
/// Initializes a new instance of the class.
public NetworkConnectionDialog()
{
opts.cbStructure = (uint)Marshal.SizeOf(typeof(CONNECTDLGSTRUCT));
nres.dwType = NETRESOURCEType.RESOURCETYPE_DISK;
}
/// Gets the connected device number. This value is only valid after successfully running the dialog.
/// The connected device number. The value is 1 for A:, 2 for B:, 3 for C:, and so on. If the user made a deviceless connection, the value is –1.
[Browsable(false)]
public int ConnectedDeviceNumber => opts.dwDevNum;
/// Gets or sets a value indicating whether to hide the check box allowing the user to restore the connection at logon.
/// true if hiding restore connection check box; otherwise, false.
[DefaultValue(false), Category("Appearance"), Description("Hide the check box allowing the user to restore the connection at logon.")]
public bool HideRestoreConnectionCheckBox
{
get => opts.dwFlags.IsFlagSet(CONN_DLG.CONNDLG_HIDE_BOX);
set => opts.dwFlags = opts.dwFlags.SetFlags(CONN_DLG.CONNDLG_HIDE_BOX, value);
}
/// Gets or sets a value indicating whether restore the connection at logon.
/// true to restore connection at logon; otherwise, false.
[DefaultValue(false), Category("Behavior"), Description("Restore the connection at logon.")]
public bool PersistConnectionAtLogon
{
get => opts.dwFlags.IsFlagSet(CONN_DLG.CONNDLG_PERSIST);
set
{
opts.dwFlags = opts.dwFlags.SetFlags(CONN_DLG.CONNDLG_PERSIST, value);
opts.dwFlags = opts.dwFlags.SetFlags(CONN_DLG.CONNDLG_NOT_PERSIST, !value);
}
}
///
/// Gets or sets a value indicating whether to display a read-only path instead of allowing the user to type in a path. This is only
/// valid if is not .
///
/// true to display a read only path; otherwise, false.
[DefaultValue(false), Category("Appearance"), Description("Display a read-only path instead of allowing the user to type in a path.")]
public bool ReadOnlyPath { get; set; }
/// Gets or sets the name of the remote network.
/// The name of the remote network.
[DefaultValue(null), Category("Behavior"), Description("The value displayed in the path field.")]
public string RemoteNetworkName { get => nres.lpRemoteName; set => nres.lpRemoteName = value; }
/// Gets or sets a value indicating whether to enter the most recently used paths into the combination box.
/// true to use MRU path; otherwise, false.
/// UseMostRecentPath
[DefaultValue(false), Category("Behavior"), Description("Enter the most recently used paths into the combination box.")]
public bool UseMostRecentPath
{
get => opts.dwFlags.IsFlagSet(CONN_DLG.CONNDLG_USE_MRU);
set
{
if (value && !string.IsNullOrEmpty(RemoteNetworkName))
throw new InvalidOperationException($"{nameof(UseMostRecentPath)} cannot be set to true if {nameof(RemoteNetworkName)} has a value.");
opts.dwFlags = opts.dwFlags.SetFlags(CONN_DLG.CONNDLG_USE_MRU, value);
}
}
///
public override void Reset()
{
opts.dwDevNum = -1;
opts.dwFlags = 0;
opts.lpConnRes = IntPtr.Zero;
ReadOnlyPath = false;
}
///
protected override bool RunDialog(IntPtr hwndOwner)
{
using (var lpnres = SafeCoTaskMemHandle.CreateFromStructure(nres))
{
opts.hwndOwner = hwndOwner;
opts.lpConnRes = lpnres.DangerousGetHandle();
if (ReadOnlyPath && !string.IsNullOrEmpty(nres.lpRemoteName))
opts.dwFlags |= CONN_DLG.CONNDLG_RO_PATH;
var ret = WNetConnectionDialog1(opts);
opts.lpConnRes = IntPtr.Zero;
if (ret == unchecked((uint)-1)) return false;
ret.ThrowIfFailed();
return true;
}
}
}
}