我想使用DLL在C ++中设置键盘和鼠标的全局系统挂钩。我的程序正在运行,但并不完全符合我的需要。例如,程序不会将鼠标事件挂钩到其他窗口或弹出菜单或模态对话框中。我想将鼠标和键盘事件挂钩到其他窗口,程序等所有系统鼠标和键盘事件中。我的代码有什么问题需要改变才能让它按照我的需要工作,我找不到自己出了什么问题,我按照文档中的描述做了,我需要帮助。
我使用VCL在C ++ Builder中进行编码
#include <vcl.h>
#include <windows.h>
#include "main.h"
#pragma hdrstop
#pragma argsused
typedef struct _HOOKSTRUCT
{
int nType;
HOOKPROC hkprc;
HHOOK hhook;
bool bInstalled;
} HOOKSTRUCT;
static HOOKSTRUCT hook[2];
HINSTANCE hDLL;
int nThreadCode;
bool bInit;
TForm1 *form;
extern "C" __stdcall __declspec(dllexport) LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
extern "C" __stdcall __declspec(dllexport) LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam);
//---------------------------------------------------------------------------
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
hDLL = hinst;
bInit = false;
return 1;
}
//---------------------------------------------------------------------------
extern "C" __stdcall __declspec(dllexport) void Init()
{
hook[0].nType = WH_KEYBOARD;
hook[0].hkprc = (HOOKPROC)KeyboardProc;
hook[0].bInstalled = false;
hook[1].nType = WH_MOUSE;
hook[1].hkprc = (HOOKPROC)MouseProc;
hook[1].bInstalled = false;
bInit = true;
}
//---------------------------------------------------------------------------
extern "C" __stdcall __declspec(dllexport) bool SetHook(int nHook)
{
if(!bInit)
{
Init();
}
hook[nHook].hhook = NULL;
hook[nHook].hhook = SetWindowsHookEx(hook[nHook].nType,
(HOOKPROC)hook[nHook].hkprc, hDLL, 0);
if(hook[nHook].hhook != NULL)
{
MessageBox(NULL, "Setup hook successful", "Information", MB_OK);
}
return true;
}
//---------------------------------------------------------------------------
extern "C" __stdcall __declspec(dllexport) void UnsetHook(int nHook)
{
UnhookWindowsHookEx(hook[nHook].hhook);
}
//---------------------------------------------------------------------------
extern "C" __stdcall __declspec(dllexport) LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if(((DWORD)lParam&0x40000000) && (HC_ACTION==nCode))
{
if(form != NULL)
{
form->Memo1->Lines->Add("Key Pressed");
}
}
return CallNextHookEx(hook[0].hhook, nCode, wParam, lParam);
}
//---------------------------------------------------------------------------
extern "C" __stdcall __declspec(dllexport) LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
char str[128];
PMOUSEHOOKSTRUCT Info = (PMOUSEHOOKSTRUCT)lParam;
wsprintf(str, "The mouse message at X: %d,Y: %d", Info->pt.x, Info->pt.y);
form->Memo2->Lines->Add(str);
return CallNextHookEx(hook[1].hhook, nCode, wParam, lParam);
}
//---------------------------------------------------------------------------
extern "C" __stdcall __declspec(dllexport) void SetControl(TForm1 *Object, int nApp)
{
form = Object;
nThreadCode = nApp;
}
#include <vcl.h>
#pragma hdrstop
#include "main.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
HINSTANCE hInst;
typedef bool (*install)(int);
typedef void (*uninstall)(int);
typedef void (*passself)(TForm1 *, int);
install InstallHook;
uninstall UninstallHook;
passself PassThis;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
N2->Enabled = true;
N3->Enabled = true;
N4->Enabled = false;
N5->Enabled = false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Memo1->Clear();
Memo2->Clear();
hInst = LoadLibrary("ch49dll.dll");
if(hInst == NULL)
{
ShowMessage("Load DLL error " + AnsiString(GetLastError()));
return;
}
InstallHook = (install)GetProcAddress(hInst, "SetHook");
if(InstallHook == NULL)
{
ShowMessage("Get SetHook ProcAddress Error");
return;
}
UninstallHook = (uninstall)GetProcAddress(hInst, "UnsetHook");
if(UninstallHook == NULL)
{
ShowMessage("Get UnsetHook ProcAddress Error");
return;
}
PassThis = (passself)GetProcAddress(hInst, "SetControl");
if(PassThis == NULL)
{
ShowMessage("Get SetControl ProcAddress Error");
return;
}
PassThis(this, 0);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
FreeLibrary(hInst);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::N2Click(TObject *Sender)
{
InstallHook(0);
N2->Enabled = false;
N4->Enabled = true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::N3Click(TObject *Sender)
{
InstallHook(1);
N3->Enabled = false;
N5->Enabled = true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::N4Click(TObject *Sender)
{
UninstallHook(0);
N4->Enabled = false;
N2->Enabled = true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::N5Click(TObject *Sender)
{
UninstallHook(1);
N5->Enabled = false;
N3->Enabled = true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::N7Click(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------
#ifndef mainH
#define mainH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Menus.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TMemo *Memo1;
TMemo *Memo2;
TMainMenu *MainMenu1;
TMenuItem *N1;
TMenuItem *N2;
TMenuItem *N3;
TMenuItem *N4;
TMenuItem *N5;
TLabel *Label1;
TLabel *Label2;
TMenuItem *N6;
TMenuItem *N7;
void __fastcall FormCreate(TObject *Sender);
void __fastcall FormDestroy(TObject *Sender);
void __fastcall N2Click(TObject *Sender);
void __fastcall N3Click(TObject *Sender);
void __fastcall N4Click(TObject *Sender);
void __fastcall N5Click(TObject *Sender);
void __fastcall N7Click(TObject *Sender);
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
所以程序工作并且可以挂钩外部事件,但对于某些对话框窗口,我的程序不会挂钩鼠标事件。例如,当我右键单击任务栏通知区域中的图标时,将显示一个弹出窗口,如果我在弹出窗口区域中输入鼠标光标,则我的程序将不会记录这些鼠标移动事件。其他情况是当我点击其他程序中的关于程序菜单,或关于菜单,然后会显示一个窗口,如果我将光标移动到该窗口的区域内,那么我的程序将不会挂钩鼠标和键盘的事件,为什么?如何使它挂钩任何窗口
答案 0 :(得分:2)
两个非常明显的问题:
如果您可以使用低级别挂钩,则应考虑采用该选项。优点是没有低水平钩子的注射。您根本不需要创建DLL。
答案 1 :(得分:0)
一些评论,希望能解决您的问题:使用&#34;低级&#34;钩子(WH_MOUSE_LL,WH_KEYBOARD_LL)因为它们保证只是全局的。我觉得你的应用程序只有一个&#34; local&#34; (线程)钩。
我与CBuilder在使用钩子时创建的DLL有不好的经验。 ...即:与您描述的完全相同的问题。我建议使用Microsoft编译器重新编译DLL(并提供要使用的.DEF文件)。
您可能需要将DLL放在标识为系统目录的位置。
您不需要将SetHook放置在DLL中,这可以通过&#34; main&#34;来完成。申请也是。
答案 2 :(得分:0)
在Win 7上,您只能挂钩具有相同或更低权限的程序中的邮件。即如果您自己的程序以标准权限运行,它将永远不会看到任何针对某个进程的鼠标或键盘消息。管理员权限。 - iamjoosy