• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 289
  • Last Modified:

Application to Paste clipboard one letter at a time.

I need to create a module or application that runs in the background (Windows, VB.net application or console application.)   When I hit a key combination (any, but say ctrl-F12 for argument sake) it pastes the text in the clipboard but one letter at a time and slowly.  Any suggestions, I can't even seem to get started here.
0
CSBTech
Asked:
CSBTech
  • 6
  • 6
1 Solution
 
CSBTechAuthor Commented:
Actually, I did get started.  I was trying to do a console application and couldn't get clipboard working, but now I have a windows application with this as a start.

Imports System.Windows.Forms

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim myText As String
        Dim myLen As Int32
        Dim I As Int32
        Dim myChar As Char

        myLen = Len(Clipboard.GetText)
        myText = Clipboard.GetText


        For I = 1 To myLen
            myChar = myText.Chars(I)

        Next

    End Sub
End Class
0
 
CSBTechAuthor Commented:
So I guess the first question is, how do I now take the myChar and paste it into another application and still loop through the I loop to get the next charactor and so on.  Then I have to worry about getting the keystroke to set it off.  Or do I NEED a console application for this, if so, how do I get that going?
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Here ya go...

The project is a WinForms app with the default Form1 and one Class.

*** Note that in VB.Net 2005, the keyboard hook does NOT work while in the IDE.  You must run the executable in the ..\bin\release folder! ***

' ----------------
'      Form1
' ----------------
Public Class Form1

    Private WithEvents llkb As New LowLevelKeyBoardhook

    Private Sub llkb_CtrlF12() Handles llkb.CtrlF12
        If Clipboard.ContainsText Then
            Dim txt As String = Clipboard.GetText
            For i As Integer = 0 To txt.Length - 1
                SendKeys.SendWait(txt(i))
                System.Threading.Thread.Sleep(250)
            Next
        End If
    End Sub

End Class


' ------------------------------------
'      Class LowLevelKeyBoardhook
' ------------------------------------
Imports System.Runtime.InteropServices
Public 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
    Private Const VK_CTRL As Integer = &H11
    Private Const KEYEVENTF_KEYUP As Integer = &H2


    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

    Private Declare Function GetAsyncKeyState Lib "user32" _
        (ByVal vKey As Integer) As Integer

    Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, _
        ByVal bScan As Byte, ByVal dwFlags As Integer, ByVal dwExtraInfo As Integer)

    Public Event CtrlF12()

    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 GetAsyncKeyState(Keys.ControlKey) AndAlso _
                            (lParam.vkCode = Keys.F12) Then
                        ' Let go of the Ctrl Key before sending other keystrokes.
                        ' Otherwise you will be sending the keystrokes while still
                        ' holding down the Ctrl key...
                        keybd_event(VK_CTRL, 0, KEYEVENTF_KEYUP, 0)

                        RaiseEvent CtrlF12()
                    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

0
Windows Server 2016: All you need to know

Learn about Hyper-V features that increase functionality and usability of Microsoft Windows Server 2016. Also, throughout this eBook, you’ll find some basic PowerShell examples that will help you leverage the scripts in your environments!

 
CSBTechAuthor Commented:
Wow, that is nearly perfect, thanks.  2 problems though.

1 - After a time, I get a windows error, probably after a certain amount of characters.  I am guess the infamous 255, but not sure.  Is there  a way to stop that or increase it?

2 - Is there a way to pause and/or stop the process?  Not thinking I went into another application and it starting pasting text into that application and I overwrote data... very sad actually, hopefully I can reverse the damage, but anyway, is there a way to use a keystroke or something to pause and/or stop it?

THanks for your help, John
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
(1) Pretty sure there is no trivial size limit at work here as a string can hold like 2 billion characters...maybe you had a non-standard character in the clipboard that SendKeys had a problem with?  What exactly did the error message say?

(2) I can write up a quick fix to allow you to cancel the sending of characters with the ESC key.
0
 
CSBTechAuthor Commented:
Actually, the error occurs on characters like ( and ) so far anyway.  Maybe others.
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Revised code to allow the cancellation of pasting characters via the ESC key:

' ----------------
'      Form1
' ----------------
Public Class Form1

    Private cancelled As Boolean
    Private WithEvents llkb As New LowLevelKeyBoardhook

    Private Sub llkb_CtrlF12() Handles llkb.CtrlF12
        If Clipboard.ContainsText Then
            cancelled = False
            Dim txt As String = Clipboard.GetText
            For i As Integer = 0 To txt.Length - 1
                SendKeys.SendWait(txt(i))
                System.Threading.Thread.Sleep(250)
                Application.DoEvents()
                If cancelled Then Exit Sub
            Next
        End If
    End Sub

    Private Sub llkb_ESC() Handles llkb.ESC
        cancelled = True
    End Sub

End Class

' ------------------------------------
'      Class LowLevelKeyBoardhook
' ------------------------------------
Imports System.Runtime.InteropServices
Public 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
    Private Const VK_CTRL As Integer = &H11
    Private Const KEYEVENTF_KEYUP As Integer = &H2


    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

    Private Declare Function GetAsyncKeyState Lib "user32" _
        (ByVal vKey As Integer) As Integer

    Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, _
        ByVal bScan As Byte, ByVal dwFlags As Integer, ByVal dwExtraInfo As Integer)

    Public Event CtrlF12()
    Public Event ESC()

    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 GetAsyncKeyState(Keys.ControlKey) AndAlso _
                            (lParam.vkCode = Keys.F12) Then
                        ' Let go of the Ctrl Key before sending other keystrokes.
                        ' Otherwise you will be sending the keystrokes while still
                        ' holding down the Ctrl key...
                        keybd_event(VK_CTRL, 0, KEYEVENTF_KEYUP, 0)

                        RaiseEvent CtrlF12()
                    ElseIf lParam.vkCode = Keys.Escape Then
                        RaiseEvent ESC()
                    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
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
A quick fix for the SendKeys() problem would be to do this:

            Dim txt As String = Clipboard.GetText
            For i As Integer = 0 To txt.Length - 1
                Try
                    SendKeys.SendWait(txt(i))
                    System.Threading.Thread.Sleep(250)
                Catch ex As Exception
                End Try
                Application.DoEvents()
                If cancelled Then Exit Sub
            Next

This will just ignore any characters that cause problems.
0
 
CSBTechAuthor Commented:
Well, the esc key won't work because I just tried it and it wiped out all the text that went in.  Apparently the esc key resets teh field in the application I am in.  So I need to change it to another key stroke.  I can probably handle that or if you want to change it fine.  As for the ( and ) problem, it isn't a big deal for what I am doing so if you have a fast solution, great, if not, I appreciate your help and you get the points.

Thanks, John
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Take a look at the second example to see how to setup a key for the cancellation...it's easy enough to change.

And my last post shows how to ignore the characters causing problems with SendKeys().
0
 
CSBTechAuthor Commented:
Yep, we cross posted.  Thanks again for your help I appreciate your fast responses.  John
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
No problem!...   ;)
0

Featured Post

NFR key for Veeam Agent for Linux

Veeam is happy to provide a free NFR license for one year.  It allows for the non‑production use and valid for five workstations and two servers. Veeam Agent for Linux is a simple backup tool for your Linux installations, both on‑premises and in the public cloud.

  • 6
  • 6
Tackle projects and never again get stuck behind a technical roadblock.
Join Now