老話題:本身編寫只截窗口客戶區的截屏軟件(VB2010)

如今能實現截屏的軟件不少,就不一一列舉了,連WIN7都自帶截屏軟件,甚至OFFICE2010開始都有截屏的功能。函數

 

截屏軟件雖多,無外乎三種截屏方式:全屏截圖、窗口截圖、自定義矩形截圖。優化

 

其中,窗口截圖用的比較多,下面就是一個窗口截圖的示例:網站

image

 

但有時咱們僅僅但願截取窗口的客戶區,以下圖所示:spa

image

 

這樣的軟件並很少,折中的辦法是用自定義矩形截圖,可是要調整矩形並非一件很容易的事。.net

 

因而,基於碼農的精神,自給自足。3d

因而上網搜了搜解決方案。有兩個對象

一、基於Win API函數的PrintWindow函數blog

二、基於Graphics對象的CopyFromScreen方法get

兩種方法各有優缺點it

 

PrintWindow函數是把指定Hwnd的窗口的內容繪製到指定的Hdc中,基於後臺完成。甚至指定的窗口最小化時,也能把窗口正常時的內容繪製到Hdc中。估計原理是,發出一個繪製命令,系統便繪製了窗口內容。不過,這個方法有很大的侷限性,若窗口內容中有用DirectX等非GDI方法時,截取的圖像是一片黑。

 

CopyFromScreen方法其實是把屏幕上的內容截取到Bitmap對象。優勢是通過系統優化,能夠截取含有DirectX等非GDI方法的內容。缺點是因爲截取的是屏幕,故指定的窗口不能最小化,還須要本身計算要截取的範圍。

 

因爲要截取含有DirectX等非GDI方法的內容。故本文采用的是CopyFromScreen方法。

 

問題就是如何計算指定窗口的客服區的範圍。

須要利用以下的Win API函數:

FindWindowByCaption:根據指定的標題文本找尋窗口,返回窗口的句柄Hwnd

GetWindowRect:得到指定Hwnd的窗口的區域,返回True表示得到成功,在參數lpRect裏得到窗口的區域。

GetClientRect:得到指定Hwnd的窗口的客戶區區域,返回非0表示成功,在參數lpRect裏得到窗口的客戶區的區域。可是該區域的X和Y份量都是0,也就是隻能得到該區域的寬和高,而不能得到該區域在屏幕上的位置。

ClientToScreen:把客戶區的座標轉換爲屏幕座標。該函數配合GetClientRect函數能夠得到窗口的客戶區區域(包括X和Y份量,即該區域在屏幕上的位置)

 

具體的得到窗口的客戶區的區域的過程以下:

一、用GetClientRect得到窗口的客戶區區域

二、用ClientToScreen函數得到客戶區的(0,0)座標在屏幕上的座標,也是客戶區在屏幕上的偏移位置。

三、把偏移量添加到步驟1中的區域,那就是得到完整的客戶區區域(包括X和Y份量,即該區域在屏幕上的位置)

 

再引入兩個輔助Win API函數:

OpenIcon:把指定Hwnd的窗口還原爲正常(也就是把最小化的窗口還原成正常窗口)

BringWindowToTop:把指定Hwnd的窗口顯示在頂部,不被其餘窗口覆蓋

 

 


    Public  Shared  Function SnapWindowByCaption(Caption As  String, Optional OnlyClient As  Boolean = False, Optional AutoRestore As  Boolean = False, Optional AutoBringToTop As  Boolean = False) As  Bitmap
        Dim Hwnd As  IntPtr = FindWindowByCaption(0, Caption)
        If Hwnd = 0 Then  Return  Nothing

        Dim R As  New  RECT(0, 0, 0, 0)

        GetWindowRect(Hwnd, R)

        If R.Width = 0 Then
            If AutoRestore = True  Then
                OpenIcon(Hwnd)
                GetWindowRect(Hwnd, R)
            Else
                Return  Nothing
            End  If
        End  If

        If AutoBringToTop = True  Then BringWindowToTop(Hwnd)

        Dim P As  New  WinPOINT(0, 0)

        If OnlyClient = True  Then
            GetClientRect(Hwnd, R)
            ClientToScreen(Hwnd, P)
            R.X += P.X
            R.Y += P.Y
        End  If

        Dim w As  Integer = R.Width
        Dim h As  Integer = R.Height
        Dim bmp As  Bitmap = New  Bitmap(w, h)
        Dim g As  Graphics = Graphics.FromImage(bmp)

        g.CopyFromScreen(R.X, R.Y, 0, 0, New  Size(w, h))

        Return bmp
    End  Function

最後說點題外話,本文中的Win API函數的申明都來在下面的網站,網站很是強大

http://www.pinvoke.net/index.aspx

相關文章
相關標籤/搜索