Skip to content

Commit eff9a9c

Browse files
Merge pull request #19 from mu88/master
Provide overloads for an Win32 handle as owning window (#18)
2 parents 491aa3a + e73a5fa commit eff9a9c

File tree

5 files changed

+207
-55
lines changed

5 files changed

+207
-55
lines changed

src/Ookii.Dialogs.Wpf/CredentialDialog.cs

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ public bool ShowDialog()
389389
/// <summary>
390390
/// Shows the credentials dialog as a modal dialog with the specified owner.
391391
/// </summary>
392-
/// <param name="owner">The <see cref="Window"/> that owns the credentials dialog.</param>
392+
/// <param name="owner">The <see cref="IntPtr"/> Win32 handle that owns the credentials dialog.</param>
393393
/// <returns><see langword="true" /> if the user clicked OK; otherwise, <see langword="false" />.</returns>
394394
/// <remarks>
395395
/// <para>
@@ -422,11 +422,13 @@ public bool ShowDialog()
422422
/// <exception cref="CredentialException">An error occurred while showing the credentials dialog.</exception>
423423
/// <exception cref="InvalidOperationException"><see cref="Target"/> is an empty string ("").</exception>
424424
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
425-
public bool ShowDialog(Window owner)
425+
public bool ShowDialog(IntPtr owner)
426426
{
427427
if( string.IsNullOrEmpty(_target) )
428428
throw new InvalidOperationException(Properties.Resources.CredentialEmptyTargetError);
429429

430+
IntPtr ownerHandle = owner == default(IntPtr) ? NativeMethods.GetActiveWindow() : owner;
431+
430432
UserName = "";
431433
Password = "";
432434
IsStoredCredential = false;
@@ -451,7 +453,6 @@ public bool ShowDialog(Window owner)
451453
storedCredentials = true;
452454
}
453455

454-
IntPtr ownerHandle = owner == null ? NativeMethods.GetActiveWindow() : new WindowInteropHelper(owner).Handle;
455456
bool result;
456457
if( NativeMethods.IsWindowsVistaOrLater )
457458
result = PromptForCredentialsCredUIWin(ownerHandle, storedCredentials);
@@ -460,6 +461,52 @@ public bool ShowDialog(Window owner)
460461
return result;
461462
}
462463

464+
/// <summary>
465+
/// Shows the credentials dialog as a modal dialog with the specified owner.
466+
/// </summary>
467+
/// <param name="owner">The <see cref="Window"/> that owns the credentials dialog.</param>
468+
/// <returns><see langword="true" /> if the user clicked OK; otherwise, <see langword="false" />.</returns>
469+
/// <remarks>
470+
/// <para>
471+
/// The credentials dialog will not be shown if one of the following conditions holds:
472+
/// </para>
473+
/// <list type="bullet">
474+
/// <item>
475+
/// <description>
476+
/// <see cref="UseApplicationInstanceCredentialCache"/> is <see langword="true"/> and the application instance
477+
/// credential cache contains credentials for the specified <see cref="Target"/>, even if <see cref="ShowUIForSavedCredentials"/>
478+
/// is <see langword="true"/>.
479+
/// </description>
480+
/// </item>
481+
/// <item>
482+
/// <description>
483+
/// <see cref="ShowSaveCheckBox"/> is <see langword="true"/>, <see cref="ShowUIForSavedCredentials"/> is <see langword="false"/>, and the operating system credential store
484+
/// for the current user contains credentials for the specified <see cref="Target"/>.
485+
/// </description>
486+
/// </item>
487+
/// </list>
488+
/// <para>
489+
/// In these cases, the <see cref="Credentials"/>, <see cref="UserName"/> and <see cref="Password"/> properties will
490+
/// be set to the saved credentials and this function returns immediately, returning <see langword="true" />.
491+
/// </para>
492+
/// <para>
493+
/// If the <see cref="ShowSaveCheckBox"/> property is <see langword="true"/>, you should call <see cref="ConfirmCredentials"/>
494+
/// after validating if the provided credentials are correct.
495+
/// </para>
496+
/// </remarks>
497+
/// <exception cref="CredentialException">An error occurred while showing the credentials dialog.</exception>
498+
/// <exception cref="InvalidOperationException"><see cref="Target"/> is an empty string ("").</exception>
499+
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
500+
public bool ShowDialog(Window owner)
501+
{
502+
IntPtr ownerHandle;
503+
if( owner == null )
504+
ownerHandle = NativeMethods.GetActiveWindow();
505+
else
506+
ownerHandle = new WindowInteropHelper(owner).Handle;
507+
return ShowDialog(ownerHandle);
508+
}
509+
463510
/// <summary>
464511
/// Confirms the validity of the credential provided by the user.
465512
/// </summary>

