Results 1 to 6 of 6

Thread: Take screenshot of external application

  1. #1

    Thread Starter
    Hyperactive Member csKanna's Avatar
    Join Date
    Dec 2005
    Location
    Tech-Tips-Now.com
    Posts
    339

    Take screenshot of external application

    Hi,

    I need to take screenshot of another (third party) application window and save it in a folder.

    Can someone guide me on this?
    Thanks
    Kanna

  2. #2
    PowerPoster Radjesh Klauke's Avatar
    Join Date
    Dec 2005
    Location
    Sexbierum (Netherlands)
    Posts
    2,244

    Re: Take screenshot of external application

    Do you already know how to create a screenshot and save it?


    If you found my post helpful, please rate it.

    Codebank Submission: FireFox Browser (Gecko) in VB.NET, Load files, (sub)folders treeview with Windows icons

  3. #3
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Take screenshot of external application

    You can use the Graphics.CopyFromScreen method to draw part of the screen onto an Image. I'm sure you'll find examples if you search. As for what part of the screen to draw, you'd have to use the Windows API. the FindWindow function will get the handle of a window and then probably GetWindowPos to get the bounds of that window.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  4. #4

    Thread Starter
    Hyperactive Member csKanna's Avatar
    Join Date
    Dec 2005
    Location
    Tech-Tips-Now.com
    Posts
    339

    Re: Take screenshot of external application

    okay thanks. I somehow managed to get screenshot of the application window. Now there are two problems.

    a. if there are other windows on top of that application, it takes the screenshot of that top most window.
    b. if i locked my pc, it simply errors and not takes screenshot.

    how to fix that?
    Kanna

  5. #5
    VB For Fun Edgemeal's Avatar
    Join Date
    Sep 2006
    Location
    WindowFromPoint
    Posts
    4,255

    Re: Take screenshot of external application

    Quote Originally Posted by csKanna View Post
    a. if there are other windows on top of that application, it takes the screenshot of that top most window.
    The PrintWindow API can capture windows even if they are behind other windows or off to the sides of the desktop area.
    One minor drawback is PrintWindow doesn't support opacity so captured windows are always solid.

    Code:
    Public Class Form1
    ' Tested on: WinXP-32 and Win7-64.
        Public Structure RECT
            Public left As Int32
            Public top As Int32
            Public right As Int32
            Public bottom As Int32
        End Structure
        Private Declare Function GetWindowRect Lib "user32.dll" (ByVal hwnd As IntPtr, ByRef lpRect As RECT) As Int32
        Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
        Private Declare Function PrintWindow Lib "User32.dll" (ByVal hWnd As IntPtr, ByVal hdcBlt As IntPtr, ByVal nFlags As Int32) As Int32
    
        Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
            ' get handle of app to capture by the titlebar text
            Dim hWnd As IntPtr = FindWindow(Nothing, "Calculator") '<<< WINDOWS CALCULATOR
    
            If hWnd = IntPtr.Zero Then
                MessageBox.Show("Window not found!", "No Window Match", MessageBoxButtons.OK, MessageBoxIcon.Information)
            Else
                ' Capture app to Bitmap
                Dim bmp As Bitmap = Capture_hWndToBitmap(hWnd)
                If bmp IsNot Nothing Then
                    Try
                        ' save bitmap to a public folder
                        bmp.Save("C:\Users\Ed\Pictures\TEST_CAPTURE.png", Imaging.ImageFormat.Png)                    
                    Catch ex As Exception
                        MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error)
                    End Try
                    bmp.Dispose()
                Else
                    MessageBox.Show("Capture failed!", "Capture Fail", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
                End If
            End If
        End Sub
    
        ' Capture window by handle to bitmap
        Private Function Capture_hWndToBitmap(ByVal WindowHandle As IntPtr) As Bitmap
            Try
                Dim WinRect As RECT
                GetWindowRect(WindowHandle, WinRect)
                Dim bmp As Bitmap = New Bitmap(WinRect.right - WinRect.left, WinRect.bottom - WinRect.top)
                Dim g As Graphics = Graphics.FromImage(bmp)
                Dim hDC As IntPtr = g.GetHdc()
                Dim pwRet As Integer = PrintWindow(WindowHandle, hDC, 0)
                g.ReleaseHdc(hDC)
                If pwRet = 0 Then ' printwindow failed!
                    Return Nothing
                Else
                    Return bmp
                End If
            Catch
                Return Nothing ' something went wrong!
            End Try
        End Function
    
    End Class
    I had posted something similar yesterday but removed it because I was getting an error when run under Win7, turns out I didn't have permission to write the file to the drive/folder I selected!
    Last edited by Edgemeal; Apr 9th, 2011 at 03:57 AM. Reason: Check PrintWindow return value.

  6. #6
    Fanatic Member
    Join Date
    Jul 2009
    Posts
    629

    Re: Take screenshot of external application

    Using BitBlt is also an option, by passing the Hdc of the Window:
    Code:
    Dim wHdc As IntPtr = GetWindowDC(hwnd)
    Remaining code is pretty large, see my Window class for all of the code.
    Main idea around it is this:
    1. Obtain Window DC
    2. Obtain Window bounds or use the DC clip size
    3. Obtain bitmap of the size of [2]
    4. Make a Graphics object and obtain its Hdc
    5. Use BitBlt to copy the data from the source to the destination (graphics)
    6. Dispose all Hdc objects (also Graphics)
    7. Return Bitmap
    In API.DC.vb
    vb Code:
    1. Private Declare Function GetClipBox Lib "gdi32" (ByVal hdc As IntPtr, ByRef lprc As WRECT) As Integer
    2. Private Declare Function BitBlt Lib "gdi32" (ByVal hdc As IntPtr, ByVal nXDest As Integer, ByVal nYDest As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal hdcSrc As IntPtr, ByVal nXSrc As Integer, ByVal nYSrc As Integer, ByVal dwRop As CopyPixelOperation) As Boolean
    3.         Public ReadOnly Property ClipBox() As Rectangle
    4.             Get
    5.                 Dim w As WRECT
    6.                 GetClipBox(Me.hdc, w)
    7.                 Return w.Value
    8.             End Get
    9.         End Property
    10.         Public ReadOnly Property ClipSize() As Size
    11.             Get
    12.                 Return Me.ClipBox.Size
    13.             End Get
    14.         End Property
    15.         Public Function ToBitmap(Optional ByVal operation As CopyPixelOperation = CopyPixelOperation.SourceCopy Or CopyPixelOperation.CaptureBlt) As Bitmap
    16.             Return ToBitmap(Me.ClipSize, operation)
    17.         End Function
    18.         Public Function ToBitmap(ByVal Resolution As Size, Optional ByVal operation As CopyPixelOperation = CopyPixelOperation.SourceCopy Or CopyPixelOperation.CaptureBlt) As Bitmap
    19.             ToBitmap = New Bitmap(Resolution.Width, Resolution.Height)
    20.             Dim g As Graphics = Graphics.FromImage(ToBitmap)
    21.             Dim ghdc As IntPtr = g.GetHdc
    22.             BitBlt(ghdc, 0, 0, Resolution.Width, Resolution.Height, Me.hdc, 0, 0, operation)
    23.             g.ReleaseHdc(ghdc)
    24.             g.Dispose()
    25.         End Function

    In Window.vb
    vb Code:
    1. Public Function CaptureWindow(ByVal g As Graphics) As Boolean
    2.         Dim DC As New API.DC(g)
    3.         Dim wDC As API.DC = Me.GetWindowDC
    4.         wDC.CopyTo(DC)
    5.         DC.Dispose()
    6.         wDC.Dispose()
    7.     End Function
    8.     Public Function CaptureWindow() As Image
    9.         Dim s As Size = Me.Size
    10.         If s.Width < 1 Or s.Height < 1 Then Return Nothing
    11.         Dim img As New Bitmap(s.Width, s.Height)
    12.         Dim g As Graphics = Graphics.FromImage(img)
    13.         CaptureWindow(g)
    14.         g.Dispose()
    15.         Return img
    16.     End Function

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width