DwmGetWindowAttribute 使用 PInvoke 返回 0

2024-02-06

我试图通过捕获特定窗口来进行屏幕捕获,并且为了准确地计算出要捕获的窗口的大小,我想使用 DwmGetWindowAttribute()。当我在 Windows 10 上使用 PInvoke 调用此函数时Rect即使结果值为 0(成功),结构也始终为空。传入的窗口句柄也是有效的,因为有后备代码调用GetWindowRect()这是有效的(尽管有边界问题)。

我有点不知所措。我不久前使用过同样的代码(也许在 Windows 8.1 上?),同样的代码似乎可以工作,但现在无论我做什么,对函数的调用总是返回一个空结构。

这是相关代码。

定义:

    [DllImport("dwmapi.dll")]
    static extern int DwmGetWindowAttribute(IntPtr hwnd, int dwAttribute, out Rect pvAttribute, int cbAttribute);


    [Flags]
    public enum DwmWindowAttribute : uint
    {
        DWMWA_NCRENDERING_ENABLED = 1,
        DWMWA_NCRENDERING_POLICY,
        DWMWA_TRANSITIONS_FORCEDISABLED,
        DWMWA_ALLOW_NCPAINT,
        DWMWA_CAPTION_BUTTON_BOUNDS,
        DWMWA_NONCLIENT_RTL_LAYOUT,
        DWMWA_FORCE_ICONIC_REPRESENTATION,
        DWMWA_FLIP3D_POLICY,
        DWMWA_EXTENDED_FRAME_BOUNDS,
        DWMWA_HAS_ICONIC_BITMAP,
        DWMWA_DISALLOW_PEEK,
        DWMWA_EXCLUDED_FROM_PEEK,
        DWMWA_CLOAK,
        DWMWA_CLOAKED,
        DWMWA_FREEZE_REPRESENTATION,
        DWMWA_LAST
    }

    [Serializable, StructLayout(LayoutKind.Sequential)]
    public struct Rect
    {
        public int Left;
        public int Top;
        public int Right;
        public int Bottom;

        public Rectangle ToRectangle()
        {
            return Rectangle.FromLTRB(Left, Top, Right, Bottom);
        }
    }

进行捕获的代码:

    public static Rectangle GetWindowRectangle(IntPtr handle)
    {
        Rectangle rected = Rectangle.Empty;

        Rect rect = new Rect();
        if (Environment.OSVersion.Version.Major < 6)
        {
            GetWindowRect(handle, out rect);
            rected = rect.ToRectangle();
        }      
        else
        {

            int size = Marshal.SizeOf(typeof(Rect));
            int res = DwmGetWindowAttribute(handle, (int)DwmWindowAttribute.DWMWA_EXTENDED_FRAME_BOUNDS, out rect, size);

            Debug.WriteLine(res.ToString("x") + " " + size + " " + handle + " " + (int) DwmWindowAttribute.DWMWA_EXTENDED_FRAME_BOUNDS);

            // allow returning of desktop and aero windows
            if (rected.Width == 0)
            {
                GetWindowRect(handle, out rect);
                rected = rect.ToRectangle();
                Debug.WriteLine("Using GetWindowRect");
            }
        }

        Debug.WriteLine(rected.ToString());
        return rected;
    }

感觉这里缺少一些简单的东西。有任何想法吗?


基于里克·斯特拉尔 https://stackoverflow.com/users/11197/rick-strahl原始代码以及汉斯·帕桑特 https://stackoverflow.com/users/17034/hans-passant更正我创建了一个更紧凑的版本获取窗口矩形。我在 Windows 10 上测试了它,下面是代码,以防将来对某人有所帮助:

