Windows 7 上的 GetWindowRect 太小 [英] GetWindowRect too small on Windows 7

查看:52
本文介绍了Windows 7 上的 GetWindowRect 太小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图解决的实际问题是,我想自动找出窗口周围边距的大小.如果你能找到更好的方法,请务必回答那个而不是这个.

The actual problem I'm trying to solve is, I want to automatically find out the size of the margins around windows. If you can find a better way, please by all means answer that instead of this.

为此,我决定截取测试窗口的屏幕截图并测量边距.这很简单,因为我预计任何边距都不会是亮粉色,但我承认这是一个黑客.我使用 GetWindowRect (py) 获取边界框,PIL 抓取屏幕截图并裁剪到边界框.问题是,虽然裁剪操作正确,但边界框不准确.Windows 7截图工具"获得正确尺寸.我该怎么做?

To do this I decided to take a screenshot of a test window and measure the margins. This is simple enough, as I expect no margins will ever be bright pink, but I admit it's a hack. I use GetWindowRect (py) to get the bounding box, and PIL to grab a screenshot and crop to the bounding box. The problem is that while the crop operates correctly, the bounding box is not accurate. The Windows 7 "Snipping Tool" gets the correct dimensions. How may I do the same?

推荐答案

下面列出了我的第一个想法,但如果如您所述,您确定 GetWindowRect 返回不正确的值,请参阅 解决方案进一步下降.

My first thoughts were listed below but if, as you state, you're certain that GetWindowRect is returning incorrect values, see RESOLUTION further down.

GetSystemMetrics(SM_CXBORDER)GetSystemMetrics(SM_CYBORDER) 有什么问题?

您使用的方法似乎是一种非常迂回的方法,如果您可以调用 GetWindowRect(),我很确定您可以调用 GetSystemMetrics() 以及.

The method you're using seems a very roundabout way of doing it and, if you can call GetWindowRect(), I'm pretty certain you can call GetSystemMetrics() as well.

另一种可能性是使用 GetWindowRect 获取窗口的整个边界矩形和 GetClientRect 获取客户端(非边界)区域的边界矩形.

One other possibility is to use GetWindowRect to get the entire bounding rectangle for the window and GetClientRect to get the bounding rectangle for the client (non-border) area.

应该分别给你类似 (100,200),(1000,900)(112,227),(988,888) 和你可以算出上边框为227-200,下边为900-888,左边为112-100,右边为900-888 (27,12,12,12).

This should give you something like (100,200),(1000,900) and (112,227),(988,888) respectively and you can work out the top border as 227-200, bottom as 900-888, left as 112-100 and right as 900-888 (27,12,12,12).

解决方案:

进行了一些调查 这个.这是 2006 年的一个帖子,指出您可能无法从 GetWindowsRect 获得正确的值.指出我这一点的线程说:

A bit of investigation turns up this. It's a thread from 2006 stating that you might not get the correct values from GetWindowsRect. The thread that pointed me to this stated:

未与 WINVER=6 链接的 Vista 下的应用程序将在此处收到一组误导性的值,这些值并未考虑 Vista Aero 应用于窗口的玻璃"像素的额外填充.即使在 Aero Basic(无玻璃)中,这似乎也会发生,以保持尺寸一致性.解决方法(如果不想设置WINVER=6)好像是动态绑定到dwmapi.dll,使用GetProcAddress()获取DwmGetWindowAttribute()函数,用DWMWA_EXTENDED_FRAME_BOUNDS参数调用来请求正版窗口框架尺寸.

Apps under Vista that are not linked with WINVER=6 will receive a misleading set of values here, that do not account for the extra padding of "glass" pixels Vista Aero applies to the window. This appears to happen even in Aero Basic (without Glass) to retain sizing consistency. The workaround (if you don't want to set WINVER=6) seems to be to dynamically bind to dwmapi.dll and use GetProcAddress() to obtain the DwmGetWindowAttribute() function, and call it with the DWMWA_EXTENDED_FRAME_BOUNDS argument to request the genuine window frame dimensions.

所以基本上,使用类似的东西(你可能必须使用 ctypes 从 Python 中做到这一点):

So basically, use something like (you may have to use ctypes to do this from Python):

RECT r;
HRESULT stat = DwmGetWindowAttribute (
    hwnd,
    DWMWA_EXTENDED_FRAME_BOUNDS,
    &r,
    sizeof(r));

这应该会给你正确的边界矩形.

and that should give you the correct bounding rectangle.

这篇关于Windows 7 上的 GetWindowRect 太小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