2010-11-16 71 views
3

我想僅獲取窗口中窗口的可見部分作爲區域。如何僅獲取窗口的可見部分(Windows,gdi32,user32等)

只想獲得用戶看到的區域。當然,以編程方式編寫代碼 。這是一個例子。我有以下窗口組成:

+------------------------------------------+ 
|           | 
|   +=============+    | 
|   |    |    | 
|   | 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(這是由操作系統創建的,不是我),以簡單的地區,其中它是由。馮遠建議您不能:

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

(添加信息)

那麼,有沒有辦法找到A的區域和將其轉換爲POLYPATH或一個不錯的幾何具有其角落座標的圖形

順便說一下,我使用JNA(Java),但解決相同問題的C#或.VB代碼就足夠了。

乾杯。

回答

2

您可以枚舉所有桌面窗口以及所有顯示器並組合它們的矩形。我不確定是否有更好的方法。

請注意,Windows對這些天窗口的確切尺寸「存在」(除非您設置特殊標誌,否則Aero窗口邊框比實際報告稍大)。

另請注意,Windows可以有每個應用程序定義的透視部分(除了透視窗口邊框,您總是在Aero下)。

您還需要注意高DPI系統,Windows對您的應用程序進行座標關於座標,除非您想方設法將其標記爲支持DPI。

還要注意,即使是「隱形」窗口也可以通過Aero的任務欄,Alt-Tab或Flip3D縮略圖功能看到。所以,實際上,在啓用了DWM的Vista和Windows 7上,答案是您的窗口可能始終完全可見。 :)

+0

忘了提及,我想避免使用DWM,兼容性問題。我知道桌面窗口管理器存在什麼問題,對於程序員來說非常棒,但是我也想要覆蓋XP盒子以及禁用DWM的盒子。 – 2010-11-16 22:29:37

+0

我並不是建議你爲任何東西使用DWM;只是指出了一堆問題,如果啓用了DWM(如果您希望在XP等之外支持它),那麼您必須擔心一些問題。 – 2010-11-16 23:17:59

+0

那麼一些代碼會更好,或者甚至可以保證它可以完成,因爲我開始懷疑它可能在XP機器或不運行DWM的機器上。 – 2010-11-17 08:19:03

0

我寫了一個小函數,它計算任何窗口的可見區域。 將窗口句柄傳遞給此函數,它將返回窗口的可見區域。

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