找回密码
 立即注册

QQ登录

只需一步,快速开始

thrall

超级版主

14

主题

174

帖子

2072

积分

超级版主

Rank: 8Rank: 8

积分
2072

活字格认证微信认证勋章

thrall
超级版主   /  发表于:2013-5-7 11:26  /   查看:7036  /  回复:0
上一篇讲到将WPF的窗口转为WinForm窗口需要注意的问题,这里给出了另一种解决方案,闲话不说,请看代码:


  1. //==============================================================================
  2. //  File Name   :   WpfModalDialogFixer.cs
  3. //
  4. //  Copyright (C) 2010 GrapeCity Inc. All rights reserved.
  5. //
  6. //  Distributable under LGPL license.
  7. //
  8. //==============================================================================

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

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

  26. using System;
  27. using System.Threading;
  28. using System.Windows;
  29. using System.Windows.Interop;
  30. using System.Runtime.InteropServices;

  31. namespace GrapeCity.Windows
  32. {
  33.     /// <summary>
  34.     ///   Represents the <see cref="WpfModalDialogFixer"/> class.
  35.     /// </summary>
  36.     public class WpfModalDialogFixer
  37.     {
  38.         [ThreadStatic]
  39.         private static WpfModalDialogFixer _fixer;
  40.         private static readonly object _rootSync = new object();

  41.         static WpfModalDialogFixer()
  42.         {
  43.             ComponentDispatcher.EnterThreadModal += new EventHandler(OnComponentDispatcherEnterThreadModal);
  44.             ComponentDispatcher.LeaveThreadModal += new EventHandler(OnComponentDispatcherLeaveThreadModal);
  45.         }

  46.         private WpfModalDialogFixer()
  47.         {
  48.         }

  49.         static void OnComponentDispatcherLeaveThreadModal(object sender, EventArgs e)
  50.         {
  51.             if (WpfModalDialogFixer.Current.Enable)
  52.             {
  53.                 HwndSource src = HwndSource.FromVisual(Application.Current.MainWindow) as HwndSource;
  54.                 if (src != null)
  55.                 {
  56.                     src.RemoveHook(new HwndSourceHook(OnComponentDispatcherThreadPreprocessMessage));
  57.                 }
  58.             }
  59.         }

  60.         static IntPtr OnComponentDispatcherThreadPreprocessMessage(IntPtr hwnd, int message, IntPtr wparam, IntPtr lparam, ref bool handled)
  61.         {
  62.             // Need take care the message: WM_SETFOCUS, and if now in Modal dialog mode.
  63.             if (message == 0x7 &amp;&amp; ComponentDispatcher.IsThreadModal)
  64.             {
  65.                 bool actived = false;
  66.                 foreach (Window w in Application.Current.Windows)
  67.                 {
  68.                     HwndSource src = HwndSource.FromVisual(w) as HwndSource;
  69.                     if (src != null /*&amp;&amp; src.Handle != hwnd*/)
  70.                     {
  71.                         if (IsWindowEnabled(src.Handle))
  72.                         {
  73.                             w.Activate();
  74.                             actived = true;
  75.                             break;
  76.                         }
  77.                     }
  78.                 }
  79.                 if (!actived) // in this case, caused by MessageBox.Show(...)
  80.                 {
  81.                     //TODO: how to handle?
  82.                 }
  83.                 handled = true; // set handled to prevent default implement.
  84.             }
  85.             return IntPtr.Zero;
  86.         }

  87.         static void OnComponentDispatcherEnterThreadModal(object sender, EventArgs e)
  88.         {
  89.             if (WpfModalDialogFixer.Current.Enable)
  90.             {
  91.                 HwndSource src = HwndSource.FromVisual(Application.Current.MainWindow) as HwndSource;
  92.                 if (src != null)
  93.                 {
  94.                     src.AddHook(new HwndSourceHook(OnComponentDispatcherThreadPreprocessMessage));
  95.                 }
  96.             }
  97.         }

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

  101.         public static WpfModalDialogFixer Current
  102.         {
  103.             get
  104.             {
  105.                 if (_fixer == null)
  106.                 {
  107.                     lock (_rootSync)
  108.                     {
  109.                         if (_fixer == null)
  110.                         {
  111.                             _fixer = new WpfModalDialogFixer();
  112.                         }
  113.                     }
  114.                 }
  115.                 return _fixer;
  116.             }
  117.         }

  118.         public bool Enable
  119.         {
  120.             get;
  121.             set;
  122.         }
  123.     }
  124. }
复制代码

0 个回复

您需要登录后才可以回帖 登录 | 立即注册
返回顶部