VS2005中如何使用键盘钩子?

gglddu 2009-06-09 03:10:52
安装键盘钩子的函数这么写对吗? SetWindowsHookEx(WH_KEYBOARD_LL,(HOOKPROC)KeyboardProc,hins,0); 用WH_KEYBOARD根本就进不了KeyboardProc函数。 我的系统是vista。

还有KeyboardProc函数到底该怎么写?
LRESULT CALLBACK KeyboardProc(int nCode,WPARAM wParam,LPARAM lParam)
{
TRACE("lParam=%d \n",lParam);
TRACE("wParam=%d \n",wParam);
TRACE("nCode=%d \n",nCode);
if(((DWORD)lParam & 0x40000000) && (HC_ACTION==nCode))
{
switch(wParam) //键盘按键标识
{
case '1':...........break;
case '2':...........break;
}
}
LRESULT RetVal = CallNextHookEx( hkb, nCode, wParam, lParam );
return RetVal;
}
这么写得不到我要的结果啊。
调试时当随便按个键结果都一样的,是:
lParam=1244664
wParam=256 //256是WM_KEYDOWN,对应的都不是我按下的那个键
nCode=0
lParam=1244664
wParam=257 //257是WM_KEYUP
nCode=0
...全文
258 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
cdcjk 2009-06-09
  • 打赏
  • 举报
回复
学习
fishion 2009-06-09
  • 打赏
  • 举报
回复
// KeyHook.cpp : 定义 DLL 的初始化例程。
//

#include "stdafx.h"
#include <afxdllx.h>
#include "KeyHook.h"


#pragma data_seg("mydata")
HINSTANCE tHinstance=NULL;
const int KeyPressMask=0x80000000; //键盘掩码常量
HHOOK glhHook=NULL;
BOOL HookStates=FALSE;
HWND glhDisplayWnd=NULL; //显示目标窗口标题编辑框的句柄
#pragma data_seg()

#ifdef _MANAGED
#error 请阅读 KeyHook.cpp 中的说明以使用 /clr 进行编译
// 如果要向您的项目中添加 /clr,必须执行下列操作:
// 1. 移除上述对 afxdllx.h 的包含
// 2. 向没有使用 /clr 且已禁用预编译头的
// 项目添加一个 .cpp 文件,其中含有下列文本:
// #include <afxwin.h>
// #include <afxdllx.h>
#endif

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


static AFX_EXTENSION_MODULE KeyHookDLL = { NULL, NULL };

#ifdef _MANAGED
#pragma managed(push, off)
#endif

extern "C" int APIENTRY
//LRESULT CALLBACK KeyBoardProc(int nCode,WPARAM wParam,WPARAM lParam) ;

DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
// 如果使用 lpReserved,请将此移除
UNREFERENCED_PARAMETER(lpReserved);

if (dwReason == DLL_PROCESS_ATTACH)
{
TRACE0("KeyHook.DLL 正在初始化!\n");

// 扩展 DLL 一次性初始化
if (!AfxInitExtensionModule(KeyHookDLL, hInstance))
return 0;

// 将此 DLL 插入到资源链中
// 注意: 如果此扩展 DLL 由
// MFC 规则 DLL (如 ActiveX 控件)隐式链接到,
// 而不是由 MFC 应用程序链接到,则需要
// 将此行从 DllMain 中移除并将其放置在一个
// 从此扩展 DLL 导出的单独的函数中。使用此扩展 DLL 的
// 规则 DLL 然后应显式
// 调用该函数以初始化此扩展 DLL。否则,
// CDynLinkLibrary 对象不会附加到
// 规则 DLL 的资源链,并将导致严重的
// 问题。

new CDynLinkLibrary(KeyHookDLL);

}
else if (dwReason == DLL_PROCESS_DETACH)
{
TRACE0("KeyHook.DLL 正在终止!\n");

// 在调用析构函数之前终止该库
AfxTermExtensionModule(KeyHookDLL);
}
tHinstance=hInstance;
return 1; // 确定
}

CKeyHook::CKeyHook()
{
}

CKeyHook::~CKeyHook()
{
stophook();
}

