> 文档中心 > [C# VSTO Word]任务窗格在不同电脑上相同宽度值不同显示效果的情况处理。暨如何正确获取Windows11/10桌面的缩放比例?

[C# VSTO Word]任务窗格在不同电脑上相同宽度值不同显示效果的情况处理。暨如何正确获取Windows11/10桌面的缩放比例?


[C# VSTO Word]任务窗格在不同电脑上相同宽度值不同显示效果的情况处理。暨如何正确获取Windows11/10桌面的缩放比例

目录

  • [C# VSTO Word]任务窗格在不同电脑上相同宽度值不同显示效果的情况处理。暨如何正确获取Windows11/10桌面的缩放比例?
    • 发现问题
    • 测试准备
    • 测试结果
    • 经验总结

请添加图片描述

发现问题

发现UserControl任务窗格,在new之后设定好的宽度,在不同的word版本展示的实际宽度不对等。

  • 一台电脑上,启动的word版本【16.0.15128.20178】宽度377

[C# VSTO Word]任务窗格在不同电脑上相同宽度值不同显示效果的情况处理。暨如何正确获取Windows11/10桌面的缩放比例?

  • 另一台电脑上,启动的word版本【16.0.14430.20298】宽度376
    [C# VSTO Word]任务窗格在不同电脑上相同宽度值不同显示效果的情况处理。暨如何正确获取Windows11/10桌面的缩放比例?
  • 目测很明显,实际宽度相差非常大。

经过几轮代码测试和环境筛查,终于发现造成这种情况不是因为word版本的问题,而是因为操作系统的缩放比例不是100%造成的。
[C# VSTO Word]任务窗格在不同电脑上相同宽度值不同显示效果的情况处理。暨如何正确获取Windows11/10桌面的缩放比例?

  • 因此将系统的缩放比例设置成100%。
    [C# VSTO Word]任务窗格在不同电脑上相同宽度值不同显示效果的情况处理。暨如何正确获取Windows11/10桌面的缩放比例?
  • 不同缩放比例下,控件的相同的宽度显示效果并不一样 甚至有的控件被阉割了:
    [C# VSTO Word]任务窗格在不同电脑上相同宽度值不同显示效果的情况处理。暨如何正确获取Windows11/10桌面的缩放比例?
    [C# VSTO Word]任务窗格在不同电脑上相同宽度值不同显示效果的情况处理。暨如何正确获取Windows11/10桌面的缩放比例?
  • 缩放比例100%模式下,UserControl任务窗格情况与之前一模一样了。
    [C# VSTO Word]任务窗格在不同电脑上相同宽度值不同显示效果的情况处理。暨如何正确获取Windows11/10桌面的缩放比例?

测试准备

  • 通过代码获取Windows的缩放比例。发现网上的都不对,指的都是未使用物理分辨率的缩放。而非系统的【缩放】。通过来自CSDN【kkbinkbi】博客的代码测试。最终确定为DPI的比例

    • 缩放100%=DPI:96
    • 缩放125%=DPI:120
    • 缩放150%=DPI:144

  • 摘录来自CSDN【kkbinkbi】博客的类代码如下。并将namespace调整为自己的目录结构。

来自CSDN【kkbinkbi】博客的类代码
来自 https://blog.csdn.net/kkbinkbi/article/details/67636930?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~aggregatepage~first_rank_ecpm_v1~rank_v31_ecpm-4-67636930-null-null.pc_agg_new_rank&utm_term=C%23+获取系统缩放比列&spm=1000.2123.3001.4430

using System;using System.Drawing;using System.Runtime.InteropServices; namespace WordAddIn_will段落处理.APIClass{    public class PrimaryScreen    { #region Win32 API  [DllImport("user32.dll")]   static extern IntPtr GetDC(IntPtr ptr);  [DllImport("gdi32.dll")]   static extern int GetDeviceCaps(  IntPtr hdc, // handle to DC  int nIndex // index of capability  );  [DllImport("user32.dll", EntryPoint = "ReleaseDC")]   static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDc); #endregion #region DeviceCaps常量  const int HORZRES = 8;  const int VERTRES = 10;  const int LOGPIXELSX = 88;  const int LOGPIXELSY = 90;  const int DESKTOPVERTRES = 117;  const int DESKTOPHORZRES = 118; #endregion  #region 属性 ///  /// 获取屏幕分辨率当前物理大小 ///     public static Size WorkingArea     {  get {      IntPtr hdc = GetDC(IntPtr.Zero);      Size size = new Size();      size.Width = GetDeviceCaps(hdc, HORZRES);      size.Height = GetDeviceCaps(hdc, VERTRES);      ReleaseDC(IntPtr.Zero, hdc);      return size;      }     } ///     /// 当前系统DPI_X 大小 一般为96 ///      public static int DpiX     {  get  {      IntPtr hdc = GetDC(IntPtr.Zero);      int DpiX = GetDeviceCaps(hdc, LOGPIXELSX );      ReleaseDC(IntPtr.Zero, hdc);      return DpiX;  }     } ///  /// 当前系统DPI_Y 大小 一般为96 ///      public static int DpiY     {  get  {      IntPtr hdc = GetDC(IntPtr.Zero);      int DpiX = GetDeviceCaps(hdc,LOGPIXELSY);      ReleaseDC(IntPtr.Zero, hdc);      return DpiX;  }     } ///      /// 获取真实设置的桌面分辨率大小 ///      public static Size DESKTOP     {  get  {      IntPtr hdc = GetDC(IntPtr.Zero);      Size size = new Size();      size.Width = GetDeviceCaps(hdc,DESKTOPHORZRES );      size.Height = GetDeviceCaps(hdc, DESKTOPVERTRES);      ReleaseDC(IntPtr.Zero, hdc);      return size;      }     }      ///      /// 获取宽度缩放百分比     ///      public static float ScaleX     {  get  {      IntPtr hdc = GetDC(IntPtr.Zero);      int t = GetDeviceCaps(hdc, DESKTOPHORZRES);      int d = GetDeviceCaps(hdc, HORZRES);      float ScaleX = (float)GetDeviceCaps(hdc, DESKTOPHORZRES) / (float)GetDeviceCaps(hdc, HORZRES);ReleaseDC(IntPtr.Zero, hdc);      return ScaleX;  }     }     ///      /// 获取高度缩放百分比     ///      public static float ScaleY     {  get  {      IntPtr hdc = GetDC(IntPtr.Zero);      float ScaleY = (float)(float)GetDeviceCaps(hdc, DESKTOPVERTRES) / (float)GetDeviceCaps(hdc, VERTRES);      ReleaseDC(IntPtr.Zero, hdc);      return ScaleY;  }     }#endregion    }}
  • 在自己的【will测试文中对象】UserControl任务窗格代码中加入识别,然后输出(输出到控件中的代码略)
#region 获取Windows操作系统的显示参数,以确定缩放比例指向string string_获取Windows操作系统的显示 = "";string_获取Windows操作系统的显示 += (string.Format("获取高度缩放百分比【{0}】" + Environment.NewLine, APIClass.PrimaryScreen.ScaleY.ToString()));string_获取Windows操作系统的显示 += (string.Format("获取宽度缩放百分比【{0}】" + Environment.NewLine, APIClass.PrimaryScreen.ScaleX.ToString()));string_获取Windows操作系统的显示 += (string.Format("获取真实设置的桌面分辨率大小【{0}】" + Environment.NewLine, APIClass.PrimaryScreen.DESKTOP.ToString()));string_获取Windows操作系统的显示 += (string.Format("获取屏幕分辨率当前物理大小【{0}】" + Environment.NewLine, APIClass.PrimaryScreen.WorkingArea.ToString()));string_获取Windows操作系统的显示 += (string.Format("当前系统DPI_Y 大小 一般为96【{0}】" + Environment.NewLine, APIClass.PrimaryScreen.DpiY.ToString()));string_获取Windows操作系统的显示 += (string.Format("当前系统DPI_X 大小 一般为96【{0}】" + Environment.NewLine, APIClass.PrimaryScreen.DpiX.ToString()));#endregion

测试结果

  • 测试缩放比例125%时:
    • 其中DPI为120;
    • 任务窗格UserControl的显示效果如下图。
      [C# VSTO Word]任务窗格在不同电脑上相同宽度值不同显示效果的情况处理。暨如何正确获取Windows11/10桌面的缩放比例?
  • 测试缩放比例150%时:
    • 其中DPI为144;
    • 任务窗格UserControl的显示效果如下图。
      [C# VSTO Word]任务窗格在不同电脑上相同宽度值不同显示效果的情况处理。暨如何正确获取Windows11/10桌面的缩放比例?
  • 测试缩放比例为100%时:
    • 其中DPI为96;
    • 任务窗格UserControl的显示效果如下图。
      [C# VSTO Word]任务窗格在不同电脑上相同宽度值不同显示效果的情况处理。暨如何正确获取Windows11/10桌面的缩放比例?

经验总结

○ 控件中with和height等属性的显示效果,受系统缩放比例,即DPI影响。○ 在控件实例化的时候,需要识别DPI,然后根据其调整控件的大小。○ 在Visual studio 中调试控件样式时,一定要测试不同系统桌面缩放比例,即DPI。

[C# VSTO Word]任务窗格在不同电脑上相同宽度值不同显示效果的情况处理。暨如何正确获取Windows11/10桌面的缩放比例?
[C# VSTO Word]任务窗格在不同电脑上相同宽度值不同显示效果的情况处理。暨如何正确获取Windows11/10桌面的缩放比例?