Avatar of dcahrakos
dcahrakos
 asked on

How to Capture and Save a screenshot using a keyboard hook.

Hi, im trying to figure out how I can go about taking, and saving a screenshot using VB.NET, I already have a keyboard hook in place so no matter what when you press the Prt Scr button it fires off an event in the program. the only problem now is how would I go about taking the screenshot then saving it to a file?

thanks in advance.
Visual Basic.NET

Avatar of undefined
Last Comment
Bob Learned

8/22/2022 - Mon
Bob Learned

If the Print Screen button was pressed the screenshot is going to be in the clipboard, so you can use whatever method your version of VB.NET requires, since it is different between 1.1 and 2.0 and higher (and you didn't say which).

Bob
dcahrakos

ASKER
im using visual studio 2008, but what would be the best way to capture the screenshot from the clipboard and save it directly to a file?
Bob Learned

If Clipboard.ContainsImage() Then
  Dim img As Image = Clipboard.GetImage()
  img.Save(fileName, ImageFormat.Png)
End If

Bob
Experts Exchange has (a) saved my job multiple times, (b) saved me hours, days, and even weeks of work, and often (c) makes me look like a superhero! This place is MAGIC!
Walt Forbes
dcahrakos

ASKER
wow, thats a lot easier than what I thought, thanks....

only 1 problem is that it seems the keyboard hook im using(which is one I found on here) doesnt let prt scr actually capture the screenshot, so is there a way to get it to capture the screenshot first using vb?
Bob Learned

You might want to look at PreFilterMessage:

IMessageFilter.PreFilterMessage Method
http://msdn2.microsoft.com/en-us/library/system.windows.forms.imessagefilter.prefiltermessage(VS.80).aspx

7.5 How can I catch keyboard messages on a application-wide basis?
http://www.syncfusion.com/FAQ/WindowsForms/FAQ_c46c.aspx

Bob
dcahrakos

ASKER
hey,

thanks again, but I cant seem to get it to work, here is the code I have right now, basically just copied a keyboard hook that I found on here, how would I implement PreFilterMessage so it lets print screen do its stuff, then fires the event in the application. I have never used PreFilterMessage before.

Thanks again.
Imports System.Runtime.InteropServices
 
 
Public Class Form1
 
    Dim i As Integer
    Private WithEvents llkb As LowLevelKeyBoardhook
 
 
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 
        llkb = New LowLevelKeyBoardhook
 
    End Sub
 
    Private Sub llkb_PrtScr() Handles llkb.PrtScr
 
        If Clipboard.ContainsImage Then
            Dim img As Image = Clipboard.GetImage
            img.Save("C:\img001.png")
        End If
 
    End Sub
 
 
    Private Class LowLevelKeyBoardhook
 
        Private Const HC_ACTION As Integer = 0
        Private Const WH_KEYBOARD_LL As Integer = 13
        Private Const WM_KEYDOWN As Integer = &H100
        Private Const WM_SYSKEYDOWN As Integer = &H104
 
        Public Structure KBDLLHOOKSTRUCT
            Public vkCode As Integer
            Public scancode As Integer
            Public flags As Integer
            Public time As Integer
            Public dwExtraInfo As Integer
        End Structure
 
        Private Declare Function SetWindowsHookEx Lib "user32" _
            Alias "SetWindowsHookExA" ( _
            ByVal idHook As Integer, _
            ByVal lpfn As LowLevelKeyboardProcDelegate, _
            ByVal hmod As Integer, _
            ByVal dwThreadId As Integer) As Integer
 
        Private Declare Function CallNextHookEx Lib "user32" ( _
            ByVal hHook As Integer, _
            ByVal nCode As Integer, _
            ByVal wParam As Integer, _
            ByVal lParam As KBDLLHOOKSTRUCT) As Integer
 
        Private Declare Function UnhookWindowsHookEx Lib "user32" ( _
            ByVal hHook As Integer) As Integer
 
        Private Delegate Function LowLevelKeyboardProcDelegate( _
            ByVal nCode As Integer, _
            ByVal wParam As Integer, _
            ByRef lParam As KBDLLHOOKSTRUCT) As Integer
 
        Public Event PrtScr()
 
        Private hhkLowLevelKeyboard As Integer
        Private keyboardDelegate As LowLevelKeyboardProcDelegate
 
        Public Sub New()
            keyboardDelegate = New LowLevelKeyboardProcDelegate(AddressOf Me.LowLevelKeyboardProc)
            hhkLowLevelKeyboard = SetWindowsHookEx(WH_KEYBOARD_LL, keyboardDelegate, _
                Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly.GetModules()(0)).ToInt32, 0)
        End Sub
 
        Private Function LowLevelKeyboardProc( _
            ByVal nCode As Integer, _
            ByVal wParam As Integer, _
            ByRef lParam As KBDLLHOOKSTRUCT) As Integer
 
            If (nCode = HC_ACTION) Then
                Select Case wParam
                    Case WM_KEYDOWN, WM_SYSKEYDOWN
                        If lParam.vkCode = Keys.PrintScreen Then
                            RaiseEvent PrtScr()
                        End If
                End Select
            End If
 
            Return CallNextHookEx(hhkLowLevelKeyboard, nCode, wParam, lParam)
        End Function
 
        Protected Overrides Sub Finalize()
            UnhookWindowsHookEx(hhkLowLevelKeyboard)
            MyBase.Finalize()
        End Sub
 
    End Class
End Class

Open in new window

⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
ASKER CERTIFIED SOLUTION
Bob Learned

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.