一种带有划词功能的屏幕取词实现方法转让专利

申请号 : CN201010590534.6

文献号 : CN102043623B

文献日 :

基本信息:

PDF:

法律信息:

相似专利:

发明人 : 姚敏尹建伟吕方敏阙杭宁沈正伟吴朝晖

申请人 : 浙江大学

摘要 :

本发明公开了一种带有划词功能的屏幕取词实现方法,包括以下步骤:步骤一:在计算机设备Windows操作系统的dll程序中利用SetWindowsHookEx API函数加载全局鼠标钩子;步骤二:当鼠标悬停的时间超过使用者设定的停留时间,鼠标钩子捕捉到鼠标停留消息WM_MOUSEHOVER后,程序执行以下操作,重画窗口;挂载API钩子,截获API函数;位置匹配;步骤三:当鼠标钩子捕捉到鼠标左键弹起消息WM_LBUTTONUP时,程序执行以下操作,保存剪贴板上的内容;模拟Ctrl+C操作;获得取词内容;恢复剪贴板内容。与现有技术相比,本发明既能方便用户使用,又能保证取词的通用性和准确性。

权利要求 :

1.一种带有划词功能的屏幕取词实现方法,其特征在于包括以下步骤:步骤一:安装全局鼠标钩子

在计算机设备Windows操作系统的dll程序中利用SetWindowsHookEx API函数加载全局鼠标钩子,用于捕捉鼠标的各个消息;当鼠标钩子捕捉到鼠标停留消息WM_MOUSEHOVER时,程序执行屏幕取词操作,其中,所述WM_MOUSEHOVER的停留时间,可以根据使用者的习惯设定;当鼠标钩子捕捉到鼠标左键弹起消息WM_LBUTTONUP时,程序执行划词取词操作;

步骤二:屏幕取词

当鼠标悬停的时间超过使用者设定的停留时间,安装的鼠标钩子捕捉到鼠标停留消息WM_MOUSEHOVER后,程序执行以下操作,a.重画窗口

通过所述鼠标钩子获取鼠标指针在显示器上当前位置的坐标数据,并将此数据保存到计算机设备的内存中,根据坐标数据,在鼠标位置下选取一个1px×1px的微小矩形框,利用API函数InvalidateRect向该矩形框发送重画消息,重画窗口;

b.挂载API钩子,截获API函数

当计算机设备的Windows系统接收到重画消息时,底层的操作系统会立即调用系统动态链接库GDI32.dll中的ExtTextOutW、ExtTextOutA、TextOutW、TextOutA这些API函数来进行文字输出,此时令程序挂载API钩子,通过API钩子截获进程对上述API函数的调用,取得该API函数的参数,从而实现对输出字符串的捕捉;

c.位置匹配

在捕捉到输出字符串后,计算出该字符串所在矩形框的边界的坐标值,然后将计算机内存中存储的当前鼠标坐标位置与该矩形框的边界坐标做比较,如果鼠标位置在矩形框内,证明该字符串就是鼠标当前所指向的字符串,直接输出即可;反之不予输出;

步骤三:划词取词

当鼠标钩子捕捉到鼠标左键弹起消息WM_LBUTTONUP时,程序执行以下操作,a.保存剪贴板上的内容在程序中,应用OpenClipboard函数打开系统剪贴板,再通过GetClipboardData函数获取剪贴板上的文本内容数据,并将其保存到计算机的内存中,定义其变量名为g_oldString,再调用CloseClipboard函数关闭系统剪贴板;

b.模拟Ctrl+C操作

在保存完剪贴板上的内容后,程序调用keybd_event函数分别模拟“Ctrl”和“C”键被按下,即进行一次复制的操作,鼠标划词的文字内容数据取代剪贴板上原有的内容数据;

c.获得取词内容

同上述 步骤三a,再 次应用所 述OpenClipboard函数打开 剪贴板,利 用GetClipboardData函数将其中的文本内容数据保存到计算机的内存中,以便在应用程序中使用;再调用所述CloseClipboard函数关闭系统剪贴板;

d.恢复剪贴板内容

应用所述OpenClipboard函数打开剪贴板,利用SetClipboardData函数将步骤三a中保存在计算机内存中的g_oldString变量值写到剪贴板中,用于恢复剪贴板上原有的内容;最后调用所述CloseClipboard函数关闭系统剪贴板。

说明书 :

一种带有划词功能的屏幕取词实现方法

技术领域

[0001] 本发明涉及屏幕上的取词方法,尤其是在Windows操作系统下的一种带有划词功能的屏幕取词实现方法。

背景技术

