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
Printable View
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
Do you already know how to create a screenshot and save it?
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.
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?
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.
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! :rolleyes: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
Using BitBlt is also an option, by passing the Hdc of the Window:
Remaining code is pretty large, see my Window class for all of the code.Code:Dim wHdc As IntPtr = GetWindowDC(hwnd)
Main idea around it is this:
In API.DC.vbQuote:
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
vb Code:
Private Declare Function GetClipBox Lib "gdi32" (ByVal hdc As IntPtr, ByRef lprc As WRECT) As Integer 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 Public ReadOnly Property ClipBox() As Rectangle Get Dim w As WRECT GetClipBox(Me.hdc, w) Return w.Value End Get End Property Public ReadOnly Property ClipSize() As Size Get Return Me.ClipBox.Size End Get End Property Public Function ToBitmap(Optional ByVal operation As CopyPixelOperation = CopyPixelOperation.SourceCopy Or CopyPixelOperation.CaptureBlt) As Bitmap Return ToBitmap(Me.ClipSize, operation) End Function Public Function ToBitmap(ByVal Resolution As Size, Optional ByVal operation As CopyPixelOperation = CopyPixelOperation.SourceCopy Or CopyPixelOperation.CaptureBlt) As Bitmap ToBitmap = New Bitmap(Resolution.Width, Resolution.Height) Dim g As Graphics = Graphics.FromImage(ToBitmap) Dim ghdc As IntPtr = g.GetHdc BitBlt(ghdc, 0, 0, Resolution.Width, Resolution.Height, Me.hdc, 0, 0, operation) g.ReleaseHdc(ghdc) g.Dispose() End Function
In Window.vb
vb Code:
Public Function CaptureWindow(ByVal g As Graphics) As Boolean Dim DC As New API.DC(g) Dim wDC As API.DC = Me.GetWindowDC wDC.CopyTo(DC) DC.Dispose() wDC.Dispose() End Function Public Function CaptureWindow() As Image Dim s As Size = Me.Size If s.Width < 1 Or s.Height < 1 Then Return Nothing Dim img As New Bitmap(s.Width, s.Height) Dim g As Graphics = Graphics.FromImage(img) CaptureWindow(g) g.Dispose() Return img End Function