我想只在窗口中看到窗口的可见部分,作为一个区域。
只想获得用户看到的区域。 当然是以编程方式。这是一个例子。我有以下窗口组成:
+------------------------------------------+
| |
| +=============+ |
| | | |
| | A +--------------------------+
| | | |
| C | | B |
| | +--------------------------+
| | | |
+-----------| |----------------+
| |
+-------------+
假设我只对窗口A感兴趣。 那么我需要的是一个区域的句柄,如下所示:
+=============+
| |
| A +-----+
| |
| |
| +-----+
| |
| |
| |
+-------------+
或者,我应该能够以下列方式获得任何其他窗口的区域。
到目前为止,我使用了本指南: http://blogs.msdn.com/b/oldnewthing/archive/2003/09/02/54758.aspx
我同意GetClipBox返回0,1,2或3,如果你有,相应地,0 - >错误,1表示NULLREGION(生成的rgn对用户不可见),2 - > SIMPLEREGION,3代表COMPLEXREGION。所以,到目前为止,我需要复杂的区域。
主要问题: 但我如何获得其坐标和尺寸 ?
(已添加信息)
是否可以将COMPLEXREGION(由操作系统而不是我创建)重建为组成它的简单REGIONS。冯远建议你不能:
http://www.codeguru.com/forum/archive/index.php/t-126543.html
(已添加信息)
那么,有没有办法找到A的区域,将其转换为PolyPath或具有角落坐标的漂亮几何图形?
顺便说一句,我使用JNA(Java),但解决相同问题的C#或.VB代码就足够了。
干杯。
答案 0 :(得分:2)
您可以枚举所有桌面窗口以及所有监视器,并组合它们的矩形。我不确定是否有更好的方法。
请注意,Windows“关于”这些天窗口的确切尺寸(除非您设置了特殊标记,否则Aero窗口边框略大于实际报告的内容)。
另请注意,窗口可以包含每个应用程序定义的透视部分(除了您在Aero下始终具有的透视窗口边框)。
您还需要注意高DPI系统,其中Windows“应用”您的应用程序关于坐标,除非您不遗余力地将其标记为DPI感知。
并且还要注意,即使是“隐形”窗口也可以通过Aero的任务栏,Alt-Tab或Flip3D缩略图功能看到......所以,真的,在启用了DWM的Vista和Windows 7上,答案是你的窗口可能始终完全可见。 :)
答案 1 :(得分:1)
我写了一个小函数来计算任何窗口的可见区域。 将窗口句柄传递给此函数,它将返回窗口的可见区域。
HRGN GetVisibleRegion(HWND hwnd)
{
//Store the region of window hwnd
RECT hwndRect={0,0,0,0};
::GetWindowRect(hwnd,&hwndRect);
HRGN rgn=::CreateRectRgn(hwndRect.left,hwndRect.top,hwndRect.right,hwndRect.bottom);
//HWND hParentWnd=::GetParent(hwnd);
HWND hParentWnd=::GetAncestor(hwnd,GA_PARENT);
HWND hChildWnd=hwnd;
//until we reaches desktop window
while(hChildWnd!=NULL && hChildWnd!=GetDesktopWindow())
{
HWND topWnd=::GetTopWindow(hParentWnd);
do
{
if(topWnd==hChildWnd)
{
break;
}
RECT topWndRect={0,0,0,0}; ::GetWindowRect(topWnd,&topWndRect);
RECT tempRect={0,0,0,0};
//Other window overlapping with hwnd
if(::IsWindowVisible(topWnd) && !::IsIconic(topWnd) && IntersectRect(&tempRect,&topWndRect,&hwndRect)!=0)
{
HRGN topWndRgn=::CreateRectRgn(topWndRect.left,topWndRect.top,topWndRect.right,topWndRect.bottom);
::CombineRgn(rgn,rgn,topWndRgn,RGN_DIFF);
::RealDeleteObject(topWndRgn);
}
topWnd = GetNextWindow(topWnd, TWO);
}while(topWnd!=NULL);
hChildWnd=hParentWnd;
//hParentWnd=::GetParent(hParentWnd);
hParentWnd=::GetAncestor(hParentWnd,GA_PARENT);
}
return rgn;
}