WPF 获取全局所有窗口的创建显示事件 监控窗口打开
本文将告诉大家如何在 WPF 里面进行全局监控任意的窗口创建显示打开,可以获取到每个 WPF 窗口的打开的时机。如此可以用来辅助定位问题和输出日志
这篇博客是有背景的,老司机告诉我说他的应用不响应鼠标和键盘点击了,于是我和他调查了半天才发现有一个 Dialog 窗口显示出来,导致消息循环被切到了一个 Dialog 窗口里面去了。然而这个 Dialog 窗口是藏起来的,在屏幕上刚好没有能看见他
此时我就好奇了,为什么我的应用就不会存在如此的逗比代码,但是老司机的应用就可能存在如此难以调试的问题。于是我就在自己的应用上写了一个逗比代码,强行弹出一个 Dialog 窗口出来,结果我就发现监控模块告诉了我有一个在白名单之外的窗口弹出了,如果确定这是符合开发预期的,那就需要手动修改白名单。这是一个开发时的辅助机制,用来让开发者不要随便弹出窗口,我又好奇这个监控模块是如何监控到我弹出一个窗口的,学习了监控模块的机制,就写了这个博客
在 WPF 里面,可以通过 EventManager 监听全局的路由事件,刚好窗口创建显示时,将会触发一些路径事件。通过路由事件监听,即可了解是哪个窗口正在准备弹出。于是就可以进行监控窗口创建显示
监听窗口的 SizeChangedEvent 路由事件是比较靠谱的方式,这个有一点点违反开发者的想法,开发者默认想的是使用 LoadedEvent 事件。但是在 WPF 里面做了一些性能优化,如果一个窗口没有 XAML 或者是没有任何代码监听了 Loaded 事件,那将不触发 LoadedEvent 路由事件。因此这里就监听窗口一定会触发的 SizeChangedEvent 事件
代码如下
public App()
{
EventManager.RegisterClassHandler(typeof(Window), Window.LoadedEvent, new RoutedEventHandler(Window_OnLoaded));
EventManager.RegisterClassHandler(typeof(Window), Window.SizeChangedEvent, new RoutedEventHandler(Window_SizeChanged));
}
private void Window_OnLoaded(object sender, RoutedEventArgs e)
{
// 如果窗口没有 XAML 或者没有监听 Loaded 事件,将不会被触发
}
private void Window_SizeChanged(object sender, RoutedEventArgs e)
{
// 所有窗口都会触发
}
窗口创建的时候,将会进入 Window_SizeChanged 事件。通过 sender 参数即可了解是哪个窗口对象被创建,接着就可以方便进行日志或者是提示开发者不要随便创建窗口等
可以自己测试一下代码,例如在 MainWindow 里面再次创建一个空窗口
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Loaded += MainWindow_Loaded;
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
var window = new Window();
window.Show();
}
}
运行以上的代码,可以看到 Window_SizeChanged 被进入两次,分别是 MainWindow 和在 MainWindow 里面创建显示的窗口。而 Window_OnLoaded 只会进入一次,在 MainWindow 准备显示时进入
我推荐在自己的项目里面,在 Debug 下加上此机制,至少输出一下窗口显示的日志,方便了解显示了哪些窗口。如果可以的话,也可以加上白名单机制,如果一个窗口是新写的之类的,可以提示开发者阅读必要的文档之后加入到白名单里面。也可以在事件里面对每个窗口注入一些有趣的逻辑,或者是监听窗口的各个事件,输出更多日志,让开发者可以通过日志了解到当前有哪些窗口依然还在显示
这是另一位大佬写的代码,请看 https://gist.github.com/mwisnicki/3104963
WPF 获取全局所有窗口的创建显示事件 监控窗口打开的更多相关文章
- 获取全局上下文(getApplicationContext)_创建Shared Preference工具类_实现自动登录
获取全局上下文(getApplicationContext)_创建Shared Preference工具类_实现自动登录 ===========================获取全局上下文(getA ...
- uCGUI窗口的创建过程分析
一.相关结构体和变量 窗口管理结构体 /* 窗口管理结构体 共30个字节 */ struct WM_Obj { GUI_RECT Rect; //窗口尺寸(x0,y0,x1,y1) 8个字节 GUI_ ...
- Add an Action that Displays a Pop-up Window 添加显示弹出窗口按钮
In this lesson, you will learn how to create an Action that shows a pop-up window. This type of Acti ...
- 有谁知道Delphi中"窗口"的创建过程?
求助:有谁知道Delphi中窗口的创建过程,此“窗口”不仅仅指 TForm 类型, 还包括一般的窗口控件,如TButton,TEdit等等,希望有能够十分详细的运作 过程,比如说CreatPara ...
- system调用命令行命令而不显示命令行窗口
system调用命令行命令而不显示命令行窗口 通常用system调用命令行命令时都会弹出黑底白字的命令行窗口,下面的代码可以不显示弹出的命令行窗口. 代码如下 #pragma comment( lin ...
- Android窗口管理服务WindowManagerService对壁纸窗口(Wallpaper Window)的管理分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8550820 Android系统中,壁纸窗口和输 ...
- WPF 获取应用的所有窗口
原文:WPF 获取应用的所有窗口 本文告诉大家如何获取应用内的所有窗口,无论这些窗口有没显示 在 WPF 可以通过 Application.Current.Windows 列举应用的所有窗口 fore ...
- WPF 获取元素(Visual)相对于屏幕设备的缩放比例,可用于清晰显示图片
原文:WPF 获取元素(Visual)相对于屏幕设备的缩放比例,可用于清晰显示图片 我们知道,在 WPF 中的坐标单位不是屏幕像素单位,所以如果需要知道某个控件的像素尺寸,以便做一些与屏幕像素尺寸相关 ...
- QT+创建两个不相干的窗口实现一个显示一个不显示
因为两个窗口互不相干,所以需要重新创建一个窗口类subWidget subWidget.cpp文件 #ifndef SUBWIDGET_H #define SUBWIDGET_H #include & ...
- WPF 获取鼠标屏幕位置、窗口位置、控件位置
原文:WPF 获取鼠标屏幕位置.窗口位置.控件位置 public struct POINT { public int X; public int Y; public POINT(int x, int ...
随机推荐
- C++关于栈对象返回的问题
本次实验环境 环境1:Win10, QT 5.12 环境2:Centos7,g++ 4.8.5 一. 主要结论 可以返回栈上的对象(各平台会有不同的优化),不可以返回栈对象的引用. 二.先看看函数传参 ...
- SpringBoot如何优雅的进行参数校验
写在前面 上一篇文章中我们学会了如何优雅的接收前端参数,传送门 SpringBoot如何优雅的接收前端参数 接收到参数后,接下来要做的就是校验参数的合法性.这一步的重要性就不用多说了. 即使前端已经对 ...
- Docker网络模型以及容器通信
本篇接着上篇:[Docker0网络及原理探究],继续深入探究容器网络通信原理,通过学习Docker网路驱动模型,更好地解决容器间的通信问题 1.Docker的网络驱动模型 1.1.Docker的网络驱 ...
- hacker守则
hacker守则 永远不要相信用户的输入,任何输入数据在证明其无害之前,都是有害的 不在任何场景下谈论hacker 学习时,养成做笔记的好习惯 不谈论所有与hack相关的文章/ 电脑 / 电脑不要说 ...
- KingabseES 表空间限额子句(QUOTA Clause)
概述 在Oracle数据库中,DBA权限用户,可以为其他用户,创建对象,即使该用户没有任何权限.当DBA用户在该用户的表,插入数据时,提示 超出表空间的空间限额 .这就需要设置该用户的表空间的空间限额 ...
- AtCoder Beginner Contest 220
传送门 A.B.C.D.F比较简单,没必要写出来 E - Distance on Large Perfect Binary Tree 题目 问一个深度为 \(n\)的满二叉树有多少个点对的距离恰好为 ...
- Java操作FileUtils读取数据与写入数据到文件
前言:用一行代码实现读取文件内容 代码如下: 一.添加FileUtils依赖: 1 <!-- FileUtils依赖--> 2 <dependency> 3 <group ...
- vue-cli4,vue3打包后页面无内容
这个问题百度了一下,各种各样的的回答都有,试了好多种方法,终于解决这个问题 解决方法: 1.在项目根目录下,新建 vue.config.js, 在文件中输入: module.exports = { ...
- SQL语言分为哪几类
SQL 语言分为哪几类 介绍 SQL 语言分为三类,包括 DDL.DML 和 DCL. DDL DDL(Data Definition Language,数据定义语言) 用来创建或者删除存储数据用的数 ...
- 限时招募高校学生,带你沉浸式体验HDC.Together 2023