// 键盘的硬件扫描码
DWORD flags;
// 一系列的标志位
//0比特位指示该键是不是扩展键(如: 功能键,或数字小键盘上的键),1表示是,0表示否
//1~3比特位保留
//4比特位用来区分该事件是否来自Win32 函数keybd_event()调用,1表示是,0表示否
//5比特位为状态描述码,如果ALT键按下,该位是1,否则是0。
//6比特位保留。
//7比特位是变换状态位,键被按下为0,键被释放为1。
DWORD time;
// 该消息事件的时间标记。
DWORD dwExtraInfo;
// 该消息的其他扩展信息。
}KBDLLHOOKSTRUCT, FAR *LPKBDLLHOOK
STRUCT, *PKBDLLHOOKSTRUCT;
实际的钩子函数的框架如下:
LRESULT CALLBACK MyLowLevelKeyboard
Proc(int nCode,WPARAM wParam,LPARAM lParam)
{
BOOL bSkipThisEvent = FALSE;
HWND hwndForeground;
HWND hwndFocus;
DWORD dwCurrentThreadId;
DWORD dwWindowThreadId;
if (nCode == HC_ACTION) {
PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT) lParam;
//系统传递来的键盘输入事件信息指针
switch (wParam) {
case WM_SYSKEYUP:
case WM_KEYUP: //if key up
/*这段代码用来获得当前拥有输入焦点的窗口的窗口句柄,以便获得该窗口的相关信息*/
/*获得前端窗口(即用户当前正在工作的窗口)的句柄,创建该窗口的线程通常拥有比其他线程稍微高一些的优先级。*/
hwndForegroud=::GetForegroundWindow(); dwCurrentThreadId=::GetCurrentThreadId(); //当前线程的Id
//获得产生前端窗口hwndForeground的线程Id值,用来惟一表示一个线程
dwWindowThreadId=::GetWindowThread-
ProcessId(hwndForegroud,NULL);
/*下面这一行代码非常重要,它的作用是使当前线程(dwCurrentThreadId)的输入处理机制依附到创建前端窗口的线程(dwWindowThreadId)的输入机制上,否则你将得不到当前拥有键盘输入焦点的窗口句柄。这是因为在Windows NT/2000操作系统通常创建不同的线程来处理相互独立的输入过程,每一个输入过程都拥有自己的输入状态(焦点、键盘状态、队列状态等),通过AttachThreadInput调用,操作系统将允许调用线程获得或者设置其他线程生成窗口的输入状态信息。只有执行该系统调用,才能够得到当前拥有键盘输入焦点的窗口的窗口句柄,否则GetFocus()系统调用将返回NULL。在这一点上Windows NT/2000与Windows 9X操作系统有很大不同,这也正是Windows NT/2000比Windows 95/98 操作系统可靠性、安全性更好的一个原因*/
AttachThreadInput(dwCurrentThreadId , dwWindowThreadId,TRUE); //
//获得拥有键盘输入焦点的窗口的窗口句柄
hwndFocus =::GetFocus();
if(hwndFocus || hwndForeground)
{
char wnm[256];
wnm[0]=0;
//变量定义后,使用之前一定要初始化。
//获得该窗口的窗口标题,就是在窗口标题栏上显示的内容
:: GetWindowText(hwndForeground,wnm,255);
char clsnm[266];
clsnm[0]=0;
//获得该窗口的类名字
:: GetClassName(hwndFocus,clsnm,255);
//获得该窗口的风格
LONG style=::GetWindowLong(hwfocus,GWL_STYLE);
/*如果你只对部分窗口感兴趣的话,可以通过下面的形式进行过滤, 从而只处理你所感兴趣的某些窗口的输入事件*/
if((stricmp(clsnm,“edit”)==0 )
|| (0x0020 &style)
|| strstr(wnm,“MyTest Wnd”))
{//你可以在此记录供以后分析使用的相关信息
LLKEY_OutputToLog(hwfore,hwfocus,wnm,clsnm,p);
}
}
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
if (p->vkCode == VK_LWIN)
/*该行代码用来将键盘上的左Win系统键(就是带有微软旗帜图案的那个键,注意是左边的那个)屏蔽掉,如果在代码执行后,用户敲击键盘上的左Win系统键,将不会弹出Windows的开始菜单。你可以根据你的需要屏蔽任何你所