Vb.net simular presion tecla INSERT

Iniciado por rapbyone, 15 Febrero 2014, 20:00 PM

0 Miembros y 1 Visitante están viendo este tema.

rapbyone

Amigos, estoy en un proyecto personal, les cuento:
Tengo un botón que al presionarlo simula la presión sobre la tecla "Insert" en windows 7 y windows 8 funciona perfecto, pero el windows xp, no me funciona, simplemente la tecla no se presiona.

Este es el código:
SendKeys.Send("{INSERT}")
No entiendo cual será el problema, ¿se puede lograr de otra manera?

x64core

Cita de: rapbyone en 15 Febrero 2014, 20:00 PM
Amigos, estoy en un proyecto personal, les cuento:
Tengo un botón que al presionarlo simula la presión sobre la tecla "Insert" en windows 7 y windows 8 funciona perfecto, pero el windows xp, no me funciona, simplemente la tecla no se presiona.

Este es el código:
SendKeys.Send("{INSERT}")

No entiendo cual será el problema, ¿se puede lograr de otra manera?
Win32: keybd_event

rapbyone


x64core

#3
Cita de: rapbyone en 15 Febrero 2014, 22:49 PM
Amigo, podrías aclararme un poco mas como usarlo?
Aqui esta la informaciónde la función:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms646304(v=vs.85).aspx

Simplemente se llama como cualquier otra función pasandole los parametros correctos.
Puede que te interese además: MapVirtualKey/MapVirtualKeyEx, GetKeyboardLayout. Apesar de eso esta función puede fallar,
así que deberia preguntar: Qué tipo de ventana estaria enviando la tecla? Por eso es que estoy interesado también.

Eleкtro

#4
Cita de: rapbyone en 15 Febrero 2014, 20:00 PMNo entiendo cual será el problema

El método SendKeys.Send envía las pulsaciones del teclado a la ventana activa, ¿has tenido eso en cuenta?.

Muestra el código restante, es imposible poder ayudarte sin ver donde cometes el fallo (si hubiera alguno) o como estás usándolo.






De todas formas una alternativa para esta tarea que requieres quizás podría ser usando el método SendInput

He estado haciendo mi implementación de SendInput, todavía está muy verde, no lo he acabado, falta documentación por añadir y mucho código que escribir, y quizás bugs que corregir, pero para lo que tu precisas puedes testear este código.

Modo de empleo:
Código (vbnet) [Seleccionar]

   Private Sub Test() Handles Button1.Click

       AppActivate(Process.GetProcessesByName("notepad").First.Id)
       Dim Result As Integer = SendInputs.SendKeys(Keys.Insert,  BlockInput:=False)

       ' Dim Result2 As Integer = SendInputs.SendKey(Convert.ToChar(Keys.Enter))
       ' Dim Result2 As Integer = SendInputs.SendKey("x"c)

#If DEBUG Then
       MessageBox.Show(String.Format("Successfull events: {0}", CStr(Result)))
#End If

   End Sub


Código (vbnet) [Seleccionar]
' ***********************************************************************
' Author   : Elektro
' Modified : 02-17-2014
' ***********************************************************************
' <copyright file="SendInputs.vb" company="Elektro Studios">
'     Copyright (c) Elektro Studios. All rights reserved.
' </copyright>
' ***********************************************************************

#Region " Imports "

Imports System.Runtime.InteropServices
Imports System.ComponentModel

#End Region

