Ejemplo n.º 1
0
        /// <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);
        }
Ejemplo n.º 2
0
        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);
        }