LRESULT CALLBACK KeyBoardProc(int nCode,WPARAM wParam,LPARAM lParam)
{
WPARAM j;
FILE *fp;
if(lParam&0x80000000)
{
j = wParam;
// fp=fopen("c:\\logfile.txt","a+");

int vKey=j; // 取得虚拟键值
char ch;
char str[10]="\0";
//测试SHIFT,CAPTION,NUMLOCK等键是否按下
int iCtrl=GetKeyState(VK_CONTROL);
int iShift=GetKeyState(VK_SHIFT);
int iCapital=GetKeyState(0x14);
int iNumLock=GetKeyState(0x90);
bool bShift=(iShift & KeyPressMask)==KeyPressMask;
bool bCapital=(iCapital & 1)==1;
bool bNumLock=(iNumLock & 1)==1;
if (vKey >=48 && vKey<=57) // 数字0-9
{
if (!bShift)
SendMessage( glhDisplayWnd, WM_SETTEXT, 0, (LPARAM)(LPCTSTR)(_T("RichEdit20A") ) );
}

/*if (vKey>=65 && vKey<=90) // A-Z a-z
{
if (!bCapital)
{
if (bShift)
ch=vKey;
else
ch=vKey+32;
}

else if (bShift)
ch=vKey+32;
else
ch=vKey;

if(bShift)
wsprintf(str,"[SHIFT]+");

if (iCtrl)
wsprintf(str,"[CTRL]+");

fprintf(fp,"%s%c",str,ch);
}

if (vKey>=96 && vKey<=105) // 小键盘0-9
{
if (bNumLock)
fprintf(fp,"%c",vKey-96+48);
}

if (vKey>=112 && vKey<=123) // 功能键 [F1]-[F12]
{
switch (vKey)
{
case 112:
strcpy(str,"[F1]");
break;
case 113:
strcpy(str,"[F2]");
break;
case 114:
strcpy(str,"[F3]");
break;
case 115:
strcpy(str,"[F4]");
break;
case 116:
strcpy(str,"[F5]");
break;
case 117:
strcpy(str,"[F6]");
break;
case 118:
strcpy(str,"[F7]");
break;
case 119:
strcpy(str,"[F8]");
break;
case 120:
strcpy(str,"[F9]");
break;
case 121:
strcpy(str,"[F10]");
break;
case 122:
strcpy(str,"[F11]");
break;
case 123:
strcpy(str,"[F12]");
break;

}

fprintf(fp,"%s",str);
}


if (vKey>=8 && vKey<=46) //方向键
{
switch (vKey)
{
case 8:
strcpy(str,"[BK]");
break;
case 9:
strcpy(str,"[TAB]");
break;
case 13:
strcpy(str,"[EN]");
break;
case 32:
strcpy(str,"[SP]");
break;
case 33:
strcpy(str,"[PU]");
break;
case 34:
strcpy(str,"[PD]");
break;
case 35:
strcpy(str,"[END]");
break;
case 36:
strcpy(str,"[HOME]");
break;
case 37:
strcpy(str,"[LF]");
break;
case 38:
strcpy(str,"[UF]");
break;
case 39:
strcpy(str,"[RF]");
break;
case 40:
strcpy(str,"[DF]");
break;
case 45:
strcpy(str,"[INS]");
break;
case 46:
strcpy(str,"[DEL]");
break;
default:
ch='n' ;
break;
}

if (ch!='n' )
{
if (g_PrvChar!=vKey)
{
fprintf(fp,"%s",str);
g_PrvChar=vKey;
}
}
}

fclose(fp);*/
}
return CallNextHookEx(glhHook,nCode,wParam,lParam);

}

BOOL CKeyHook::starthook(HWND hwnd)
{
BOOL bResult=FALSE;
glhHook=SetWindowsHookEx(WH_KEYBOARD,KeyBoardProc,tHinstance,0);
if(NULL!=glhHook)
HookStates=bResult=TRUE;
glhDisplayWnd=hwnd;
return bResult;
}
BOOL CKeyHook::stophook() //卸载钩子
{
BOOL bResult=FALSE;
if(glhHook)
{
bResult= UnhookWindowsHookEx(glhHook);
if(bResult)
{
glhDisplayWnd=NULL;//清变量
glhHook=NULL;
}
}
HookStates=FALSE;
return bResult;
}
#ifdef _MANAGED
#pragma managed(pop)
#endif

参考一下这个
gglddu 2009-06-09
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 danxuezx 的回复:]
呵呵,这个问题我见面刚解决过。楼主仔细看一下MSDN就知道了。
如果用WH_KEYBOARD_LL,不能根据wParam来判断按键的,要用lParam所指向的 KBDLLHOOKSTRUCT 结构体中的scanCode和vkCode来进行判断。
WH_KEYBOARD才可以用您代码中的方法。
[/Quote]

弱弱的问下,如何找到lParam所指向的 KBDLLHOOKSTRUCT 结构体中的scanCode和vkCode??
我用lParam-> 没反应啊...
还有安装钩子时用WH_KEYBOARD根本就运行不到KeyboardProc函数里面去,这是为什么呢?
望高手解答,谢谢啦!
gglddu 2009-06-09
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 fengrx 的回复:]
右击以管理员权限运行程序试试。

Vista下一般都会有意想不到的问题哟,
[/Quote]

不行呀...
danxuezx 2009-06-09
  • 打赏
  • 举报
回复
呵呵,这个问题我见面刚解决过。楼主仔细看一下MSDN就知道了。
如果用WH_KEYBOARD_LL,不能根据wParam来判断按键的,要用lParam所指向的 KBDLLHOOKSTRUCT 结构体中的scanCode和vkCode来进行判断。
WH_KEYBOARD才可以用您代码中的方法。
fengrx 2009-06-09
  • 打赏
  • 举报
回复
右击以管理员权限运行程序试试。

Vista下一般都会有意想不到的问题哟,
gglddu 2009-06-09
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 skyxie 的回复:]
WH_KEYBOARD_LL只能是全局钩子
钩子函数必须放到单独的dll中
[/Quote]

我是放到单独的dll中的啊。
我是将调用该dll的MFC应用程序和MFC dll放到了同一个解决方案中的。
skyxie 2009-06-09
  • 打赏
  • 举报
回复
WH_KEYBOARD_LL只能是全局钩子
钩子函数必须放到单独的dll中

16,551

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Creator Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