32位钩子不会忽略64位进程

时间:2015-05-06 14:56:23

标签: delphi 32bit-64bit setfocus

我使用全局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.

1 个答案:

答案 0 :(得分:3)

您的32位挂钩不会加载到64位进程中。这意味着您的问题可能在其他地方。