为什么在切换监视器时会意外地表现出DWMGETWINDOWATTRIBUTE,而DWMWA_EXTEDDEND_FRAM

Why does DwmGetWindowAttribute with DWMWA_EXTENDED_FRAME_BOUNDS behave unexpectedly when switching monitors?

本文关键字:DWMGETWINDOWATTRIBUTE DWMWA FRAM EXTEDDEND 地表 监视器 意外 为什么      更新时间:2023-10-16

当我的Winform应用程序从主监视器移动到辅助监视器时,这些属性返回的范围(窗口的高度和宽度(值和Winapi函数不会更改:ul>

  • form.bounds
  • form.size
  • getWindowRect((
  • 但是DwmGetWindowAttribute返回的DWMWA_EXTENDED_FRAME_BOUNDS返回的值急剧变化。

    在注释中提出的建议之后:例如,在主监视器中 dwmgetWindowAttribute 返回宽度和高度292, 100的rect,而其他值返回306, 107。考虑到滴影占7像素,这是连贯的。但是,当窗口移动到辅助显示器时, dwmgetWindowAttribute 返回 437, 150 ,其他方法返回相同的306, 107

    实际上,我的两个监视器均为决议1920 * 1080(但尺度有所不同,如果很重要(

    问题:为什么这样会这样?是我还是其他人面临类似的问题?最终,我想计算落下阴影大小。还有其他方法吗?

    复制:

    如果您想复制此功能,请创建一个Winform项目。使用 AllocConsole((在构造函数中分配控制台。为LocationChanged添加事件处理程序,然后将以下代码添加到事件处理程序:

    private void AgentMainForm_LocationChanged(object sender, EventArgs e)
    {
          Console.WriteLine("bounds: {0}, {1}", Bounds.Width, Bounds.Height);
          Console.WriteLine("Size: {0}, {1}", Size.Width, Size.Height);
          Console.WriteLine("Window Rect: {0}, {1}", GetSizeWithShadow().Width, GetSizeWithShadow().Height);
          Console.WriteLine("Window Rect: {0}, {1}", GetSizeWithoutShadow().Width, GetSizeWithoutShadow().Height);
    }
    [DllImport("user32.dll", SetLastError = true)]
    public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);
    [DllImport("dwmapi.dll")]
    public static extern int DwmGetWindowAttribute(IntPtr hwnd, int dwAttribute, out RECT pvAttribute, int cbAttribute);
    public Size GetSizeWithoutShadow()
    {
          RECT regionWithoutShadow;
          IntPtr hWnd = this.Handle;
          if (Environment.OSVersion.Version.Major < 6) //DwmGetWindowAttribute does not work in XP, compatible only from Vista
          {
                GetWindowRect(hWnd, out regionWithoutShadow);
          }
          else
          {
                if (DwmGetWindowAttribute(hWnd, DWMWA_EXTENDED_FRAME_BOUNDS, out regionWithoutShadow, Marshal.SizeOf(typeof(RECT))) != 0)
                {
                     //Handle for failure
                }
          }
          return new Size(regionWithoutShadow.right - regionWithoutShadow.left, regionWithoutShadow.bottom - regionWithoutShadow.top);
    }
    public Size GetSizeWithShadow()
    {
         RECT regionWithoutShadow;
         IntPtr hWnd = this.Handle;
         GetWindowRect(hWnd, out regionWithoutShadow);
         return new Size(regionWithoutShadow.right - regionWithoutShadow.left, regionWithoutShadow.bottom - regionWithoutShadow.top);
    }
    [StructLayout(LayoutKind.Sequential)]
    public struct RECT
    {
        public int left;
        public int top;
        public int right;
        public int bottom;
    }
    

    您得到此答案,因为一个显示器的DPI量表为1.5,另一个显示器为1.0。可以使用getDpiforWindow调和。

    相关文章:
    • 没有找到相关文章