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...