惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

MyScale Blog
MyScale Blog
P
Privacy International News Feed
Hugging Face - Blog
Hugging Face - Blog
U
Unit 42
博客园 - 叶小钗
月光博客
月光博客
Microsoft Security Blog
Microsoft Security Blog
Apple Machine Learning Research
Apple Machine Learning Research
The Cloudflare Blog
Project Zero
Project Zero
Cisco Talos Blog
Cisco Talos Blog
The Hacker News
The Hacker News
T
Tor Project blog
阮一峰的网络日志
阮一峰的网络日志
Google DeepMind News
Google DeepMind News
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Help Net Security
Help Net Security
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Security Latest
Security Latest
I
Intezer
L
LINUX DO - 最新话题
Blog — PlanetScale
Blog — PlanetScale
T
The Exploit Database - CXSecurity.com
Hacker News - Newest:
Hacker News - Newest: "LLM"
酷 壳 – CoolShell
酷 壳 – CoolShell
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Webroot Blog
Webroot Blog
WordPress大学
WordPress大学
A
About on SuperTechFans
P
Proofpoint News Feed
T
Tailwind CSS Blog
I
InfoQ
The Register - Security
The Register - Security
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
AWS News Blog
AWS News Blog
博客园 - Franky
Simon Willison's Weblog
Simon Willison's Weblog
Last Week in AI
Last Week in AI
博客园 - 聂微东
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Google Online Security Blog
Google Online Security Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Attack and Defense Labs
Attack and Defense Labs
T
Tenable Blog
大猫的无限游戏
大猫的无限游戏
K
Kaspersky official blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
W
WeLiveSecurity
S
Security @ Cisco Blogs
MongoDB | Blog
MongoDB | Blog

博客园 - HotSky

Chrome启用CDP(chrome-devtools-protocol)进行远程操控 WPF 让ScrollViewer支持按住鼠标中键拖拽滚动内容 WPF 让ScrollViewer支持鼠标中键滚动缩放内容 Nodejs使用 nodejs中写sql需要用in时的写法 C#城市最短路径 C#Animation Sqlite PDF附录A: 内容流操作码 WPF FPS类 生命模拟 C# Sql帮助类,可扩展 WPF WriteableBitmap通过GDI+绘制帮助类 Alpha混合 Bmp读写二值图 WPF支持任意快捷键+鼠标组合的绑定类 WPF DataGrid自动增长序号列 C#访问或修改私有类、函数、变量、属性 WPF一个简单的属性编辑控件
WPF阻止窗体被系统缩放,使用显示器DPI
HotSky · 2024-06-11 · via 博客园 - HotSky

WPF默认是跟随系统DPI变化(缩放与布局)而缩放窗体的;

微软把它称为默认DPI感知,当DPI发生变化时WPF感知到后缩放窗体,介绍链接:设置进程的默认 DPI 感知 (Windows) - Win32 apps | Microsoft Learn

如果我们不希望窗体被缩放,而是让窗体使用显示器DPI该怎么办呢?

首先修改app.manifest,如下xml改到对应的xml

  <application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
      <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware>
      <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
      <longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
    </windowsSettings>
  </application>

然后在主窗体创建前执行一次如下代码就可以阻止所有窗体跟随系统缩放。

//TypeUtil -> https://www.cnblogs.com/RedSky/p/18215093
TypeUtil.InvokeMethod(null, 
    TypeUtil.GetType("PresentationCore", "System.LocalAppContext"), "DefineSwitchDefault",
    new Type[] { typeof(string), typeof(bool) },
    new object[] { "Switch.System.Windows.DoNotScaleForDpiChanges", true });
var v = TypeUtil.GetType("WindowsBase", "MS.Win32.NativeMethods+PROCESS_DPI_AWARENESS").GetEnumValues().GetValue(0);
TypeUtil.SetProperty(null, typeof(HwndTarget), "ProcessDpiAwareness", v);
TypeUtil.SetProperty(null, typeof(HwndTarget), "AppManifestProcessDpiAwareness", v);

但是之后Window的DpiChanged就不会起作用了,如果想要监听DPI变化可以重写窗体OnSourceInitialized,使用如下方法:

protected override void OnSourceInitialized(EventArgs e)
{
    var aa = (HwndSource)HwndSource.FromDependencyObject(this);
    aa.AddHook(new HwndSourceHook(HwndTargetFilterMessage));
    base.OnSourceInitialized(e);
}
private IntPtr HwndTargetFilterMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    IntPtr result = IntPtr.Zero;
    //WindowMessage: https://referencesource.microsoft.com/#WindowsBase/Base/MS/Internal/Interop/NativeValues.cs
    result = HandleMessage((WindowMessage)msg, wParam, lParam);
    if (result != IntPtr.Zero)
        handled = true;

    return result;
}
internal IntPtr HandleMessage(WindowMessage msg, IntPtr wparam, IntPtr lparam)
{
    IntPtr result = IntPtr.Zero;
    switch (msg)
    {
        case WindowMessage.WM_DPICHANGED:
            Debug.WriteLine("WindowMessage.WM_DPICHANGED");
            break;
        case WindowMessage.WM_DPICHANGED_AFTERPARENT:
            Debug.WriteLine("WindowMessage.WM_DPICHANGED_AFTERPARENT");
            break;
    }
    return result;
}