Programa que pulse "X" tecla en "Y" ventanas/procesos

Iniciado por bySprigans, 30 Septiembre 2017, 15:07 PM

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

bySprigans

Hola buenas,

Es la primera vez que búsco algo en específico ya que no he encontrado nada esclarecedor por la red ( a ver he estado como 10 - 15 min en inlgés y español y no he encontrado nada útil, quizá lo he pasado por alto pero... vamos creo que no he encontrado nada que me ayude...)
Hace poco me he puesto a jugar a Wakfu (un juego por turnos) y tengo un par de cuentas ahora mism. La cosa es que las cuentas de nivel bajo las tengo subiendo con otra cuenta que tiene nivel más alto, lo bueno es que el juego tiene una función de entrar por defecto en todos los combates lanzados si estás en grupo, entonces estas cuentas de nivel bajo con simplemente pulsar el espacio pasan turno en ese combate.

Y aquí viene mi duda:

Existe algún programa o sería posible programar algo fácil (sé un poco pero lo básico vamos...), algo que le diese a "X" tecla en este caso "espacio" para "Y" proceso (sería un coñazo tener que estar cambiando el proceso en el programa por que imagino que serán distintos por cada vez que lanzas el juego en el launcher por cuenta, no lo he mirado bien aún) o para "Y" ventana (esto sería más fácil, pero supongo que más complejo de programar).

Bueno no sé si me he explicado con claridad (lo he intendado :P), estaré pendiente por si me respondeis lo que sea, espero vuestra ayuda. Muchas gracias :)

Saludos.

PD; No sé si el tema está bien ubicado...

Eleкtro

#1
Cita de: bySprigans en 30 Septiembre 2017, 15:07 PM¿ sería posible programar (...) algo que le diese a "X" tecla (...) para "Y" ventana ?

Cita de: bySprigans en 30 Septiembre 2017, 15:07 PMno he encontrado nada esclarecedor por la red ( a ver he estado como 10 - 15 min en inlgés y español y no he encontrado nada útil, quizá lo he pasado por alto pero... vamos creo que no he encontrado nada que me ayude...)

Hola.

Si, es posible, y no es algo complejo de realizar, pero si reconoces que solo eres capaz de dedicarle entre 10 a 15 minutos para llevar a cabo una simple investigación (como si eso fuese un gran esfuerzo... lo que algunas personas le dedican a leer la primera página del periódico cada mañana), dudo mucho que seas capaz de invertir el tiempo suficiente para aprender un lenguaje de programación a nivel usuario junto a los conceptos básicos de la programación de la API de Windows (incluyendo colas de mensajes, mensajes de ventana y teclas virtuales) para llevar a cabo ese tipo de tarea.

Respondiendo a tu pregunta: por lo que he entendido lo que pretendes es simular la pulsación de una tecla en una ventana que no tiene el foco de entrada (o input focus por su nombre en Inglés), bien, eso puedes hacerlo con las funciones SendMessage y PostMessage de la API de Windows dependiendo de la situación/circunstancias (la primera función es sincrónica y la otra asincrónica). También puedes utilizar otras funciones (como SendMessageTimeOut y en otras circunstancias SendNotifyMessage), además en otras circunstancias tal vez quisieras darle foco a la ventana objetivo y usar la función SendInput para enviar composiciones de teclas, pero para el caso que nos concierne a esta pregunta la función más conveniente en un principio sería PostMessage.

No has especificado un lenguaje de programación, así que te explico la solución a modo de pseudocódigo:

Declare Constant WINDOW_MESSAGE_KEYDOWN = 256
Declare Constant VIRTUAL_KEY_SPACE = 32

Declare Variable process = GetProcess("nombre de proceso")
Declare Variable windowHandle = GetWindowHandle(process)

Call PostMessage(windowHandle, WINDOW_MESSAGE_KEYDOWN, VIRTUAL_KEY_SPACE, null)


Esto traducido a VB.NET sería más o menos tal que así:

Código (vbnet) [Seleccionar]
Imports System.ComponentModel
Imports System.Linq
Imports System.Runtime.InteropServices
Imports System.Security


Código (vbnet) [Seleccionar]
Const WM_KeyDown As Integer = 256 'https://msdn.microsoft.com/en-us/library/windows/desktop/ms646280(v=vs.85).aspx
Const VK_Space As Integer = 32    'https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
' WindowsForms: VK_Space As Integer = System.Windows.Forms.Keys.Space
' WPF: VK_Space As Integer = System.Windows.Input.KeyInterop.VirtualKeyFromKey(System.Windows.Input.Key.Space)

Using p As Process = Process.GetProcessesByName("nombre del proceso").SingleOrDefault()
   If (p IsNot Nothing) Then

       Dim result As Boolean = NativeMethods.PostMessage(p.MainWindowHandle, WM_KeyDown, New IntPtr(VK_Space), IntPtr.Zero)
       If Not (result) Then
           Throw New Win32Exception(Marshal.GetLastWin32Error())
       End If

   End If
End Using


Código (vbnet) [Seleccionar]
' https://docs.microsoft.com/en-us/visualstudio/code-quality/ca1060-move-p-invokes-to-nativemethods-class
Friend NotInheritable Class NativeMethods
   Private Sub New()
   End Sub

   ' https://msdn.microsoft.com/es-es/library/windows/desktop/ms644944(v=vs.85).aspx
   <SuppressUnmanagedCodeSecurity>
   <DllImport("User32.dll", SetLastError:=True)>
   Friend Shared Function PostMessage(
        hWnd As IntPtr, msg As Integer, wParam As IntPtr, lParam As IntPtr
   ) As <MarshalAs(UnmanagedType.Bool)> Boolean
   End Function
End Class


PD: Si deseas traducir el código de arriba al lenguaje C#, puedes utilizar mi aplicación gratuita:




EDITO: La alternativa a la programación sería utilizar cualquier grabador de macros, como por ejemplo JitBit Macro Recorder:
...dicho programa provee una amplia diversidad de características, entre ellas: localizar ventanas según el título de ventana de ésta y enviar pulsacioens del teclado, pero también vas a tener que necesitar invertir su debido tiempo en aprender como crear una macro... ya que se asemeja ligeramente a la creación de un script de programación (en el JitBit Macro Recorder puedes crear "bloques" de condicionales IF, búcles FOR y etiquetas GOTO).



Saludos.








bySprigans

Muchísimas gracias, pero tienes razón, veo que esto escapa a mis conocimientos (por el momento), intentaré invertir más tiempo en aprender lo que pueda y retomaré las indicaciones que me has dado dentro de unos meses; Probaré lo del macro que tiene pinta de ser más sencillo, pero imagino que a la larga acabaré consiguiendo programar lo que me dices.

Gracias de nuevo por tu tiempo la próxima vez investigaré más tiempo al buscar lo que necesito (más de lo que tarda alguien en leer el periódico por la mañana  :laugh:).

Saludos :) :)