加载中
加载中
表情图片
评为精选
鼓励
加载中...
分享
加载中...
文件下载
加载中...
修改排序
加载中...
让WPF支持Win8.1/10的多显示器DPI特性(预览版)
acmilan2016/04/10软件综合 IP:四川
Win8.1/10引入了多显示器DPI特性,允许对不同显示器指定不同DPI,窗口拖到不同DPI的显示器时,会通知程序动态进行缩放。但是目前为止,WPF的稳定版是不支持Win8.1/10的这种特性的。为了支持这个特性,必须安装最新版.NET框架4.6.2 Preview。

对于低于4.6.2版本的编译,默认是不响应DPI变化的,开启DPI响应需要修改app.config,如下所示:

XML
<?xml version="1.0" encoding="utf-8"?> <configuration>   <runtime>          <appcontextswitchoverrides value="Switch.System.Windows.DoNotScaleForDpiChanges=false">   </appcontextswitchoverrides></runtime>   <startup>     <supportedruntime version="v4.0.30319">   </supportedruntime></startup> </configuration>

以上只是开启了WPF内部的DPI响应支持。在目前的4.6.2 Preview版本中,默认DPI级别还是等于1(支持系统级DPI),需要手动设置DPI级别为2(支持多显示器DPI)。暂时还没有找到用一般的方法如何改,在这里提供了一个用C#代码调用系统函数修改的方法。

首先在AssemblyInfo.cs中加入这一句,不让WPF自己设置DPI缩放级别:
Other
[assembly: System.Windows.Media.DisableDpiAwareness()]

然后在App.cs中改成如下所示:
Other
using System; using System.Collections.Generic; using System.Configuration; using System.Data; using System.Linq; using System.Threading.Tasks; using System.Windows; using System.Runtime.InteropServices; // DllImport using System.Diagnostics; // Debug    namespace WpfApplication8 {     /// <summary>     /// Interaction logic for App.xaml     /// </summary>     public partial class App : Application     {         [DllImport("kernel32.dll")]         private static extern IntPtr LoadLibrary(string libname);         [DllImport("kernel32.dll")]         private static extern void FreeLibrary(IntPtr hlib);         [DllImport("kernel32.dll", CharSet = CharSet.Ansi)]         private static extern IntPtr GetProcAddress(IntPtr hlib, string procname);         private delegate int ProcSetProcessDpiAwareness(int level);         private delegate void ProcSetProcessDPIAware();            static void Win7SetDPIAware()         {             IntPtr hUser32 = LoadLibrary("user32.dll");             if (hUser32 != IntPtr.Zero)             {                 IntPtr addrSetProcessDPIAware = GetProcAddress(hUser32, "SetProcessDPIAware");                 if (addrSetProcessDPIAware != IntPtr.Zero)                 {                     ProcSetProcessDPIAware SetProcessDPIAware =                         (ProcSetProcessDPIAware)                         Marshal.GetDelegateForFunctionPointer(addrSetProcessDPIAware,                             typeof(ProcSetProcessDPIAware));                     SetProcessDPIAware();                 }                 FreeLibrary(hUser32);             }         }            // 需要在AssemblyInfo.cs里面设置         // [assembly: System.Windows.Media.DisableDpiAwareness()]         static bool Win81SetDPIAware()         {             IntPtr hShcore = LoadLibrary("shcore.dll");             if (hShcore != IntPtr.Zero)             {                 IntPtr addrSetProcessDpiAwareness = GetProcAddress(hShcore, "SetProcessDpiAwareness");                 if (addrSetProcessDpiAwareness != IntPtr.Zero)                 {                     // Win8.1以上版本,支持多显示器DPI                     ProcSetProcessDpiAwareness SetProcessDpiAwareness =                         (ProcSetProcessDpiAwareness)                         Marshal.GetDelegateForFunctionPointer(addrSetProcessDpiAwareness,                             typeof(ProcSetProcessDpiAwareness));                        Type t = typeof(Window);                     var evt = t.GetEvent("DpiChanged");                     if (evt != null)                     {                         // 4.6.2新版WPF,支持DPI响应                         // 需在app.config里面设置                         // <runtime>                         //   <appcontextswitchoverrides value="Switch.System.Windows.DoNotScaleForDpiChanges=false">                         // </appcontextswitchoverrides></runtime>                         if (SetProcessDpiAwareness(2) < 0)                         {                             Debug.WriteLine("SetProcessDpiAwareness(2) failed!");                         }                         else                         {                             Debug.WriteLine("SetProcessDpiAwareness(2) succeeded!");                         }                     }                     else                     {                         // 旧版WPF,不支持DPI响应                         SetProcessDpiAwareness(1);                     }                     FreeLibrary(hShcore);                     return true;                 }                 else // 找不到SetProcessDpiAwareness                 {                     FreeLibrary(hShcore);                     return false;                 }             }             else // 找不到shcore.dll             {                 return false;             }         }            static App()         {             if (!Win81SetDPIAware())             {                 Win7SetDPIAware();             }         }     } }

[修改于 9年5个月前 - 2016/04/10 19:27:45]

来自:计算机科学 / 软件综合
0
新版本公告
~~空空如也

想参与大家的讨论?现在就 登录 或者 注册

所属专业
所属分类
上级专业
同级专业
acmilan
进士 学者 笔友
文章
461
回复
2934
学术分
4
2009/05/30注册,6年7个月前活动
暂无简介
主体类型:个人
所属领域:无
认证方式:邮箱
IP归属地:未同步
插入公式
评论控制
加载中...
文号:{{pid}}
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

笔记
{{note.content}}
{{n.user.username}}
{{fromNow(n.toc)}} {{n.status === noteStatus.disabled ? "已屏蔽" : ""}} {{n.status === noteStatus.unknown ? "正在审核" : ""}} {{n.status === noteStatus.deleted ? '已删除' : ''}}
  • 编辑
  • 删除
  • {{n.status === 'disabled' ? "解除屏蔽" : "屏蔽" }}
我也是有底线的