public static Rectangle GetWindowRectangle(IntPtr handle)
    {
        Rect rect = new Rect();
                        
        if (Environment.OSVersion.Version.Major >= 6)
        {
            int size = Marshal.SizeOf(typeof(Rect));
            DwmGetWindowAttribute(handle, (int)DwmWindowAttribute.DWMWA_EXTENDED_FRAME_BOUNDS, out rect, size);
        }
        else if (Environment.OSVersion.Version.Major < 6 || rect.ToRectangle().Width == 0)
        {
            GetWindowRect(handle, out rect);
        }

        return rect.ToRectangle();
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

DwmGetWindowAttribute 使用 PInvoke 返回 0 的相关文章

  • 从值获取键 - Dictionary>

    我无法通过指定值来获取密钥 我实现这一目标的最佳方法是什么 var st1 new List
  • 未定义的参考错误 - rand

    我正在创建一个命令行 C 测试应用程序 可执行 以便在我的 root Android 设备上运行 该可执行文件使用多个预构建的 C 库 其中之一使用 rand 在链接状态期间我收到错误 rand 的未定义引用 为了检查路径是否设置正确 我尝
  • 如何在 Windows 上检查子进程是否被信号杀死

    问题 给定一个在 python 中启动的子进程 其代码类似于 import subprocess p subprocess Popen command stdout subprocess PIPE stderr subprocess PIP
  • 获取在 Unity 中实现接口的所有类型

    如果您只想知道解决方案 请跳至更新 我有一个应用程序 它使用以下代码来获取并运行许多工作方法 var type typeof IJob var types AppDomain CurrentDomain GetAssemblies Sele
  • Microsoft.Web.Administration 内存泄漏

    拥有一个 Windows 服务 除其他外 还可以监视 IIS 应用程序池 如果任何池已配置应用程序但未运行 则该池 池 将启动 这已经运行良好一段时间了 最近发现该服务存在内存泄漏 查看内存转储 罪魁祸首是用于检查应用程序池的 Micros
  • unique_ptr需要存储删除器怎么可能没有开销呢?

    先看看C Primer讲了什么unique ptr and shared ptr 16 1 6 美元 效率和灵活性 我们可以确定的是shared ptr不将删除者视为直接成员 因为删除器的类型直到运行时才知道 因为删除器的类型是a类型的一部
  • 如何从 nuget 包中排除子目录和内容

    所以我有一个网站正在尝试打包用于 Octopus Deploy 我有以下文件夹结构 Web Views WantThis Dontwantthis WantThis1 WantThis2 lots more Scripts 我试图排除 Do
  • 隐藏树视图列表中的节点。在 C# 中

    我正在使用 VS 2005 C 正在处理一个未完成的 WinForm 我已将 XML 解析为树视图列表 但遇到了一些问题 我想知道是否有一种方法可以隐藏 过滤 删除名称中包含 this text 的某个节点 而不必依赖文本框 这就是我对这个
  • 为什么编译器不对同一翻译单元中的 ODR 违规发出警告

    在同一个翻译单元中 ODR 问题很容易诊断 那么为什么编译器不会针对同一翻译单元中的 ODR 违规发出警告呢 例如在下面的代码中https wandbox org permlink I0iyGdyw9ynRgny6 https wandbo
  • GridView必须添加到表单标签中才能渲染

    TextWriter tr new StringWriter HtmlTextWriter writer new HtmlTextWriter tr HtmlForm form new HtmlForm form Controls Add
  • 通过 PsExec 在远程计算机中执行批处理文件

    我正在尝试通过 PSExec 在远程 PC 上运行批处理文件 在批处理文件中我刚刚编写了 记事本 下面的 psexec 命令在我的笔记本电脑上运行 但无法在远程 PC 上执行任何操作 我什至没有看到 记事本 在远程计算机的进程列表上运行 c
  • C# 如何在没有 GacUtil 的情况下在 GAC 中注册程序集?

    我需要使用批处理文件在 GAC 中注册程序集 有没有办法找到安装位置GacUtil exe或者有没有办法在没有 GacUtil 的情况下注册程序集 Your bestbet is to use a powershell script tha
  • 如何在调试时轻松查看事件订阅数量?

    在调试时 我可以查看一下textBox1 TextChanged查看事件订阅数量 如果是 那么我该如何钻取它 我需要知道在给定时间有多少订阅进行调试 因为看起来一个事件被多次触发 但我怀疑这个错误确实是因为textBox1 TextChan
  • CGAL:如何有效计算多面体的面面积?

    我有一个多面体 其面是三角形 我知道在 CGAL 中 Triangle 3 类提供了 squared area 方法 通过它我们可以计算三角形的面积 有什么方法可以将其应用到多面体方面吗 或者关于如何计算每个面的面积有什么想法吗 这是一个例
  • 从多页 tiff 中提取帧 - C#

    有一个多页 tiff 我想从此 Tiff 文件中提取第 n 页 帧 n 并保存它 如果我的多页 tiff 有 3 帧 在我提取一页 帧后 我想留下 1 张图像有 2 页 帧 并且 1 张图像只有 1 页 帧 下面是一些代码 用于将多帧 ti
  • OpenXML 如何获取范围内的单元格

    请帮助我获取范围内的单元格 例如从 A 1 到 E 11 都是矩形单元格 目前我的理想是 Worksheet worksheet GetWorksheet document sheetName SheetData sheetData wor
  • 什么时候适合在 C++ 中使用 static(在未命名的命名空间上)?

    我一整天都在阅读有关未命名命名空间的文章 大多数文章都解释了何时应该在 static 关键字上使用未命名命名空间 但我仍然有一个大问题什么时候适合使用静态 毕竟它还没有完全弃用 那么带有静态函数的头文件我现在应该将它们放入未命名的命名空间中
  • 使用 C++20 概念避免 std::function

    过去 当我想要回调作为函数参数时 我通常决定使用std function 在极少数情况下 我绝对从不使用捕获 我使用了typedef改为函数声明 因此 通常我的带有回调参数的声明看起来像这样 struct Socket void on re
  • 将base64字符串转换为图像c#时出错

    我想在我的网页上显示图像 并单击应该下载的链接按钮 存储的图像文件以二进制格式存储在db中 将 base64 字符串转换为图像时显示错误 详细信息如下 帮助我找到合适的解决方案 谢谢 Error Code protected void Pa
  • Windows docker:权限被拒绝 /var/run/docker.sock

    当我尝试使用自动发现运行 filebeat 时 出现以下错误 退出 自动发现提供程序设置中出现错误 已获得权限 尝试连接到 Docker 守护程序套接字时被拒绝 unix var run docker sock 获取http 2Fvar 2

随机推荐