zoukankan      html  css  js  c++  java
  • 把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;
            }
        }
    }


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


  • 相关阅读:
    P4568 [JLOI2011]飞行路线(分层图)
    打地鼠游戏(贪心)
    雷神领域(并查集真是个好东西)并查集+流氓dp
    P2934 [USACO09JAN]安全出行
    P2893 [USACO08FEB]修路
    P2894 [USACO08FEB]酒店Hotel
    P4145 上帝造题的七分钟2 / 花神游历各国
    P2579 [ZJOI2005]沼泽鳄鱼(邻接矩阵,快速幂)
    P2905 [USACO08OPEN]农场危机Crisis on the Farm(简单dp+麻烦“回溯”)
    day 2 上午 挂饰 背包
  • 原文地址:https://www.cnblogs.com/powertoolsteam/p/1861494.html
Copyright © 2011-2022 走看看