''' <summary>
'''
''' </summary>
Public Class SendInputs

#Region " P/Invoke "

   Friend Class NativeMethods

#Region " Methods "

       ''' <summary>
       ''' Blocks keyboard and mouse input events from reaching applications.
       ''' For more info see here:
       ''' http://msdn.microsoft.com/en-us/library/windows/desktop/ms646290%28v=vs.85%29.aspx
       ''' </summary>
       ''' <param name="fBlockIt">
       ''' The function's purpose.
       ''' If this parameter is 'TRUE', keyboard and mouse input events are blocked.
       ''' If this parameter is 'FALSE', keyboard and mouse events are unblocked.
       ''' </param>
       ''' <returns>
       ''' If the function succeeds, the return value is nonzero.
       ''' If input is already blocked, the return value is zero.
       ''' </returns>
       ''' <remarks>
       ''' Note that only the thread that blocked input can successfully unblock input.
       ''' </remarks>
       <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall,
       SetLastError:=True)>
       Friend Shared Function BlockInput(
              ByVal fBlockIt As Boolean
       ) As Integer
       End Function

       ''' <summary>
       ''' Synthesizes keystrokes, mouse motions, and button clicks.
       ''' For more info see here:
       ''' http://msdn.microsoft.com/en-us/library/windows/desktop/ms646310%28v=vs.85%29.aspx
       ''' </summary>
       ''' <param name="nInputs">
       ''' Indicates the number of structures in the pInputs array.
       ''' </param>
       ''' <param name="pInputs">
       ''' Indicates an Array of 'INPUT' structures.
       ''' Each structure represents an event to be inserted into the keyboard or mouse input stream.
       ''' </param>
       ''' <param name="cbSize">
       ''' The size, in bytes, of an 'INPUT' structure.
       ''' If 'cbSize' is not the size of an 'INPUT' structure, the function fails.
       ''' </param>
       ''' <returns>
       ''' The function returns the number of events that it successfully
       ''' inserted into the keyboard or mouse input stream.
       ''' If the function returns zero, the input was already blocked by another thread.
       ''' </returns>
       <DllImport("user32.dll", SetLastError:=True)>
       Friend Shared Function SendInput(
              ByVal nInputs As Integer,
              <MarshalAs(UnmanagedType.LPArray), [In]> ByVal pInputs As INPUT(),
              ByVal cbSize As Integer
       ) As Integer
       End Function

#End Region

#Region " Enumerations "

       ''' <summary>
       ''' VirtualKey codes.
       ''' </summary>
       Friend Enum VirtualKeys As Short

           ''' <summary>
           ''' The Shift key.
           ''' VK_SHIFT
           ''' </summary>
           SHIFT = &H10S

           ''' <summary>
           ''' The DEL key.
           ''' VK_DELETE
           ''' </summary>
           DELETE = 46S

           ''' <summary>
           ''' The ENTER key.
           ''' VK_RETURN
           ''' </summary>
           [RETURN] = 13S

       End Enum

       ''' <summary>
       ''' The type of the input event.
       ''' For more info see here:
       ''' http://msdn.microsoft.com/en-us/library/windows/desktop/ms646270%28v=vs.85%29.aspx
       ''' </summary>
       <Description("Enumeration used for 'type' parameter of 'INPUT' structure")>
       Friend Enum InputType As Integer

           ''' <summary>
           ''' The event is a mouse event.
           ''' Use the mi structure of the union.
           ''' </summary>
           Mouse = 0

           ''' <summary>
           ''' The event is a keyboard event.
           ''' Use the ki structure of the union.
           ''' </summary>
           Keyboard = 1

           ''' <summary>
           ''' The event is a hardware event.
           ''' Use the hi structure of the union.
           ''' </summary>
           Hardware = 2

       End Enum

       ''' <summary>
       ''' Specifies various aspects of a keystroke.
       ''' This member can be certain combinations of the following values.
       ''' For more info see here:
       ''' http://msdn.microsoft.com/en-us/library/windows/desktop/ms646271%28v=vs.85%29.aspx
       ''' </summary>
       <Description("Enumeration used for 'dwFlags' parameter of 'KEYBDINPUT ' structure")>
       <Flags>
       Friend Enum KeyboardInput_Flags As Integer

           ''' <summary>
           ''' If specified, the scan code was preceded by a prefix byte that has the value '0xE0' (224).
           ''' </summary>
           ExtendedKey = &H1

           ''' <summary>
           ''' If specified, the key is being pressed.
           ''' </summary>
           KeyDown = &H0

           ''' <summary>
           ''' If specified, the key is being released.
           ''' If not specified, the key is being pressed.
           ''' </summary>
           KeyUp = &H2

           ''' <summary>
           ''' If specified, 'wScan' identifies the key and 'wVk' is ignored.
           ''' </summary>
           ScanCode = &H8

           ''' <summary>
           ''' If specified, the system synthesizes a 'VK_PACKET' keystroke.
           ''' The 'wVk' parameter must be '0'.
           ''' This flag can only be combined with the 'KEYEVENTF_KEYUP' flag.
           ''' </summary>
           Unicode = &H4

       End Enum

#End Region

#Region " Structures "

       ''' <summary>
       ''' Used by 'SendInput' function
       ''' to store information for synthesizing input events such as keystrokes, mouse movement, and mouse clicks.
       ''' For more info see here:
       ''' http://msdn.microsoft.com/en-us/library/windows/desktop/ms646270%28v=vs.85%29.aspx
       ''' </summary>
       <Description("Structure used for 'INPUT' parameter of 'SendInput' API method")>
       <StructLayout(LayoutKind.Explicit)>
       Friend Structure INPUT

           ' ******
           '  NOTE
           ' ******
           ' Field offset for 32 bit machine: 4
           ' Field offset for 64 bit machine: 8

           ''' <summary>
           ''' The type of the input event.
           ''' </summary>
           <FieldOffset(0)>
           Public type As InputType

           ''' <summary>
           ''' The information about a simulated mouse event.
           ''' </summary>
           <FieldOffset(8)>
           Public mi As MOUSEINPUT

           ''' <summary>
           ''' The information about a simulated keyboard event.
           ''' </summary>
           <FieldOffset(8)>
           Public ki As KEYBDINPUT

           ''' <summary>
           ''' The information about a simulated hardware event.
           ''' </summary>
           <FieldOffset(8)>
           Public hi As HARDWAREINPUT

       End Structure

       ''' <summary>
       ''' Contains information about a simulated mouse event.
       ''' For more info see here:
       ''' http://msdn.microsoft.com/en-us/library/windows/desktop/ms646273%28v=vs.85%29.aspx
       ''' </summary>
       <Description("Structure used for 'mi' parameter of 'INPUT' structure")>
       Friend Structure MOUSEINPUT

           ''' <summary>
           '''
           ''' </summary>
           Public dx As Integer

           ''' <summary>
           '''
           ''' </summary>
           Public dy As Integer

           ''' <summary>
           '''
           ''' </summary>
           Public mouseData As Integer

           ''' <summary>
           '''
           ''' </summary>
           Public dwFlags As Integer

           ''' <summary>
           '''
           ''' </summary>
           Public time As Integer

           ''' <summary>
           '''
           ''' </summary>
           Public dwExtraInfo As IntPtr

       End Structure

       ''' <summary>
       ''' Contains information about a simulated keyboard event.
       ''' For more info see here:
       ''' http://msdn.microsoft.com/en-us/library/windows/desktop/ms646271%28v=vs.85%29.aspx
       ''' </summary>
       <Description("Structure used for 'ki' parameter of 'INPUT' structure")>
       Friend Structure KEYBDINPUT

           ''' <summary>
           ''' A virtual-key code.
           ''' The code must be a value in the range '1' to '254'.
           ''' If the 'dwFlags' member specifies 'KEYEVENTF_UNICODE', wVk must be '0'.
           ''' </summary>
           Public wVk As Short

           ''' <summary>
           ''' A hardware scan code for the key.
           ''' If 'dwFlags' specifies 'KEYEVENTF_UNICODE',
           ''' 'wScan' specifies a Unicode character which is to be sent to the foreground application.
           ''' </summary>
           Public wScan As Short

           ''' <summary>
           ''' Specifies various aspects of a keystroke.
           ''' </summary>
           Public dwFlags As KeyboardInput_Flags

           ''' <summary>
           ''' The time stamp for the event, in milliseconds.
           ''' If this parameter is '0', the system will provide its own time stamp.
           ''' </summary>
           Public time As Integer

           ''' <summary>
           ''' An additional value associated with the keystroke.
           ''' Use the 'GetMessageExtraInfo' function to obtain this information.
           ''' </summary>
           Public dwExtraInfo As IntPtr

       End Structure

       ''' <summary>
       ''' Contains information about a simulated message generated by an input device other than a keyboard or mouse.
       ''' For more info see here:
       ''' http://msdn.microsoft.com/en-us/library/windows/desktop/ms646269%28v=vs.85%29.aspx
       ''' </summary>
       <Description("Structure used for 'hi' parameter of 'INPUT' structure")>
       Friend Structure HARDWAREINPUT

           ''' <summary>
           ''' The message generated by the input hardware.
           ''' </summary>
           Public uMsg As Integer

           ''' <summary>
           ''' The low-order word of the lParam parameter for uMsg.
           ''' </summary>
           Public wParamL As Short

           ''' <summary>
           ''' The high-order word of the lParam parameter for uMsg.
           ''' </summary>
           Public wParamH As Short

       End Structure

