Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# DwmGetWindowAttribute使用PInvoke返回0_C#_Windows_Pinvoke - Fatal编程技术网

C# DwmGetWindowAttribute使用PInvoke返回0

C# DwmGetWindowAttribute使用PInvoke返回0,c#,windows,pinvoke,C#,Windows,Pinvoke,我试图通过捕获特定窗口来进行屏幕捕获,为了准确计算要捕获的窗口的大小,我想使用DwmGetWindowAttribute()。在Windows 10上使用PInvoke调用此函数时,Rect结构始终为空,即使结果值为0(成功)。传入的窗口句柄也是有效的,因为存在调用GetWindowRect()的回退代码(尽管存在边界问题) 我有点不知所措。我不久前使用过同样的代码(可能在Windows 8.1上?),同样的代码似乎可以工作,但现在无论我做什么,对函数的调用总是返回一个空结构 这是相关代码 定义

我试图通过捕获特定窗口来进行屏幕捕获,为了准确计算要捕获的窗口的大小,我想使用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;
    }
公共静态矩形GetWindowRectangle(IntPtr句柄)
{
矩形rected=Rectangle.Empty;
Rect Rect=新的Rect();
if(Environment.OSVersion.Version.Major<6)
{
GetWindowRect(句柄,out rect);
rected=rect.ToRectangle();
}      
其他的
{
int size=Marshal.SizeOf(typeof(Rect));
int res=DwmGetWindowAttribute(句柄,(int)DwmWindowAttribute.DWMWA_扩展_帧_边界,外矩形,大小);
Debug.WriteLine(res.ToString(“x”)+“”+size+“”+handle+“”+(int)DwmWindowAttribute.DWMWA_EXTENDED_FRAME_BOUNDS);
//允许返回桌面和aero窗口
如果(rected.Width==0)
{
GetWindowRect(句柄,out rect);
rected=rect.ToRectangle();
WriteLine(“使用GetWindowRect”);
}
}
Debug.WriteLine(rected.ToString());
归位;
}

感觉这里缺少了一些简单的东西。有什么想法吗?

使用
GetWindowRect
而不是
DwmGetWindowAttribute
来接收窗口的
RECT

[DllImport("user32.dll", SetLastError = true)]
public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);
基于原始代码和更正,我创建了一个更紧凑的版本GetWindowsRectangle。我在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();
    }
公共静态矩形GetWindowRectangle(IntPtr句柄)
{
Rect Rect=新的Rect();
如果(Environment.OSVersion.Version.Major>=6)
{
int size=Marshal.SizeOf(typeof(Rect));
DwmGetWindowAttribute(句柄,(int)DwmWindowAttribute.DWMWA_扩展_帧_边界,out rect,size);
}
else if(Environment.OSVersion.Version.Major<6 | | rect.ToRectangle().Width==0)
{
GetWindowRect(句柄,out rect);
}
返回rect.ToRectangle();
}

它工作正常,您的代码中有一个简单的错误。在测试rected.Width属性之前,必须调用rect.ToRectangle()。利用C#的确定赋值跟踪特性,初始化rected变量是一个错误。Duh。是的,你说得对。想回答这个问题吗?否则我可以将其删除为“愚蠢的用户错误”:-)我已经投票以“输入错误”结束。这对其他人没有帮助。它确实帮助了我。我得到了一个我需要的工作示例:)这里赢10,rect返回空。rect不是空的,但坐标(偏移)错误。。