把WPF Dialog转成WinForm Dialog需要注意的问题续
上一篇讲到将WPF的窗口转为WinForm窗口需要注意的问题,这里给出了另一种解决方案,闲话不说,请看代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | //============================================================================== // 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 ; } } } |
标签:
WPF/Silverlight
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理