src/Ookii.Dialogs.Wpf/ProgressDialog.cs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,37 @@ public void ShowDialog(Window owner)
487487
ShowDialog(owner, null);
488488
}
489489

490+
/// <summary>
491+
/// Displays the progress dialog as a modal dialog.
492+
/// </summary>
493+
/// <param name="owner">The <see cref="IntPtr"/> Win32 handle that is the owner of this dialog.</param>
494+
/// <remarks>
495+
/// <para>
496+
/// The ShowDialog function for most .Net dialogs will not return until the dialog is closed. However,
497+
/// the <see cref="ShowDialog()"/> function for the <see cref="ProgressDialog"/> class will return immediately.
498+
/// The parent window will be disabled as with all modal dialogs.
499+
/// </para>
500+
/// <para>
501+
/// Although this function returns immediately, you cannot use the UI thread to do any processing. The dialog
502+
/// will not function correctly unless the UI thread continues to handle window messages, so that thread may
503+
/// not be blocked by some other activity. All processing related to the progress dialog must be done in
504+
/// the <see cref="DoWork"/> event handler.
505+
/// </para>
506+
/// <para>
507+
/// The progress dialog's window will appear in the taskbar. This behaviour is also contrary to most .Net dialogs,
508+
/// but is part of the underlying native progress dialog API so cannot be avoided.
509+
/// </para>
510+
/// <para>
511+
/// When possible, it is recommended that you use a modeless dialog using the <see cref="Show()"/> function.
512+
/// </para>
513+
/// </remarks>
514+
/// <exception cref="InvalidOperationException">The animation specified in the <see cref="Animation"/> property
515+
/// could not be loaded, or the operation is already running.</exception>
516+
public void ShowDialog(IntPtr owner)
517+
{
518+
ShowDialog(owner, null);
519+
}
520+
490521
/// <summary>
491522
/// Displays the progress dialog as a modal dialog.
492523
/// </summary>
@@ -519,6 +550,38 @@ public void ShowDialog(Window owner, object argument)
519550
RunProgressDialog(owner == null ? NativeMethods.GetActiveWindow() : new WindowInteropHelper(owner).Handle, argument);
520551
}
521552

553+
/// <summary>
554+
/// Displays the progress dialog as a modal dialog.
555+
/// </summary>
556+
/// <param name="owner">The <see cref="IntPtr"/> Win32 handle that is the owner of this dialog.</param>
557+
/// <param name="argument">A parameter for use by the background operation to be executed in the <see cref="DoWork"/> event handler.</param>
558+
/// <remarks>
559+
/// <para>
560+
/// The ShowDialog function for most .Net dialogs will not return until the dialog is closed. However,
561+
/// the <see cref="ShowDialog()"/> function for the <see cref="ProgressDialog"/> class will return immediately.
562+
/// The parent window will be disabled as with all modal dialogs.
563+
/// </para>
564+
/// <para>
565+
/// Although this function returns immediately, you cannot use the UI thread to do any processing. The dialog
566+
/// will not function correctly unless the UI thread continues to handle window messages, so that thread may
567+
/// not be blocked by some other activity. All processing related to the progress dialog must be done in
568+
/// the <see cref="DoWork"/> event handler.
569+
/// </para>
570+
/// <para>
571+
/// The progress dialog's window will appear in the taskbar. This behaviour is also contrary to most .Net dialogs,
572+
/// but is part of the underlying native progress dialog API so cannot be avoided.
573+
/// </para>
574+
/// <para>
575+
/// When possible, it is recommended that you use a modeless dialog using the <see cref="Show()"/> function.
576+
/// </para>
577+
/// </remarks>
578+
/// <exception cref="InvalidOperationException">The animation specified in the <see cref="Animation"/> property
579+
/// could not be loaded, or the operation is already running.</exception>
580+
public void ShowDialog(IntPtr owner, object argument)
581+
{
582+
RunProgressDialog(owner == default(IntPtr) ? NativeMethods.GetActiveWindow() : owner, argument);
583+
}
584+
522585
/// <summary>
523586
/// Updates the dialog's progress bar.
524587
/// </summary>

