/// <include file='doc\CommonDialog.uex' path='docs/doc[@for="CommonDialog.ShowDialog1"]/*' /> /// <devdoc> /// <para> /// Runs a common dialog box, parented to the given IWin32Window. /// </para> /// </devdoc> public DialogResult ShowDialog(IWin32Window owner) { IntSecurity.SafeSubWindows.Demand(); if (owner == null || owner.Handle == IntPtr.Zero) { return(ShowDialog()); } if (!SystemInformation.UserInteractive) { throw new InvalidOperationException(SR.GetString(SR.CantShowModalOnNonInteractive)); } if (helpMsg == 0) { helpMsg = SafeNativeMethods.RegisterWindowMessage("commdlg_help"); } IntPtr hwndOwner = owner.Handle; defOwnerWndProc = UnsafeNativeMethods.GetWindowLong(new HandleRef(owner, hwndOwner), NativeMethods.GWL_WNDPROC); // define ownerproc out here so it won't be garbage collected before the finally // clause runs NativeMethods.WndProc ownerProc = new NativeMethods.WndProc(this.OwnerWndProc); DialogResult result = DialogResult.Cancel; try { UnsafeNativeMethods.SetWindowLong(new HandleRef(owner, hwndOwner), NativeMethods.GWL_WNDPROC, ownerProc); Application.BeginModalMessageLoop(); try { result = RunDialog(hwndOwner) ? DialogResult.OK : DialogResult.Cancel; GC.KeepAlive(ownerProc); } finally { Application.EndModalMessageLoop(); } } finally { if (UnsafeNativeMethods.IsWindow(new HandleRef(owner, hwndOwner))) { UnsafeNativeMethods.SetWindowLong(new HandleRef(owner, hwndOwner), NativeMethods.GWL_WNDPROC, new HandleRef(null, defOwnerWndProc)); } } return(result); }
public DialogResult ShowDialog(IWin32Window owner) { if (!SystemInformation.UserInteractive) { throw new InvalidOperationException(SR.CantShowModalOnNonInteractive); } NativeWindow native = null;//This will be used if there is no owner or active window (declared here so it can be kept alive) IntPtr hwndOwner = IntPtr.Zero; DialogResult result = DialogResult.Cancel; try { if (owner != null) { hwndOwner = Control.GetSafeHandle(owner); } if (hwndOwner == IntPtr.Zero) { hwndOwner = UnsafeNativeMethods.GetActiveWindow(); } if (hwndOwner == IntPtr.Zero) { //We will have to create our own Window native = new NativeWindow(); native.CreateHandle(new CreateParams()); hwndOwner = native.Handle; } if (helpMsg == 0) { helpMsg = SafeNativeMethods.RegisterWindowMessage("commdlg_help"); } NativeMethods.WndProc ownerProc = new NativeMethods.WndProc(this.OwnerWndProc); hookedWndProc = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate(ownerProc); System.Diagnostics.Debug.Assert(IntPtr.Zero == defOwnerWndProc, "The previous subclass wasn't properly cleaned up"); IntPtr userCookie = IntPtr.Zero; try { //UnsafeNativeMethods.[Get|Set]WindowLong is smart enough to call SetWindowLongPtr on 64-bit OS defOwnerWndProc = UnsafeNativeMethods.SetWindowLong(new HandleRef(this, hwndOwner), NativeMethods.GWL_WNDPROC, ownerProc); if (Application.UseVisualStyles) { userCookie = UnsafeNativeMethods.ThemingScope.Activate(); } Application.BeginModalMessageLoop(); try { result = RunDialog(hwndOwner) ? DialogResult.OK : DialogResult.Cancel; } finally { Application.EndModalMessageLoop(); } } finally { IntPtr currentSubClass = UnsafeNativeMethods.GetWindowLong(new HandleRef(this, hwndOwner), NativeMethods.GWL_WNDPROC); if (IntPtr.Zero != defOwnerWndProc || currentSubClass != hookedWndProc) { UnsafeNativeMethods.SetWindowLong(new HandleRef(this, hwndOwner), NativeMethods.GWL_WNDPROC, new HandleRef(this, defOwnerWndProc)); } UnsafeNativeMethods.ThemingScope.Deactivate(userCookie); defOwnerWndProc = IntPtr.Zero; hookedWndProc = IntPtr.Zero; //Ensure that the subclass delegate will not be GC collected until after it has been subclassed GC.KeepAlive(ownerProc); } } finally { if (null != native) { native.DestroyHandle(); } } return(result); }