|
3 | 3 |
|
4 | 4 | using Microsoft.Extensions.Logging;
|
5 | 5 | using System.Runtime.InteropServices;
|
6 |
| -using System.Windows.Forms; |
7 |
| -using Vanara.Extensions; |
8 | 6 | using Windows.Win32;
|
9 | 7 | using Windows.Win32.Foundation;
|
10 | 8 | using Windows.Win32.NetworkManagement.WNet;
|
@@ -162,139 +160,59 @@ public bool Open_FileSaveDialog(nint hWnd, bool pickFoldersOnly, string[] filter
|
162 | 160 | }
|
163 | 161 |
|
164 | 162 | /// <inheritdoc/>
|
165 |
| - public bool Open_NetworkConnectionDialog(nint hWind, bool hideRestoreConnectionCheckBox = false, bool persistConnectionAtLogon = false, bool readOnlyPath = false, string? remoteNetworkName = null, bool useMostRecentPath = false) |
| 163 | + public unsafe bool Open_NetworkConnectionDialog(nint hWind, bool hideRestoreConnectionCheckBox = false, bool persistConnectionAtLogon = false, bool readOnlyPath = false, string? remoteNetworkName = null, bool useMostRecentPath = false) |
166 | 164 | {
|
167 |
| - using var dialog = new NetworkConnectionDialog() |
168 |
| - { |
169 |
| - HideRestoreConnectionCheckBox = hideRestoreConnectionCheckBox, |
170 |
| - PersistConnectionAtLogon = persistConnectionAtLogon, |
171 |
| - ReadOnlyPath = readOnlyPath, |
172 |
| - RemoteNetworkName = remoteNetworkName!, |
173 |
| - UseMostRecentPath = useMostRecentPath, |
174 |
| - }; |
175 |
| - |
176 |
| - var window = Win32Helper.Win32Window.FromLong(hWind.ToInt64()); |
| 165 | + NETRESOURCEW netRes = default; |
| 166 | + CONNECTDLGSTRUCTW dialogOptions = default; |
177 | 167 |
|
178 |
| - return dialog.ShowDialog(window) == System.Windows.Forms.DialogResult.OK; |
179 |
| - } |
| 168 | + dialogOptions.cbStructure = (uint)Marshal.SizeOf(typeof(CONNECTDLGSTRUCTW)); |
| 169 | + netRes.dwType = NET_RESOURCE_TYPE.RESOURCETYPE_DISK; |
180 | 170 |
|
181 |
| - private sealed class NetworkConnectionDialog : CommonDialog |
182 |
| - { |
183 |
| - private NETRESOURCEW netRes = new(); |
184 |
| - private CONNECTDLGSTRUCTW dialogOptions; |
| 171 | + if (hideRestoreConnectionCheckBox) |
| 172 | + dialogOptions.dwFlags |= CONNECTDLGSTRUCT_FLAGS.CONNDLG_HIDE_BOX; |
| 173 | + else |
| 174 | + dialogOptions.dwFlags &= ~CONNECTDLGSTRUCT_FLAGS.CONNDLG_HIDE_BOX; |
185 | 175 |
|
186 |
| - /// <summary>Initializes a new instance of the <see cref="NetworkConnectionDialog"/> class.</summary> |
187 |
| - public NetworkConnectionDialog() |
| 176 | + if (persistConnectionAtLogon) |
188 | 177 | {
|
189 |
| - dialogOptions.cbStructure = (uint)Marshal.SizeOf(typeof(CONNECTDLGSTRUCTW)); |
190 |
| - netRes.dwType = NET_RESOURCE_TYPE.RESOURCETYPE_DISK; |
| 178 | + dialogOptions.dwFlags |= CONNECTDLGSTRUCT_FLAGS.CONNDLG_PERSIST; |
| 179 | + dialogOptions.dwFlags |= CONNECTDLGSTRUCT_FLAGS.CONNDLG_NOT_PERSIST; |
191 | 180 | }
|
192 |
| - |
193 |
| - /// <summary>Gets the connected device number. This value is only valid after successfully running the dialog.</summary> |
194 |
| - /// <value>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.</value> |
195 |
| - [Browsable(false)] |
196 |
| - public int ConnectedDeviceNumber => (int)dialogOptions.dwDevNum; |
197 |
| - |
198 |
| - /// <summary>Gets or sets a value indicating whether to hide the check box allowing the user to restore the connection at logon.</summary> |
199 |
| - /// <value><c>true</c> if hiding restore connection check box; otherwise, <c>false</c>.</value> |
200 |
| - [DefaultValue(false), Category("Appearance"), Description("Hide the check box allowing the user to restore the connection at logon.")] |
201 |
| - public bool HideRestoreConnectionCheckBox |
| 181 | + else |
202 | 182 | {
|
203 |
| - get => dialogOptions.dwFlags.HasFlag(CONNECTDLGSTRUCT_FLAGS.CONNDLG_HIDE_BOX); |
204 |
| - set |
205 |
| - { |
206 |
| - if (value) |
207 |
| - dialogOptions.dwFlags |= CONNECTDLGSTRUCT_FLAGS.CONNDLG_HIDE_BOX; |
208 |
| - else |
209 |
| - dialogOptions.dwFlags &= ~CONNECTDLGSTRUCT_FLAGS.CONNDLG_HIDE_BOX; |
210 |
| - } |
| 183 | + dialogOptions.dwFlags &= ~CONNECTDLGSTRUCT_FLAGS.CONNDLG_PERSIST; |
| 184 | + dialogOptions.dwFlags &= ~CONNECTDLGSTRUCT_FLAGS.CONNDLG_NOT_PERSIST; |
211 | 185 | }
|
212 | 186 |
|
213 |
| - /// <summary>Gets or sets a value indicating whether restore the connection at logon.</summary> |
214 |
| - /// <value><c>true</c> to restore connection at logon; otherwise, <c>false</c>.</value> |
215 |
| - [DefaultValue(false), Category("Behavior"), Description("Restore the connection at logon.")] |
216 |
| - public bool PersistConnectionAtLogon |
217 |
| - { |
218 |
| - get => dialogOptions.dwFlags.IsFlagSet(CONNECTDLGSTRUCT_FLAGS.CONNDLG_PERSIST); |
219 |
| - set |
220 |
| - { |
221 |
| - dialogOptions.dwFlags = dialogOptions.dwFlags.SetFlags(CONNECTDLGSTRUCT_FLAGS.CONNDLG_PERSIST, value); |
222 |
| - dialogOptions.dwFlags = dialogOptions.dwFlags.SetFlags(CONNECTDLGSTRUCT_FLAGS.CONNDLG_NOT_PERSIST, !value); |
223 |
| - } |
224 |
| - } |
| 187 | + fixed (char* lpcRemoteName = remoteNetworkName) |
| 188 | + netRes.lpRemoteName = lpcRemoteName; |
225 | 189 |
|
226 |
| - /// <summary> |
227 |
| - /// 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 |
228 |
| - /// valid if <see cref="RemoteNetworkName"/> is not <see langword="null"/>. |
229 |
| - /// </summary> |
230 |
| - /// <value><c>true</c> to display a read only path; otherwise, <c>false</c>.</value> |
231 |
| - [DefaultValue(false), Category("Appearance"), Description("Display a read-only path instead of allowing the user to type in a path.")] |
232 |
| - public bool ReadOnlyPath { get; set; } |
233 |
| - |
234 |
| - /// <summary>Gets or sets the name of the remote network.</summary> |
235 |
| - /// <value>The name of the remote network.</value> |
236 |
| - [DefaultValue(null), Category("Behavior"), Description("The value displayed in the path field.")] |
237 |
| - public string RemoteNetworkName |
238 |
| - { |
239 |
| - get => netRes.lpRemoteName.ToString(); |
240 |
| - set |
241 |
| - { |
242 |
| - unsafe |
243 |
| - { |
244 |
| - fixed (char* lpcRemoteName = value) |
245 |
| - netRes.lpRemoteName = lpcRemoteName; |
246 |
| - } |
247 |
| - } |
248 |
| - } |
249 |
| - |
250 |
| - /// <summary>Gets or sets a value indicating whether to enter the most recently used paths into the combination box.</summary> |
251 |
| - /// <value><c>true</c> to use MRU path; otherwise, <c>false</c>.</value> |
252 |
| - /// <exception cref="InvalidOperationException">UseMostRecentPath</exception> |
253 |
| - [DefaultValue(false), Category("Behavior"), Description("Enter the most recently used paths into the combination box.")] |
254 |
| - public bool UseMostRecentPath |
255 |
| - { |
256 |
| - get => dialogOptions.dwFlags.IsFlagSet(CONNECTDLGSTRUCT_FLAGS.CONNDLG_USE_MRU); |
257 |
| - set |
258 |
| - { |
259 |
| - if (value && !string.IsNullOrEmpty(RemoteNetworkName)) |
260 |
| - throw new InvalidOperationException($"{nameof(UseMostRecentPath)} cannot be set to true if {nameof(RemoteNetworkName)} has a value."); |
261 |
| - |
262 |
| - dialogOptions.dwFlags = dialogOptions.dwFlags.SetFlags(CONNECTDLGSTRUCT_FLAGS.CONNDLG_USE_MRU, value); |
263 |
| - } |
264 |
| - } |
| 190 | + if (useMostRecentPath && !string.IsNullOrEmpty(remoteNetworkName)) |
| 191 | + throw new InvalidOperationException($"{nameof(useMostRecentPath)} cannot be set to true if {nameof(remoteNetworkName)} has a value."); |
265 | 192 |
|
266 |
| - /// <inheritdoc/> |
267 |
| - public unsafe override void Reset() |
268 |
| - { |
269 |
| - dialogOptions.dwDevNum = unchecked((uint)-1); |
270 |
| - dialogOptions.dwFlags = 0; |
271 |
| - dialogOptions.lpConnRes = null; |
272 |
| - ReadOnlyPath = false; |
273 |
| - } |
| 193 | + if (useMostRecentPath) |
| 194 | + dialogOptions.dwFlags |= CONNECTDLGSTRUCT_FLAGS.CONNDLG_USE_MRU; |
| 195 | + else |
| 196 | + dialogOptions.dwFlags &= ~CONNECTDLGSTRUCT_FLAGS.CONNDLG_USE_MRU; |
274 | 197 |
|
275 |
| - /// <inheritdoc/> |
276 |
| - protected unsafe override bool RunDialog(IntPtr hwndOwner) |
277 |
| - { |
278 |
| - dialogOptions.hwndOwner = new(hwndOwner); |
| 198 | + dialogOptions.hwndOwner = new(hWind); |
279 | 199 |
|
280 |
| - fixed (NETRESOURCEW* lpConnRes = &netRes) |
281 |
| - dialogOptions.lpConnRes = lpConnRes; |
| 200 | + dialogOptions.lpConnRes = &netRes; |
282 | 201 |
|
283 |
| - if (ReadOnlyPath && !string.IsNullOrEmpty(netRes.lpRemoteName.ToString())) |
284 |
| - dialogOptions.dwFlags |= CONNECTDLGSTRUCT_FLAGS.CONNDLG_RO_PATH; |
| 202 | + if (readOnlyPath && !string.IsNullOrEmpty(netRes.lpRemoteName.ToString())) |
| 203 | + dialogOptions.dwFlags |= CONNECTDLGSTRUCT_FLAGS.CONNDLG_RO_PATH; |
285 | 204 |
|
286 |
| - var result = PInvoke.WNetConnectionDialog1W(ref dialogOptions); |
| 205 | + var result = PInvoke.WNetConnectionDialog1W(ref dialogOptions); |
287 | 206 |
|
288 |
| - dialogOptions.lpConnRes = null; |
| 207 | + dialogOptions.lpConnRes = null; |
289 | 208 |
|
290 |
| - if ((uint)result == unchecked((uint)-1)) |
291 |
| - return false; |
| 209 | + if ((uint)result == unchecked((uint)-1)) |
| 210 | + return false; |
292 | 211 |
|
293 |
| - if (result == 0) |
294 |
| - throw new Win32Exception("Cannot display dialog"); |
| 212 | + if (result == 0) |
| 213 | + throw new Win32Exception("Cannot display dialog"); |
295 | 214 |
|
296 |
| - return true; |
297 |
| - } |
| 215 | + return true; |
298 | 216 | }
|
299 | 217 | }
|
300 | 218 | }
|
0 commit comments