如何只获取窗口的可见部分(Windows、gdi32、user32等)

nbewdwxp  于 2022-11-26  发布在  Windows
关注(0)|答案(2)|浏览(245)

我只想获取windows中窗口的可见部分,作为一个区域。
只想得到用户看到的区域。当然是编程的。这里有一个例子。我有下面的窗口组成:

+------------------------------------------+
 |                                          |
 |           +=============+                |
 |           |             |                |
 |           |    A   +--------------------------+
 |           |        |                          |
 |    C      |        |             B            |
 |           |        +--------------------------+
 |           |             |                |
 +-----------|             |----------------+
             |             |
             +-------------+

假设我只对窗口A感兴趣,那么我需要一个区域的句柄,如下所示:

+=============+                
          |             |                
          |    A  +-----+
          |       |                          
          |       |                         
          |       +-----+
          |             |                
          |             |
          |             |
          +-------------+

或者,我应该能够以下面的方式获得任何其他窗口的区域。
到目前为止,我使用了this guide,并且我同意GetClipBox返回0、1、2或3,如果相应地,0 -〉Error,1表示NULLREGION(用户看不到结果的rgn),2 -〉SIMPLEREGION,3表示COMPLEXREGION。
主要问题:但是我怎么才能得到它的坐标和尺寸呢

  • (新增信息)*

是否可以将一个COMPLEXREGION(由操作系统创建,而不是我)重建为组成它的简单REGIONS。冯源建议您不能:
http://www.codeguru.com/forum/archive/index.php/t-126543.html

  • (新增信息)*

那么,有没有办法找到A的区域,并将其转换为一个多边形路径,或者一个漂亮的几何图形,它有它的角的坐标
顺便说一句,我使用JNA(Java),但是用C#或.VB代码解决同样的问题就足够了。
干杯干杯干杯

pftdvrlh

pftdvrlh1#

你可以枚举所有的桌面窗口,加上所有的监视器,并合并它们的矩形。我不确定是否有更好的方法。
请注意,Windows最近对窗口的确切尺寸“撒谎”(Aero窗口边框比实际报告的略大,除非设置了特殊标志)。
另请注意,窗口可以具有由每个应用程序定义的透明部分(除了您在Aero下始终具有的透明窗口边框之外)。
在高DPI系统中,Windows在坐标方面对应用“撒谎”,除非您特意将其标记为DPI感知。
还要注意,即使是“不可见”的窗口也可以通过Aero的任务栏、Alt-Tab或Flip 3D缩略图功能显示......因此,在启用DWM的Vista和Windows 7上,答案是您的窗口可能始终完全可见。:)

6ie5vjzr

6ie5vjzr2#

我写了一个小函数,它可以计算任何窗口的可见区域。将窗口句柄传递给这个函数,它将返回窗口的可见区域。

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;
}

相关问题