关于键盘钩子的问题

chzhk007 2010-07-26 10:52:54
我做了个键盘Hook函数,以截获键盘回车消息,
但是我不知道有什么办法来得知该消息是作用在哪个控件上了,比如"确定","取消"按钮等。

有高手知道如何获取按下回车键时,所激活的控件的句柄吗?
...全文
112 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
castlater 2010-07-29
  • 打赏
  • 举报
回复
可以使用消息钩子 WH_GETMESSAGE
angloy 2010-07-27
  • 打赏
  • 举报
回复
那你还得HOOK消息才行,用来得到是哪个窗口得到了getfouce消息。
angloy 2010-07-27
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 chzhk007 的回复:]
HOOK的参数并没有指定当前光标所在的控件。
又是个无解的问题啊!悲剧。
[/Quote]
我的意思是lz你要换种思路来考虑这个问题.你想当用户回车或敲打键盘时作用的是那个控件,是根据哪个控件得到了getfouce这个消息后才能相应键盘消息.如果考虑到这个问题,则可以通过hook消息WH_GETMESSAGE来得到是哪个控件得到了getfouce这个消息也可以遍历所有窗口及控件得到窗口的状态是否为得到焦点状态,既然知道了哪个控件处于焦点状态,就知道哪个控件相应了键盘消息.
周药师 2010-07-27
  • 打赏
  • 举报