[0002] 随着信息时代的来临,各式各样的文字信息充斥在人们的电脑上。有时,为了获取屏幕上的词语,用户不得不通过复制、粘贴等一系列繁琐的操作来获得该词,这给用户带来极大不便。人们希望可以通过更简单的操作来提取屏幕上的词语。于是,屏幕上的取词技术应运而生。现有的屏幕上的取词方法主要有两种:
[0003] 一是屏幕取词,该方法通过移动鼠标来直接提取屏幕上鼠标所在位置的词语,采用该方法,用户获取词语的操作方式简单、快捷,不足之处有二,1.由于分词技术不够成熟,从而导致取到的词语不够准确,与用户的想法不符,2.有些应用软件采用了一些特殊的文字输出方式(如pdf阅读器输出的为图片格式),致使屏幕取词功能在其中完全丧失,给用户的使用带来不便;
[0004] 二是划词取词,即用户通过拖拽鼠标划取屏幕上的词语来获取词语,与屏幕取词相比,该方法能够更准确地取到屏幕上的词语,可以在一些屏幕取词取不到的地方取词,但取词操作较屏幕取词繁琐。
[0005] 为克服屏幕取词和划词取词的不足,我们提出将划词取词和屏幕取词结合起来使用的方法,取两者取词之优点。将划词取词和屏幕取词相结合,传统的认识是不能实现的。然而,经过研究我们发现,将屏幕取词和划词取词结合到一起在技术上是完全能够实现的。因为,在Windows操作系统下,屏幕上的文字大多数都是通过动态库GDI32.dll中的ExtTextOutW、ExtTextOutA、TextOutW、TextOutA四个函数输出的,其中ExtTextOutW和TextOutW用于Unicode字符的输出,而ExtTextOutA和TextOutA用于ANSI字符的输出,因此,想要抓取屏幕上的词语只需通过API HOOK技术拦截系统对以上API函数的调用,并从中截获这些函数的参数即可,这便是实现屏幕取词的通用方法。本发明在实现上述传统屏幕取词的基础上,创造性的融入了划词取词的方法,实现了划词取词和屏幕取词的有机结合。

发明内容

[0006] 本发明的目的在于:提供一种带有划词功能的屏幕取词实现方法,既能方便用户使用,又能保证取词的通用性和准确性。
[0007] 本发明为解决技术问题所采用的技术方案为:
[0008] 本发明一种带有划词功能的屏幕取词实现方法,包括以下步骤:
[0009] 步骤一:安装全局鼠标钩子
[0010] 在计算机设备Windows操作系统的dll程序中利用SetWindowsHookEx API函数加载全局鼠标钩子,用于捕捉鼠标的各个消息;当鼠标钩子捕捉到鼠标停留消息WM_MOUSEHOVER时,程序执行屏幕取词操作,其中,所述WM_MOUSEHOVER的停留时间,可以根据使用者的习惯设定;当鼠标钩子捕捉到鼠标左键弹起消息WM_LBUTTONUP时,程序执行划词取词操作;
[0011] 步骤二:屏幕取词
[0012] 当鼠标悬停的时间超过使用者设定的停留时间,安装的鼠标钩子捕捉到鼠标停留消息WM_MOUSEHOVER后,程序执行以下操作,
[0013] a.重画窗口
[0014] 通过所述鼠标钩子获取鼠标指针在显示器上当前位置的坐标数据,并将此数据保存到计算机设备的内存中,根据坐标数据,在鼠标位置下选取一个1px×1px的微小矩形框,利用API函数InvalidateRect向该矩形框发送重画消息,重画窗口;
[0015] b.挂载API钩子,截获API函数
[0016] 当计算机设备的Windows系统接收到重画消息时,底层的操作系统会立即调用系统动态链接库GDI32.dll中的ExtTextOutW、ExtTextOutA、TextOutW、TextOutA这些API函数来进行文字输出,此时令程序挂载API钩子,通过API钩子截获进程对上述API函数的调用,取得该API函数的参数,从而实现对输出字符串的捕捉;
[0017] c.位置匹配
[0018] 在捕捉到输出字符串后,计算出该字符串所在矩形框的边界的坐标值,然后将计算机内存中存储的当前鼠标坐标位置与该矩形框的边界坐标做比较,如果鼠标位置在矩形框内,证明该字符串就是鼠标当前所指向的字符串,直接输出即可;反之不予输出;
[0019] 步骤三:划词取词
[0020] 当鼠标钩子捕捉到鼠标左键弹起消息WM_LBUTTONUP时,程序执行以下操作,[0021] a.保存剪贴板上的内容
[0022] 在程序中,应用OpenClipboard函数打开系统剪贴板,再通过GetClipboardData函数获取剪贴板上的文本内容数据,并将其保存到计算机的内存中,定义其变量名为g_oldString,再调用CloseClipboard函数关闭系统剪贴板;
[0023] b.模拟Ctrl+C操作
[0024] 在保存完剪贴板上的内容后,程序调用keybd_event函数分别模拟“Ctrl”和“C”键被按下,即进行一次复制的操作,鼠标划词的文字内容数据取代剪贴板上原有的内容数据;
[0025] c.获得取词内容
[0026] 同上述步骤三a,再次应用所述OpenClipboard函数打开剪贴板,利用GetClipboardData函数将其中的文本内容数据保存到计算机的内存中,以便在应用程序中使用;再调用所述CloseClipboard函数关闭系统剪贴板;
[0027] d.恢复剪贴板内容
[0028] 应用所述OpenClipboard函数打开剪贴板,利用SetClipboardData函数将步骤三a中保存在计算机内存中的g_oldString变量值写到剪贴板中,用于恢复剪贴板上原有的内容;最后调用所述CloseClipboard函数关闭系统剪贴板。
[0029] 本发明的有益效果:本发明采用了全局鼠标钩子,并通过模拟键盘操作“Ctrl+C”(复制操作)来替换并获取剪贴板上取词内容,实现了划词取词和屏幕取词的有机结合,而且还能够及时回复剪切板中原有的内容数据,与现有的屏幕上的取词方法相比,具有如下有益效果,
[0030] 一、进程边界墙被打破,在大多数程序中均可正常取到词(如pdf阅读器输出的图片格式),即使在部分应用程序中,屏幕取词功能受限,但是有划词取词的补充,依然能够保障取词功能的正常实现;
[0031] 二、仅通过鼠标移动就可获取屏幕上的词语,方便快捷,省去复制、粘贴等繁琐操作;
[0032] 三、在方便快捷的同时,取词更有准确性的保证;
[0033] 四、两种取词方式可供选择,用户可根据个人习惯、喜好进行挑选。

