两个dll合并在一起

时间:2021-08-05 14:52:44
从网上下载了两个dll,一个是键盘钩子,一个是鼠标钩子,有源代码,有test工程代码.

我想把这两个dll合并在一起,把代码做了一些修改编译成功;后来发现,在挂钩的时候不能同时起作用,后挂的那个有用,前面挂的就没用了.

在代码里面我是把键盘钩子放在后面的,也就是说,如果我只放在一个过程里面挂钩,只有键盘钩子有效;

如果把两个钩子拆开放在两个过程里面,挂了一个另一个就无效了..

就好象我的钩子在挂鼠标的时候就把键盘吞掉了,挂键盘的时候就把鼠标给吞掉了一样.....但是按道理应该不会这样的,我的函数设了返回值,其他的窗口都能接收到键盘鼠标消息,说明钩子没有吞掉消息...


我想请人帮我大致分析一下,只要思路,不用帮我看代码..

应该怎样做才能让两个钩子都有效呢?


另:这两个dll用到了内存映射文件来共享数据,会不会是这里出了问题?难道必须要拆开?

5 个解决方案

#1


调用后要及时释放.

#2


请大虾帮我看一下,下面是dll里的源码,这个dll好象是用到了两个自定义的接口(类),我估计调用的时候想让两个钩子都有效,可能跟那两个主工程中的pas单元也就是借口没多大关系,所以代码就不贴上来了:

library MMSoundd;

uses
  Windows,
  Messages;

const
  MappingFileName = '57D6A971_MMSounddDLL_442C0DB1';
  MSGMOUSEMOVE: PChar = 'MSGMOUSEMOVE57D6A971-049B-45AF-A8CD-37E0B706E036';
  MSGMOUSECLICK: PChar = 'MSGMOUSECLICK442C0DB1-3198-4C2B-A718-143F6E2D1760';
  MSGKEYDOWN: PChar = 'MSGKEYDOWN57D6A971-049B-45AF-A8CD-37E0B706E037';
  MSGKEYUP: PChar = 'MSGKEYUP442C0DB1-3198-4C2B-A718-143F6E2D1761';
type
  TMappingMem = record
    Handle: DWORD;
    MsgID: DWORD;
    MouseStruct: TMOUSEHOOKSTRUCT;
    KeyCode: Integer;
  end;
  PMappingMem = ^TMappingMem;

var
  MSG_MOUSEMOVE: UINT;
  MSG_MOUSECLICK: UINT;
  MSG_KEYDOWN: UINT;
  MSG_KEYUP: UINT;
  hMappingFile: THandle;
  pMapMem: PMappingMem;
  mhook: HHook;
  fblocked: BOOL = True;



  khook: HHook;
  //CriticalSection: TRTLCriticalSection;

