[Post Migrado] Emular key-strokes en una aplicación DirectX - DotNetClubs
en

DotNetClubs

Comunidades de estudiantes entusiastas de la tecnología

[Post Migrado] Emular key-strokes en una aplicación DirectX

Último artículo 01-18-2008 22:18 escrito por Manu_Leon. 8 respuestas.
Página 1 de 1 (9 elementos)
Ordenar mensajes: Anterior Siguiente
  • 01-18-2008 13:07

    • Csar
    • Contribuyente Top 10
    • Se unió el 07-31-2006
    • Albacete - Spain
    • Envíos: 96
    • Puntos: 520
    • DotNetClub_Coordinadores
      DotNetClub_Miembros

    [Post Migrado] Emular key-strokes en una aplicación DirectX

     [FROM iayucar]

    Esta mañana he recibido un email de un chavalote llamado Manu preguntando un temilla que igual le viene bien a otra gente, así que lo posteo aqui y la respuesta en el post siguiente:

    Manu:

    Quería probar a realizar un programa de macros para un videojuego (no es online, es de mi pc). El caso es que con juegos que usaban hasta directx 8, podía emular las pulsaciones de teclado con la funcion kb_event de la libreria user32 de windows. Pero a partir de directx 9 esto no me funciona. No entiendo mucho de directx asi que por eso te pregunto.

    Supongo que directx 8  leia de las APIs de Windows y que directx 9 lo hara directamente de hardware.

    ¿Hay forma de emular una pulsación de teclado para directx 9?. Supongo que el programa usará DirectInput

    Gracias por tu tiempo.

     

    César Reneses
    http://labloguera.net/blogs/csharp
    Coordinador Albacete DotNetClub
    • Puntos de post: 5
  • 01-18-2008 13:07 en respuesta a

    • Csar
    • Contribuyente Top 10
    • Se unió el 07-31-2006
    • Albacete - Spain
    • Envíos: 96
    • Puntos: 520
    • DotNetClub_Coordinadores
      DotNetClub_Miembros

    Re: [Post Migrado] Emular key-strokes en una aplicación DirectX

    [FROM iayucar]

    Pues la verdad es que es algo que nunca he tenido que hacer, pero he buscado un poco de info y he encontrado un buen link en uno de los mejores recursos para game-devs:

    http://www.gamedev.net/community/forums/topic.asp?topic_id=419710

    En ese thread del foro tienes toda una discusión del tema. Por la parte de abajo hay alguien que incluso se ha currado una clasecilla en C# para enviar entradas emuladas a una aplicación. Veo que toma como parámetros incluso los KeyCodes de DirectInput, así que en principio no deberías tener problema alguno con eso de que sea DirectX 9.

    Si alguien sabe más sobre este tema, please help manu.

    Thnks!

     

    César Reneses
    http://labloguera.net/blogs/csharp
    Coordinador Albacete DotNetClub
    • Puntos de post: 5
  • 01-18-2008 13:08 en respuesta a

    • Csar
    • Contribuyente Top 10
    • Se unió el 07-31-2006
    • Albacete - Spain
    • Envíos: 96
    • Puntos: 520
    • DotNetClub_Coordinadores
      DotNetClub_Miembros

    Re: [Post Migrado] Emular key-strokes en una aplicación DirectX

     [FROM Spear]

    Yo lo he hecho alguna vez en C++, te comento como debería hacerse... para usar Direct Input para leer el teclado, debería: Código en C++

    Variables necesarias:

    LPDIRECTINPUTDEVICE8 keyboard_device;

    char keyboard_state[ 256 ];

    Inicializar el teclado:

     HRESULT hr;
     if (FAILED(hr=direct_input->CreateDevice(GUID_SysKeyboard,&keyboard_device,NULL)))
      return;

     if (keyboard_device->SetDataFormat(&c_dfDIKeyboard))
      return;

     DWORD flags = 0;

      flags = DISCL_NONEXCLUSIVE;
      flags |= DISCL_BACKGROUND;

     if( keyboard_device->SetCooperativeLevel( hWnd, flags ) )
      return;

     if( keyboard_device )
      keyboard_device->Acquire( );

    update de teclado

     HRESULT hr = keyboard_device->GetDeviceState( sizeof( keyboard_state ), &keyboard_state );
     while( hr == DIERR_INPUTLOST  || hr == DIERR_NOTACQUIRED ) 
         hr = keyboard_device->Acquire( );

    para comprovar si una tecla ha sido pulsada

    bool isKeyPressed( int key ) const {

       return (keyboard_state[ key ] & 0x80) != 0;

    }


    Spear
    Web

     

    César Reneses
    http://labloguera.net/blogs/csharp
    Coordinador Albacete DotNetClub
    • Puntos de post: 5
  • 01-18-2008 13:08 en respuesta a

    • Csar
    • Contribuyente Top 10
    • Se unió el 07-31-2006
    • Albacete - Spain
    • Envíos: 96
    • Puntos: 520
    • DotNetClub_Coordinadores
      DotNetClub_Miembros

    Re: [Post Migrado] Emular key-strokes en una aplicación DirectX

     [FROM Manu_Leon]

    Saludos a Todos!!

    Gracias de verdad por vuestra ayuda. Era lo que buscaba. Espero que me funcione :) :)

     

    César Reneses
    http://labloguera.net/blogs/csharp
    Coordinador Albacete DotNetClub
    • Puntos de post: 5
  • 01-18-2008 13:09 en respuesta a

    • Csar
    • Contribuyente Top 10
    • Se unió el 07-31-2006
    • Albacete - Spain
    • Envíos: 96
    • Puntos: 520
    • DotNetClub_Coordinadores
      DotNetClub_Miembros

    Re: [Post Migrado] Emular key-strokes en una aplicación DirectX

    [FROM Spear]

    Te lo he puesto en C++, jeje, es que nunca lo he usado en C# la verdad. Smile

    Saludos,


    Spear
    Web

     

    César Reneses
    http://labloguera.net/blogs/csharp
    Coordinador Albacete DotNetClub
    • Puntos de post: 5
  • 01-18-2008 13:10 en respuesta a

    • Csar
    • Contribuyente Top 10
    • Se unió el 07-31-2006
    • Albacete - Spain
    • Envíos: 96
    • Puntos: 520
    • DotNetClub_Coordinadores
      DotNetClub_Miembros

    Re: [Post Migrado] Emular key-strokes en una aplicación DirectX

    [FROM iayucar]

    Aupa!

    Según entiendo yo, lo que este hombre busca es emular los key-strokes, más que leer del teclado. Es decir, llamar a una función que "engañe" a una aplicación para que piense que se ha pulsado una tecla.

    Es así Manu?

     

    César Reneses
    http://labloguera.net/blogs/csharp
    Coordinador Albacete DotNetClub
    • Puntos de post: 5
  • 01-18-2008 13:11 en respuesta a

    • Csar
    • Contribuyente Top 10
    • Se unió el 07-31-2006
    • Albacete - Spain
    • Envíos: 96
    • Puntos: 520
    • DotNetClub_Coordinadores
      DotNetClub_Miembros

    Re: [Post Migrado] Emular key-strokes en una aplicación DirectX

    [FROM Javi]

    Buenas Manu,

    si lo que intentas hacer como dice Iñaki es enviar pulsaciones de teclas desde una aplicación a otra. Te puedo contar un poco como se hace eso, ya que el año pasado estuve haciendo algunas frikadas relacionadas XD. En mi caso lo que quería era que el código fuente de una charla se escribiera solo en el visual studio mientras yo lo único que hacía era pulsar espacio XD (que flojo verdad), pues la gente lo flipaba cuando Alberto Sanchez me decía que escribiera de espaldas XD.

    Bueno no me enrollo más y te cuento como iba (En C#):

    Primero empecé a probar la instrucción SendKeys que puedes usar directamente:

    SendKeys.SendWait("2");

    Le colocas un timer de 1 segundo, arrancas la aplicación y abres el notepad podrás comprobar como cada segundo se escribe un 2 en el notepad.
    Si lo que quieres enviar son pulsaciones de teclas puedes mirar los códigos correspondientes en esta dirección: http://msdn2.microsoft.com/en-us/library/system.windows.forms.sendkeys.send(VS.80).aspx

    Una vez conseguido esto, puedes crearle un timer a la hora de empezar para que te dé tiempo a lanzar la otra aplicación. También puedes lanzar la otra aplicación desde tu código en C#. Esas pulsaciones de teclas las recibirá aquella aplicación que tenga el foco del sistema en cada momento.

    A lo mejor prefieres tener algo para activar y desactivar las pulsaciones de teclas aunque la aplicación no tenga el foco. Para ello tendrás que usar la Api de Win32 para acceder de forma asíncrona al teclado, para hacer esto desde C# puedes usar la técnica PInvoke, que se utiliza para comunicar librerías nativas con código C#, muy interesante para el desarrollo de wrappers (Cuidado que engancha XD).

    Bueno yo me puse a crear un wrapper de la API win32 de windows, pero para capturar de forma asíncrona teclas solo necesitarías usar estas funciones, te pego el código:

    [DllImport("User32.dll")]
    public static extern bool GetAsyncKeyState(Keys vKey);   //Si quieres usar los Keys de Windows Forms (Recomendado)
    [DllImport("user32.dll")]
    public static extern bool GetAsyncKeyState(System.Int32 vKey); //Si quieres usar los códigos de teclas directamente

    Luego para capturar si una tecla ha sido pulsada aunque la aplicación no tenga el foco, lo harías de la siguiente forma:

    if (GetAsyncKeyState(Keys.F8))
    // Para o activar el envio de teclas a la aplicación que tiene el foco

    Bueno y cabe una tercera posibilidad que es, arrancar tu aplicación, esta que busque entre las ventanas que están abiertas en el sistema, encuentre la tuya por el nombre, o que te muestre una lista y tu la selecciones. Y directamente le asignes el foco a esa aplicación y empieces a mandarle teclas.
    ¿Porque la tienes que buscar?, pues porque necesitas el handler de la ventana.

    Como puedes buscar la una ventana, pues te puedes traer todas las ventanas e ir filtrando aquellas que no están minimizadas por ejemplo, y que son visibles, porque al pedirle la lista a Win32 te devuelve todo y más XD.

    Bueno como buscar por nombre pues declarando esto:
    [DllImport("USER32.DLL")]
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    Por ejemplo busquemos si la calculadora de windows está abierta (en tu windows en spanish XD)
    IntPtr calculatorHandle = FindWindow(null, "Calculadora");
    if (calculatorHandle == IntPtr.Zero)
        //La Calculadora no está abierta
    else
        //La calculadora está abierta

    Ahora habría que aplicarle el foco del sistema, declaras la función:
    [DllImport("USER32.DLL")]
    public static extern bool SetForegroundWindow(IntPtr hWnd);

    Y luego llamandola de la siguiente forma:
    SetForegroundWindow(calculatorHandle);

    Y en ese momento esta aplicación tendrá el foco, el listar todas las ventanas visibles y que puedas seleccionar una a mano creo que lo puedes sacar sin que lo explique.

    Espero no haber aburrido a la peña XD, y espero Manu que te hayas enterado de la explicación si es esto lo que buscabas.

    Saludos


    www.codeplex.com/XNACommunity

     

    César Reneses
    http://labloguera.net/blogs/csharp
    Coordinador Albacete DotNetClub
    • Puntos de post: 5
  • 01-18-2008 13:11 en respuesta a

    • Csar
    • Contribuyente Top 10
    • Se unió el 07-31-2006
    • Albacete - Spain
    • Envíos: 96
    • Puntos: 520
    • DotNetClub_Coordinadores
      DotNetClub_Miembros

    Re: [Post Migrado] Emular key-strokes en una aplicación DirectX

    [FROM Javi]

    Vaya no me quería cargar el hilo con un post aburrido y largo :(. Estaria bien que respondiera Iñaki o Manu comentando si han conseguido lo que quería, y como lo ha solucionado.


    www.codeplex.com/XNACommunity

     

    César Reneses
    http://labloguera.net/blogs/csharp
    Coordinador Albacete DotNetClub
    • Puntos de post: 20
  • 01-18-2008 22:18 en respuesta a

    • Manu_Leon
    • Contribuyente Top 500
    • Se unió el 01-18-2008
    • Envíos: 1
    • Puntos: 5

    Re: [Post Migrado] Emular key-strokes en una aplicación DirectX

    Pues sí, quería emular key-strokes, como bien dicen, engañar al programa haciendole ver que pulsé el teclado. No era leer de teclado.ç

    Lo que sí me valió son los enlacesque puso Iñaki ;)

    El ejemplo que me pone Javi es precisamente algo como lo que yo tenía programado. Sendkeys no funciona.

    Hasta directx 8 se podía engañar al programa con kb_event, pero a partir de dx 9, supongo que dx9 leerá directamente de hardware evitando pasar pos las API de windows.

    Por eso ni Sendkeys ni kb_event funcionan con aplicaciones que leen el teclado con dx 9.

    El resultado es que si activas el bloc de notas, utro programa, sí que reciben las teclas, pero con un juego dx9, ni se inmuta.

    Por ello, supongo k no se puede evitar pasar por directx 9. Imagino que el programa usará DirectInput (aunque desconozco realmente si hay otros métodos), por lo que la questión no es mandar teclas a un programa, sino hacer una emulacion para que DirectInput (de directx9, ya digo que con 8 sí funcionaba), las lea. 

    En los enlaces que pasó Iñaki, pude ver mucha gente con mi mismo problema.

    Sigo investigando y si encuentro la solución la publico.

    Supongo que tendréque leerme la documentación de las librerías dx9 y ahí podréencontrar algo.

     Saludos y gracias por vuestra ayuda :):)

    • Puntos de post: 5
Página 1 de 1 (9 elementos)
(c) DotNetClubs 2008
Ofrecido por Community Server (Commercial Edition)