6

ウィンドウのウィンドウの表示部分のみを領域として取得したい。

ユーザーが見ている領域だけを取得したい。もちろん、プログラム的に。ここに例があります。次のウィンドウ構成があります。

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

ウィンドウ A だけに関心があるとします。その場合、次のような領域へのハンドルが必要になります。

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

または、次の方法で他のウィンドウの領域を取得できるはずです。

これまでのところ、次のガイドを使用しました: http://blogs.msdn.com/b/oldnewthing/archive/2003/09/02/54758.aspx

また、GetClipBox が 0、1、2、または 3 を返すことに同意します。したがって、0 -> エラー、NULLREGION の場合は 1 (結果の rgn はユーザーには表示されません)、2 -> SIMPLEREGION、および COMPLEXREGION の場合は 3 です。これまでのところ、複雑な領域が必要です。

マスターの質問:しかし、どうすればその座標と寸法を取得できますか?

(情報追加)

COMPLEXREGION (私ではなく、OS によって作成された) を、構成されている単純な REGION に再構築することは可能ですか? Feng Yuan は、次のことはできないと提案しています。

http://www.codeguru.com/forum/archive/index.php/t-126543.html

(情報追加)

それで、Aの領域を見つけて、それをPolyPathまたはその角の座標を持つ素敵な幾何学的図形に変換する方法はありますか?

ちなみに、私は JNA (Java) を使用していますが、同じ問題を解決する C# または .VB コードで十分です。

乾杯。

4

2 に答える 2

4

すべてのデスクトップ ウィンドウとすべてのモニターを列挙し、それらの四角形を組み合わせることができます。もっと良い方法があるかどうかはわかりません。

最近の Windows は、ウィンドウの正確な寸法について「嘘」をついていることに注意してください (Aero ウィンドウの境界は、特別なフラグを設定しない限り、実際に報告されているよりもわずかに大きくなっています)。

また、ウィンドウには、各アプリケーションによって定義されたシースルー部分がある場合があることに注意してください (Aero の下に常にあるシースルー ウィンドウの境界に加えて)。

また、わざわざ DPI 対応としてフラグを立てない限り、Windows が座標についてアプリに「嘘をつく」高 DPI システムでも注意する必要があります。

また、「見えない」ウィンドウでさえ、タスクバー、Alt-Tab、または Aero の Flip3D サムネイル機能を介して表示される可能性があることに注意してください...したがって、実際には、DWM が有効になっている Vista および Windows 7 では、ウィンドウが潜在的に常に完全に表示されます。:)

于 2010-11-16T17:47:30.767 に答える
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;
}
于 2012-12-14T05:25:01.100 に答える