Код библиотеки Tracker.dpr:
| Код | library tracker;
uses Windows, Messages, Shared;
var hKeyBoardHook: THandle = 0;
function KeyBoardHook(nCode, wParam, lParam: Integer): lResult; stdcall; begin if (nCode >= 0) and (GlobalData^.hForm <> 0) then //SendMessage(GlobalData^.hForm, WMKeyHook, 0, 0); PostMessage(GlobalData^.hForm, WMKeyHook, 0, 0); Result:= CallNextHookEx(hKeyBoardHook, nCode, wParam, lParam); end;
procedure SetHook; begin if hKeyBoardHook = 0 then hKeyBoardHook:= SetWindowsHookEx(WH_KEYBOARD, @KeyBoardHook, hInstance, 0); end;
procedure RemoveHook; begin if hKeyBoardHook <> 0 then begin UnhookWindowsHookEx(hKeyBoardHook); hKeyBoardHook:= 0; end; end;
procedure DLLEntryPoint(dwReason: DWord); begin case dwReason of DLL_PROCESS_ATTACH: OpenSharedData; DLL_PROCESS_DETACH: CloseSharedData; end; end;
exports GetDLLData, RemoveHook, SetHook;
begin DllProc:= @DLLEntryPoint; DLLEntryPoint(DLL_PROCESS_ATTACH); end.
|
Код юнита Shared.pas:
| Код | unit Shared;
interface
uses Windows;
type PGlobalDLLData = ^TGlobalDLLData; TGlobalDLLData = record hForm: HWND; end;
const MapFileName: PAnsiChar = 'Test'; var GlobalData: PGlobalDLLData; hMap: THandle; SA: TSecurityAttributes; WMKeyHook: Integer = 0;
procedure GetDLLData(var PGlobalData: PGlobalDLLData); procedure OpenSharedData; procedure CloseSharedData;
implementation
procedure GetDLLData(var PGlobalData: PGlobalDLLData); begin PGlobalData:= GlobalData; end;
procedure OpenSharedData; var Size: Integer; begin Size:= SizeOf(TGlobalDLLData); hMap:= CreateFileMapping(DWord(-1), @SA, PAGE_READWRITE, 0, Size, MapFileName); GlobalData:= MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, Size); if GlobalData = nil then CloseHandle(hMap); end;
procedure CloseSharedData; begin UnmapViewOfFile(GlobalData); CloseHandle(hMap); end;
initialization WMKeyHook:= RegisterWindowMessage(MapFileName); SA.nLength:= SizeOf(SA); SA.bInheritHandle:= True; GetMem(SA.lpSecurityDescriptor, SECURITY_DESCRIPTOR_MIN_LENGTH); InitializeSecurityDescriptor(SA.lpSecurityDescriptor, 1{SECURITY_DESCRIPTOR_REVISION}); SetSecurityDescriptorDacl(SA.lpSecurityDescriptor, True, nil, False); //All access finalization FreeMem(SA.lpSecurityDescriptor, SECURITY_DESCRIPTOR_MIN_LENGTH); end.
|
Код проекта Project1.dpr:
| Код | unit Unit1;
interface
uses Windows, Forms, Shared, Classes, AppEvnts;
type TForm1 = class(TForm) ApplicationEvents1: TApplicationEvents; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean); private { Private declarations } public { Public declarations } end; procedure RemoveHook; external 'Tracker.dll'; procedure SetHook; external 'Tracker.dll'; procedure GetDLLData(var AGlobalData: PGlobalDLLData); external 'Tracker.dll';
var Form1: TForm1; FData: PGlobalDLLData;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject); begin GetDLLData(FData); FData^.hForm:= Handle; SetHook; end;
procedure TForm1.FormDestroy(Sender: TObject); begin RemoveHook; end;
procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean); begin if Msg.message = WMKeyHook then MessageBox(0, 'KeyBoardHook', 'Test', MB_OK); end;
end.
|
Пример демонстрирует извещение основного приложения о срабатывании хука на клаву. Суть проблемы заключается в том, что в фунции хука клавиатуры KeyBoardHook вызов PostMessage срабатывает, а SendMessage нет. Исходники примера прикреплены. Попробуйте изменить SendMessage на PostMessage для проверки эффекта. В чём может быть проблема? |