src/Ookii.Dialogs.Wpf/TaskDialog.cs

Lines changed: 71 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,6 +1081,76 @@ public TaskDialogButton ShowDialog(Window owner)
10811081
return ShowDialog(ownerHandle);
10821082
}
10831083

1084+
/// <summary>
1085+
/// Shows the task dialog as a modal dialog.
1086+
/// </summary>
1087+
/// <param name="owner">The <see cref="IntPtr"/> Win32 handle that is the owner of this task dialog.</param>
1088+
/// <returns>The button that the user clicked. Can be <see langword="null" /> if the user cancelled the dialog using the
1089+
/// title bar close button.</returns>
1090+
/// <exception cref="InvalidOperationException">
1091+
/// <para>
1092+
/// One of the properties or a combination of properties is not valid.
1093+
/// </para>
1094+
/// <para>
1095+
/// -or-
1096+
/// </para>
1097+
/// <para>
1098+
/// The dialog is already running.
1099+
/// </para>
1100+
/// </exception>
1101+
/// <exception cref="NotSupportedException">Task dialogs are not supported on the current operating system.</exception>
1102+
/// <exception cref="InvalidOperationException">Thrown if task dialog is already being displayed.</exception>
1103+
/// <exception cref="InvalidOperationException">Thrown if no buttons are present.</exception>
1104+
public TaskDialogButton ShowDialog(IntPtr owner)
1105+
{
1106+
if( !OSSupportsTaskDialogs )
1107+
throw new NotSupportedException(Properties.Resources.TaskDialogsNotSupportedError);
1108+
1109+
if( IsDialogRunning )
1110+
throw new InvalidOperationException(Properties.Resources.TaskDialogRunningError);
1111+
1112+
if( _buttons.Count == 0 )
1113+
throw new InvalidOperationException(Properties.Resources.TaskDialogNoButtonsError);
1114+
1115+
_config.hwndParent = owner;
1116+
_config.dwCommonButtons = 0;
1117+
_config.pButtons = IntPtr.Zero;
1118+
_config.cButtons = 0;
1119+
List<NativeMethods.TASKDIALOG_BUTTON> buttons = SetupButtons();
1120+
List<NativeMethods.TASKDIALOG_BUTTON> radioButtons = SetupRadioButtons();
1121+
1122+
SetupIcon();
1123+
1124+
try
1125+
{
1126+
MarshalButtons(buttons, out _config.pButtons, out _config.cButtons);
1127+
MarshalButtons(radioButtons, out _config.pRadioButtons, out _config.cRadioButtons);
1128+
int buttonId;
1129+
int radioButton;
1130+
bool verificationFlagChecked;
1131+
using( new ComCtlv6ActivationContext(true) )
1132+
{
1133+
NativeMethods.TaskDialogIndirect(ref _config, out buttonId, out radioButton, out verificationFlagChecked);
1134+
}
1135+
IsVerificationChecked = verificationFlagChecked;
1136+
1137+
TaskDialogRadioButton selectedRadioButton;
1138+
if( _radioButtonsById.TryGetValue(radioButton, out selectedRadioButton) )
1139+
selectedRadioButton.Checked = true;
1140+
1141+
TaskDialogButton selectedButton;
1142+
if( _buttonsById.TryGetValue(buttonId, out selectedButton) )
1143+
return selectedButton;
1144+
else
1145+
return null;
1146+
}
1147+
finally
1148+
{
1149+
CleanUpButtons(ref _config.pButtons, ref _config.cButtons);
1150+
CleanUpButtons(ref _config.pRadioButtons, ref _config.cRadioButtons);
1151+
}
1152+
}
1153+
10841154
/// <summary>
10851155
/// Simulates a click on the verification checkbox of the <see cref="TaskDialog"/>, if it exists.
10861156
/// </summary>
@@ -1220,57 +1290,7 @@ internal void ClickItem(TaskDialogItem item)
12201290
#endregion
12211291