附图说明

[0034] 图1是本发明的屏幕取词的实现方法流程示意图;
[0035] 图2是本发明的划词取词的实现方法流程示意图。

具体实施方式

[0036] 如图1和图2所示,本发明一种带有划词功能的屏幕取词实现方法,其具体实施包括以下步骤:
[0037] 步骤一:安装全局鼠标钩子
[0038] 在计算机设备Windows操作系统的dll程序中利用SetWindowsHookEx API函数加载全局鼠标钩子。关于SetWindowsHookEx函数的具体用法,很多书中都有提到,并且这不是本发明的重点所在,因此这里不再赘述。
[0039] 设定捕捉到鼠标消息后的预处理函数为GetMsgProc。在GetMsgProc需要处理鼠标的以下几种消息:
[0040] WINAPI GetMsgProc(MSG*msg)
[0041] {
[0042] if(msg->message==WM_MOUSEMOVE){
[0043] g_ptCurrentPoint.x=msg->pt.x;
[0044] g_ptCurrentPoint.y=msg->pt.y;//得到鼠标的当前坐标[0045] }
[0046] else if(msg->message==WM_MOUSEHOVER)
[0047] ScreeGetWord();
[0048] else if(msg->message==WM_LBUTTONUP)
[0049] DrugGetWord();
[0050] }
[0051] 当鼠标钩子捕捉到鼠标停留消息WM_MOUSEHOVER时,可以认为鼠标正悬停于取词处,此时执行屏幕取词操作,其中,鼠标钩子捕捉到鼠标停留消息WM_MOUSEHOVER的停留时间,可以根据使用者的习惯设定;当鼠标钩子捕捉到鼠标左键弹起消息WM_LBUTTONUP时,可以认为用户已经划词完毕,程序执行划词取词操作;
[0052] 步骤二:屏幕取词
[0053] 在安装鼠标钩子的过程中,用到的API函数有SetWindowsHookEx,当安装的鼠标钩子捕捉到鼠标停留消息WM_MOUSEHOVER时,程序执行以下操作,
[0054] a.重画窗口
[0055] 利用鼠标钩子得到鼠标的当前位置,然后在鼠标位置下选取一个1px×1px的小矩形框(若矩形框选取过大,会造成屏幕闪烁),利用API函数InvalidateRect向矩形框发送重画消息,重画窗口;
[0056] RECT rc;
[0057] rc.left=g_ptCurrentPoint.x;
[0058] rc.top=g_ptCurrentPoint.y;
[0059] rc.right=g_ptCurrentPoint.x+1;
[0060] rc.bottom=g_ptCurrentPoint.y+1;
[0061] InvalidateRect(g_hwndCurrentWnd,&rc,TRUE);//发送重画消息[0062] b.挂载API钩子,截获API函数
[0063] 在拦截API函数的时候,采用现有技术通用的改写输入地址表来实现。具体的步骤如下:
[0064] 1)找到gdi32.dll模块的基地址:
[0065] HMODULE hmodule=GetModuleHandle(“gdi32.dll”);
[0066] 2)获取API函数的地址,以TextOutA为例:
[0067] FARPROC m_pfnRawProc=GetProcAddress(hmodule,”TextOutA”);
[0068] 3)调用ImageDirectoryEntryToData函数查看某应用程序是否有输入节(即是否需要加载动态库)。如果返回NULL说明该程序没有输入节,则不做任何操作直接返回。
[0069] 4)如果有输入节,ImageDirectoryEntryToData将返回指向输入节信息的指针。扫描所有的输入节信息,查看其中是否有gdi32.dll模块,如果没有,则不做任何操作直接返回。
[0070] 5)如果找到gdi32.dll模块就可以得到一个IMAGE-THUNK-DATA结构的数组地址,在该地址中包含输入符号信息。依次扫描该数组地址,查找是否有和要拦截的API函数地址想匹配的地址。
[0071] 6)如果查找到有这些API函数的地址,则用WriteProcessMemory函数将AP原型函数的入口地址改为我们自己写的替代函数地址。
[0072] 7)在替代函数中,即可取得其中的参数为程序所用,在使用完后,必须调用原型API函数,以免影响系统正常工作。以TextOutA为例,其替代函数为:
[0073] BOOL WINAPI Hook_TextOutA(HDC hdc,intx,int y,LPCSTR IpString,int c)[0074] {
[0075] //这里进行对IpString的处理
[0076] ……
[0077] //调用原型API函数
[0078] int iResult=((pfnTextOutA)(PROC)g_TextOutA)(hdc,x,y,IpString,c);
[0079] return iResult;
[0080] }
[0081] c.位置匹配
[0082] 在替代函数Hook_TextOutA的参数中,lpString即为要输出屏幕的文字。而x、y为该字符串的左上角的x、y坐标值。利用GetTextExtentPoint32W函数可以得到当前字符串中单个字符的大小,从而可以计算出整个字符串的矩形框坐标。代码如下:
[0083] if(g_ptCurrentPoint.x>=RectWord.left && g_ptCurrentPoint.x<=[0084] RectWord.right && g_ptCurrentPoint.y>=RectWord.top&&
[0085] g_ptCurrentPoint.x<=RectWord.bottom)
[0086] {
[0087] //鼠标正处在当前字符串内,可以对其进行输出或其他操作[0088] …
[0089] }
[0090] 以上为屏幕取词的具体实现过程。
[0091] 步骤三:划词取词
[0092] 划词一般有三个动作,即鼠标左键按下、拖拽、左键弹起。在划词取词中主要就是对剪贴板的操作。当鼠标钩子捕捉到鼠标左键弹起消息WM_LBUTTONUP时,程序执行以下操作,
[0093] a.保存剪贴板上的内容
[0094] 应用一些系统函数可以实现剪贴板内容的提取。
[0095] if(OpenClipboard(NULL)) //打开剪贴板
[0096] {
[0097] HANDLE hClipboardData=GetClipboardData(CF_TEXT);//获取内容[0098] char*tempc=(char*)GlobalLock(hClipboardData);//锁定[0099] g_oldString=tempc; //保存内容
[0100] GlobalUnlock(hClipboardData);//解除锁定
[0101] CloseClipboard();
[0102] }
[0103] b.模拟Ctrl+C操作
[0104] 调用keybd_event函数即可实现按键模拟操作:
[0105] keybd_event(VK_CONTROL,MapVirtualKey(VK_CONTROL,0),0,0);
[0106] keybd_event(′C′,MapVirtualKey(′C′,0),0,0);
[0107] keybd_event(′C′,MapVirtualKey(′C′,0),KEYEVENTF_KEYUP,0);
[0108] keybd_event(VK_CONTROL,MapVirtualKey(VK_CONTROL,0),
[0109] KEYEVENTF_KEYU P,0);
[0110] c.获得取词内容
[0111] 这里同步骤三a的保存剪贴板内容的操作一样,保存取词内容,取词完成。
[0112] d.恢复剪贴板内容
[0113] 用OpenClipboard()打开剪贴板后,调用系统函数SetClipboardData()实现剪贴板内容的恢复。
[0114] if(OpenClipboard(NULL)) //打开剪贴板
[0115] {
[0116] EmptyClipboard(); //清空剪贴板
[0117] SetClipboardData(g_oldString);//设置剪贴板内同为原来内容[0118] CloseClipboard();
[0119] }
[0120] 以上步骤必须在接收到鼠标WM_LBUTTONUP消息后迅速执行,中间不可穿插过多其余操作,否则恢复剪贴板内容时间过长,有可能导致用户复制、粘贴操作过快而剪贴板内容还没来得及恢复的情况出现,粘贴功能受到影响。