chhook


Normalerweise kann die eigene Anwendung nur solche Ereignisse empfangen, die für sie bestimmt sind. Ein Mausklick auf dem Desktop beispielsweise führt nicht dazu, dass die Anwendung reagiert.

Um dies zu erreichen, ist ein Systemhook einzurichten. Dieser wird über die WIN 32 API Funktion SetWindowsHookEx gesetzt und mit UnhookWindowsHookEx wieder gelöscht. Dabei kann dann angegeben werden, welche Ereignistypen beachtet werden sollen, welcher Funktion aufgerufen werden sollen. Hookfunktionen sind grundsätzlich in einer DLL bereitzustellen.

Diese DLL stellt nun einfache Funktionen zur Verfügung um bestimmte systemweite Tastaturereignisse and die eigene Anwendung zu senden.

Funktionen der DLL bezüglich der Tastaturereignisse

Die DLL hat für den Anwender zwei Funktionen für die Tastaturereignisse:

Die erste Funktion startet den Hook für die Tastatur, die zweite beendet ihn wieder.

Parameter der ersten Funktion

HWND handle Das Handle des Fensters, an den die Nachricht über das Tastaturereignis geschickt wird. Die DLL sendet ein KEYDOWN Ereignis an das Fenster
WORD key Der virtuelle Keycode der Taste. (Achtung die Sondertasten haben zwar einen virtuellen Keycode. aber dieser wird nicht über WM_KEYDOWN erfasst.
Wird 0 als Parameter übergeben, werden alle Tastendrücke gesandt.
sKeys s Hier kann die Sondertaste angegeben werden:
KEY_NONE keine Sondertaste
KEY_SHIFT Shifttaste
KEY_STRG STRG-Taste
KEY_ALT ALT-Taste

Parameter der zweiten Funktion

Die zweite Funktion hat keine Parameter.

Nutzung des Tastaturhooks im eigenen Programm

Hierzu ist die DLL entweder statisch oder dynamisch in das Programm aufzunehmem

Danach muss zunächst die Hookfunktion aktiviert werden. Die beste Möglichkeit ist im ONCREATE Ereignis des Fomulars:

void __fastcall TForm1::FormCreate(TObject *Sender)
{

StartTastaturHook(Form1->Handle,66,KEY_NONE);
}
//---------------------------------------------------------------------------

Im obigen Beispiel wird auf den Druck der Taste "B" gewartet. Eine Sondertaste ist nicht erwünscht. Das Handle des Fensters wir von der VCL bequem bereitgestellt.

void __fastcall TForm1::FormCreate(TObject *Sender)
{

StartTastaturHook(Form1->Handle,65,KEY_ALT);
}
//---------------------------------------------------------------------------

Obiges Beispiel zeigt, wie auf den Tastendruck "A+ALT" gewartet.

Nun soll ja etwas passieren, wenn die von uns gewünschte Taste gedrückt wird. Da die DLL ein KEYDOWN Ereignis erzeugt, richten wir dieses ein .
Das KEYDOWN Ereignis für die Taste "B"

void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,TShiftState Shift)
{
if(Key==66)
	{
	ShowMessage("Tastatur");
	}
}
//---------------------------------------------------------------------------

Das KEYDOWN Ereignis für die Tasten "A+ALT"

void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,TShiftState Shift)
{
if(Key==65&&Shift.Contains(ssAlt))
	{
	ShowMessage("Tastatur");
	}
}
//---------------------------------------------------------------------------

Wird der Hook nicht mehr benötigt, so ist dieser aus dem System zu entfernen. Das geschieht am Besten im CLOSE Ereignis des Formulars:

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
StopTastaturHook();
}
//---------------------------------------------------------------------------


Das ist natürlich nicht alles was man mit den Tastaturereignissen anstellen kann, aber für den Anfänger sollte das erst mal ausreichen. Bei Gelegenheit werde ich die DLL um weitere Ereignistypen (Maus, usw.) erweitern.



Funktionen der DLL bezüglich der Mausereignisse

Die DLL hat für den Anwender zwei Funktionen für die Tastaturereignisse:

Die erste Funktion startet den Hook für die Maus, die zweite beendet ihn wieder.

Parameter der ersten Funktion