12221292
#region Private members
1223-
1224-
private TaskDialogButton ShowDialog(IntPtr owner)
1225-
{
1226-
if( !OSSupportsTaskDialogs )
1227-
throw new NotSupportedException(Properties.Resources.TaskDialogsNotSupportedError);
1228-
1229-
if( IsDialogRunning )
1230-
throw new InvalidOperationException(Properties.Resources.TaskDialogRunningError);
1231-
1232-
if( _buttons.Count == 0 )
1233-
throw new InvalidOperationException(Properties.Resources.TaskDialogNoButtonsError);
1234-
1235-
_config.hwndParent = owner;
1236-
_config.dwCommonButtons = 0;
1237-
_config.pButtons = IntPtr.Zero;
1238-
_config.cButtons = 0;
1239-
List<NativeMethods.TASKDIALOG_BUTTON> buttons = SetupButtons();
1240-
List<NativeMethods.TASKDIALOG_BUTTON> radioButtons = SetupRadioButtons();
1241-
1242-
SetupIcon();
1243-
1244-
try
1245-
{
1246-
MarshalButtons(buttons, out _config.pButtons, out _config.cButtons);
1247-
MarshalButtons(radioButtons, out _config.pRadioButtons, out _config.cRadioButtons);
1248-
int buttonId;
1249-
int radioButton;
1250-
bool verificationFlagChecked;
1251-
using( new ComCtlv6ActivationContext(true) )
1252-
{
1253-
NativeMethods.TaskDialogIndirect(ref _config, out buttonId, out radioButton, out verificationFlagChecked);
1254-
}
1255-
IsVerificationChecked = verificationFlagChecked;
1256-
1257-
TaskDialogRadioButton selectedRadioButton;
1258-
if( _radioButtonsById.TryGetValue(radioButton, out selectedRadioButton) )
1259-
selectedRadioButton.Checked = true;
1260-
1261-
TaskDialogButton selectedButton;
1262-
if( _buttonsById.TryGetValue(buttonId, out selectedButton) )
1263-
return selectedButton;
1264-
else
1265-
return null;
1266-
}
1267-
finally
1268-
{
1269-
CleanUpButtons(ref _config.pButtons, ref _config.cButtons);
1270-
CleanUpButtons(ref _config.pRadioButtons, ref _config.cRadioButtons);
1271-
}
1272-
}
1273-
1293+
12741294
internal void UpdateDialog()
12751295
{
12761296
if( IsDialogRunning )

src/Ookii.Dialogs.Wpf/VistaFileDialog.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -542,10 +542,21 @@ public virtual void Reset()
542542
else
543543
{
544544
IntPtr ownerHandle = owner == null ? NativeMethods.GetActiveWindow() : new WindowInteropHelper(owner).Handle;
545-
return new bool?(RunFileDialog(ownerHandle));
545+
return ShowDialog(ownerHandle);
546546
}
547547
}
548548

549+
/// <summary>
550+
/// Displays the file dialog.
551+
/// </summary>
552+
/// <param name="owner">The <see cref="IntPtr"/> Win32 handle that is the owner of this dialog.</param>
553+
/// <returns>If the user clicks the OK button of the dialog that is displayed (e.g. <see cref="VistaOpenFileDialog" />, <see cref="VistaSaveFileDialog" />), <see langword="true" /> is returned; otherwise, <see langword="false" />.</returns>
554+
public bool? ShowDialog(IntPtr owner)
555+
{
556+
IntPtr ownerHandle = owner == default(IntPtr) ? NativeMethods.GetActiveWindow() : owner;
557+
return new bool?(RunFileDialog(ownerHandle));
558+
}
559+
549560
#endregion
550561

551562
#region Protected Methods

src/Ookii.Dialogs.Wpf/VistaFolderBrowserDialog.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,17 @@ public void Reset()
154154
public bool? ShowDialog(Window owner)
155155
{
156156
IntPtr ownerHandle = owner == null ? NativeMethods.GetActiveWindow() : new WindowInteropHelper(owner).Handle;
157+
return ShowDialog(ownerHandle);
158+
}
159+
160+
/// <summary>
161+
/// Displays the folder browser dialog.
162+
/// </summary>
163+
/// <param name="owner">The <see cref="IntPtr"/> Win32 handle that is the owner of this dialog.</param>
164+
/// <returns>If the user clicks the OK button, <see langword="true" /> is returned; otherwise, <see langword="false" />.</returns>
165+
public bool? ShowDialog(IntPtr owner)
166+
{
167+
IntPtr ownerHandle = owner == default(IntPtr) ? NativeMethods.GetActiveWindow() : owner;
157168
return new bool?(IsVistaFolderDialogSupported ? RunDialog(ownerHandle) : RunDialogDownlevel(ownerHandle));
158169
}
159170

0 commit comments

Comments
 (0)