Share via


VB.Net - Multi Screen Capture


 

Overview

This is a multi-function screen capture application, that gives options about which screen, window, or region you want to capture. The capture runs on the PrtScr button, capturing whatever you have currently selected in the Options form. Additionally, it allows your newly captured image to be opened immediately in Paint. There is also the option to run this app. at windows startup. The running app. resides in your Windows notification bar, and the options form remains invisible until you choose to reveal it...

The application consists of two Forms and one Class. The main Form is the options Form, which is the startup Form. The second Form is used for selecting a rectangle within the active screen. The Class contains most of the image capturing code.

On Form_Load, the PrtScr button is registered as a system wide hotkey. This overrides the standard action for the PrtScr button, and allows optional screen capturing...


Catching the hotkey

Protected Overrides  Sub WndProc(ByRef m As System.Windows.Forms.Message)
 
    Const WM_SYSCOMMAND As Integer  = &H112
    Const SC_MINIMIZE As Integer  = &HF020
    If m.Msg = WM_HOTKEY Then
        Dim fileName As String  = My.Application.Info.DirectoryPath & "\images\" & Replace(Replace(Now.ToString.Replace("/", "-"), ":", "."), " ", "_") & ".png"
        Select Case  My.Settings.scChoice
            Case 0 'all screens as one image
                'remove key hook and simulate standard PRTSCR press
                UnregisterHotKey(Me.Handle, 0)
                keyboardevent(VK_Snapshot, 0, KeyEventF_Keydown, 0)
                keyboardevent(VK_Snapshot, 0, KeyEventF_Keyup, 0)
                Clipboard.GetImage.Save(fileName, Imaging.ImageFormat.Png)
                RegisterHotKey(Me.Handle, 0, 0, 44)
            Case 1 'active screen
                sc.CaptureScreen.Save(fileName, Imaging.ImageFormat.Png)
            Case 2 'active window
                sc.captureActiveWindow.Save(fileName, Imaging.ImageFormat.Png)
            Case 3 'selected rectangle
                If My.Application.OpenForms("Form2") Is  Nothing Then
                    Form2.Show()
                Else
                    If Form2.regionDrawn Then
                        sc.CaptureDeskTopRectangle(Form2.boundsRect).Save(fileName, Imaging.ImageFormat.Png)
                        Form2.Close()
                    End If
                End If
        End Select
        If IO.File.Exists(fileName) And CheckBox1.Checked Then
            Process.Start("mspaint.exe", Chr(34) & fileName & Chr(34))
        End If
    ElseIf m.Msg = WM_SYSCOMMAND AndAlso m.WParam.ToInt32() = SC_MINIMIZE Then
        My.Settings.startPosition = Me.Location
        My.Settings.Save()
        animate(Me, "screen capture", animationEffect.shrink)
        Me.Opacity = 0
        Return
    End If
    MyBase.WndProc(m)
 
End Sub

clsScreenCapture

Imports System.Runtime.InteropServices
 
Public Class  clsScreenCapture
 
    Public Function  CaptureScreen() As  Image
        Dim screens() As Screen = Screen.AllScreens
        Return CaptureWindow(Nothing, screens.First(Function(s) s.Bounds.Contains(Cursor.Position)).Bounds)
    End Function
 
    Public Function  captureActiveWindow() As Image
        Return CaptureWindow(User32.GetForegroundWindow, Nothing)
    End Function
 
    Public Function  CaptureDeskTopRectangle(ByVal r As Rectangle) As Image
        Return CaptureWindow(Nothing, r)
    End Function
 
    Public Function  CaptureWindow(ByVal  handle As  IntPtr, ByVal  r As  Rectangle) As  Image
        ' get the size
        Dim windowRect As New  User32.RECT
 
        Dim width As Integer
        Dim height As Integer
 
 
        If r = Nothing Then
            User32.DwmGetWindowAttribute(handle, User32.DWMWA_EXTENDED_FRAME_BOUNDS, windowRect, Marshal.SizeOf(windowRect))
 
            width = windowRect.right - windowRect.left
            height = windowRect.bottom - windowRect.top
        Else
            windowRect.left = r.Left + 1
            windowRect.top = r.Top + 1
            width = r.Width - 1
            height = r.Height - 1
            windowRect.right = windowRect.left + width
            windowRect.bottom = windowRect.top + height
        End If
 
        Dim img As Bitmap = New Bitmap(width, height)
        Dim gr As Graphics = Graphics.FromImage(img)
        gr.CopyFromScreen(windowRect.left, windowRect.top, 0, 0, New  Size(width, height))
 
        Return img
 
    End Function
 
 
    '/ Helper class containing User32 API functions
    Public Class  User32
 
        Public Structure  RECT
            Public left As Integer
            Public top As Integer
            Public right As Integer
            Public bottom As Integer
        End Structure
 
        Declare Function  GetForegroundWindow Lib "user32.dll" _
        Alias "GetForegroundWindow"  () As  IntPtr
 
        Public Const  DWMWA_EXTENDED_FRAME_BOUNDS As Integer  = 9
 
        <DllImport("dwmapi.dll")>
        Shared Function  DwmGetWindowAttribute(ByVal hwnd As IntPtr, ByVal dwAttribute As Integer, ByRef  pvAttribute As  RECT, ByVal  cbAttribute As  Integer) As Integer
        End Function
 
    End Class
 
End Class

Conclusion

This is a Windows 7 application that has been updated for Windows 10. There are some differences, such as support for multiple monitors. There's an improvement for capturing the active window, with the unreliable GetWindowRect API function replaced with the DwmGetWindowAttribute API function. 
With the improvements mentioned, this is a versatile screen capturing tool...


Download

Download here...