Imports System
Imports System.Collections.Generic
Imports System.Text
Imports System.Drawing
Imports System.Runtime.InteropServices
Imports System.ComponentModel
Imports System.Data
Imports System.Linq
Imports System.Windows.Forms
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim prcs As System.Diagnostics.Process() = System.Diagnostics.Process.GetProcessesByName("notepad")
For Each prc As System.Diagnostics.Process In prcs
Dim screenshot As Bitmap = Spazzarama.ScreenCapture.Direct3DCapture.CaptureWindow(prc.MainWindowHandle)
screenshot.Save("C:\er.bmp", System.Drawing.Imaging.ImageFormat.Bmp)
Next
End Sub
End Class
Namespace Spazzarama.ScreenCapture
Public Module Direct3DCapture
Sub New()
End Sub
Private _direct3D9 As New SlimDX.Direct3D9.Direct3D()
Private _direct3DDeviceCache As New Dictionary(Of IntPtr, SlimDX.Direct3D9.Device)()
''' <summary>
''' Capture the entire client area of a window
''' </summary>
''' <param name="hWnd"></param>
''' <returns></returns>
Public Function CaptureWindow(ByVal hWnd As IntPtr) As Bitmap
Return CaptureRegionDirect3D(hWnd, NativeMethods.GetAbsoluteClientRect(hWnd))
End Function
''' <summary>
''' Capture a region of the screen using Direct3D
''' </summary>
''' <param name="handle">The handle of a window</param>
''' <param name="region">The region to capture (in screen coordinates)</param>
''' <returns>A bitmap containing the captured region, this should be disposed of appropriately when finished with it</returns>
Public Function CaptureRegionDirect3D(ByVal handle As IntPtr, ByVal region As Rectangle) As Bitmap
Dim hWnd As IntPtr = handle
Dim bitmap As Bitmap = Nothing
' We are only supporting the primary display adapter for Direct3D mode
Dim adapterInfo As SlimDX.Direct3D9.AdapterInformation = _direct3D9.Adapters.DefaultAdapter
Dim device As SlimDX.Direct3D9.Device
'#Region "Get Direct3D Device"
' Retrieve the existing Direct3D device if we already created one for the given handle
If _direct3DDeviceCache.ContainsKey(hWnd) Then
device = _direct3DDeviceCache(hWnd)
Else
' We need to create a new device
' Setup the device creation parameters
Dim parameters As New SlimDX.Direct3D9.PresentParameters()
parameters.BackBufferFormat = adapterInfo.CurrentDisplayMode.Format
Dim clientRect As Rectangle = NativeMethods.GetAbsoluteClientRect(hWnd)
parameters.BackBufferHeight = clientRect.Height
parameters.BackBufferWidth = clientRect.Width
parameters.Multisample = SlimDX.Direct3D9.MultisampleType.None
parameters.SwapEffect = SlimDX.Direct3D9.SwapEffect.Discard
parameters.DeviceWindowHandle = hWnd
parameters.PresentationInterval = SlimDX.Direct3D9.PresentInterval.[Default]
parameters.FullScreenRefreshRateInHertz = 0
' Create the Direct3D device
device = New SlimDX.Direct3D9.Device(_direct3D9, adapterInfo.Adapter, SlimDX.Direct3D9.DeviceType.Hardware, hWnd, SlimDX.Direct3D9.CreateFlags.SoftwareVertexProcessing, parameters)
_direct3DDeviceCache.Add(hWnd, device)
End If
'#End Region
' Capture the screen and copy the region into a Bitmap
Using surface As SlimDX.Direct3D9.Surface = SlimDX.Direct3D9.Surface.CreateOffscreenPlain(device, adapterInfo.CurrentDisplayMode.Width, adapterInfo.CurrentDisplayMode.Height, SlimDX.Direct3D9.Format.A8R8G8B8, SlimDX.Direct3D9.Pool.SystemMemory)
device.GetFrontBufferData(0, surface)
bitmap = New Bitmap(SlimDX.Direct3D9.Surface.ToStream(surface, SlimDX.Direct3D9.ImageFileFormat.Bmp, New Rectangle(region.Left, region.Top, region.Right, region.Bottom)))
End Using
Return bitmap
End Function
End Module
#Region "Native Win32 Interop"
''' <summary>
''' The RECT structure defines the coordinates of the upper-left and lower-right corners of a rectangle.
''' </summary>
<Serializable(), StructLayout(LayoutKind.Sequential)> _
Friend Structure RECT
Public Left As Integer
Public Top As Integer
Public Right As Integer
Public Bottom As Integer
Public Sub New(ByVal left As Integer, ByVal top As Integer, ByVal right As Integer, ByVal bottom As Integer)
Me.Left = left
Me.Top = top
Me.Right = right
Me.Bottom = bottom
End Sub
Public ReadOnly Property AsRectangle() As Rectangle
Get
Return New Rectangle(Me.Left, Me.Top, Me.Right - Me.Left, Me.Bottom - Me.Top)
End Get
End Property
Public Shared Function FromXYWH(ByVal x As Integer, ByVal y As Integer, ByVal width As Integer, ByVal height As Integer) As RECT
Return New RECT(x, y, x + width, y + height)
End Function
Public Shared Function FromRectangle(ByVal rect As Rectangle) As RECT
Return New RECT(rect.Left, rect.Top, rect.Right, rect.Bottom)
End Function
End Structure
<System.Security.SuppressUnmanagedCodeSecurity()> _
Friend NotInheritable Class NativeMethods
<DllImport("user32.dll")> _
Friend Shared Function GetClientRect(ByVal hWnd As IntPtr, ByRef lpRect As RECT) As Boolean
End Function
<DllImport("user32.dll")> _
Friend Shared Function GetWindowRect(ByVal hWnd As IntPtr, ByRef lpRect As RECT) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
''' <summary>
''' Get a windows client rectangle in a .NET structure
''' </summary>
''' <param name="hwnd">The window handle to look up</param>
''' <returns>The rectangle</returns>
Friend Shared Function GetClientRect(ByVal hwnd As IntPtr) As Rectangle
Dim rect As New RECT()
GetClientRect(hwnd, rect)
Return rect.AsRectangle
End Function
''' <summary>
''' Get a windows rectangle in a .NET structure
''' </summary>
''' <param name="hwnd">The window handle to look up</param>
''' <returns>The rectangle</returns>
Friend Shared Function GetWindowRect(ByVal hwnd As IntPtr) As Rectangle
Dim rect As New RECT()
GetWindowRect(hwnd, rect)
Return rect.AsRectangle
End Function
Friend Shared Function GetAbsoluteClientRect(ByVal hWnd As IntPtr) As Rectangle
Dim windowRect As Rectangle = NativeMethods.GetWindowRect(hWnd)
Dim clientRect As Rectangle = NativeMethods.GetClientRect(hWnd)
' This gives us the width of the left, right and bottom chrome - we can then determine the top height
Dim chromeWidth As Integer = CInt(((windowRect.Width - clientRect.Width) / 2))
Return New Rectangle(New Point(windowRect.X + chromeWidth, windowRect.Y + (windowRect.Height - clientRect.Height - chromeWidth)), clientRect.Size)
End Function
End Class
#End Region
End Namespace