回复
系统钩子和DLL
钩子的本质是一段用以处理系统消息的程序,通过系统调用,将其挂入系统。钩子的种类有很多,每种钩子可以截获并处理相应的消息,每当特定的消息发出,在到达目的窗口之前,钩子程序先行截获该消息、得到对此消息的控制权。此时在钩子函数中就可以对截获的消息进行加工处理,甚至可以强制结束消息的传递。
在本程序中我们需要捕获在任意窗口上的键盘输入,这就需要采用全局钩子以便拦截整个系统的消息,而全局钩子函数必须以DLL(动态连接库)为载体进行封装,VC6中有三种形式的MFC DLL可供选择,即Regular statically linked to MFC DLL(标准静态链接MFC DLL)、Regular using the shared MFC DLL(标准动态链接MFC DLL)以及Extension MFC DLL(扩展MFC DLL)。 在本程序中为方便起见采用了标准静态连接MFC DLL。
三、键盘钩子程序示例
本示例程序用到全局钩子函数,程序分两部分:可执行程序KeyHook和动态连接库LaunchDLL。
1、首先编制MFC扩展动态连接库LaunchDLL.dll:
(1)选择MFC AppWizard(DLL)创建项目LaunchDLL;在接下来的选项中选择Regular statically linked to MFC DLL(标准静态链接MFC DLL)。
(2)在LaunchDLL.h中添加宏定义和待导出函数的声明:
#define DllExport __declspec(dllexport)
……
DllExport void WINAPI InstallLaunchEv();
……
class CLaunchDLLApp : public CWinApp
{
public:
CLaunchDLLApp();

//{{AFX_VIRTUAL(CLaunchDLLApp)
//}}AFX_VIRTUAL

//{{AFX_MSG(CLaunchDLLApp)
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
(3)在LaunchDLL.cpp中添加全局变量Hook和全局函数LauncherHook、SaveLog:
HHOOK Hook;
LRESULT CALLBACK LauncherHook(int nCode,WPARAM wParam,LPARAM lParam);
void SaveLog(char* c);
(4)完成以上提到的这几个函数的实现部分:
……
CLaunchDLLApp theApp;
……
DllExport void WINAPI InstallLaunchEv()
{
Hook=(HHOOK)SetWindowsHookEx(WH_KEYBOARD,
(HOOKPROC)LauncherHook,
theApp.m_hInstance,
0);
}
在此我们实现了Windows的系统钩子的安装,首先要调用SDK中的API函数SetWindowsHookEx来安装这个钩子函数,其原型是:
HHOOK SetWindowsHookEx(int idHook,
HOOKPROC lpfn,
HINSTANCE hMod,
DWORD dwThreadId);
其中,第一个参数指定钩子的类型,常用的有WH_MOUSE、WH_KEYBOARD、WH_GETMESSAGE等,在此我们只关心键盘操作所以设定为WH_KEYBOARD;第二个参数标识钩子函数的入口地址,当钩子钩到任何消息后便调用这个函数,即当不管系统的哪个窗口有键盘输入马上会引起LauncherHook的动作;第三个参数是钩子函数所在模块的句柄,我们可以很简单的设定其为本应用程序的实例句柄;最后一个参数是钩子相关函数的ID用以指定想让钩子去钩哪个线程,为0时则拦截整个系统的消息,在本程序中钩子需要为全局钩子,故设定为0。
……
LRESULT CALLBACK LauncherHook(int nCode,WPARAM wParam,LPARAM lParam)
{
LRESULT Result=CallNextHookEx(Hook,nCode,wParam,lParam);
if(nCode==HC_ACTION)
{
if(lParam & 0x80000000)
{
char c[1];
c[0]=wParam;
SaveLog(c);
}
}
return Result;
}
虽然调用CallNextHookEx()是可选的,但调用此函数的习惯是很值得推荐的;否则的话,其他安装了钩子的应用程序将不会接收到钩子的通知而且还有可能产生不正确的结果,所以我们应尽量调用该函数除非绝对需要阻止其他程序获取通知。
……
void SaveLog(char* c)
{
CTime tm=CTime::GetCurrentTime();
CString name;
name.Format( "c:\\Key_%d_%d.log ",tm.GetMonth(),tm.GetDay());
CFile file;
if(!file.Open(name,CFile::modeReadWrite))
{
file.Open(name,CFile::modeCreate|CFile::modeReadWrite);
}
file.SeekToEnd();
file.Write(c,1);
file.Close();
}
当有键弹起的时候就通过此函数将刚弹起的键保存到记录文件中从而实现对键盘进行监控记录的目的。
编译完成便可得到运行时所需的键盘钩子的动态连接库LaunchDLL.dll和进行静态链接时用到的LaunchDLL.lib。
2、下面开始编写调用此动态连接库的主程序,并实现最后的集成:
(1)用MFC的AppWizard(EXE)创建项目KeyHook;
(2)选择单文档,其余几步可均为确省;
(3)把LaunchDLL.h和LaunchDLL.lib复制到KeyHook工程目录中,LaunchDLL.dll复制到Debug目录下。
(4)链接DLL库,即在 "Project ", "Settings… "的 "Link "属性页内,在 "Object/librarymodules: "中填 入 "LaunchDLL.lib "。再通过 "Project ", "Add To Project ", "Files… "将LaunchDLL.h添加到工程中来,最后在视类的源文件KeyHook.cpp中加入对其的引用:
#include "LaunchDLL.h "
这样我们就可以象使用本工程内的 函数一样使用动态连接库LaunchDLL.dll中的所有导出函数了。
(5)在视类中添加虚函数OnInitialUpdate(),并添加代码完成对键盘钩子的安装:
……
InstallLaunchEv();
……
(6)到此为止其实已经完成了所有的功能,但作为一个后台监控软件,运行时并不希望有界面,可以在应用程序类CkeyHookApp的InitInstance()函数中将m_pMainWnd-> ShowWindow(SW_SHOW);改为m_pMainWnd-> ShowWindow (SW_HIDE);即可。
四、运行与检测
编译运行程序,运行起来之后并无什么现象,但通过Alt+Ctrl+Del在关闭程序对话框内可以找到我们刚编写完毕的程序 "KeyHook ",随便在什么程序中通过键盘输入字符,然后打开记录文件,我们会发现:通过键盘钩子,我们刚才输入的字符都被记录到记录文件中了。
小结:系统钩子具有相当强大的功能,通过这种技术可以对几乎所有的Windows系统消息进行拦截、监视、处理。这种技术广泛应用于各种自动监控系统中
chzhk007 2010-07-27
  • 打赏
  • 举报
回复
HOOK的参数并没有指定当前光标所在的控件。
又是个无解的问题啊!悲剧。

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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