检索没有Windows阴影的窗口大小

问题描述 投票:12回答:2

我正在尝试基于Window句柄捕获C#中的桌面窗口。我正在使用.NET,并使用PInvoke到GetWindowRect()捕获窗口矩形。我的窗口选择和矩形捕获工作正常。

但是,捕获的窗口矩形不仅包括实际的窗口大小,还包括窗口的装饰物,例如其周围的阴影。当我尝试将窗口裁剪为位图时,位图包含区域和阴影。在Windows 10上,我得到了透明阴影区域,其中包括在活动窗口下方可能可见的所有内容:

enter image description here

我使用的代码很简单,即通过PInvoke调用使用Win32 GetWindowRect()捕获窗口:

var rect = new Rect();
GetWindowRect(handle, ref rect);
var bounds = new Rectangle(rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top);
var result = new Bitmap(bounds.Width, bounds.Height);

using (var graphics = Graphics.FromImage(result))
{
    graphics.CopyFromScreen(new Point(bounds.Left, bounds.Top), Point.Empty, bounds.Size);
}

return result;

然后我捕获图像并将其分配到图片框中。

此外,各个窗口之间似乎有些差异-有些窗口有阴影,而另一些则没有。大多数功能都可以做到,但是像Visual Studio和Chrome这样的功能却不能,因此剥离多余像素甚至不是一件简单的事情。

我已经尝试过使用GetClientRect(),但这只是我所需要的客户区域,而不是我所追求的。我想要得到的是带有边框但没有阴影的实际Window矩形。

反正有这样做吗?

c# windows winapi pinvoke
2个回答
6
投票

我正在运行Windows 10,编写应用程序将窗口捕捉到屏幕顶部或底部时遇到相同的问题。我发现DwmGetWindowAttribute()可以工作。它返回的RECT值与GetWindowRect()略有不同。

来自示例窗口的结果:

GetWindowRect():{X = 88,Y = 26,Width = 871,Height = 363}

DwmGetWindowAttribute():{X = 95,Y = 26,Width = 857,Height = 356}

我的测试表明,GetWindowRect()包含了装饰,而DwmGetWindowAttribute()没有。

如果从带有装饰物的窗口上的两种方法获得相同的结果,则可能是该特定窗口正在绘制其自身的装饰物,或者该窗口设置了其他一些属性需要将其纳入帐户。


0
投票

您可以使用DwmGetWindowAttribute。请参阅以下示例。您可以将GetWindowRectangle与任何手柄一起使用以获取其实际大小。

© www.soinside.com 2019 - 2024. All rights reserved.