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;
            }
        }
    }


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


  • 相关阅读:
    Analysis Services features supported by SQL Server editions
    Azure DevOps to Azure AppServices
    Power BI For Competition
    Win10开机“提示语音”以及”随机播放音乐”
    Azure DevOps
    Allow Only Ajax Requests For An Action In ASP.NET Core
    Mobile CI/CD 101
    Configure SSL for SharePoint 2013
    AWS Step Function Serverless Applications
    Cordova Upload Images using File Transfer Plugin and .Net core WebAPI
  • 原文地址:https://www.cnblogs.com/powertoolsteam/p/1861494.html
Copyright © 2011-2022 走看看