把WPF Dialog转成WinForm Dialog需要注意的问题续

简介: 上一篇讲到将WPF的窗口转为WinForm窗口需要注意的问题,这里给出了另一种解决方案,闲话不说,请看代码: //============================================================================== // File Name : WpfModalDialogFixer.

上一篇讲到将WPF的窗口转为WinForm窗口需要注意的问题,这里给出了另一种解决方案,闲话不说,请看代码:

//==============================================================================
//  File Name   :   WpfModalDialogFixer.cs
//
//  Copyright (C) 2010 GrapeCity Inc. All rights reserved.
//
//  Distributable under LGPL license.
//
//==============================================================================

// <fileinformation>
//   <summary>
//     This file defines the class WpfModalDialogFixer for solve the problem as below:
//     When showing a modal dialog which ShowTaskBar is false, first deactive the application the activate it again.
//     The modal dialog would be at behind of MainWindow.
//   </summary>
//   <author name="WinkingZhang" mail="Winking.Zhang@GrapeCity.com"/>
//   <seealso ref=""/>
//   <remarks>
//     
//   </remarks>
// </fileinformation>

// <history>
//   <record date="10/21/2010 6:07:04 PM" author="WinkingZhang" revision="1.00.000">
//     Create the file and define the class.
//   </record>
// </history>

using System;
using System.Threading;
using System.Windows;
using System.Windows.Interop;
using System.Runtime.InteropServices;

namespace GrapeCity.Windows
{
    /// <summary>
    ///   Represents the <see cref="WpfModalDialogFixer"/> class.
    /// </summary>
    public class WpfModalDialogFixer
    {
        [ThreadStatic]
        private static WpfModalDialogFixer _fixer;
        private static readonly object _rootSync = new object();

        static WpfModalDialogFixer()
        {
            ComponentDispatcher.EnterThreadModal += new EventHandler(OnComponentDispatcherEnterThreadModal);
            ComponentDispatcher.LeaveThreadModal += new EventHandler(OnComponentDispatcherLeaveThreadModal);
        }

        private WpfModalDialogFixer()
        {
        }

        static void OnComponentDispatcherLeaveThreadModal(object sender, EventArgs e)
        {
            if (WpfModalDialogFixer.Current.Enable)
            {
                HwndSource src = HwndSource.FromVisual(Application.Current.MainWindow) as HwndSource;
                if (src != null)
                {
                    src.RemoveHook(new HwndSourceHook(OnComponentDispatcherThreadPreprocessMessage));
                }
            }
        }

        static IntPtr OnComponentDispatcherThreadPreprocessMessage(IntPtr hwnd, int message, IntPtr wparam, IntPtr lparam, ref bool handled)
        {
            // Need take care the message: WM_SETFOCUS, and if now in Modal dialog mode.
            if (message == 0x7 && ComponentDispatcher.IsThreadModal)
            {
                bool actived = false;
                foreach (Window w in Application.Current.Windows)
                {
                    HwndSource src = HwndSource.FromVisual(w) as HwndSource;
                    if (src != null /*&& src.Handle != hwnd*/)
                    {
                        if (IsWindowEnabled(src.Handle))
                        {
                            w.Activate();
                            actived = true;
                            break;
                        }
                    }
                }
                if (!actived) // in this case, caused by MessageBox.Show(...)
                {
                    //TODO: how to handle?
                }
                handled = true; // set handled to prevent default implement.
            }
            return IntPtr.Zero;
        }

        static void OnComponentDispatcherEnterThreadModal(object sender, EventArgs e)
        {
            if (WpfModalDialogFixer.Current.Enable)
            {
                HwndSource src = HwndSource.FromVisual(Application.Current.MainWindow) as HwndSource;
                if (src != null)
                {
                    src.AddHook(new HwndSourceHook(OnComponentDispatcherThreadPreprocessMessage));
                }
            }
        }

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool IsWindowEnabled(IntPtr hwnd);

        public static WpfModalDialogFixer Current
        {
            get
            {
                if (_fixer == null)
                {
                    lock (_rootSync)
                    {
                        if (_fixer == null)
                        {
                            _fixer = new WpfModalDialogFixer();
                        }
                    }
                }
                return _fixer;
            }
        }

        public bool Enable
        {
            get;
            set;
        }
    }
}
相关文章
|
C# Windows
2000条你应知的WPF小姿势 基础篇<78-81 Dialog/Location/WPF设备无关性>
2000条你应知的WPF小姿势 基础篇<78-81 Dialog/Location/WPF设备无关性>
85 0
|
C# Windows
wpf怎么使用WindowsFormsHost(即winform控件)
原文:wpf怎么使用WindowsFormsHost(即winform控件) 使用方法:   1、首先,我们需要向项目中的引用(reference)中添加两个动态库dll,一个是.
5446 0
|
C# 容器
在WPF中使用winform控件WebBrowser
在WPF中使用winform控件WebBrowser
|
前端开发 C#
WPF和Winform中picturebox图片局部放大
原文:WPF和Winform中picturebox图片局部放大 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yangyisen0713/article/details/19152607 ...
1772 0
|
C# Windows 安全
WinForm控件与WPF控件的交互
原文:WinForm控件与WPF控件的交互 这个问题其实也可以理解为:怎样在WPF/XAML中使用Winform中的控件(如PictureBox)?首先看看XAML代码:(注意下面加粗的部分)              ...
1088 0
|
Shell C# Windows
在Winform或WPF中System.Diagnostics.Process.Start的妙用
原文:在Winform或WPF中System.Diagnostics.Process.Start的妙用 我们经常会遇到在Winform或是WPF中点击链接或按钮打开某个指定的网址, 或者是需要打开电脑中某个指定的硬盘分区及文件夹, 甚至是"控制面板"相关的东西, 那么如何做呢? 答案是使用System.Diagnostics.Process.Start()。
1288 0
|
C#
WinForm和WPF颜色对象的转换
原文:WinForm和WPF颜色对象的转换 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huangli321456/article/details/52956846 ...
874 0
|
C# Windows
Winform与WPF对话框(MessageBox, Dialog)之比较
原文:Winform与WPF对话框(MessageBox, Dialog)之比较 Winform:使用System.Windows.Forms命名空间中相应控件; WPF则调用Microsoft.Win32。
2484 0
|
C#
WPF 嵌入Winform GDI 、 开启AllowsTransparenc问题
原文:WPF 嵌入Winform GDI 、 开启AllowsTransparenc问题 此文章可以解决2至少2个问题: 1.开启AllowsTransparenc造成的GDI+组件不显示问题 2.WPF 组件无法覆盖嵌入WPF窗口的任何第三方GDI+组件上层   方案1:自制双层 原理:用一个新的窗口来承载GDI+组件,实现 父窗口 拖动、缩放、最小化、最大化 的联动 事件。
1249 0