精华内容
下载资源
问答
  • 屏幕取词原理与实现

    2012-02-17 11:31:45
    文章描述了通过截获系统API实现 Windows NT内核屏幕取词的方法。以一个屏幕取词应用的具体实现为主线, 对实现屏幕取词的关键技术——截获API(API Hook) ——进行了详细的分析。其中涉及的相关技术有Windows内存...
  • 屏幕取词原理 -- HOOK消息功能的使用
  • 屏幕取词原理

    2011-12-28 00:48:44
    给出屏幕取词的一种C#实现,可供学习者尝试
  • 屏幕取词原理.doc 屏幕取词原理.doc 屏幕取词原理.doc 屏幕取词原理.doc
  • 自己写的 金山词霸类翻译软件的屏幕取词的原理性的源代码 分为三个部分 dll中是HOOK TextOutA的代码和安装钩子的代码 test是目标程序 此程序使用了TextOut函数 DLL_test是将DLL注入到目标程序的
  • GetWord是一款专业的屏幕取词组件(控件),它可以帮助您在公司产品中快速便捷地集成屏幕取词功能,有效降低软件开发成本。目前,遍布世界各地的50多个国家和地区的众多客户都在使用GetWord。这些客户有:Apple(美国...
  • 鼠标屏幕取词技术的原理和实现 “鼠标屏幕取词”技术是在电子字典中得到广泛地应用的,如四通利方和金山词霸等软件,这个技术看似简单,其实在WINDOWS系统中实现却是非常复杂的,总的来说有两种实现方式: 第一种:...
  • “鼠标屏幕取词”技术是在电子字典中得到广泛地应用的,如四通利方和金山词霸等软件,这个技术看似简单,其实在windows系统中实现却是非常复杂的
  • 屏幕取词技术实现原理

    千次阅读 2016-10-29 02:47:24
    屏幕取词技术实现原理   1.2. 需要用到winapi (不推荐,传统方法、】 需要进行全局鼠标Hook 然后在Hook事件里 根据鼠标的位置找到相应window的handle (WindowFromPoint) 再取回文本...

    屏幕取词技术实现原理

     



    1.2. 需要用到winapi  (不推荐,传统方法、】


    需要进行全局鼠标Hook
    然后在Hook事件里 根据鼠标的位置找到相应window的handle  (WindowFromPoint)
    再取回文本(GetWindowText)

     

    为什么不推荐这个方法呢,很简单,跨系统性很差,不说xp win7 vista ,平板,linuxmac机不能通用。。不能兼容未来的位置gui系统。。

     

    而且,对于使用自绘ui界面的系统来说,也不能使用。。

     

    还有好多app是安卓体系下的app,通过模拟器在pc上运行,也不能截取这类app的文字。。

     

     

    此外 文档少,实现难度也大,比较麻烦。

     

    1.3. 推荐使用截屏+ocr

    优点,十分明显,跨系统 gui体系。自绘还是win api还是Linuxmac界面,安卓系统app界面,全部统统一网打尽。。

     

    1.4. 具体流程大概如下

    获取鼠标坐标,这个很容易获取到。连js都可以容易获取到。

    鼠标选取

    第二,截取坐标范围文本。,因为鼠标选取了,文字反白了,很容易获得文字区域。。

    Ocr得到文字。。

    这样就得到文字了。。。

     

    至于得到文字后如何处理,一般是显示一个翻译框到文字或者鼠标附近。。

    涉及到gui的东西,当然最好使用跨平台跨gui系统最好的h5技术啦。。可以使用javac#做个html解析器(一般使用browser控件即可)外壳,里面调用h5即可啦。。可以使用html css来控制显示的效果,方便快捷

     

    参考资料

    屏幕取词技术实现原理与关键源码 - 伯乐共勉 - 博客园.html

     

    作者:: 绰号:老哇的爪子 ( 全名::Attilax Akbar Al Rapanui 阿提拉克斯 阿克巴 阿尔 拉帕努伊 ) 

    汉字名:艾提拉(艾龙)   EMAIL:1466519819@qq.com

    转载请注明来源: http://blog.csdn.net/attilax

    Atiend

     

    展开全文
  • 鼠标屏幕取词原理 (VC++)

    千次阅读 2009-09-23 10:00:00
    “鼠标屏幕取词”技术是在电子字典中得到广泛地应用的,如四通利方和金山词霸等软件,这个技术看似简单,其实在windows系统中实现却是非常复杂的,总的来说有两种实现方式: 第一种:采用截获对部分gdi的api调用来...
    “鼠标 屏幕取词”技术是在电子字典中得到广泛地应用的,如四通利方和金山词霸等软件,这个技术看似简单,其实在windows系统中实现却是非常复杂的,总的来说有两种实现方式: 
    第一种:采用截获对部分gdi的api调用来实现,如textout,textouta等。 
    第二种:对每个设备上下文(dc)做一分copy,并跟踪所有修改上下文(dc)的操作。 
    第二种方法更强大,但兼容性不好,而第一种方法使用的截获windowsapi的调用,这项技术的强大可能远远超出了您的想象,毫不夸张的说,利用windowsapi拦截技术,你可以改造整个操作系统,事实上很多外挂式windows中文平台就是这么实现的!而这项技术也正是这篇文章的主题。 
    截windowsapi的调用,具体的说来也可以分为两种方法: 
    第一种方法通过直接改写winapi 在内存中的映像,嵌入汇编代码,使之被调用时跳转到指定的地址运行来截获;第二种方法则改写iat(import address table 输入地址表),重定向winapi函数的调用来实现对winapi的截获。 
    第一种方法的实现较为繁琐,而且在win95、98下面更有难度,这是因为虽然微软说win16的api只是为了兼容性才保留下来,程序员应该尽可能地调用32位的api,实际上根本就不是这样!win 9x内部的大部分32位api经过变换调用了同名的16位api,也就是说我们需要在拦截的函数中嵌入16位汇编代码! 
    我们将要介绍的是第二种拦截方法,这种方法在win95、98和nt下面运行都比较稳定,兼容性较好。由于需要用到关于windows虚拟内存的管理、打破进程边界墙、向应用程序的进程空间中注入代码、pe(portable executable)文件格式和iat(输入地址表)等较底层的知识,所以我们先对涉及到的这些知识大概地做一个介绍,最后会给出拦截部分的关键代码。 
    先说windows虚拟内存的管理。windows9x给每一个进程分配了4gb的地址空间,对于nt来说,这个数字是2gb,系统保留了2gb到 4gb之间的地址空间禁止进程访问,而在win9x中,2gb到4gb这部分虚拟地址空间实际上是由所有的win32进程所共享的,这部分地址空间加载了共享win32 dll、内存映射文件和vxd、内存管理器和文件系统码,win9x中这部分对于每一个进程都是可见的,这也是win9x操作系统不够健壮的原因。win9x中为16位操作系统保留了0到4mb的地址空间,而在4mb到2gb之间也就是win32进程私有的地址空间,由于 每个进程的地址空间都是相对独立的,也就是说,如果程序想截获其它进程中的api调用,就必须打破进程边界墙,向其它的进程中注入截获api调用的代码,这项工作我们交给钩子函数(setwindowshookex)来完成,关于如何创建一个包含系统钩子的动态链接库,《电脑高手杂志》在第?期已经有过专题介绍了,这里就不赘述了。所有系统钩子的函数必须要在动态库里,这样的话,当进程隐式或显式调用一个动态库里的函数时,系统会把这个动态库映射到这个进程的虚拟地址空间里,这使得dll成为进程的一部分,以这个进程的身份执行,使用这个进程的堆栈,也就是说动态链接库中的代码被钩子函数注入了其它gui进程的地址空间(非gui进程,钩子函数就无能为力了), 
    当包含钩子的dll注入其它进程后,就可以取得映射到这个进程虚拟内存里的各个模块(exe和dll)的基地址,如: 
    hmodule hmodule=getmodulehandle(“mypro.exe”); 
    在mfc程序中,我们可以用afxgetinstancehandle()函数来得到模块的基地址。exe和dll被映射到虚拟内存空间的什么地方是由它们的基地址决定的。它们的基地址是在链接时由链接器决定的。当你新建一个win32工程时, vc++链接器使用缺省的基地址0x00400000。可以通过链接器的base选项改变模块的基地址。exe通常被映射到虚拟内存的0x00400000处,dll也随之有不同的基地址,通常被映射到不同进程 
    的相同的虚拟地址空间处。 
    系统将exe和dll原封不动映射到虚拟内存空间中,它们在内存中的结构与磁盘上的静态文件结构是一样的。即pe (portable executable) 文件格式。我们得到了进程模块的基地址以后,就可以根据pe文件的格式穷举这个模块的image_import_descriptor数组,看看进程空间中是否引入了我们需要截获的函数所在的动态链接库,比如需要截获“textouta”,就必须检查“gdi32.dll”是否被引入了。说到这里,我们有必要介绍一下pe文件的格式,如右图,这是pe文件格式的大致框图,最前面是文件头,我们不必理会,从pe file optional header后面开始,就是文件中各个段的说明,说明后面才是真正的段数据,而实际上我们关心的只有一个段,那就是“.idata”段,这个段中包含了所有的引入函数信息,还有iat(import address table)的rva(relative virtual address)地址。 
    说到这里,截获windowsapi的整个原理就要真相大白了。实际上所有进程对给定的api函数的调用总是通过pe文件的一个地方来转移的,这就是一个该模块(可以是exe或dll)的“.idata”段中的iat输入地址表(import address table)。在那里有所有本模块调用的其它dll的函数名及地址。对其它dll的函数调用实际上只是跳转到输入地址表,由输入地址表再跳转到dll真正的函数入口。 

    具体来说,我们将通过image_import_descriptor数组来访问“.idata”段中引入的dll的信息,然后通过image_thunk_data数组来针对一个被引入的dll访问该dll中被引入的每个函数的信息,找到我们需要截获的函数的跳转地址,然后改成我们自己的函数的地址……具体的做法在后面的关键代码中会有详细的讲解。 
    讲了这么多原理,现在让我们回到“鼠标 屏幕取词”的专题上来。除了api函数的截获,要实现“鼠标 屏幕取词”,还需要做一些其它的工作,简单的说来,可以把一个完整的取词过程归纳成以下几个步骤: 
    1. 安装鼠标钩子,通过钩子函数获得鼠标消息。 
    使用到的api函数:setwindowshookex 
    2. 得到鼠标的当前位置,向鼠标下的窗口发重画消息,让它调用系统函数重画窗口。 
    使用到的api函数:windowfrompoint,screentoclient,invalidaterect 
    3. 截获对系统函数的调用,取得参数,也就是我们要取的词。 
    对于大多数的windows应用程序来说,如果要取词,我们需要截获的是“gdi32.dll”中的“textouta”函数。 
    我们先仿照textouta函数写一个自己的mytextouta函数,如: 
    bool winapi mytextouta(hdc hdc, int nxstart, int nystart, lpcstr lpszstring,int cbstring) 

    // 这里进行输出lpszstring的处理 
    // 然后调用正版的textouta函数 

    把这个函数放在安装了钩子的动态连接库中,然后调用我们最后给出的hookimportfunction函数来截获进程 
    对textouta函数的调用,跳转到我们的mytextouta函数,完成对输出字符串的捕捉。hookimportfunction的 
    用法: 
    hookfuncdesc hd; 
    proc porigfuns; 
    hd.szfunc="textouta"; 
    hd.pproc=(proc)mytextouta; 
    hookimportfunction (afxgetinstancehandle(),"gdi32.dll",&hd,porigfuns); 
    下面给出了hookimportfunction的源代码,相信详尽的注释一定不会让您觉得理解截获到底是怎么实现的 
    很难,ok,let’s go: 

    / begin /// 
    #include 

    // 这里定义了一个产生指针的宏 
    #define makeptr(cast, ptr, addvalue) (cast)((dword)(ptr)+(dword)(addvalue)) 

    // 定义了hookfuncdesc结构,我们用这个结构作为参数传给hookimportfunction函数 
    typedef struct tag_hookfuncdesc 

    lpcstr szfunc; // the name of the function to hook. 
    proc pproc; // the procedure to blast in. 
    } hookfuncdesc , * lphookfuncdesc; 

    // 这个函数监测当前系统是否是windownt 
    bool isnt(); 

    // 这个函数得到hmodule -- 即我们需要截获的函数所在的dll模块的引入描述符(import descriptor) 
    pimage_import_descriptor getnamedimportdescriptor(hmodule hmodule, lpcstr szimportmodule); 

    // 我们的主函数 
    bool hookimportfunction(hmodule hmodule, lpcstr szimportmodule, 
    lphookfuncdesc pahookfunc, proc* paorigfuncs) 

    /// 下面的代码检测参数的有效性  
    _assert(szimportmodule); 
    _assert(!isbadreadptr(pahookfunc, sizeof(hookfuncdesc))); 
    #ifdef _debug 
    if (paorigfuncs) _assert(!isbadwriteptr(paorigfuncs, sizeof(proc))); 
    _assert(pahookfunc.szfunc); 
    _assert(*pahookfunc.szfunc != ''); 
    _assert(!isbadcodeptr(pahookfunc.pproc)); 
    #endif 
    if ((szimportmodule == null) || (isbadreadptr(pahookfunc, sizeof(hookfuncdesc)))) 

    _assert(false); 
    setlasterrorex(error_invalid_parameter, sle_error); 
    return false; 

    // 

    // 监测当前模块是否是在2gb虚拟内存空间之上 
    // 这部分的地址内存是属于win32进程共享的 
    if (!isnt() && ((dword)hmodule >= 0x80000000)) 

    _assert(false); 
    setlasterrorex(error_invalid_handle, sle_error); 
    return false; 

    // 清零 
    if (paorigfuncs) memset(paorigfuncs, null, sizeof(proc)); 

    // 调用getnamedimportdescriptor()函数,来得到hmodule -- 即我们需要 
    // 截获的函数所在的dll模块的引入描述符(import descriptor) 
    pimage_import_descriptor pimportdesc = getnamedimportdescriptor(hmodule, szimportmodule); 
    if (pimportdesc == null) 
    return false; // 若为空,则模块未被当前进程所引入 

    // 从dll模块中得到原始的thunk信息,因为pimportdesc->firstthunk数组中的原始信息已经 
    // 在应用程序引入该dll时覆盖上了所有的引入信息,所以我们需要通过取得pimportdesc->originalfirstthunk 
    // 指针来访问引入函数名等信息 
    pimage_thunk_data porigthunk = makeptr(pimage_thunk_data, hmodule, 
    pimportdesc->originalfirstthunk); 

    // 从pimportdesc->firstthunk得到image_thunk_data数组的指针,由于这里在dll被引入时已经填充了 
    // 所有的引入信息,所以真正的截获实际上正是在这里进行的 
    pimage_thunk_data prealthunk = makeptr(pimage_thunk_data, hmodule, pimportdesc->firstthunk); 

    // 穷举image_thunk_data数组,寻找我们需要截获的函数,这是最关键的部分! 
    while (porigthunk->u1.function) 

    // 只寻找那些按函数名而不是序号引入的函数 
    if (image_ordinal_flag != (porigthunk->u1.ordinal & image_ordinal_flag)) 

    // 得到引入函数的函数名 
    pimage_import_by_name pbyname = makeptr(pimage_import_by_name, hmodule, 
    porigthunk->u1.addressofdata); 

    // 如果函数名以null开始,跳过,继续下一个函数 
    if ('' == pbyname->name[0]) 
    continue; 

    // bdohook用来检查是否截获成功 
    bool bdohook = false; 

    // 检查是否当前函数是我们需要截获的函数 
    if ((pahookfunc.szfunc[0] == pbyname->name[0]) && 
    (strcmpi(pahookfunc.szfunc, (char*)pbyname->name) == 0)) 

    // 找到了! 
    if (pahookfunc.pproc) 
    bdohook = true; 

    if (bdohook) 

    // 我们已经找到了所要截获的函数,那么就开始动手吧 
    // 首先要做的是改变这一块虚拟内存的内存保护状态,让我们可以自由存取 
    memory_basic_information mbi_thunk; 
    virtualquery(prealthunk, &mbi_thunk, sizeof(memory_basic_information)); 
    _assert(virtualprotect(mbi_thunk.baseaddress, mbi_thunk.regionsize, 
    page_readwrite, &mbi_thunk.protect)); 

    // 保存我们所要截获的函数的正确跳转地址 
    if (paorigfuncs) 
    paorigfuncs = (proc)prealthunk->u1.function; 

    // 将image_thunk_data数组中的函数跳转地址改写为我们自己的函数地址! 
    // 以后所有进程对这个系统函数的所有调用都将成为对我们自己编写的函数的调用 
    prealthunk->u1.function = (pdword)pahookfunc.pproc; 

    // 操作完毕!将这一块虚拟内存改回原来的保护状态 
    dword dwoldprotect; 
    _assert(virtualprotect(mbi_thunk.baseaddress, mbi_thunk.regionsize, 
    mbi_thunk.protect, &dwoldprotect)); 
    setlasterror(error_success); 
    return true; 


    // 访问image_thunk_data数组中的下一个元素 
    porigthunk++; 
    prealthunk++; 

    return true; 


    // getnamedimportdescriptor函数的实现 
    pimage_import_descriptor getnamedimportdescriptor(hmodule hmodule, lpcstr szimportmodule) 

    // 检测参数 
    _assert(szimportmodule); 
    _assert(hmodule); 
    if ((szimportmodule == null) || (hmodule == null)) 

    _assert(false); 
    setlasterrorex(error_invalid_parameter, sle_error); 
    return null; 


    // 得到dos文件头 
    pimage_dos_header pdosheader = (pimage_dos_header) hmodule; 

    // 检测是否mz文件头 
    if (isbadreadptr(pdosheader, sizeof(image_dos_header)) || 
    (pdosheader->e_magic != image_dos_signature)) 

    _assert(false); 
    setlasterrorex(error_invalid_parameter, sle_error); 
    return null; 


    // 取得pe文件头 
    pimage_nt_headers pntheader = makeptr(pimage_nt_headers, pdosheader, pdosheader->e_lfanew); 

    // 检测是否pe映像文件 
    if (isbadreadptr(pntheader, sizeof(image_nt_headers)) || 
    (pntheader->signature != image_nt_signature)) 

    _assert(false); 
    setlasterrorex(error_invalid_parameter, sle_error); 
    return null; 


    // 检查pe文件的引入段(即 .idata section) 
    if (pntheader->optionalheader.datadirectory[image_directory_entry_import].virtualaddress == 0) 
    return null; 

    // 得到引入段(即 .idata section)的指针 
    pimage_import_descriptor pimportdesc = makeptr(pimage_import_descriptor, pdosheader, 
    pntheader->optionalheader.datadirectory[image_directory_entry_import].virtualaddress); 

    // 穷举pimage_import_descriptor数组寻找我们需要截获的函数所在的模块 
    while (pimportdesc->name) 

    pstr szcurrmod = makeptr(pstr, pdosheader, pimportdesc->name); 
    if (stricmp(szcurrmod, szimportmodule) == 0) 
    break; // 找到!中断循环 
    // 下一个元素 
    pimportdesc++; 


    // 如果没有找到,说明我们寻找的模块没有被当前的进程所引入! 
    if (pimportdesc->name == null) 
    return null; 

    // 返回函数所找到的模块描述符(import descriptor) 
    return pimportdesc; 


    // isnt()函数的实现 
    bool isnt() 

    osversioninfo stosvi; 
    memset(&stosvi, null, sizeof(osversioninfo)); 
    stosvi.dwosversioninfosize = sizeof(osversioninfo); 
    bool bret = getversionex(&stosvi); 
    _assert(true == bret); 
    if (false == bret) return false; 
    return (ver_platform_win32_nt == stosvi.dwplatformid); 

    /// end // 

    不知道在这篇文章问世之前,有多少朋友尝试过去实现“鼠标 屏幕取词”这项充满了挑战的技术,也只有尝试过的朋友才能体会到其间的不易,尤其在探索api函数的截获时,手头的几篇资料没有一篇是涉及到关键代码的,重要的地方都是一笔代过,msdn更是显得苍白而无力,也不知道除了image_import_descriptor和image_thunk_data,微软还隐藏了多少秘密,好在硬着头皮还是把它给攻克了,希望这篇文章对大家能有所帮助。
    展开全文
  • c# 实现的屏幕取词

    2016-04-19 20:28:28
    利用金山词霸控件XdictGrb.dll实现的屏幕取词软件源码
  • 就是基本的代码。。。和原理通过这个学习。。。可以截取屏幕上的文字
  • 要用CAJViewer浏览器查看,涉及有关屏幕取词原理与实现
  • GetWord 3.3 屏幕取词

    2020-12-02 06:04:35
    据说针对IE的取词很难,所以也就打消了自己开发的念头,找一找好用的控件。发现了两个可以用的,一个是金山词霸的XdictGrb.dll文件,一个就是上面的GetWord。1.1 金山词霸 XdictGrb.dllC# 的例子似乎不太稳定,取几...

    1. 缘起

    要搞一个作弊软件,需要把屏幕上的试题取下来。

    据说针对IE的取词很难,所以也就打消了自己开发的念头,找一找好用的控件。

    发现了两个可以用的,一个是金山词霸的XdictGrb.dll文件,一个就是上面的GetWord。

    1.1 金山词霸 XdictGrb.dll

    C# 的例子似乎不太稳定,取几个词之后就取不到了,不知道卡在哪里了。

    而且 C# 转换为 Python 也遇到了困难,主要是不太熟悉COM和Python的相互调用,留着以后解决。

    1.2 GetWord 3.3

    GetWord 3.3,自带VB\VC\C#\Delphi的例子。

    大概看了下原理:首先需要自己创建一个窗体。每当控件取词成功之后就会向这个窗口发送一个消息作为通知。窗体接受到消息之后可以做进一步的处理。

    1.3 GetWord 官方版

    官网版本比较高,接口变化挺大的,似乎调用起来比以前方便,不用像 3.3 那样非要自己实现一个窗口来接受消息,直接注册一个回调函数就可以了。可惜的是没有找到官方的例子,按照帮助文档试了试,没成功,也就放弃了。反正3.3也好用。

    2. Python + GetWord 3.3

    GetWord 3.3 有两种调用方式,一种是作为ActiveX控件,一种是直接调用DLL内的函数。还是DLL的方法比较简单。

    下面的代码是从 C# 转过来的,由于没有文档,有些函数也不明白是什么意思,不过照猫画虎的能用。

    import win32con,win32gui,win32api

    import ctypes

    class MyWindow():

    def __init__(self):

    self.getword_loaded = False

    #注册一个窗口类

    wc = win32gui.WNDCLASS()

    wc.lpszClassName = 'MyWindow'

    wc.hbrBackground = win32con.COLOR_BTNFACE+1

    wc.lpfnWndProc = self.wndProc

    class_atom=win32gui.RegisterClass(wc)

    #创建窗口

    self.hwnd = win32gui.CreateWindow(

    class_atom, u'窗口标题', win32con.WS_OVERLAPPEDWINDOW,

    win32con.CW_USEDEFAULT, win32con.CW_USEDEFAULT,

    200, 100,

    0,0, 0, None)

    #显示窗口

    win32gui.ShowWindow(self.hwnd, win32con.SW_SHOWNORMAL)

    self._init_getword()

    def _init_getword(self):

    LICENSEID = "{00000000-0000-0000-0000-000000000000}"

    MOUSEHOOK_CAPTURE_OK_MSG = "MOUSEHOOK_CAPTUREOK_MSG-" + LICENSEID

    self.MOUSEHOOK_CAPTURE_OK = win32gui.RegisterWindowMessage(MOUSEHOOK_CAPTURE_OK_MSG)

    self.icall = ctypes.windll.LoadLibrary('ICall')

    self.icall.SetMouseHook(self.hwnd)

    self.icall.MouseEnableCap(True)

    self.icall.GetWordEnableCap(True)

    self.getword_loaded = True

    def _del_getword(self):

    self.getword_loaded = False

    self.icall.RemoveMouseHook()

    hdll = win32api.GetModuleHandle('ICall.dll')

    win32api.FreeLibrary(hdll)

    def _capture_text(self):

    MAX_OUTPUT_LEN = 1024

    x,y = win32gui.GetCursorPos()

    hrwnd = self.icall.GetRealWindow(x, y)

    strtmp = ctypes.create_unicode_buffer('\0' * MAX_OUTPUT_LEN)

    i=ctypes.c_int(-1)

    ok = self.icall.GetWord(hrwnd, x, y, strtmp, MAX_OUTPUT_LEN, ctypes.byref(i))

    if ok:

    print u'全部文本:%s' % strtmp.value

    print u'单词位置:%s' % i.value

    #消息处理

    def wndProc(self, hwnd, msg, wParam, lParam):

    if self.getword_loaded and msg == self.MOUSEHOOK_CAPTURE_OK:

    print 'MOUSEHOOK_CAPTURE_OK'

    self._capture_text()

    if msg == win32con.WM_CLOSE:

    print 'WM_CLOSE'

    self._del_getword()

    if msg == win32con.WM_DESTROY:

    print 'WM_DESTROY'

    win32gui.PostQuitMessage(0)

    return win32gui.DefWindowProc(hwnd, msg, wParam, lParam)

    mw = MyWindow()

    win32gui.PumpMessages()

    3. 其实也不用那么麻烦

    如果只是用来捕获屏幕上某点的文本,而忽略其提供的一套鼠标和键盘响应机制,那么就十分简单了。

    下面的代码单独封装了取词功能。

    from ctypes import *

    from ctypes import wintypes

    class GetWord():

    '''封装 GetWord 3.3 的取词功能'''

    def __init__(self):

    self.icall = windll.LoadLibrary('ICall.dll')

    self.icall.GetWordEnableCap(True)

    def __del__(self):

    hdll = windll.Kernel32.GetModuleHandleA('ICall.dll')

    windll.Kernel32.FreeLibrary(hdll)

    def getText(self,x,y):

    '''屏幕取词,返回坐标所指的一行文字,以及所指字符在行中的索引'''

    MAX_OUTPUT_LEN = 1024

    hrwnd = self.icall.GetRealWindow(x, y)

    strtmp = create_unicode_buffer('\0' * MAX_OUTPUT_LEN)

    i = c_int(-1)

    ok = self.icall.GetWord(hrwnd, x, y, strtmp, MAX_OUTPUT_LEN, byref(i))

    if ok:

    return strtmp.value, i.value

    鼠标和键盘的响应机制包括判断鼠标悬停、快捷键等功能。下面用 pyHook 勉强模仿一下,粗糙简陋,仅仅作为取词演示。

    from pyHook import HookManager

    from pythoncom import PumpMessages

    _gw = GetWord()

    def onKeyDown(event):

    if event.IsAlt(): #当按下Alt键的时候,进行鼠标取词,并打印出来。

    global _gw

    point = wintypes.POINT()

    windll.User32.GetCursorPos(byref(point))

    r = _gw.getText(point.x, point.y)

    if r:

    print u'整行文本:%s' % r[0]

    print u'字符位置:%s' % r[1]

    return True

    if __name__ == "__main__":

    hm = HookManager()

    hm.KeyDown = onKeyDown

    hm.HookKeyboard()

    PumpMessages()

    基于C#利用金山取词组件实现屏幕取词功能

    这个程序在网上有很多例子,近期要做的项目中有和这个有某些一点点相似的地方,就练练,发现在本机上(Win 7 64位)不能实现其功能,可能原因是API组件太老了吧,毕竟金山大佬公布他的组件是2005年, ...

    delphi中使用词霸2005的动态库XdictGrb.dll实现屏幕取词

    近日来,在网上发现关于屏幕取词技术的捷径,搜索很长时间,发现实现方式以VB出现的居多,但是通过Delphi来实现的却好象没有看到,自己参考着VB的相关代码琢磨了一下通过delphi来实现的方式. 其实 ...

    [代码]--c#实现屏幕取词源码下载

    最近公司有一个 项目需要实现类似于金山词霸,有道词典等的屏幕取词功能,准确来说是划词功能,网上搜了各种屏幕取词无外乎就两种: A.金山词霸组件法 B.Nhw32.dll法 百度搜到的重复内容真的太多了 ...

    mac 10.9开启有道词典取词功能

    取词时候,有道词典给出提示,说要去开启辅助功能,但提示的是在mac 10.8上面怎么操作,在10.9的话,就是以下位置去改了. 补充以下: 在mac机器上,实际上大多数的单词都能从自带的词典中查找到. ...

    有道词典for mac不能取词解决方案

    在mac上装了有道词典,发现在Chrome上不能取词,网上也没有搜到合适的解决方案,后来发现解决这个问题很简单,打开有道词典,点击设置, 再点击软件更新,就会发现有chrome取词插件,安装就OK了. ...

    2013-2-1 pdf中无法用金山词霸取词问题

    打开pdf的编辑——〉首选项——〉一般——〉选项——〉开始——〉只有经过认证的插件,把‘checkbox’里的勾去掉,重启. ★在acrobat reader启动画面里如果没有加载xdict32(工具 ...

    document.selection window.getSelection()

    IE9以下支持:document.selection  IE9.Firefox.Safari.Chrome和Opera支持:window.getSelection() 屏幕取词 function ge ...

    Mac 词典工具推荐:Youdao Alfred Workflow(可同步单词本)

    想必大家都有用过 Mac 下常见的几款词典工具: 特性 系统 Dictionary 欧路词典 Mac 版 有道词典 Mac 版 在线搜索 ✗ ✔ ✔ 屏幕取词 ☆☆☆ ★★☆ ★☆☆ 划词搜索 ★★★ ...

    Linux学习内容

    Linux学习要点(转载自红联) 一.学习Linux的基本要求1. 掌握至少50个以上的常用命令. 2. 熟悉Gnome/KDE等X-windows桌面环境操作 . 3. 掌握.tgz..rpm等软件 ...

    随机推荐

    用js实现动画效果核心方式

    为了做好导航菜单,有时候需要在菜单下拉的时候实现动画效果,所以这几天就研究了研究如何用js实现动画效果,实现动画核心要用到两个函数,一个是setTimeOut,另一个是setInterval. 下边我 ...

    (Xaml) Type 'DeviceA' is not defined.

    修改了一些Xaml, 始终提示 Compiler error(s) encountered processing expression "deviceA.B".Type 'Devi ...

    普通用户安装 R 包

    转自 http://bnuzhutao.cn/archives/901 一般 R 语言的书籍上,介绍安装 R 包的方法都是这样的: install.packages("packagename ...

    JAVA 调用matlab 出错总结

    1.Java:Unsupported major.minor version 51.0 (unable to load class 出现该错误是由于class编译器的JDK版本高于运行期的JDK版本. ...

    unigui TUniTreeView demo

    unit untTree; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, For ...

    日志logger

    1.使用指定类初始化日志对象 在日志输出的时候,可以打印出日志信息所在类如:Logger logger = LoggerFactory.getLogger(com.Book.class);       ...

    HDU 3966 Aragorn's Story (树链点权剖分,成段修改单点查询)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3966 树链剖分的模版,成段更新单点查询.熟悉线段树的成段更新的话就小case啦. //树链剖分 边权修 ...

    抓取天涯文章的蜘蛛代码,刚经过更新(因为天涯页面HTML代码变化)

    #_*_coding:utf-8-*- import urllib2 import traceback import codecs from BeautifulSoup import Beautifu ...

    最强大的跨语言调用生成工具:Swig 快速实用教程

    swig是一个生成其他高级语言调用c和C++代码的工具,比如,大家都知道java的jni,可能没写过,因为非常麻烦,swig可以帮助生成这样的代码,编译生成的代码后,它会生成java类和c代码文件.分 ...

    检测三种不同操作系统的Bash脚本

    检测三种不同操作系统(GNU/Linux, Mac OS X, Windows NT)的Bash脚本. 设计: 1.使用“uname”命令获取系统信息,带上“-s”参数个打印内核名称. 2.使用“ex ...

    展开全文
  • 说到屏幕取词,就是通过拦截windows的显示API,获取输出的文本,然后提取出自己想要的信息的一个技术手段。windows有这么几个常用的,TextOutA,TextOutW,ExtTextOutA,ExtTextOutW以及Diretc3D的一些绘制函数(nopad,...

     说到屏幕取词,就是通过拦截windows的显示API,获取输出的文本,然后提取出自己想要的信息的一个技术手段。windows有这么几个常用的,TextOutA,TextOutW,ExtTextOutA,ExtTextOutW以及Diretc3D的一些绘制函数(nopad,IE的输入框使用的是ExtTextOut, chrome使用的D3D的绘制函数,一些UI库的静态文本框基本是使用textOut),只要HOOK住这个这些函数,就可以完成我们相应的功能了。目前我使用的是detours库:

    该方法使用比较简单,比如;

    static BOOL(WINAPI *OLD_DrawTextExW)(HDC  hdc, LPWSTR  lpchText, int  cchText, LPRECT  lprc, UINT   dwDTFormat, LPDRAWTEXTPARAMS lpDTParams) = DrawTextExW;
    int WINAPI MyDrawTextExW(HDC  hdc, LPWSTR  lpchText, int  cchText, LPRECT  lprc, UINT   dwDTFormat, LPDRAWTEXTPARAMS lpDTParams);
    

    然后在初始化那里调用下面代码,

    DetourAttach(&(PVOID&)OLD_DrawTextExW, MyDrawTextExW);

    当系统每次调用DrawTextExW的时候就会进入我们写的函数MyDrawTextExW。该方法只能对本进程有效,不能HOOK住其它进程里面的东西,如果想HOOK住其它进程里面的函数,那么我们需要进行远程注入,需要调用CreateRemoteThreadEx或者CreateRemoteThread进行远程注入,只要注入到其它进程里面就可以拦截我们想要的API了。最后我们通过管道或者一些通信手段将我们想要的信息发出来即可

    远程注入的方法参考 http://blog.csdn.net/xiaocaiju/article/details/7668473


    至于屏幕取词,原理更加简单,首先先注册一个粘贴板事件,调用 SetClipboardViewer (参加MSDN),然后再通过鼠标钩子拦截鼠标按下以及鼠标弹起时的位置,模拟CTRL + C的按键,发出去就可以了,

    keyAction(VK_CONTROL, 1);
    keyAction('C', 1);
    keyAction('C', 0);
    keyAction(VK_CONTROL, 0);

    当收到粘贴板事件后,通过处理粘贴板里面的数据进行相关操作即可




    展开全文
  • 我的电脑WIN7_64,前两者目前的屏幕取词的支持不太好.尤其是对android studio.后来试了试必应ok了. 必应使用注意:按ctrl进行取词同时鼠标进行移动后才开始实施取词,而不是按ctrl后就直接取词. 为什么找到了必应:在...
  • 1.1. 鼠标取词 屏幕取词技术实现原理       1.2. 需要用到winapi (不推荐,传统方法、】 需要进行全局鼠标Hook然后在Hook事件里 根据鼠标的位置找到相应window的handle (WindowFromPoint)再取回文本...
  • 屏幕取词编程学习总结

    千次阅读 2017-04-22 19:05:06
    屏幕取词的研究 现在词典市场金山词霸占了绝对优势,所以再做字典也没什么前途了。我就是这么认为的,所以我虽然 掌握了这项技术,却没去做字典软件。只做了一个和词霸相似的软件自己用,本来想拿出来做共享软件...
  • 一个用VC写的屏幕取词例子

    热门讨论 2011-07-28 16:27:21
    VC屏幕取词例子,APIHook原理,例子用VS2008编译.
  • 鼠标屏幕取词原理

    千次阅读 2006-07-28 00:22:00
    鼠标屏幕取词 原理“鼠标屏幕取词”技术是在电子字典中得到广泛地应用的,如四通利方和金山词霸等软件,这个技术看似简单,其实在windows系统中实现却是非常复杂的,总的来说有两种实现方式: 第一种:采用截获对...
  • 屏幕取词技术实现原理与关键源码

    千次阅读 2018-01-17 16:00:18
    虽然屏幕取词技术早已经不是什么秘密,以至于除了汉化工具、翻译工具、中文平台等等这些东西之外,连像SnagIt这样的抓图软件也能把抓取屏幕文本的功能做得像模像样,但金山词霸的取词技术就细节而言还是有着众多的...
  • 原文地址::http://www.360doc.com/content/08/0618/21/7635_1348255.shtml    
  • 鼠标屏幕取词技术的原理和实现 “鼠标屏幕取词”技术是在电子字典中得到广泛地应用的,如四通利方和金山词霸等软件,这个技术看似简单,其实在WINDOWS系统中实现却是非常复杂的,总的来说有两种实现方式:  第...
  • Python屏幕取词(整理)

    千次阅读 2017-01-12 11:07:29
    原文地址::... 相关文章 1、屏幕取词技术实现原理与关键源码----http://blog.csdn.net/chuan014/article/details/1569955 Ubuntu 下可以监视 gtk.Clipboard 来获取当前选中文字和位置。  

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,134
精华内容 4,053
关键字:

屏幕取词原理