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

keybd_event & SendInput. Simulating Scroll-Lock Press and Release?

Hello Experts,

I'm trying to optimize some VB6 code to .NET and was wondering if you could present any code samples in VB .NET/2005 on how to simulate Scroll-Lock Key press & release using SENDINPUT. Something that would replace the use of keybd_event I think...
  • 5
  • 4
1 Solution
I know the difference between SendKeys and SendInput, but why do you need API if there is the managed class with exactly the same functionality?

This is information about SendInput API, if you have reasons to use it:
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

donniedarko801Author Commented:
I'm behind a firewall, can you please post the code?
donniedarko801Author Commented:
SendKeys is bad programing... I need reliable stuff...
Public Class NativeMethods

    <DllImport("user32.dll", SetLastError:=True)> _
    Friend Shared Function SendInput(ByVal cInputs As Int32, ByRef pInputs As INPUT, ByVal cbSize As Int32) As Int32
    End Function

    <StructLayout(LayoutKind.Explicit, pack:=1, Size:=28)> _
    Friend Structure INPUT
    <FieldOffset(0)> Public dwType As InputType
    <FieldOffset(4)> Public mi As MOUSEINPUT
    <FieldOffset(4)> Public ki As KEYBDINPUT
    <FieldOffset(4)> Public hi As HARDWAREINPUT
    End Structure

    <StructLayout(LayoutKind.Sequential, pack:=1)> _
    Friend Structure MOUSEINPUT
    Public dx As Int32
    Public dy As Int32
    Public mouseData As Int32
    Public dwFlags As MOUSEEVENTF
    Public time As Int32
    Public dwExtraInfo As IntPtr
    End Structure

    <StructLayout(LayoutKind.Sequential, pack:=1)> _
    Friend Structure KEYBDINPUT
    Public wVk As Int16
    Public wScan As Int16
    Public dwFlags As KEYEVENTF
    Public time As Int32
    Public dwExtraInfo As IntPtr
    End Structure

    <StructLayout(LayoutKind.Sequential, pack:=1)> _
    Friend Structure HARDWAREINPUT
    Public uMsg As Int32
    Public wParamL As Int16
    Public wParamH As Int16
    End Structure

    Friend Enum InputType As Integer
    Mouse = 0
    Keyboard = 1
    Hardware = 2
    End Enum

    <Flags()> _
    Friend Enum MOUSEEVENTF As Integer
    MOVE = &H1
    LEFTDOWN = &H2
    LEFTUP = &H4
    RIGHTUP = &H10
    MIDDLEUP = &H40
    XDOWN = &H80
    XUP = &H100
    WHEEL = &H800
    ABSOLUTE = &H8000
    End Enum

    <Flags()> _
    Friend Enum KEYEVENTF As Integer
    KEYUP = 2
    UNICODE = 4
    SCANCODE = 8
    End Enum

End Class

    Private Sub DoKeyBoard(ByVal flags As NativeMethods.KEYEVENTF, ByVal key As Keys)
    Dim input As New NativeMethods.INPUT
    Dim ki As New NativeMethods.KEYBDINPUT
    input.dwType = NativeMethods.InputType.Keyboard
    input.ki = ki
    input.ki.wVk = Convert.ToInt16(key)
    input.ki.wScan = 0
    input.ki.time = 0
    input.ki.dwFlags = flags
    input.ki.dwExtraInfo = IntPtr.Zero
    Dim cbSize As Integer = Marshal.SizeOf(GetType(NativeMethods.INPUT))
    Dim result As Integer = NativeMethods.SendInput(1, input, cbSize)
    If result = 0 Then Debug.WriteLine(Marshal.GetLastWin32Error)
    End Sub

    Dim message As String = "HELLO WORLD"
    For Each c As Char In message
        Dim key As UInteger = Convert.ToInt16(c)
        DoKeyBoard(0, key)  ' key down is 0 - no flag...
        DoKeyBoard(NativeMethods.KEYEVENTF.KEYUP, key)
    DoKeyBoard(0, Keys.Decimal) ' example using keys enum which I think matches the VKEY values
    DoKeyBoard(NativeMethods.KEYEVENTF.KEYUP, Keys.Decimal)
donniedarko801Author Commented:
Thanks Alex!
donniedarko801Author Commented:
That works well, but how would you string a keypress and an release into 1 array of structs to be sent all at the same time? And why do lowercase characters not print if you change the string?
ex. message = "HELLO WORLD"
outputs "hello world."
ex. message = "HELLO World"
outputs "hello w/4."
ex. message = "hello world"
outputs "85/ /4."

UINT SendInput( UINT nInputs, LPINPUT pInputs, int cbSize);
******[in] Specifies the number of structures in the pInputs array. ***** <---use this to send the down and up together
[in] Pointer to an array of INPUT structures. Each structure represents an event to be inserted into the keyboard or mouse input stream.
[in] Specifies the size, in bytes, of an INPUT structure. If cbSize is not the size of an INPUT structure, the function will fail.
To get upper case you need to press Shift programmatically.
About array of structures: you must allocate array of structures in unmanaged memory using Marshal class. See: Marshal.AllocHGlobal, Marshal.StructureToPtr methods. In this case second SendInput parameter must be defined as IntPtr.

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

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