//----------------------*.dll-----------------------------------------------------
#include <windows.h>
#pragma hdrstop
// User defined Message-ID definieren
#define WM_MOUSEHOOK WM_USER+100
//---------------------------------------------------------------------------
// Funktionen deklarieren
extern "C" __declspec(dllexport) __stdcall void SetHook(HWND);
extern "C" __declspec(dllexport) __stdcall void RemoveHook(void);
extern "C" __declspec(dllexport) __stdcall MOUSEHOOKSTRUCT GetMouseData(void);
LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam);
//---------------------------------------------------------------------------
// Typ-Definitionen
struct HOOKSTRUCT
{
HWND hwnd;
MOUSEHOOKSTRUCT MouseHookStruct;
};
//---------------------------------------------------------------------------
// Globale Variablen
HHOOK ghHook = NULL; // Hook-Handle
HINSTANCE ghInst; // Instanz-Handle
LPVOID lpvMem = NULL; // Zeiger auf das shared memory
HOOKSTRUCT* pHookStruct = NULL;
//---------------------------------------------------------------------------
BOOL WINAPI DllEntryPoint(HINSTANCE hinst, DWORD reason, LPVOID)
{
HANDLE hMapFile = NULL; // Ein File-Mapping-Handle
BOOL bFirstProcess;
// Das Instanz-Handle der DLL speichern
// Wird unten in SetHook() benötigt
ghInst = hinst;
switch(reason)
{
// Die DLL wird in den Adressraum eines Prozesses geladen
case DLL_PROCESS_ATTACH:
{
// Ein File-Mapping-Objekt erstellen (mit Name)
// (wird nicht neu erstellt, wenn schon existent)
hMapFile = CreateFileMapping(
(HANDLE)0xFFFFFFFF, // Paging File benutzen
NULL, // Keine Security Attributes
PAGE_READWRITE, // read/write access
0, // Größe des Files (obere 32 Bit): 0
sizeof(HOOKSTRUCT), // Größe des Files (untere 32 Bit)
"DLLMemFileMap"); // Ein Name für unser File-Mapping-Objekt
if(hMapFile == NULL)
return FALSE;
// bFirstProcess == true nur im ersten ladenden Prozess
bFirstProcess = (GetLastError() != ERROR_ALREADY_EXISTS);
if(!bFirstProcess)
{
hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, // Voller Zugriff
FALSE, // Den Namen nicht vererben
"DLLMemFileMap"); // Name des Objektes
if(hMapFile == NULL)
return FALSE;
}
// Einen Zeiger auf das file-mapped shared memory bekommen
lpvMem = MapViewOfFile(
hMapFile, // Das Objekt
FILE_MAP_ALL_ACCESS, // Voller Zugriff
0, // high offset: Von Anfang
0, // low offset: Von Anfang
0); // default: Das ganze File mappen
if(lpvMem == NULL)
return FALSE;
if(bFirstProcess)
// Den Speicher initialisieren
memset(lpvMem, '\0', sizeof(HOOKSTRUCT));
// pHookStruct setzen auf das erste Byte im shared Memory
pHookStruct = (HOOKSTRUCT*)lpvMem;
}
break;
// Neuer Thread im Prozess
case DLL_THREAD_ATTACH:
break;
// Beenden eines Threads im Prozess
case DLL_THREAD_DETACH:
break;
// Die DLL wird aus dem Adressraum eines Prozesses freigegeben
case DLL_PROCESS_DETACH:
{
// Den Speicher aus dem Adressraum des Prozesses "rausmappen"
UnmapViewOfFile(lpvMem);
// Das Handle des Prozesses auf das File-Mapping-Objekt schließen
CloseHandle(hMapFile);
}
break;
}
return TRUE;
}
//---------------------------------------------------------------------------
void __stdcall SetHook(HWND hwnd)
{
// Hier wird hwnd in das shared Memory geschrieben
HOOKSTRUCT* phs = (HOOKSTRUCT*)lpvMem;
phs->hwnd = hwnd;
if(!ghHook)
{
// Starten des Mouse-Hooks
ghHook = SetWindowsHookEx(WH_MOUSE, (HOOKPROC)MouseHookProc, ghInst, 0);
if(!ghHook)
MessageBox(NULL, "Hook kann nicht erstellt werden", "ERROR", MB_OK|MB_ICONERROR);
}
else
MessageBox(NULL, "Hook ist bereits erstellt", "MouseHook", MB_OK);
}
//---------------------------------------------------------------------------
void __stdcall RemoveHook(void)
{
// Beenden des Hooks
UnhookWindowsHookEx(ghHook);
}
//---------------------------------------------------------------------------
MOUSEHOOKSTRUCT __stdcall GetMouseData()
{
// Die MOUSEHOOKSTRUCT zurückliefern
return pHookStruct->MouseHookStruct;
}
//---------------------------------------------------------------------------
LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if( nCode >= 0 ) // means: nCode==HC_ACTION or nCode==HC_NOREMOVE
{
// Hier wird die MouseHookStruct in das shared memory geschrieben
// damit die aufrufende Anwendung die Daten per GetMouseData()
// abrufen kann
MOUSEHOOKSTRUCT mhs = *(MOUSEHOOKSTRUCT*)lParam;
pHookStruct->MouseHookStruct = mhs;
// Die Message an die Form senden (Msg-ID und Koordinaten)
LONG lPoint = MAKELONG((WORD)mhs.pt.x, (WORD)mhs.pt.y);
SendMessage(pHookStruct->hwnd, WM_MOUSEHOOK, wParam, (LPARAM)lPoint);
}
// Die nächste Hook-Prozedur aufrufen (optional)
return CallNextHookEx(ghHook, nCode, wParam, lParam);
}
//---------------------------------------------------------------------------
// Die Header-Datei
//
//---------------------------------------------------------------------------
#ifndef HookUnitH
#define HookUnitH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
// Userdefined Message
// Wird beim Eingehen von Mouse-Messages von der DLL gesendet
// und von der MainForm empfangen (s.u.: MESSAGE_MAP)
#define WM_MOUSEHOOK WM_USER+100
//---------------------------------------------------------------------------
class TMouseHookForm : public TForm
{
__published: // Komponenten, die von der IDE verwaltet werden
TLabel *Label1; // Caption: "Label1"
TLabel *Label2; // Caption: "Label2"
TLabel *Label3; // Caption: "X"
TLabel *Label4; // Caption: "Y"
TLabel *Label5; // Caption: "Msg-ID:"
TLabel *Label6; // Caption: "Label6"
void __fastcall FormCreate(TObject *Sender);
void __fastcall FormDestroy(TObject *Sender);
private: // Benutzerdeklarationen
void __fastcall wmMessage(TMessage& msg);
protected:
// Ist dafür zuständig, dass die Message WM_MOUSEHOOK
// an die Funktion wmMessage weitergeleitet wird
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_MOUSEHOOK, TMessage, wmMessage);
END_MESSAGE_MAP(TForm);
public: // Benutzerdeklarationen
__fastcall TMouseHookForm(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TMouseHookForm *MouseHookForm;
//---------------------------------------------------------------------------
#endif
//-----------------------*.cpp----------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "HookUnit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
//---------------------------------------------------------------------------
// Die Funktionen aus der dem Projekt hinzugefügten LIB deklarieren
extern "C" __declspec(dllexport) __stdcall void SetHook(HWND);
extern "C" __declspec(dllexport) __stdcall void RemoveHook(void);
extern "C" __declspec(dllexport) __stdcall MOUSEHOOKSTRUCT GetMouseData(void);
//---------------------------------------------------------------------------
TMouseHookForm *MouseHookForm;
//---------------------------------------------------------------------------
__fastcall TMouseHookForm::TMouseHookForm(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TMouseHookForm::FormCreate(TObject *Sender)
{
// Den Hook starten
SetHook(Handle);
// Die Form vor alle anderen Fenster setzen, damit die Maus-Koordianten
// immer präsent sind
SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
}
//---------------------------------------------------------------------------
void __fastcall TMouseHookForm::FormDestroy(TObject *Sender)
{
// Naja, weg mit dem Hook ;)
RemoveHook();
}
//---------------------------------------------------------------------------
// Hier geht die Message WM_MOUSEHOOK ein
void __fastcall TMouseHookForm::wmMessage(TMessage& msg)
{
// Die Labels mit den Koordinaten beschriften
Label1->Caption = GetMouseData().pt.x; // x-Koordinate
Label2->Caption = GetMouseData().pt.y; // y-Koordinate
// Alternativ: (schönes Wort ;))
//Label1->Caption = LOWORD(msg.LParam);
//Label2->Caption = HIWORD(msg.LParam);
// Wenn der rechte Maus-Button gedrückt und losgelassen wurde
if(msg.WParam == WM_RBUTTONUP)
// Gib eine MessageBox aus
MessageBox(Handle, "YOU CLICKED RIGHT", "HUHU",
MB_OK|MB_ICONINFORMATION|MB_SYSTEMMODAL);
// Die ID der eingehenden Maus-Message ins Label schreiben
Label6->Caption = (int)msg.WParam;
}
//---------------------------------------------------------------------------