none
SetWindowsHookEx desde Managed C++ RRS feed

  • Pregunta

  •  Hola

    Debido a la necisidad dle programa, tengo que capturar todos los enventos del teclado, me he creado una Dll en C++ que funciona sin ningun problema, el problema viene al ser llamada desde Managed C++
    Intento usar la API SetWindowsHookEx No hay forma.

    He probado por dos metodos distintos, metiendo codigo no managed:
    #include "stdafx.h"  
    #pragma unmanaged  
     
    #include <windows.h> 
    #include <stdio.h> 
     
    typedef  LRESULT (CALLBACK *HPROC)(int , WPARAM , LPARAM );  
     
    bool lalaLoadDllKeyboard()  
    {  
          
        HOOKPROC hkprcSysMsg;   
        HPROC hkprcSysMsg2;   
        HINSTANCE hinstDLL;   
        HHOOK hhookSysMsg;    
       
        hinstDLL = LoadLibrary( "keyboard.dll");   
        if ( hinstDLL != NULL)  
        {  
     
            hkprcSysMsg2 = (HPROC)GetProcAddress(hinstDLL, "_keyboardHookProc@12");   
            if ( hkprcSysMsg2 != NULL)  
            {  
                OutputDebugString ( "2> OK\n");  
                  
                //hhookSysMsg = SetWindowsHookEx(WH_KEYBOARD_LL,hkprcSysMsg2,hinstDLL,LocalhPrevInstance); // original  
                hhookSysMsg = SetWindowsHookEx(WH_KEYBOARD_LL,hkprcSysMsg2,hinstDLL,0); // original  
                if( hhookSysMsg != NULL)  
                {  
                    OutputDebugString ( "3> OK\n");  
                    return true;  
                }  
            }  
        }  
        return false;  
     
    }  
     
    #pragma managed 

    Error de compilacion:
    1>------ Operación Generar iniciada: proyecto: WinFormsHookKeyboard, configuración: Debug Win32 ------  
    1>Vinculando...  
    1>codeunamanged.obj : error LNK2019: símbolo externo _SetWindowsHookExA@16 sin resolver al que se hace referencia en la función "bool __cdecl lalaLoadDllKeyboard(void)" (?lalaLoadDllKeyboard@@YA_NXZ)  
    1>H:\Test SRC\WinFormsHookKeyboard\Debug\WinFormsHookKeyboard.exe : fatal error LNK1120: 1 externos sin resolver  
    1>El registro de compilación se guardó en el "file://h:\Test SRC\WinFormsHookKeyboard\WinFormsHookKeyboard\Debug\BuildLog.htm"  
    1>WinFormsHookKeyboard - 2 errores, 0 advertencias 
    ========== Generar: 0 correctos, 1 incorrectos, 0 actualizados, 0 omitidos ==========  
     

    Otra forma seria llamado a la api http://msdn.microsoft.com/en-us/library/ms644990(VS.85).aspx pero no idea de como implementarlo en proyecto.
    #ifndef KeyboardHook_H  
    #define KeyboardHook_H  
     
     
    namespace CapitanHook  
    {  
        using namespace System;  
        using namespace System::Threading;  
        using namespace System::Runtime::InteropServices;  
        using namespace System::Diagnostics;  
     
     
     
        ref class keyboardHook  
        {  
        public:  
              
            [DllImport("user32.dll")]   
            static int SetWindowsHookEx(int idHook, HOOKPROC lpfn, HINSTANCE hMod,DWORD dwThreadId);  
        private:  
        };  
     
    }  
     
    #endif 
     
    He probado a ponerlo  asi pero ciertamente no se si es correcto o no, despues estan los tipos HOOKPROC y HINSTANCE  que ni idea como ponerlos en Managed C++

    Espero haberme explicado correctamente

    Un saludo y gracias.
    domingo, 1 de febrero de 2009 22:02

Todas las respuestas

  • Hola Zyklon,

    Para hacer un hook te recomiendo que uses un proyecto C++ normal, en tu caso una DLL.
    Esto te permitirá llamar directamente a la función SetWindowsHookEx puesto que la mayoría de proyectos incluyen automáticamente a Windows.h y enlazan con userlib32.lib. 
    Tendrás que proporcionar una función para la gestión de los eventos y otra parte de tu lógica instalará el hook mediante SetWindowsHookEx.
    Parece que el tipo de hook que deseas hacer es  WH_KEYBOARD_LL. Este tipo de hook es global por lo que tendrás que hacer una DLL que exporte la función del hook, que tendrá la siguiente firma:

    LRESULT CALLBACK LowLevelKeyboardProc(int nCode,WPARAM wParam,LPARAM lParam)
    {
         // Pon tu código aquí
        // Es recomendable que llames a CallNextHookEx (y obligado si nCode es <0
    }

    La documentación de esta función puedes consultarla en:
    http://msdn.microsoft.com/en-us/library/ms644985(VS.85).aspx

    Por el contrario, si deseas hacerlo en C#, la dificultad estará en importar las llamadas nativas para poder usarlas desde C#.
    He encontrado este artículo que creo que puede ser de utilidad,
    http://www.preguntaalexperto.net/articles/lontivero-Capturando-eventos-del-teclado-con-las-API-de-Windows-y-C.aspx

    Saludos



     

    Si este mensaje responde a tu pregunta, márcalo como respuesta correcta o vótalo como útil.
    Sergio Ortiz
    i-Card Software CTO
    sábado, 18 de abril de 2009 14:28