HWND handle Das Handle des Fensters, an den die Nachricht über das Tastaturereignis geschickt wird. Die DLL sendet ein KEYDOWN Ereignis an das Fenster
int mess Nummer der Nachricht, an die die Ereignisse gesandt werden
bool move=false Hier kann die Sondertaste angegeben werden, ob auch "nur" Mausbewegungen gemeldet werden, In der Voreinstellung werden keine "nur" Mausbewegungen gemeldet.

Parameter der zweiten Funktion

Die zweite Funktion hat keine Parameter.

Nutzung des Maushooks im eigenen Programm

Hierzu ist die DLL entweder statisch oder dynamisch in das Programm aufzunehmem

Danach muss zunächst die Hookfunktion aktiviert werden. Die beste Möglichkeit ist im ONCREATE Ereignis des Fomulars:

void __fastcall TForm1::FormCreate(TObject *Sender)
{

StartMausHook(Form1->Handle,10);

}
//---------------------------------------------------------------------------

Hier ist die 10 als Nachrichtennummer angegeben worden. Es macht keinen Sinn, die Mausereignisse des ganzen System als Mausereignis an die eigene Anwendung weiterzuleiten. Hier muss eine "eigene" Botschaft her. Im folgenden wird beschrieben, wie eine eigene Message im C++Builder erstellt wird. Eigene Botschaften haben immer einen Wert. Dieser wir gebildet aus WM_USER+Wert. Dieser Wert ist die Nachrichtennummer, die im Aufruf "StartMausHook" angegeben wird. Eine eigene Message wird in der HEADER Datei des Formulars definiert. Im folgenden die Headerdatei (die roten Zeilen sind einzufügen):

//---------------------------------------------------------------------------

#ifndef UnitMainH
#define UnitMainH
//---------------------------------------------------------------------------
#include 
#include 
#include 
#include 

#define MYMESSAGE WM_USER + 10            //neu


//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// Von der IDE verwaltete Komponenten
	TButton *Button1;
	TButton *Button2;
	void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
	void __fastcall FormKeyDown(TObject *Sender, WORD &Key,
          TShiftState Shift);
	void __fastcall Button1Click(TObject *Sender);
	void __fastcall Button2Click(TObject *Sender);
private:	// Anwender-Deklarationen
 void __fastcall OnMyMessage(TMessage& Message);    //neu
public:		// Anwender-Deklarationen
	__fastcall TForm1(TComponent* Owner);

BEGIN_MESSAGE_MAP                                       //neu
MESSAGE_HANDLER(MYMESSAGE, TMessage, OnMyMessage)      //neu
END_MESSAGE_MAP(TForm)                                 //neu
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

Mit diesen Einstellungen in der Headerdatei wird eine neue Message mit dem Namen MYMESSAGE definiert. Alle eingehenden Nachrichten werden an die Funktion OnMyMessage der Klasse weitergeleitet werden.

Diese Funktion OnMyMessage existiert noch nicht. Diese wird in die CPP-Datei geschrieben:

void __fastcall TForm1::OnMyMessage(TMessage& Message)
{
int x,y;
String ausgabe;
switch(Message.WParam)
	{
	case WM_MOUSEWHEEL:
	if(Message.LParam==1)
		ausgabe="Rad vorwärts";
	else if(Message.LParam==-1)
		ausgabe="Rad rückwärts";
	break;

	case WM_LBUTTONDOWN:
	x=Message.LParamLo;    //Maus X
	y=Message.LParamHi;   //Maus Y
	ausgabe=IntToStr(x)+":"+IntToStr(y)+" Linke Taste";
	break;

	case WM_RBUTTONDOWN:
	x=Message.LParamLo;    //Maus X
	y=Message.LParamHi;   //Maus Y
	ausgabe=IntToStr(x)+":"+IntToStr(y)+" Rechte Taste";
	break;
	}
ShowMessage(ausgabe);
}    //neu

Obiges Beispiel zeigt, wie die X und Y Koordinaten gelesen werden. Der Parameter Message.WParam enthält die Botschaft. Hier werden nur 2 Botschaften (WM_LBUTTONDOWN und WM_RBUTTONDOWN) gesucht. Es gibt noch viele andere die gesandt werden.

Wird der Hook nicht mehr benötigt, so ist dieser aus dem System zu entfernen. Das geschieht am Besten im CLOSE Ereignis des Formulars:

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
StopMausHook();
}
//---------------------------------------------------------------------------

Download

chhook.dll 67 KB

Revision

1.7.0.74 WM_MOUSEWHEEL berücksichtigt
1.7.0.62 Migration auf C++ Builder 2006