function MouseHookProc(iCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall
begin
  if fblocked then
    Result := 0
  else
    Result := 0;

  if iCode < 0 then
    CallNextHookEx(mhook, iCode, wParam, lParam);

  case wParam of
    WM_MOUSEMOVE, WM_NCMouseMove:
      begin
        pMapMem^.MsgID := MSG_MOUSEMOVE;
        pMapMem^.MouseStruct := pMOUSEHOOKSTRUCT(lparam)^;
        SendMessage(pMapMem^.Handle, pMapMem^.MsgID, 0, 0);

      end;
    WM_LBUTTONDOWN, WM_NCLBUTTONDOWN:
      begin
        pMapMem^.KeyCode := wParam;
        pMapMem^.MsgID := MSG_MOUSECLICK;
        pMapMem^.MouseStruct := pMOUSEHOOKSTRUCT(lparam)^;
        SendMessage(pMapMem^.Handle, pMapMem^.MsgID, 0, 0);
      end;
    WM_LBUTTONUP:
      begin
      end;
    WM_LBUTTONDBLCLK:
      begin
      end;
    WM_RBUTTONDOWN:
      begin
        pMapMem^.KeyCode := wParam;
        pMapMem^.MsgID := MSG_MOUSECLICK;
        pMapMem^.MouseStruct := pMOUSEHOOKSTRUCT(lparam)^;
        SendMessage(pMapMem^.Handle, pMapMem^.MsgID, 0, 0);
      end;
    WM_RBUTTONUP:
      begin
      end;
    WM_RBUTTONDBLCLK:
      begin
      end;
    WM_MBUTTONDOWN:
      begin
      end;
    WM_MBUTTONUP:
      begin
      end;
    WM_MBUTTONDBLCLK:
      begin
      end;
  end;

end;


function EnableMouseHook(hWindow: HWND; Blocked: BOOL): BOOL; stdcall;
begin
  Result := False;
  if mhook <> 0 then
    Exit;
  pMapMem^.Handle := hWindow;
  fblocked := Blocked;
  mhook := SetWindowsHookEx(WH_MOUSE, MouseHookProc, HInstance, 0);
  Result := mhook <> 0;
end;


function GetKey: integer; export;
begin
  Result := pMapMem^.KeyCode;
end;



function DisableMouseHook: BOOL; stdcall;
begin
  if mhook <> 0 then
  begin
    UnhookWindowshookEx(mhook);
    mhook := 0;
  end;
  Result := mhook = 0;
end;










function KeyboardHookProc(iCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall
begin
  Result := 0;

  if iCode < 0 then
    Result := CallNextHookEx(khook, iCode, wParam, lParam);

  if iCode = HC_ACTION then
  begin
    pMapMem^.KeyCode := wParam;
    case ((lParam shr 30) and $F) of
      0:                                // Key down
        begin
          pMapMem^.MsgID := MSG_KEYDOWN;
          SendMessage(pMapMem^.Handle, pMapMem^.MsgID, 0, 0);
        end;
      1:                                // key up
        begin
          pMapMem^.MsgID := MSG_KEYUP;
          SendMessage(pMapMem^.Handle, pMapMem^.MsgID, 0, 0);
        end;
    end;
  end;
end;

function EnableKeyboardHook(hWindow: HWND): BOOL; stdcall;
begin
  Result := False;
  if khook <> 0 then
    Exit;
  pMapMem^.Handle := hWindow;
  khook := SetWindowsHookEx(WH_KEYBOARD, KeyboardHookProc, HInstance, 0);
  Result := khook <> 0;
end;

function DisableKeyboardHook: BOOL; stdcall;
begin
  if khook <> 0 then
  begin
    UnhookWindowshookEx(khook);
    khook := 0;
  end;
  Result := khook = 0;
end;















procedure DllMain(dwReason: DWORD);
begin
  case dwReason of
    DLL_PROCESS_ATTACH:
      begin
        //InitializeCriticalSection(CriticalSection);
        hMappingFile := OpenFileMapping(FILE_MAP_WRITE, False, MappingFileName);
        if hMappingFile = 0 then
        begin
          hMappingFile := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE,
            0, SizeOf(TMappingMem), MappingFileName);
        end;
        if hMappingFile = 0 then
          MessageBox(0, 'cannot create share memory!', 'Error', MB_OK or MB_ICONERROR);

        pMapMem := MapViewOfFile(hMappingFile, FILE_MAP_WRITE or FILE_MAP_READ,
          0, 0, 0);
        if pMapMem = nil then
        begin
          CloseHandle(hMappingFile);
          MessageBox(0, 'cannot map share memory!', 'Error', MB_OK or MB_ICONERROR);
        end;
        mhook := 0;
        khook := 0;
        MSG_MOUSEMOVE := RegisterWindowMessage(MSGMOUSEMOVE);
        MSG_MOUSECLICK := RegisterWindowMessage(MSGMOUSECLICK);
        MSG_KEYDOWN := RegisterWindowMessage(MSGKEYDOWN);
        MSG_KEYUP := RegisterWindowMessage(MSGKEYUP);
      end;
    DLL_PROCESS_DETACH:
      begin
        UnMapViewOfFile(pMapMem);
        CloseHandle(hMappingFile);
        if mhook <> 0 then
          DisableMouseHook;
        //DeleteCriticalSection(CriticalSection);
        if khook <> 0 then
          DisableKeyboardHook;
        //DeleteCriticalSection(CriticalSection);
      end;
    DLL_THREAD_ATTACH:
      begin
      end;
    DLL_THREAD_DETACH:
      begin
      end;
  end;
end;

exports
  EnableMouseHook,
  DisableMouseHook,
  GetKey,
  EnableKeyboardHook,
  DisableKeyboardHook;
begin
  DisableThreadLibraryCalls(HInstance);
  DLLProc := @DLLMain;
  DLLMain(DLL_PROCESS_ATTACH);
end.

#3


上面那段代码其实是我将两个DLL中的代码合并在一起的,但在调用的时候老是发现只有其中之一起作用.....


我怀疑是
khook: HHook;
mhook: HHook;这个地方好象只能存在其中之一,不能并存,是不是要用数据共享?

#4


问题解决了,呵呵,高兴中,随便散分罗~~~~~~~~~~~~~快来接啊~~~~~~~lishan200012 你运气真好~

#5


怎么解决的阿,楼主.....

#1


调用后要及时释放.

#2


请大虾帮我看一下,下面是dll里的源码,这个dll好象是用到了两个自定义的接口(类),我估计调用的时候想让两个钩子都有效,可能跟那两个主工程中的pas单元也就是借口没多大关系,所以代码就不贴上来了:

library MMSoundd;

uses
  Windows,
  Messages;

const
  MappingFileName = '57D6A971_MMSounddDLL_442C0DB1';
  MSGMOUSEMOVE: PChar = 'MSGMOUSEMOVE57D6A971-049B-45AF-A8CD-37E0B706E036';
  MSGMOUSECLICK: PChar = 'MSGMOUSECLICK442C0DB1-3198-4C2B-A718-143F6E2D1760';
  MSGKEYDOWN: PChar = 'MSGKEYDOWN57D6A971-049B-45AF-A8CD-37E0B706E037';
  MSGKEYUP: PChar = 'MSGKEYUP442C0DB1-3198-4C2B-A718-143F6E2D1761';
type
  TMappingMem = record
    Handle: DWORD;
    MsgID: DWORD;
    MouseStruct: TMOUSEHOOKSTRUCT;
    KeyCode: Integer;
  end;
  PMappingMem = ^TMappingMem;

var
  MSG_MOUSEMOVE: UINT;
  MSG_MOUSECLICK: UINT;
  MSG_KEYDOWN: UINT;
  MSG_KEYUP: UINT;
  hMappingFile: THandle;
  pMapMem: PMappingMem;
  mhook: HHook;
  fblocked: BOOL = True;



  khook: HHook;
  //CriticalSection: TRTLCriticalSection;

function MouseHookProc(iCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall
begin
  if fblocked then
    Result := 0
  else
    Result := 0;

  if iCode < 0 then
    CallNextHookEx(mhook, iCode, wParam, lParam);

  case wParam of
    WM_MOUSEMOVE, WM_NCMouseMove:
      begin
        pMapMem^.MsgID := MSG_MOUSEMOVE;
        pMapMem^.MouseStruct := pMOUSEHOOKSTRUCT(lparam)^;
        SendMessage(pMapMem^.Handle, pMapMem^.MsgID, 0, 0);

      end;
    WM_LBUTTONDOWN, WM_NCLBUTTONDOWN:
      begin
        pMapMem^.KeyCode := wParam;
        pMapMem^.MsgID := MSG_MOUSECLICK;
        pMapMem^.MouseStruct := pMOUSEHOOKSTRUCT(lparam)^;
        SendMessage(pMapMem^.Handle, pMapMem^.MsgID, 0, 0);
      end;
    WM_LBUTTONUP:
      begin
      end;
    WM_LBUTTONDBLCLK:
      begin
      end;
    WM_RBUTTONDOWN:
      begin
        pMapMem^.KeyCode := wParam;
        pMapMem^.MsgID := MSG_MOUSECLICK;
        pMapMem^.MouseStruct := pMOUSEHOOKSTRUCT(lparam)^;
        SendMessage(pMapMem^.Handle, pMapMem^.MsgID, 0, 0);
      end;
    WM_RBUTTONUP:
      begin
      end;
    WM_RBUTTONDBLCLK:
      begin
      end;
    WM_MBUTTONDOWN:
      begin
      end;
    WM_MBUTTONUP:
      begin
      end;
    WM_MBUTTONDBLCLK:
      begin
      end;
  end;

end;


function EnableMouseHook(hWindow: HWND; Blocked: BOOL): BOOL; stdcall;
begin
  Result := False;
  if mhook <> 0 then
    Exit;
  pMapMem^.Handle := hWindow;
  fblocked := Blocked;
  mhook := SetWindowsHookEx(WH_MOUSE, MouseHookProc, HInstance, 0);
  Result := mhook <> 0;
end;


function GetKey: integer; export;
begin
  Result := pMapMem^.KeyCode;
end;



function DisableMouseHook: BOOL; stdcall;
begin
  if mhook <> 0 then
  begin
    UnhookWindowshookEx(mhook);
    mhook := 0;
  end;
  Result := mhook = 0;
end;










function KeyboardHookProc(iCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall
begin
  Result := 0;

  if iCode < 0 then
    Result := CallNextHookEx(khook, iCode, wParam, lParam);

  if iCode = HC_ACTION then
  begin
    pMapMem^.KeyCode := wParam;
    case ((lParam shr 30) and $F) of
      0:                                // Key down
        begin
          pMapMem^.MsgID := MSG_KEYDOWN;
          SendMessage(pMapMem^.Handle, pMapMem^.MsgID, 0, 0);
        end;
      1:                                // key up
        begin
          pMapMem^.MsgID := MSG_KEYUP;
          SendMessage(pMapMem^.Handle, pMapMem^.MsgID, 0, 0);
        end;
    end;
  end;
end;

function EnableKeyboardHook(hWindow: HWND): BOOL; stdcall;
begin
  Result := False;
  if khook <> 0 then
    Exit;
  pMapMem^.Handle := hWindow;
  khook := SetWindowsHookEx(WH_KEYBOARD, KeyboardHookProc, HInstance, 0);
  Result := khook <> 0;
end;

function DisableKeyboardHook: BOOL; stdcall;
begin
  if khook <> 0 then
  begin
    UnhookWindowshookEx(khook);
    khook := 0;
  end;
  Result := khook = 0;
end;















procedure DllMain(dwReason: DWORD);
begin
  case dwReason of
    DLL_PROCESS_ATTACH:
      begin
        //InitializeCriticalSection(CriticalSection);
        hMappingFile := OpenFileMapping(FILE_MAP_WRITE, False, MappingFileName);
        if hMappingFile = 0 then
        begin
          hMappingFile := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE,
            0, SizeOf(TMappingMem), MappingFileName);
        end;
        if hMappingFile = 0 then
          MessageBox(0, 'cannot create share memory!', 'Error', MB_OK or MB_ICONERROR);

        pMapMem := MapViewOfFile(hMappingFile, FILE_MAP_WRITE or FILE_MAP_READ,
          0, 0, 0);
        if pMapMem = nil then
        begin
          CloseHandle(hMappingFile);
          MessageBox(0, 'cannot map share memory!', 'Error', MB_OK or MB_ICONERROR);
        end;
        mhook := 0;
        khook := 0;
        MSG_MOUSEMOVE := RegisterWindowMessage(MSGMOUSEMOVE);
        MSG_MOUSECLICK := RegisterWindowMessage(MSGMOUSECLICK);
        MSG_KEYDOWN := RegisterWindowMessage(MSGKEYDOWN);
        MSG_KEYUP := RegisterWindowMessage(MSGKEYUP);
      end;
    DLL_PROCESS_DETACH:
      begin
        UnMapViewOfFile(pMapMem);
        CloseHandle(hMappingFile);
        if mhook <> 0 then
          DisableMouseHook;
        //DeleteCriticalSection(CriticalSection);
        if khook <> 0 then
          DisableKeyboardHook;
        //DeleteCriticalSection(CriticalSection);
      end;
    DLL_THREAD_ATTACH:
      begin
      end;
    DLL_THREAD_DETACH:
      begin
      end;
  end;
end;

exports
  EnableMouseHook,
  DisableMouseHook,
  GetKey,
  EnableKeyboardHook,
  DisableKeyboardHook;
begin
  DisableThreadLibraryCalls(HInstance);
  DLLProc := @DLLMain;
  DLLMain(DLL_PROCESS_ATTACH);
end.

#3


上面那段代码其实是我将两个DLL中的代码合并在一起的,但在调用的时候老是发现只有其中之一起作用.....


我怀疑是
khook: HHook;
mhook: HHook;这个地方好象只能存在其中之一,不能并存,是不是要用数据共享?

#4


问题解决了,呵呵,高兴中,随便散分罗~~~~~~~~~~~~~快来接啊~~~~~~~lishan200012 你运气真好~

#5


怎么解决的阿,楼主.....