Probleme mit SetWindowsHookEx



  • Hallo zusammen!

    Ich verwende in einer dialogbasierten anwendung mit vc++.net die methode SetWindowsHookEx() um auf eine keyboardeingabe zu reagieren. Die methode läßt sich initialisieren, das hab ich kontrolliert, aber wenn ich eine taste drücke passiert nichts. vielleicht hat jemand eine ahnung was ich vergessen habe?

    mein code:

    Das ist der Aufruf irgendwo im Programm.

    HHOOK hookreturn; /*ist global angelegt.*/
    
    hookreturn = SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,(HINSTANCE) NULL,GetCurrentThreadId())
    

    Davor steht die dazugehörige callback funktion:

    LRESULT CALLBACK KeyboardProc(int code,WPARAM wParam,LPARAM lParam)
    {
    	AfxMessageBox("irgendwas");
    	return CallNextHookEx(hookreturn,code,wParam,lParam);
    }
    

    nach meinem Verständnis sollte wenn jetzt eine taste gedrückt wird die callbackfunktion aufgerufen werden oder? Tut sie aber nicht.

    kann mir vielleicht jemand helfen, wäre überaus dankbar 😉

    lg,l00P



  • ...habe gerade herausgefunden das es in einem leeren mini-dialog programm schon funktioniert, das problem ist nur das ich gerade eien sdl-Window offen habe und darin zeichne. ich nehme mal an ich muß der funktion SetWindowsHookEx() den threadhandle des sdl screens geben. aber wie bekomme ich den.?!?

    Ich habs mal mit GetThreadId(handleToSdlScreen) versucht. läßt sich kompilieren, gibt aber gleich nach dem start folgende fehlermeldung in einer art messagebox aus:

    "The procedure entry point GetThreadId could not be located in the dynamic link library KERNEL32.dll"

    weiß jemand darüber bescheid?!?

    danke schonmal



  • Hallo,

    dafür brauchst du keinen Handle auf das SDI-Fenster.

    Ich würde den Hook im Mainframe erstellen.

    // MainFrm.cpp : Implementierung der Klasse CMainFrame
    //
    
    #include "stdafx.h"
    #include "KeyHook.h"
    
    #include "MainFrm.h"
    
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif
    
    // CMainFrame
    
    IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
    
    BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
    	ON_WM_CREATE()
    	ON_WM_DESTROY()
    END_MESSAGE_MAP()
    
    static UINT indicators[] =
    {
    	ID_SEPARATOR,           // Statusleistenanzeige
    	ID_INDICATOR_CAPS,
    	ID_INDICATOR_NUM,
    	ID_INDICATOR_SCRL,
    };
    
    // Globaler Keyboard Hookhandle
    HHOOK g_hKeyHook;
    
    // Keyboard Hook-Prozedur
    LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
    	return ::CallNextHookEx(g_hKeyHook, nCode, wParam, lParam);
    }
    
    // CMainFrame Erstellung/Zerstörung
    
    CMainFrame::CMainFrame()
    {
    	// TODO: Hier Code für die Memberinitialisierung einfügen
    }
    
    CMainFrame::~CMainFrame()
    {
    }
    
    int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
    	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
    		return -1;
    
    	if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
    		| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
    		!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
    	{
    		TRACE0("Symbolleiste konnte nicht erstellt werden\n");
    		return -1;      // Fehler bei Erstellung
    	}
    
    	if (!m_wndStatusBar.Create(this) ||
    		!m_wndStatusBar.SetIndicators(indicators,
    		  sizeof(indicators)/sizeof(UINT)))
    	{
    		TRACE0("Statusleiste konnte nicht erstellt werden\n");
    		return -1;      // Fehler bei Erstellung
    	}
    	// TODO: Löschen Sie diese drei Zeilen, wenn Sie nicht möchten, dass die Systemleiste andockbar ist
    	m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
    	EnableDocking(CBRS_ALIGN_ANY);
    	DockControlBar(&m_wndToolBar);
    
    	// erstelle Keyboardhook
    	g_hKeyHook = ::SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, NULL, ::GetCurrentThreadId());
    
    	return 0;
    }
    
    BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
    {
    	if( !CFrameWnd::PreCreateWindow(cs) )
    		return FALSE;
    	// TODO: Ändern Sie hier die Fensterklasse oder die Darstellung, indem Sie
    	//  CREATESTRUCT cs modifizieren.
    
    	return TRUE;
    }
    
    // CMainFrame Diagnose
    
    #ifdef _DEBUG
    void CMainFrame::AssertValid() const
    {
    	CFrameWnd::AssertValid();
    }
    
    void CMainFrame::Dump(CDumpContext& dc) const
    {
    	CFrameWnd::Dump(dc);
    }
    
    #endif //_DEBUG
    
    // CMainFrame Meldungshandler
    
    void CMainFrame::OnDestroy()
    {
    	CFrameWnd::OnDestroy();
    
    	// Hook zerstören
    
    	::UnhookWindowsHookEx(g_hKeyHook);
    }
    

    So sollte es funktionieren.

    Gruss



  • such mal unter hooks in diesem Forum - Ernsti hat ne schräge Übersicht - welche stark ! FAQ würdig ist !!! geschrieben -



  • ... so die funktion läuft schon mal, !ABER! - alle tastenanschläge werden gebuffert und erst am ende der anwendung an die callbackfunktion übergeben - wie geht das denn?!? ich dachte jedesmal wenn eine taste gedrückt wird wird die callback aufgerufen oder irre ich mich da?!?

    danke


Anmelden zum Antworten