我试图通过捕获一个特定的窗口来进行屏幕捕获,为了准确地计算出要捕获的窗口的大小,我想使用DwmGetWindowAttribute()。当我在Windows10上使用PInvoke调用此函数时,即使结果值为0(成功),Rect结构也始终为空。传入的窗口句柄也是有效的,因为有调用GetWindowRect()的回退代码,可以正常工作(尽管有边界问题)。
我有点不知所措。我以前用过同样的代码(可能是在Windows8.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;
}感觉这里缺少了一些简单的东西。有什么想法吗?
发布于 2021-01-06 17:30:26
基于GetWindowsRectangle.的Rick Strahl原始代码和Hans Passant校正,我创建了一个更紧凑的版本我在Windows10上测试了它,这是它的代码,以防它在未来对某人有帮助:
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();
}发布于 2018-06-08 20:41:20
使用GetWindowRect而不是DwmGetWindowAttribute接收窗口的RECT。
[DllImport("user32.dll", SetLastError = true)]
public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);https://stackoverflow.com/questions/38685405
复制相似问题