Hi,
Here is the code to a keyboard hook component that i wrote. It
raises an event when the print screen button is pressed. The event returns
the image copied to the clipboard.
Imports System.Runtime.InteropServices
Imports System.Reflection
Imports System.Drawing
Imports System.Threading
<ToolboxBitmap(GetType(KeyboardHook), "KEYS03.ICO")> _
Public Class KeyboardHook
Inherits System.ComponentModel.Component
Dim WithEvents kbd As KeyboardHelper
#Region " Windows Form Designer generated code "
Public Sub New()
MyBase.New()
'This call is required by the Windows Form Designer.
InitializeComponent()
'Add any initialization after the InitializeComponent() call
If Not Me.DesignMode Then
kbd = New KeyboardHelper
kbd.HookKeyboard()
End If
End Sub
'UserControl overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
components = New System.ComponentModel.Container
End Sub
#End Region
Public Event NumLockPressed(ByVal sender As Object, ByVal e As EventArgs)
Public Event CapLockPressed(ByVal sender As Object, ByVal e As EventArgs)
Public Event ScrollLockPressed(ByVal sender As Object, ByVal e As EventArgs)
Public Event PrintScreenPressed(ByVal sender As Object, ByVal e As
PrintScreenEventArgs)
Protected Overrides Sub Finalize()
kbd.UnhookKeyboard()
kbd = Nothing
MyBase.Finalize()
End Sub
Private Sub kbd_CapLock() Handles kbd.CapLock
RaiseEvent CapLockPressed(Me, New EventArgs)
End Sub
Private Sub kbd_NumLock() Handles kbd.NumLock
RaiseEvent NumLockPressed(Me, New EventArgs)
End Sub
Private Sub kbd_PrintScreen() Handles kbd.PrintScreen
RaiseEvent PrintScreenPressed(Me, New PrintScreenEventArgs)
End Sub
Private Sub kbd_ScrollLock() Handles kbd.ScrollLock
RaiseEvent ScrollLockPressed(Me, New EventArgs)
End Sub
End Class
Friend Class KeyboardHelper
Public Event NumLock()
Public Event CapLock()
Public Event ScrollLock()
Public Event PrintScreen()
Private Declare Function UnhookWindowsHookEx Lib "user32" _
(ByVal hHook As Integer) As Integer
Private Declare Function SetWindowsHookEx Lib "user32" _
Alias "SetWindowsHookExA" (ByVal idHook As Integer, _
ByVal lpfn As KeyboardHookDelegate, ByVal hmod As Integer, _
ByVal dwThreadId As Integer) As Integer
Private Declare Function GetAsyncKeyState Lib "user32" _
(ByVal vKey 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
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
' Low-Level Keyboard Constants
Private Const HC_ACTION As Integer = 0
' Virtual Keys
Const VK_SNAPSHOT As Integer = &H2C
Const VK_CAPITAL As Integer = &H14
Const VK_NUMLOCK As Integer = &H90
Const VK_SCROLL As Integer = &H91
Private Const WH_KEYBOARD_LL As Integer = 13&
Private KeyboardHandle As Integer
' Implement this function to block as many
' key combinations as you'd like
Public Function IsHooked( _
ByRef Hookstruct As KBDLLHOOKSTRUCT) As Boolean
If Hookstruct.vkCode = VK_SNAPSHOT Then RaiseEvent PrintScreen()
If Hookstruct.vkCode = VK_CAPITAL Then RaiseEvent CapLock()
If Hookstruct.vkCode = VK_NUMLOCK Then RaiseEvent NumLock()
If Hookstruct.vkCode = VK_SCROLL Then RaiseEvent ScrollLock()
Return False
End Function
Private Sub HookedState(ByVal Text As String)
Debug.WriteLine(Text)
End Sub
Public Function KeyboardCallback(ByVal Code As Integer, _
ByVal wParam As Integer, _
ByRef lParam As KBDLLHOOKSTRUCT) As Integer
If (Code = HC_ACTION) Then
Debug.WriteLine("Calling IsHooked")
If (IsHooked(lParam)) Then
Return 1
End If
End If
Return CallNextHookEx(KeyboardHandle, _
Code, wParam, lParam)
End Function
Public Delegate Function KeyboardHookDelegate( _
ByVal Code As Integer, _
ByVal wParam As Integer, ByRef lParam As KBDLLHOOKSTRUCT) _
As Integer
<MarshalAs(UnmanagedType.FunctionPtr)> _
Private callback As KeyboardHookDelegate
Public Sub HookKeyboard()
callback = New KeyboardHookDelegate(AddressOf KeyboardCallback)
KeyboardHandle = SetWindowsHookEx( _
WH_KEYBOARD_LL, callback, _
Marshal.GetHINSTANCE( _
[Assembly].GetExecutingAssembly.GetModules()(0)).ToInt32, 0)
CheckHooked()
End Sub
Public Sub CheckHooked()
If (Hooked()) Then
Debug.WriteLine("Keyboard hooked")
Else
Debug.WriteLine("Keyboard hook failed: " & Err.LastDllError)
End If
End Sub
Private Function Hooked() As Boolean
Hooked = KeyboardHandle <> 0
End Function
Public Sub UnhookKeyboard()
If (Hooked()) Then
UnhookWindowsHookEx(KeyboardHandle)
End If
End Sub
End Class
Public Class PrintScreenEventArgs
Inherits EventArgs
Dim bm As Bitmap
Public Sub New()
Dim data As IDataObject
data = Clipboard.GetDataObject()
If data.GetDataPresent(GetType(System.Drawing.Bitmap)) Then
bm = CType(data.GetData(GetType(System.Drawing.Bitmap)), Bitmap)
End If
End Sub
Public ReadOnly Property ScreenShot() As Bitmap
Get
Return bm
End Get
End Property
End Class
Ken
--------------------------------
Is there any way of telling if the print Screen btn was
pressed? Window seams to catch the event first. urg.
I would prefer the solution not to include a regedit,
or editing any of the register keys. I dont realy want
to pole the button either.
Any ideas?
jamie