我使用全局CBT挂钩来识别Windows setfocus
消息
键盘焦点发生变化时,我希望我的应用程序注意到这一点。
因此,我使用内存映射文件存储应用程序的句柄,以便每个进程可以使用它在焦点更改后向应用程序发送消息。
我在hook.dll和应用程序中都使用32位窗口作为目标平台。
现在,据我所知,应该挂钩32位进程,忽略64位进程。在32位系统上,应用程序运行良好
当它在64位窗口上使用时,它也可以在32位进程中工作(例如delphi IDE),
但有时应用程序会冻结。
例如,当我启动Internet Explorer时。 我注意到Internet Explorer运行时,任务管理器中有32位和64位iexplore.exe。
这可能是问题吗?我不明白为什么64位进程不会被忽略......请帮忙!
以下是主应用程序调用的hook.dll的代码:
library Project1;
uses
{System.SysUtils,
System.Classes,
sharemem,
windows,
messages,}
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants;
const
WM_MYFOCUSCHANGED = WM_USER + 1;
type
PHookRec = ^THookRec;
THookRec = packed Record
HookHandle: hhook;
WindowHandle: hwnd;
End;
var
MapHandle: THandle; // File Mapping Objekt
IpHookRec: PHookRec; // Zeiger auf Hook Record
{$R *.res}
procedure MapFileMemory(dwAllocSize: DWORD);
begin
{Create a process wide memory mapped variable}
MapHandle := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, dwAllocSize, 'HookRecMemBlock');
if (MapHandle = 0) then
begin
MessageBox(0, 'Hook DLL', 'Could not create file map object', MB_OK);
exit;
end;
{Get a pointer to our process wide memory mapped variable}
ipHookRec := MapViewOfFile(MapHandle, FILE_MAP_WRITE, 0, 0, dwAllocSize);
if (ipHookRec = nil) then
begin
CloseHandle(MapHandle);
MessageBox(0, 'Hook DLL', 'Could not map file', MB_OK);
exit;
end;
end;
procedure UnMapFileMemory;
begin
{Delete our process wide memory mapped variable}
if (ipHookRec <> nil) then
begin
UnMapViewOfFile(ipHookRec);
ipHookRec := nil;
end;
if (MapHandle > 0) then
begin
CloseHandle(MapHandle);
MapHandle := 0;
end;
end;
function GetHookRecPointer: pointer stdcall;
begin
{Return a pointer to our process wide memory mapped variable}
result := ipHookRec;
end;
function FocusHookProc(code: integer; wParam: wParam; lParam: lParam): LResult; stdcall;
begin
if (code < 0) then
begin
result := CallNextHookEx(ipHookRec^.HookHandle, code, wParam, lParam);
exit;
end;
result := 0;
if (code = HCBT_SETFOCUS) then
begin
if (ipHookRec^.WindowHandle <> INVALID_HANDLE_VALUE) then
PostMessage(ipHookRec^.WindowHandle, WM_MYFOCUSCHANGED, wParam, lParam);
// wParam: Handle to the window gaining the keyboard focus
end;
end;
procedure InstallHook(Hwnd: Cardinal); stdcall;
begin
if ((ipHookRec <> nil) and (ipHookRec^.HookHandle = 0) and (ipHookRec^.WindowHandle = 0)) then
begin
ipHookRec^.WindowHandle := Hwnd; // handle to the application window
ipHookRec^.HookHandle := SetWindowsHookEx(WH_CBT, @FocusHookProc, Hinstance, 0);
end;
end;
procedure UninstallHook; stdcall;
begin
if ((ipHookRec <> nil) and (ipHookRec^.HookHandle <> 0)) then
begin
{Remove our hook and clear our hook handle}
if (UnHookWindowsHookEx(ipHookRec^.HookHandle) <> FALSE) then
begin
ipHookRec^.HookHandle := 0;
ipHookRec^.WindowHandle := 0;
end;
end;
end;
procedure DllEntryPoint(dwReason: DWORD);
var
currHwnd: Hwnd;
is64: Boolean;
begin
case dwReason of
Dll_Process_Attach:
begin
{If we are getting mapped into a process, then get a pointer to our
process wide memory mapped variable}
MapHandle := 0;
ipHookRec := nil;
MapFileMemory(sizeof(ipHookRec^));
end;
Dll_Process_Detach:
begin
{If we are getting unmapped from a process then, remove the pointer to
our process wide memory mapped variable}
UnMapFileMemory;
end;
end;
end;
exports
InstallHook name 'INSTALLHOOK',
UninstallHook name 'UNINSTALLHOOK',
GetHookRecPointer name 'GETHOOKRECPOINTER';
begin
DLLProc := @DllEntryPoint; // set DLL main entry point
DllEntryPoint(Dll_Process_Attach); // call DLL main entry point
end.
答案 0 :(得分:3)
您的32位挂钩不会加载到64位进程中。这意味着您的问题可能在其他地方。