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


    上一篇讲到将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;
            }
        }
    }


    本文是由葡萄城技术开发团队发布,转载请注明出处:葡萄城官网


  • 相关阅读:
    docker学习及应用
    openstack入门及应用
    C# 值类型,引用类型区别
    C# 继承
    Unity 使用Plugins接入安卓SDK 基础篇
    详谈 Unity3D AssetBundle 资源加载,结合实际项目开发实例
    Unity3D 协程 浅谈
    《俄罗斯,有点意思》
    老男孩之《生日快乐》
    【诗歌系列】《神曲》
  • 原文地址:https://www.cnblogs.com/powertoolsteam/p/1861494.html
Copyright © 2020-2023  润新知