使用钩子机制监控输入法

------------------------------------------------------------------
大家好,我是平夏雨,微软拼音的测试工程师。今天向大家介绍一个跟测试相关的具体的编程技术——如何使用钩子机制动态监控输入法。
------------------------------------------------------------------

为了自动化测试输入法,我们经常需要动态的得到各种输入法程序的候选项。得到它们的方法有很多,例如可以使用内部的API,当然前提是可以得到这些API;使用UI Automation的机制,将来有机会可以有其他篇幅来介绍;另外就是今天我们今天要介绍的钩子机制。

钩子机制简介

钩子机制是Windows系统的一种标准机制。钩子程序能够截获Windows程序的各种消息并对其进行处理,有点像是一个后门程序。

钩子程序有很多种类型,例如:

· 键盘钩子可以监控各种键盘消息 (WH_KEYBOARD, WH_ KEYBOARD_LL)

· 鼠标钩子可以监控各种鼠标消息 (WH_MOUSE, WH_MOUSE_LL)

· 外壳钩子可以监控各种外壳事件消息 (WM_SHELL)

· 日志钩子可以监控从系统消息队列中取出的各种事件消息 (WH_JOURNALPLAYBACK, WH_JOURNALRECORD)

· 窗口过程钩子可以监控所有目标窗口的消息 (WH_CALLWNDPROC, WH_CALLWNDPROCRET)

监控输入法

以动态得到输入法的候选项为例,要用到的钩子是WH_GETMESSAGE类型的线程钩子,这个类型的钩子用来监控从GetMessage或者PeekMessage函数返回的消息。可以使用WH_GETMESSAGE钩子来监控鼠标和键盘输入,以及其他发送到消息队列中的消息。

第一步:设置钩子

使用SetWindowsHookEx来设置钩子。

hhook = SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)HookProcess,hModule,threadid)

其中HookProcess是我们需要准备的钩子程序,hModule是所在dll的句柄,threadid是被监控线程的Id号。hhook是返回的对应钩子函数的句柄,之后撤销钩子的时候要用到。

第二步:准备钩子函数

LRESULT CALLBACK HookProcess(int nCode,WPARAM wParam,LPARAM lParam)

钩子函数是一种回调函数,函数体可以这样写:

PMSG pmsg = (PMSG)lParam;

// 只关心WM_IME_NOTIFY这个消息,对应输入法程序的变化

if (pmsg->message == WM_IME_NOTIFY)

{

     // 这里只关心IMN_CHANGECANDIDATE这个消息,输入法选项的变化

     if (pmsg->wParam & IMN_CHANGECANDIDATE)

     {

          // 获取当前正在输入的窗口的输入法句柄

          hIMC = ImmGetContext(hWnd);

          // 通过句柄得到IMC结构 (input method context)

          lpImc = ImmLockIMC(hIMC);

          // 得到候选项信息

          lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpImc->hCandInfo);

          // 得到输入法的候选项列表

          lpCandList = (LPCANDIDATELIST)(((LPBYTE)lpCandInfo) + lpCandInfo->dwOffset[0]);

          // 成功:)之后就可以做进一步的处理

     }

}

第三步:撤销钩子

UnhookWindowsHookEx(hhook)

这里用到了之前设置钩子的时候用到的句柄。由于钩子程序消耗较多的系统资源,所以我们在用完了之后要及时地撤销钩子。

总而言之,钩子机制是一种很强大的机制,在监听消息方面可以说是无所不能。使用这种机制得到输入法的候选项由于是基于消息的,所以和具体的输入法无关。

参考文献:

MSDN 钩子机制 http://msdn.microsoft.com/en-us/library/ms644959(VS.85).aspx


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用C++安装钩子监控串口通信,你可以使用Windows API中的串口通信函数和钩子函数来实现。下面是一个示例代码,用于安装钩子监控串口通信: ```cpp #include <iostream> #include <Windows.h> HHOOK g_hookHandle; // 全局钩子句柄 LRESULT CALLBACK SerialPortHookProc(int code, WPARAM wParam, LPARAM lParam) { if (code >= 0) { if (wParam == HC_ACTION) // 监听串口通信事件 { PMSG pMsg = reinterpret_cast<PMSG>(lParam); if (pMsg->message == WM_COMMNOTIFY) // 检查通信通知消息 { // 在这里可以获取串口通信相关信息并进行自定义操作 std::cout << "Serial port communication event detected!" << std::endl; } } } return CallNextHookEx(g_hookHandle, code, wParam, lParam); } int main() { // 安装钩子 g_hookHandle = SetWindowsHookEx(WH_GETMESSAGE, SerialPortHookProc, NULL, GetCurrentThreadId()); if (g_hookHandle == NULL) { std::cout << "Failed to install hook!" << std::endl; return -1; } std::cout << "Serial port hook installed. Press any key to exit." << std::endl; std::cin.get(); // 卸载钩子 UnhookWindowsHookEx(g_hookHandle); return 0; } ``` 这个示例代码使用`SetWindowsHookEx`函数安装一个全局的钩子来拦截串口通信事件。钩子处理函数中,我们检查钩子事件的消息类型,如果是串口通信相关的消息(如`WM_COMMNOTIFY`),则可以获取相关信息并进行自定义操作。 请注意,为了安装全局钩子,程序需要具有管理员权限。另外,这个示例只是演示了如何安装钩子监控串口通信,具体的操作和处理逻辑需要根据你的实际需求来进行调整。 希望这个示例对你有所帮助!如果你还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值