zoukankan      html  css  js  c++  java
  • C# 监听窗口分辨率/DPI变更

    当程序运行,窗口已经加载后,如果修改屏幕分辨率,会影响窗口的正常显示。

    举个案例:

    悬浮窗口,显示在屏幕右下角。当分辨率、文本显示比例变更后,窗口位置可能会超出屏幕范围。

    所以当屏幕变更时,我们需要知道准确的时机,然后针对的处理。

    通过窗口消息监听屏幕显示变更

    对窗口添加钩子

    1     var windowInteropHelper = new WindowInteropHelper(this);
    2     var hwnd = windowInteropHelper.Handle;
    3     HwndSource source = HwndSource.FromHwnd(hwnd);
    4     source?.AddHook(Hook);

    对窗口消息添加处理

    1     private const int WmDisplayChange = 0x007e;
    2     private IntPtr Hook(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam, ref bool handled)
    3     {
    4         if (msg == WmDisplayChange)
    5         {
    6             SetLocation();
    7         }
    8         return IntPtr.Zero;
    9     }

    “0x007e”是屏幕分辨率以及文本显示比例变更对应的消息标识。

    通过系统事件监听屏幕显示变更

    上面通过钩子来判断相应的窗口消息,其实也有系统事件封装了这类的处理:

    1     public MainWindow()
    2     {
    3         InitializeComponent();
    4         Microsoft.Win32.SystemEvents.DisplaySettingsChanged += SystemEvents_DisplaySettingsChanged;
    5     }
    6     private void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e)
    7     {
    8 
    9     }

    屏幕变更时,回调事件参数如下:

    这个系统静态事件和窗口消息是一样的,触发次数和时机一样。调试发现触发顺序:窗口消息->系统静态事件。

    更新窗口位置

    屏幕显示变更的时机有了,可以根据时间添加相应的操作:

     1     private void SetLocation()
     2     {
     3         using (Graphics currentGraphics = Graphics.FromHwnd(new WindowInteropHelper(this).Handle))
     4         {
     5             double dpixRatioX = currentGraphics.DpiX / 96;
     6             double dpixRatioY = currentGraphics.DpiY / 96;
     7 
     8             var intPtr = new WindowInteropHelper(this).Handle;//获取当前窗口的句柄
     9             var screen = Screen.FromHandle(intPtr);//获取当前屏幕
    10             var locationX = (screen.Bounds.Width - 300) / dpixRatioX;
    11             var locationY = (screen.Bounds.Height - 300) / dpixRatioY;
    12             Left = locationX;
    13             Top = locationY;
    14         }
    15     }

    获取对应屏幕的DPI信息,并转换成WPF的DPI比例,计算出窗口的最新位置。

    关键字:监听分辨率、分辨率变更

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    实例图解SQL SERVER2000使用AWE进行内存优化
    使用Power Designer正反向数据库及生成设计报告
    使用SVN+CruiseControl+ANT实现持续集成之二环境搭建和配置介绍
    使用SVN+CruiseControl+ANT实现持续集成之三构建操作及监视
    【排序】排序算法之分配排序
    [Cocoa]自定义TableViewCell实现圆角/渐变色TableView
    [Cocoa]XCode 3.2 常用快捷键
    [Cocoa]实现了一套自定义动画库
    Vim 使用入门快捷键
    [Cocoa] iPhone/iPad 时区转换
  • 原文地址:https://www.cnblogs.com/kybs0/p/14861154.html
Copyright © 2011-2022 走看看