WPF Dialog 를 WinForm Dialog 로 전환 할 때 주의해 야 할 문제 계속

WPF 창 을 WinForm 창 으로 전환 하 는 데 주의해 야 할 문제 에 대해 서 는 또 다른 해결 방안 을 제시 하 였 습 니 다. 잡담 은 하지 않 고 코드 를 보십시오.
//==============================================================================
//  File Name   :   WpfModalDialogFixer.cs
//
//  Copyright (C) 2010 GrapeCity Inc. All rights reserved.
//
//  Distributable under LGPL license.
//
//==============================================================================

// 
//   
//     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.
//   
//   
//   
//   
//     
//   
// 

// 
//   
//     Create the file and define the class.
//   
// 

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

namespace GrapeCity.Windows
{
    /// 
    ///   Represents the  class.
    /// 
    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;
        }
    }
}

다음으로 전송:https://www.cnblogs.com/powertoolsteam/archive/2010/10/26/1861494.html

좋은 웹페이지 즐겨찾기