title: VB.Net: Sending Virtual Keystrokes to Remote Desktop Application
body: <p>I am attempting to build an onscreen numeric keypad using VB.net and MS Visual Studios. I have a working prototype which works great on my local machine except when sending keystrokes to an active form within the Windows RDC application. I have attempted solutions using SendKeys() and keybd_event both of which have hit the same road block. My research thus far indicates that while SendKeys has some limitations both the SendMessage and SendInput APIs should work with the Windows RDP application when used with the correct Keyboard Scan Codes;however I have been unsuccessful in implementing these APIs in my code and have searched far an wide for working example code but have been unsuccessful so far. </p>
  
  <p>Can someone please provide some sample code which outlines how to implement either of these API functions in VB.Net / Visual Studios. </p>
  
  <p>Below I have included some sample code which works with most applications on the host PC but not with the Windows RDC software. </p>
  
  <p><b>Declare Hex Variables</b></p>
  
  <pre><code>Private Const WM_NCLBUTTONDOWN As Int32 = &amp;HA1
  Private Const WM_NCMOUSEMOVE As Int32 = &amp;HA0
  Private Const WS_EX_NOACTIVATE As Int32 = &amp;H8000000
  Private Const KEYEVENTF_KEYDOWN As Integer = &amp;H0
  Private Const KEYEVENTF_KEYUP As Integer = &amp;H2 
  Private Const VK_SPACE As Integer = &amp;H20
  Private Const WM_KEYDOWN As Int32 = &amp;H100
  Private Const WM_KEYUP As Int32 = &amp;H101
  Private Const WM_CHAR = &amp;H102
  </code></pre>
  
  <p><b>Prevent the Onscreen Keyboard from Stealing Focus</b> </p>
  
  <pre><code>Protected Overrides ReadOnly Property CreateParams() As CreateParams
      Get
          Dim cp As CreateParams = MyBase.CreateParams
          cp.ExStyle = cp.ExStyle Or CInt(Fix(WS_EX_NOACTIVATE))
          Return cp
      End Get
  End Property
  
  Dim previousForegroundWindow As IntPtr
  Protected Overrides Sub WndProc(ByRef m As Message)
  
      Dim foregroundWindow As IntPtr
      Select Case m.Msg
          Case WM_NCLBUTTONDOWN
  
              foregroundWindow = GetForegroundWindow()
  
              If foregroundWindow = Me.Handle Then
                  SetForegroundWindow(Me.Handle)
  
                  If foregroundWindow = IntPtr.Zero Then
                      previousForegroundWindow = foregroundWindow
                  End If
              End If
  
          Case WM_NCMOUSEMOVE
  
              If IsWindow(previousForegroundWindow) Then
                  SetForegroundWindow(previousForegroundWindow)
              End If
  
          Case Else
      End Select
  
      MyBase.WndProc(m)
  End Sub
  </code></pre>
  
  <p><b> Import keybd_event function from "user32"</b></p>
  
  <pre><code>Declare Function keybd_event Lib "user32" Alias "keybd_event" _
      (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Integer,
       ByVal dwExtraInfo As Integer) As Integer 
  </code></pre>
  
  <p><b>Send Key Events to window / form when label is clicked</b></p>
  
  <pre><code>Private Sub Label1_Click(ByVal sender As System.Object, ByVal e As   System.EventArgs) Handles Label1.Click
      ''Key 7
      keybd_event(Keys.D7, 0, KEYEVENTF_KEYDOWN, 0)
      keybd_event(Keys.D7, 0, KEYEVENTF_KEYUP, 0)
  </code></pre>