From e73a5fa9d57812274b3f53369c41c00e46130c5f Mon Sep 17 00:00:00 2001 From: mu88 <4560672+mu88@users.noreply.github.com> Date: Wed, 28 Oct 2020 15:55:32 +0100 Subject: [PATCH] Provide overloads for an Win32 handle as owning window (augustoproiete/ookii-dialogs-wpf#18) --- src/Ookii.Dialogs.Wpf/CredentialDialog.cs | 53 +++++++- src/Ookii.Dialogs.Wpf/ProgressDialog.cs | 63 +++++++++ src/Ookii.Dialogs.Wpf/TaskDialog.cs | 122 ++++++++++-------- src/Ookii.Dialogs.Wpf/VistaFileDialog.cs | 13 +- .../VistaFolderBrowserDialog.cs | 11 ++ 5 files changed, 207 insertions(+), 55 deletions(-) diff --git a/src/Ookii.Dialogs.Wpf/CredentialDialog.cs b/src/Ookii.Dialogs.Wpf/CredentialDialog.cs index e23e905..64b0ba4 100644 --- a/src/Ookii.Dialogs.Wpf/CredentialDialog.cs +++ b/src/Ookii.Dialogs.Wpf/CredentialDialog.cs @@ -389,7 +389,7 @@ public bool ShowDialog() /// /// Shows the credentials dialog as a modal dialog with the specified owner. /// - /// The that owns the credentials dialog. + /// The Win32 handle that owns the credentials dialog. /// if the user clicked OK; otherwise, . /// /// @@ -422,11 +422,13 @@ public bool ShowDialog() /// An error occurred while showing the credentials dialog. /// is an empty string (""). [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] - public bool ShowDialog(Window owner) + public bool ShowDialog(IntPtr owner) { if( string.IsNullOrEmpty(_target) ) throw new InvalidOperationException(Properties.Resources.CredentialEmptyTargetError); + IntPtr ownerHandle = owner == default(IntPtr) ? NativeMethods.GetActiveWindow() : owner; + UserName = ""; Password = ""; IsStoredCredential = false; @@ -451,7 +453,6 @@ public bool ShowDialog(Window owner) storedCredentials = true; } - IntPtr ownerHandle = owner == null ? NativeMethods.GetActiveWindow() : new WindowInteropHelper(owner).Handle; bool result; if( NativeMethods.IsWindowsVistaOrLater ) result = PromptForCredentialsCredUIWin(ownerHandle, storedCredentials); @@ -460,6 +461,52 @@ public bool ShowDialog(Window owner) return result; } + /// + /// Shows the credentials dialog as a modal dialog with the specified owner. + /// + /// The that owns the credentials dialog. + /// if the user clicked OK; otherwise, . + /// + /// + /// The credentials dialog will not be shown if one of the following conditions holds: + /// + /// + /// + /// + /// is and the application instance + /// credential cache contains credentials for the specified , even if + /// is . + /// + /// + /// + /// + /// is , is , and the operating system credential store + /// for the current user contains credentials for the specified . + /// + /// + /// + /// + /// In these cases, the , and properties will + /// be set to the saved credentials and this function returns immediately, returning . + /// + /// + /// If the property is , you should call + /// after validating if the provided credentials are correct. + /// + /// + /// An error occurred while showing the credentials dialog. + /// is an empty string (""). + [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] + public bool ShowDialog(Window owner) + { + IntPtr ownerHandle; + if( owner == null ) + ownerHandle = NativeMethods.GetActiveWindow(); + else + ownerHandle = new WindowInteropHelper(owner).Handle; + return ShowDialog(ownerHandle); + } + /// /// Confirms the validity of the credential provided by the user. /// diff --git a/src/Ookii.Dialogs.Wpf/ProgressDialog.cs b/src/Ookii.Dialogs.Wpf/ProgressDialog.cs index 4601c2e..1f50145 100644 --- a/src/Ookii.Dialogs.Wpf/ProgressDialog.cs +++ b/src/Ookii.Dialogs.Wpf/ProgressDialog.cs @@ -487,6 +487,37 @@ public void ShowDialog(Window owner) ShowDialog(owner, null); } + /// + /// Displays the progress dialog as a modal dialog. + /// + /// The Win32 handle that is the owner of this dialog. + /// + /// + /// The ShowDialog function for most .Net dialogs will not return until the dialog is closed. However, + /// the function for the class will return immediately. + /// The parent window will be disabled as with all modal dialogs. + /// + /// + /// Although this function returns immediately, you cannot use the UI thread to do any processing. The dialog + /// will not function correctly unless the UI thread continues to handle window messages, so that thread may + /// not be blocked by some other activity. All processing related to the progress dialog must be done in + /// the event handler. + /// + /// + /// The progress dialog's window will appear in the taskbar. This behaviour is also contrary to most .Net dialogs, + /// but is part of the underlying native progress dialog API so cannot be avoided. + /// + /// + /// When possible, it is recommended that you use a modeless dialog using the function. + /// + /// + /// The animation specified in the property + /// could not be loaded, or the operation is already running. + public void ShowDialog(IntPtr owner) + { + ShowDialog(owner, null); + } + /// /// Displays the progress dialog as a modal dialog. /// @@ -519,6 +550,38 @@ public void ShowDialog(Window owner, object argument) RunProgressDialog(owner == null ? NativeMethods.GetActiveWindow() : new WindowInteropHelper(owner).Handle, argument); } + /// + /// Displays the progress dialog as a modal dialog. + /// + /// The Win32 handle that is the owner of this dialog. + /// A parameter for use by the background operation to be executed in the event handler. + /// + /// + /// The ShowDialog function for most .Net dialogs will not return until the dialog is closed. However, + /// the function for the class will return immediately. + /// The parent window will be disabled as with all modal dialogs. + /// + /// + /// Although this function returns immediately, you cannot use the UI thread to do any processing. The dialog + /// will not function correctly unless the UI thread continues to handle window messages, so that thread may + /// not be blocked by some other activity. All processing related to the progress dialog must be done in + /// the event handler. + /// + /// + /// The progress dialog's window will appear in the taskbar. This behaviour is also contrary to most .Net dialogs, + /// but is part of the underlying native progress dialog API so cannot be avoided. + /// + /// + /// When possible, it is recommended that you use a modeless dialog using the function. + /// + /// + /// The animation specified in the property + /// could not be loaded, or the operation is already running. + public void ShowDialog(IntPtr owner, object argument) + { + RunProgressDialog(owner == default(IntPtr) ? NativeMethods.GetActiveWindow() : owner, argument); + } + /// /// Updates the dialog's progress bar. /// diff --git a/src/Ookii.Dialogs.Wpf/TaskDialog.cs b/src/Ookii.Dialogs.Wpf/TaskDialog.cs index 45ecdb7..b106398 100644 --- a/src/Ookii.Dialogs.Wpf/TaskDialog.cs +++ b/src/Ookii.Dialogs.Wpf/TaskDialog.cs @@ -1081,6 +1081,76 @@ public TaskDialogButton ShowDialog(Window owner) return ShowDialog(ownerHandle); } + /// + /// Shows the task dialog as a modal dialog. + /// + /// The Win32 handle that is the owner of this task dialog. + /// The button that the user clicked. Can be if the user cancelled the dialog using the + /// title bar close button. + /// + /// + /// One of the properties or a combination of properties is not valid. + /// + /// + /// -or- + /// + /// + /// The dialog is already running. + /// + /// + /// Task dialogs are not supported on the current operating system. + /// Thrown if task dialog is already being displayed. + /// Thrown if no buttons are present. + public TaskDialogButton ShowDialog(IntPtr owner) + { + if( !OSSupportsTaskDialogs ) + throw new NotSupportedException(Properties.Resources.TaskDialogsNotSupportedError); + + if( IsDialogRunning ) + throw new InvalidOperationException(Properties.Resources.TaskDialogRunningError); + + if( _buttons.Count == 0 ) + throw new InvalidOperationException(Properties.Resources.TaskDialogNoButtonsError); + + _config.hwndParent = owner; + _config.dwCommonButtons = 0; + _config.pButtons = IntPtr.Zero; + _config.cButtons = 0; + List buttons = SetupButtons(); + List radioButtons = SetupRadioButtons(); + + SetupIcon(); + + try + { + MarshalButtons(buttons, out _config.pButtons, out _config.cButtons); + MarshalButtons(radioButtons, out _config.pRadioButtons, out _config.cRadioButtons); + int buttonId; + int radioButton; + bool verificationFlagChecked; + using( new ComCtlv6ActivationContext(true) ) + { + NativeMethods.TaskDialogIndirect(ref _config, out buttonId, out radioButton, out verificationFlagChecked); + } + IsVerificationChecked = verificationFlagChecked; + + TaskDialogRadioButton selectedRadioButton; + if( _radioButtonsById.TryGetValue(radioButton, out selectedRadioButton) ) + selectedRadioButton.Checked = true; + + TaskDialogButton selectedButton; + if( _buttonsById.TryGetValue(buttonId, out selectedButton) ) + return selectedButton; + else + return null; + } + finally + { + CleanUpButtons(ref _config.pButtons, ref _config.cButtons); + CleanUpButtons(ref _config.pRadioButtons, ref _config.cRadioButtons); + } + } + /// /// Simulates a click on the verification checkbox of the , if it exists. /// @@ -1220,57 +1290,7 @@ internal void ClickItem(TaskDialogItem item) #endregion #region Private members - - private TaskDialogButton ShowDialog(IntPtr owner) - { - if( !OSSupportsTaskDialogs ) - throw new NotSupportedException(Properties.Resources.TaskDialogsNotSupportedError); - - if( IsDialogRunning ) - throw new InvalidOperationException(Properties.Resources.TaskDialogRunningError); - - if( _buttons.Count == 0 ) - throw new InvalidOperationException(Properties.Resources.TaskDialogNoButtonsError); - - _config.hwndParent = owner; - _config.dwCommonButtons = 0; - _config.pButtons = IntPtr.Zero; - _config.cButtons = 0; - List buttons = SetupButtons(); - List radioButtons = SetupRadioButtons(); - - SetupIcon(); - - try - { - MarshalButtons(buttons, out _config.pButtons, out _config.cButtons); - MarshalButtons(radioButtons, out _config.pRadioButtons, out _config.cRadioButtons); - int buttonId; - int radioButton; - bool verificationFlagChecked; - using( new ComCtlv6ActivationContext(true) ) - { - NativeMethods.TaskDialogIndirect(ref _config, out buttonId, out radioButton, out verificationFlagChecked); - } - IsVerificationChecked = verificationFlagChecked; - - TaskDialogRadioButton selectedRadioButton; - if( _radioButtonsById.TryGetValue(radioButton, out selectedRadioButton) ) - selectedRadioButton.Checked = true; - - TaskDialogButton selectedButton; - if( _buttonsById.TryGetValue(buttonId, out selectedButton) ) - return selectedButton; - else - return null; - } - finally - { - CleanUpButtons(ref _config.pButtons, ref _config.cButtons); - CleanUpButtons(ref _config.pRadioButtons, ref _config.cRadioButtons); - } - } - + internal void UpdateDialog() { if( IsDialogRunning ) diff --git a/src/Ookii.Dialogs.Wpf/VistaFileDialog.cs b/src/Ookii.Dialogs.Wpf/VistaFileDialog.cs index 4524995..75c9f93 100644 --- a/src/Ookii.Dialogs.Wpf/VistaFileDialog.cs +++ b/src/Ookii.Dialogs.Wpf/VistaFileDialog.cs @@ -542,10 +542,21 @@ public virtual void Reset() else { IntPtr ownerHandle = owner == null ? NativeMethods.GetActiveWindow() : new WindowInteropHelper(owner).Handle; - return new bool?(RunFileDialog(ownerHandle)); + return ShowDialog(ownerHandle); } } + /// + /// Displays the file dialog. + /// + /// The Win32 handle that is the owner of this dialog. + /// If the user clicks the OK button of the dialog that is displayed (e.g. , ), is returned; otherwise, . + public bool? ShowDialog(IntPtr owner) + { + IntPtr ownerHandle = owner == default(IntPtr) ? NativeMethods.GetActiveWindow() : owner; + return new bool?(RunFileDialog(ownerHandle)); + } + #endregion #region Protected Methods diff --git a/src/Ookii.Dialogs.Wpf/VistaFolderBrowserDialog.cs b/src/Ookii.Dialogs.Wpf/VistaFolderBrowserDialog.cs index 5572d3a..991404c 100644 --- a/src/Ookii.Dialogs.Wpf/VistaFolderBrowserDialog.cs +++ b/src/Ookii.Dialogs.Wpf/VistaFolderBrowserDialog.cs @@ -154,6 +154,17 @@ public void Reset() public bool? ShowDialog(Window owner) { IntPtr ownerHandle = owner == null ? NativeMethods.GetActiveWindow() : new WindowInteropHelper(owner).Handle; + return ShowDialog(ownerHandle); + } + + /// + /// Displays the folder browser dialog. + /// + /// The Win32 handle that is the owner of this dialog. + /// If the user clicks the OK button, is returned; otherwise, . + public bool? ShowDialog(IntPtr owner) + { + IntPtr ownerHandle = owner == default(IntPtr) ? NativeMethods.GetActiveWindow() : owner; return new bool?(IsVistaFolderDialogSupported ? RunDialog(ownerHandle) : RunDialogDownlevel(ownerHandle)); }