屏幕划词的实现

最近朋友让我写一个屏幕取词的小工具,考虑了一下主要步骤大致如下:

1.下全局鼠标钩子,Hook鼠标WM_MOUSEMOVE消息

2. WM_MOUSEMOVE消息函数中设定时器,判断鼠标停留时间

3.触发定时器事件,注DLL到目标进程(鼠标停留进程),可根据鼠标位置判断目标进程(GetWindowThreadProcessId),DLL中Hook目标进程的某些函数,如ExtTextOutW等;

4.使目标进程控件强制刷新,以此触发字符串显示函数

5.将Hook到的字符串通过(管道、共享内存、消息)等方式传回屏幕取词进程

6.卸载目标进程注入的DLL(取消函数钩子)

理论上并不复杂,但在实现时发现不同窗体的绘制函数都不一样,Hook和强制刷新存在一定难度,效率也比较低,甚至可能都不如暴力搜索内存效率高,就退而求其次先写了一个屏幕划词的小东西。

屏幕划词比屏幕取词难度就小很多,设置某个热键,触发热键按下事件时通过剪贴板过度选中的词,然后显示出来,我实现的主要步骤如下:

1.通过SetWindowsHookEx函数下全局低级键盘钩子(WH_KEYBOARD_LL),判断键盘按下(WM_KEYUP)及按下的键值(VK_F2)

注:WH_KEYBOARD_LL钩子可以在EXE中直接实现,无需通过DLL

钩子的回调函数大体如下:

 

这时候有人可能会问了,为啥CallNextHookEx第一个参数可以为NULL 【其实我也是某天偶然在MSDN上查了一下这函数,写了好几年才知道第一个参数可以为空……..

2.触发事件,先保存原剪贴板中内容

注:需同时保存内容和格式,剪贴板中可能为图片等其他格式

读取剪贴板代码如下:

3.模拟键盘按键Ctrl+C

注:模拟按下和模拟松开中间要加入一段时间sleep,不然会认为时间太短没有按下

 

 

4.从剪贴板读出划词对应的文本

 

 

我在这里并没有判断格式,直接认为是文本来做的。读出文本之后就可以按照自己的想法对文本进行操作,我就不多说了。

5.将原剪贴板数据回写到剪贴板

 

 

至此为止,屏幕划词的功能已经实现,但在测试中发现,仍然需要开UAC并提权,否则在读某些进程的文本时会出现问题,提权的代码太常规这里就不贴了。

发表评论

电子邮件地址不会被公开。 必填项已用*标注