Keyboard Hook to intercept clipboard pasting
I have a need to copy a numeric value to the clipboard and upon pasting it into a document having it increment the number with each paste. I am using a keyboard hook to intercept the CTRL-V, Un-register the hook, read the clipboard and if it can be incremented then do so, paste the clipboard (by use of SendKeys to send a CTRL-V), then Re-register the keyboard hook.
This works, however by using SendKeys to paste the clipboard it kills the ability for key-repeat. I can keep pasting one number at a time as long as I lift the CTRL key each time, otherwise the key repeat kicks in and pastes a bunch of v's.
I am trying to find an alternative to using SendKeys as a way of continuing the paste operation or a way of letting the computer recognize the CTRL key as part of the key repeat. Anyone?
Thanks,
Jim
Code:
Imports System.Runtime.InteropServices
Public Class Form1
Public Const VK_ALT As Integer = &H1
Public Const VK_CTRL As Integer = &H2
Public Const VK_SHIFT As Integer = &H4
Public Const VK_CTRL_ALT As Integer = &H1 + &H2
Public Const VK_CTRL_SHIFT As Integer = &H2 + &H4
Public Const WM_HOTKEY As Integer = &H312
<DllImport("User32.dll")> _
Public Shared Function RegisterHotKey(ByVal hwnd As IntPtr, ByVal id As Integer, ByVal fsModifiers As Integer, ByVal vk As Integer) As Integer
End Function
<DllImport("User32.dll")> _
Public Shared Function UnregisterHotKey(ByVal hwnd As IntPtr, ByVal id As Integer) As Integer
End Function
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
RegisterHotKey(Me.Handle, 100, VK_CTRL, Keys.V)
End Sub
Private Sub Form1_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
UnregisterHotKey(Me.Handle, 100)
End Sub
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = WM_HOTKEY Then
Dim id As IntPtr = m.WParam
Dim iData As IDataObject = Clipboard.GetDataObject()
Dim Numb As Integer = 0
UnregisterHotKey(Me.Handle, 100)
If id.ToString = "100" Then
If iData.GetDataPresent(DataFormats.Text) Then
Try
Numb = CType(iData.GetData(DataFormats.Text), String) + 1
Clipboard.SetText(Numb.ToString)
System.Windows.Forms.SendKeys.Send("^v")
Catch ex As Exception
System.Windows.Forms.SendKeys.Send("^v")
End Try
Else
System.Windows.Forms.SendKeys.Send("^v")
End If
End If
RegisterHotKey(Me.Handle, 100, VK_CTRL, Keys.V)
End If
MyBase.WndProc(m)
End Sub
End Class
Re: Keyboard Hook to intercept clipboard pasting
this should help. it's a clipboard hook:
Code:
Public Class Form1
Private Const WM_DRAWCLIPBOARD As Integer = &H308
Private Declare Function SetClipboardViewer Lib "user32" Alias "SetClipboardViewer" (ByVal hwnd As Integer) As Integer
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = WM_DRAWCLIPBOARD Then
'clipboard has changed
Dim value As Decimal
If Decimal.TryParse(Clipboard.GetText, value) Then
'clipboard contains a decimal
End If
End If
MyBase.WndProc(m)
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim hWnd As Integer = SetClipboardViewer(Me.Handle.ToInt32)
While hWnd <> Me.Handle.ToInt32
hWnd = SetClipboardViewer(Me.Handle.ToInt32)
End While
End Sub
End Class
Re: Keyboard Hook to intercept clipboard pasting
Paul,
Thanks for the code example. It looks like it may be pointing me in the right direction, but I was not able to get it to work correctly. I added a couple of lines of code to increment the value and copy it back to the clipboard:
value = value + 1
Clipboard.SetText(value.ToString)
It did increment on the first paste, but not on consecutive pastes. It seems that this clipboard hook will intercept manual modifications to the clipboard (^C, ^X). I need something that will intercept every paste so that I can increment the value with each paste, whether a single paste or a repeat by holding down the ^V keys. Am I using your code as intended?
Thanks,
Jim
Re: Keyboard Hook to intercept clipboard pasting
I wouldn't increment the value and write it back to the clipboard. That would cause an infinite recursion
Re: Keyboard Hook to intercept clipboard pasting
On the original code I posted (The keyboard hook), I was able to accomplish what I was trying to do, except I had to lift the control button with each paste. I was intercepting the ^v, modifying the clipboard, and using SendKeys.Send("^v") to resume the paste command. I disabled the hook and re-enabled it after modifying the clipboard to eliminate infinite looping. The problem I was having was with resuming the paste command by using sendkeys, the CONTRL key was no longer seen as part of the keyboard repeat so instead on repeated ^v I was only getting the v’s. I also tried using a different hotkey so that I wouldn’t need to disable the hook between pastes, but I still had the same problem with key-repeats.
The Clipboard hook you sent works with key-repeats, but it only repeats the same last value and only increments if I copy a new value to the clipboard manually by pressing ^c or ^X. I am trying to increment every paste value whether a single ^v or repeated by holding down ^v. Being able to hook the clipboard paste rather than clipboard changes would work, but only if I could resume the paste after modifying the clipboard contents. Maybe an interrupt to the paste would work if that is possible. Any other ideas?
Quote:
Originally Posted by
JimAvanti
Paul,
Thanks for the code example. It looks like it may be pointing me in the right direction, but I was not able to get it to work correctly. I added a couple of lines of code to increment the value and copy it back to the clipboard:
value = value + 1
Clipboard.SetText(value.ToString)
It did increment on the first paste, but not on consecutive pastes. It seems that this clipboard hook will intercept manual modifications to the clipboard (^C, ^X). I need something that will intercept every paste so that I can increment the value with each paste, whether a single paste or a repeat by holding down the ^V keys. Am I using your code as intended?
Thanks,
Jim
Re: Keyboard Hook to intercept clipboard pasting
I don't think your original code is possible. RegisterHotkey doesn't recognize the ctrl key being pressed after the first event, and all of the workarounds that I can think of that might emulate the key being re-pressed don't work