#End Region

   End Class

#End Region

#Region " Public Methods "

   ''' <summary>
   ''' Sends a keystroke.
   ''' </summary>
   ''' <param name="key">
   ''' Indicates the keystroke to simulate.
   ''' </param>
   ''' <param name="BlockInput">
   ''' If set to <c>true</c>, the keyboard and mouse are blocked until the keystroke is sent.
   ''' </param>
   ''' <returns>
   ''' The function returns the number of events that it successfully
   ''' inserted into the keyboard or mouse input stream.
   ''' If the function returns zero, the input was already blocked by another thread.
   ''' </returns>
   Public Shared Function SendKey(ByVal key As Char,
                                  Optional BlockInput As Boolean = False) As Integer

       ' Block Keyboard and mouse.
       If BlockInput Then NativeMethods.BlockInput(True)

       ' The inputs structures to send.
       Dim Inputs As New List(Of NativeMethods.INPUT)

       ' The current input to add into the Inputs list.
       Dim CurrentInput As New NativeMethods.INPUT

       ' Determines whether a character is an alphabetic letter.
       Dim IsAlphabetic As Boolean = Not (key.ToString.ToUpper = key.ToString.ToLower)

       ' Determines whether a character is an uppercase alphabetic letter.
       Dim IsUpperCase As Boolean =
           (key.ToString = key.ToString.ToUpper) AndAlso Not (key.ToString.ToUpper = key.ToString.ToLower)

       ' Determines whether the CapsLock key is pressed down.
       Dim CapsLockON As Boolean = My.Computer.Keyboard.CapsLock

       ' Set the passed key to upper-case.
       If IsAlphabetic AndAlso Not IsUpperCase Then
           key = Convert.ToChar(key.ToString.ToUpper)
       End If

       ' If character is UpperCase and CapsLock is pressed down,
       ' OrElse character is not UpperCase and CapsLock is not pressed down.
       If (IsAlphabetic AndAlso IsUpperCase AndAlso CapsLockON) _
       OrElse (IsAlphabetic AndAlso Not IsUpperCase AndAlso Not CapsLockON) _
       OrElse (Not IsAlphabetic) Then

           ' Hold the character key.
           With CurrentInput
               .type = NativeMethods.InputType.Keyboard
               .ki.wVk = Convert.ToInt16(CChar(key))
               .ki.dwFlags = 0
           End With : Inputs.Add(CurrentInput)

           ' Release the character key.
           With CurrentInput
               .type = NativeMethods.InputType.Keyboard
               .ki.wVk = Convert.ToInt16(CChar(key))
               .ki.dwFlags = NativeMethods.KeyboardInput_Flags.KeyUp
           End With : Inputs.Add(CurrentInput)

           ' If character is UpperCase and CapsLock is not pressed down,
           ' OrElse character is not UpperCase and CapsLock is pressed down.
       ElseIf (IsAlphabetic AndAlso IsUpperCase AndAlso Not CapsLockON) _
       OrElse (IsAlphabetic AndAlso Not IsUpperCase AndAlso CapsLockON) Then

           ' Hold the Shift key.
           With CurrentInput
               .type = NativeMethods.InputType.Keyboard
               .ki.wVk = NativeMethods.VirtualKeys.SHIFT
               .ki.dwFlags = NativeMethods.KeyboardInput_Flags.KeyDown
           End With : Inputs.Add(CurrentInput)

           ' Hold the character key.
           With CurrentInput
               .type = NativeMethods.InputType.Keyboard
               .ki.wVk = Convert.ToInt16(CChar(key))
               .ki.dwFlags = NativeMethods.KeyboardInput_Flags.KeyDown
           End With : Inputs.Add(CurrentInput)

           ' Release the character key.
           With CurrentInput
               .type = NativeMethods.InputType.Keyboard
               .ki.wVk = Convert.ToInt16(CChar(key))
               .ki.dwFlags = NativeMethods.KeyboardInput_Flags.KeyUp
           End With : Inputs.Add(CurrentInput)

           ' Release the Shift key.
           With CurrentInput
               .type = NativeMethods.InputType.Keyboard
               .ki.wVk = NativeMethods.VirtualKeys.SHIFT
               .ki.dwFlags = NativeMethods.KeyboardInput_Flags.KeyUp
           End With : Inputs.Add(CurrentInput)

       End If ' UpperCase And My.Computer.Keyboard.CapsLock is...

       ' Send the input key.
       Return NativeMethods.SendInput(Inputs.Count, Inputs.ToArray,
                                      Marshal.SizeOf(GetType(NativeMethods.INPUT)))

       ' Unblock Keyboard and mouse.
       If BlockInput Then NativeMethods.BlockInput(False)

   End Function

   ''' <summary>
   ''' Sends a keystroke.
   ''' </summary>
   ''' <param name="key">
   ''' Indicates the keystroke to simulate.
   ''' </param>
   ''' <param name="BlockInput">
   ''' If set to <c>true</c>, the keyboard and mouse are blocked until the keystroke is sent.
   ''' </param>
   ''' <returns>
   ''' The function returns the number of events that it successfully
   ''' inserted into the keyboard or mouse input stream.
   ''' If the function returns zero, the input was already blocked by another thread.
   ''' </returns>
   Public Shared Function SendKey(ByVal key As Keys,
                                  Optional BlockInput As Boolean = False) As Integer

       Return SendKey(Convert.ToChar(key), BlockInput)

   End Function

   ''' <summary>
   ''' Sends a string.
   ''' </summary>
   ''' <param name="String">
   ''' Indicates the string to send.
   ''' </param>
   ''' <param name="BlockInput">
   ''' If set to <c>true</c>, the keyboard and mouse are blocked until the keystroke is sent.
   ''' </param>
   ''' <returns>
   ''' The function returns the number of events that it successfully
   ''' inserted into the keyboard or mouse input stream.
   ''' If the function returns zero, the input was already blocked by another thread.
   ''' </returns>
   Public Shared Function SendKeys(ByVal [String] As String,
                                   Optional BlockInput As Boolean = False) As Integer

       Dim SuccessCount As Integer = 0

       ' Block Keyboard and mouse.
       If BlockInput Then NativeMethods.BlockInput(True)

       For Each c As Char In [String]
           SuccessCount += SendKey(c, BlockInput:=False)
       Next c

       ' Unblock Keyboard and mouse.
       If BlockInput Then NativeMethods.BlockInput(False)

       Return SuccessCount

   End Function

#End Region

End Class


Saludos