小型翻译软件的实现原理是什么?(300分)(300分)

  • 主题发起人 主题发起人 cqcredit
  • 开始时间 开始时间
C

cqcredit

Unregistered / Unconfirmed
GUEST, unregistred user!
有谁知道一般翻译软件的实现原理吗? 类似于中文之星,南极之星.用DELPHI开发工具可以实现吗?我要求完成以下功能:<br>&nbsp; &nbsp; 1.可以仅翻译我指定的某个软件或界面,当然整个windows界面可以切换也可以.<br>&nbsp; &nbsp; 2.仅要求支持简体中文翻译成越南文,及简体中文翻译成英文.<br>&nbsp; &nbsp; 3.在windowsXP和windows2000下可以运行.主要在windowsXP下运行.<br>&nbsp; &nbsp; 4.翻译的语言包可以自定义
 
两部分:翻译引擎与界面更新。<br>前者涉及到字典与部分人工智能,后者涉及到运行期的输出截获与资源分析修改。
 
有用到屏幕取詞技朮﹐當然你得有相應的詞庫﹐<br>用D當然能實現。。這部分在 思科的 &lt;&lt;Delphi深入Windows核心編程&gt;&gt;里有。。。不過這書現在很難買到了。。。
 
给我做一个外包吧
 
to: housir<br>&nbsp; 可以简单说一下原理吗?
 
主题  屏幕取词技术系列讲座(一)<br>作者   亦东<br>很多人对这个问题感兴趣。<br>原因是这项技术让人感觉很神奇,也很有商业价值。<br>现在词典市场金山词霸占了绝对优势,所以再做字典也没什么前途了。我就是这么认为的,所以我虽然掌握了这项技术,却没去做字典软件。只做了一个和词霸相似的软件自己用,本来想拿出来做共享软件,但我的词库是“偷”来的,而且词汇不多,所以也就算了,词库太小,只能取词有什么用呢?而且词霸有共享版的。<br>但既然很多人想了解这项技术,我也不会保留。我准备分多次讲述这项技术的所有细节。<br>大约每周一两次。想知道的人就常常来看看吧!<br>一.基础知识<br>首先想编这种程序需要一些基础知识。<br>会用Vc++,包括16/32位。<br>精通Windows API特别是GDI,KERNEL部分。<br>懂汇编语言,会用softice调试程序,因为这种程序最好用softice调试。<br>二.基本原理<br>在Window 3.x时代,windows系统提供的字符输出函数只有很少的几个。<br>TextOut<br>ExtTextOut<br>DrawText<br>......<br>其中DrawText最终是用ExtTextOut实现的。<br>所以Windows的所有字符输出都是由调用TextOut和ExtTextOut实现的。因此,如果你可以修改这两个函数的入口,让程序先调用你自己的一个函数再调用系统的字符输出,你就可以得到Windows所有输出的字符了。<br>到了Windows95时代,原理基本没变,但是95比3.x要复杂。开始的时候,一些在windows3.x下编写的取词软件仍然可以是使用。但是后来出了个IE4,结果很多词典软件就因为不支持IE4而被淘汰了,但同时也给一些软件创造了机会,如金山词霸。其实IE4的问题并不复杂,只不过它的输出的是unicode字符,是用TextOutW和ExtTextOutW输出的。知道了这一点,只要也截取就可以了。不过实现方法复杂一点,以后会有详细讲解。现在又出了个IE5,结果词霸也不好用了,微软真是#^@#$%$*&amp;^&amp;#@#@..........<br>我研究后找到了一种解决办法,但还有些问题,有时会取错,正在继续研究,希望大家共同探讨。<br>另外还有WindowsNT,原理也是一样,只是实现方法和95下完全不同。<br>三.技术要点<br>要实现取词,主要要解决以下技术问题。<br>1.截取API入口,获得API的参数。<br>2.安全地潜入Windows内部,良好地兼容Windows的各个版本<br>3.计算鼠标所在的单词和字母。<br>4.如果你在Window95下,做32位程序,还涉及Windows32/16混合编程的技术。<br>今天先到这里吧!最好准备一份softice for 95/98和金山词霸,让我们先来分析一下别人是怎么做的。<br>欢迎与我联系<br>E-Mail:yeedong@163.net<br>主题  屏幕取词技术系列讲座(二)<br>作者   亦东<br>很抱歉让大家久等了!<br>我看了一些人的回帖,发现很多人对取词的原理还是不太清楚。<br>首先我来解释一下hook问题。词霸中的确用到了hook,而且他用了两种hook其中一种是Windows标准hook,通过SetWindowHook安装一个回调函数,它安装了一个鼠标hook,是为了可以及时响应鼠标的消息用的和取词没太大关系。<br>另一种钩子是API钩子,这才是取词的核心技术所在。他在TextOut等函数的开头写了一个jmp语句,跳转到自己的代码里。<br>你用softice看不到这个跳转语句是因为它只在取词的一瞬间才存在,平时是没有的。<br>你可以在TextOut开头设一个读写断点<br>bpm textout<br>再取词,就会找到词霸用来写钩子的代码了。<br>/**********************************<br>所以我在次强调,想学这种技术一定要懂汇编语言和熟练使用softice.<br>**********************************/<br>至于从cjktl95中dump出来的未公开函数是和Windows32/16混合编程有关的,以后我会提到他们。<br>我先来讲述取词的过程,<br>0 判断鼠标是否在一个地方停留了一段时间<br>1 取得鼠标当前位置<br>2 以鼠标位置为中心生成一个矩形<br>3 挂上API钩子<br>4 让这个矩形产生重画消息<br>5 在钩子里等输出字符<br>6 计算鼠标在哪个单词上面,把这个单词保存下来<br>7 如果得到单词则摘掉API钩子,在一段时间后,无论是否得到单词都摘掉API钩子<br>8 用单词查词库,显示解释框。<br>很多步骤实现起来都有一些难度,所以在中国可以做一个完善的取词词典的人屈指可数。<br>其中0,1,2,7,8比较简单就不提了。<br>先说如何挂钩子:<br>所谓钩子其实就是在WindowsAPI入口写一个JMP XXXX:XXXX语句,跳转到自己的代码里。<br>步骤如下:<br>1.取得Windows API入口,用GetProcAddress实现<br>2.保存API入口的前五个字节,因为JMP是0xEA,地址是4个字节<br>3.写入跳转语句<br>这步最复杂<br>Windows的代码段本来是不可以写的,但是Microsoft给自己留了个后门。<br>有一个未公开函数是AllocCsToDsAlias,<br>UINT WINAPI ALLOCCSTODSALIAS(UINT);<br>你可以取到这个函数的入口,把API的代码段的选择符(要是不知道什么是选择符,就先去学学保护模式编程吧)传给他,他会返回一个可写的数据段选择符。这个选择符用完要释放的。用新选择符和API入口的偏移量合成一个指针就可以写windows的代码段了。<br>这就是取词技术的最核心的东东,不止取词,连外挂中文平台全屏汉化都是使用的这种技术。现在知道为什么这么简单的几句话却很少知道了吧?因为太多的产品使用他,太多的公司靠他赚钱了。<br>这些公司和产品有:中文之星,四通利方,南极星,金山词霸,实达铭泰的东方快车,roboword,译典通,即时汉化专家等等等等。。。。还有至少20多家小公司。他们的具体实现虽然不同,但大致原理是相同的。<br>我这些都是随手写的,也没有提纲之类的东西,以后如果有机会我会整理一下,大家先凑合着看吧!xixi...<br>?<br>主题  关于屏幕取词的讨论(三)<br>作者   亦东<br><br>让大家久等,很抱歉,前些时候工作忙硬盘又坏了,太不幸了。<br>这回来点真格的。<br>咱们以截取TextOut为例。<br>下面是代码:<br>//截取TextOut<br>typedef UINT (WINAPI* ALLOCCSTODSALIAS)(UINT);<br>ALLOCCSTODSALIAS AllocCsToDsAlias;<br>BYTE NewValue[5];//保存新的入口代码<br>BYTE OldValue[5];//API原来的入口代码<br>unsigned char * Address=NULL;//可写的API入口地址<br>UINT DsSelector=NULL;//指向API入口的可写的选择符<br>WORD OffSetEntry=NULL;//API的偏移量<br>BOOL bHookAlready = FALSE; //是否挂钩子的标志<br>BOOL InitHook()<br>{<br>HMODULE hKernel,hGdi;<br>hKernel = GetModuleHandle("Kernel");<br>if(hKernel==NULL)<br>return FALSE;<br>AllocCsToDsAlias = (ALLOCCSTODSALIAS)GetProcAddress(hKernel,"AllocCsToDsAlias");//这是未公开的API所以要这样取地址<br>if(AllocCsToDsAlias==NULL)<br>return FALSE;<br>hGdi = GetModuleHandle("Gdi");<br>if(hmGdi==NULL)<br>return FALSE;<br>FARPROC Entry = GetProcAddress(hGdi,"TextOut");<br>if(Entry==NULL)<br>return FALSE;<br>OffSetEntry = (WORD)(FP_OFF(Entry));//取得API代码段的选择符<br>DsSelector = AllocCsToDsAlias(FP_SEG(Entry));//分配一个等同的可写的选择符<br>Address = (unsigned char*)MK_FP(DsSelector,OffSetEntry);//合成地址<br>NewValue[0]=0xEA;<br>*((DWORD*)(NewValue+1)) = (DWORD)MyTextOut;<br>OldValue[0]=Address[0];<br>*((DWORD*)(OldValue+1)) = *((DWORD*)(Address+1));<br>}<br>BOOL ClearHook()<br>{<br>if(bHookAlready)<br>HookOff();<br>FreeSelector(DsSelector);<br>}<br>BOOL HookOn()<br>{<br>if(!bHookAlready){<br>for(int i=0;i&lt;5;i++){<br>Address=NewValue;<br>}<br>bHookAlready=TRUE;<br>}<br>}<br>BOOL HookOff()<br>{<br>if(bHookAlready){<br>for(int i=0;i&lt;5;i++){<br>Address=OldValue;<br>}<br>bHookAlready=FALSE;<br>}<br>}<br>//钩子函数,一定要和API有相同的参数和声明<br>BOOL WINAPI MyTextOut(HDC hdc,int nXStart,int nYStart,LPCSTR lpszString,UINT cbString)<br>{<br>BOOL ret;<br>HookOff();<br>ret = TextOut(hdc,nXStart,nYStart,lpszString,cbString);//调原来的TextOut<br>HookOn();<br>return ret;<br>}<br>上面的代码是一个最简单的挂API钩子的例子,我要提醒大家的是,这段代码是我凭记忆写的,我以前的代码丢了,我没有编译测试过<br>因为我没有VC++1.52.所以代码可能会有错。<br>建议使用Borland c++,按16位编译。<br>如果用VC++1.52,则要改个选项<br>在VC++1.52的Option里,有个内存模式的设置,选大模式,和"DS!=SS DS Load on Function entry.",切记,否则会系统崩溃。<br>有什么不明白的可以给我写信<br>yeedong@163.net
 
谢谢大家的回答,我想对问题作以下补充和强调:<br>&nbsp; 1.我需要对软件界面全部进行翻译处理,而不是采用金山词霸那种方式,鼠标移动到单词上,才翻译.<br>&nbsp; 2.希望有高手能提供DELPHI的演示程序.<br>&nbsp; 3.是否可以对我指定的某个应用程序进行翻译,其它不进行翻译.
 
提取资源,然后修改,VC/VB,BC/DElphi/PB 格式不同,当然也不一定能够翻译完整.汉化工具漫天飞,Updating &nbsp; Resources &nbsp; <br>&nbsp; The &nbsp; following &nbsp; example &nbsp; copies &nbsp; a &nbsp; dialog &nbsp; box &nbsp; resource &nbsp; from &nbsp; one &nbsp; executable &nbsp; file, &nbsp; Hand.exe, &nbsp; to &nbsp; another, &nbsp; Foot.exe, &nbsp; by &nbsp; following &nbsp; these &nbsp; steps: &nbsp; &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; Use &nbsp; the &nbsp; LoadLibrary &nbsp; function &nbsp; to &nbsp; load &nbsp; the &nbsp; executable &nbsp; file &nbsp; Hand.exe. &nbsp; &nbsp; <br>&nbsp; Use &nbsp; the &nbsp; FindResource &nbsp; and &nbsp; LoadResource &nbsp; functions &nbsp; to &nbsp; locate &nbsp; and &nbsp; load &nbsp; the &nbsp; dialog &nbsp; box &nbsp; resource. &nbsp; &nbsp; <br>&nbsp; Use &nbsp; the &nbsp; LockResource &nbsp; function &nbsp; to &nbsp; retrieve &nbsp; a &nbsp; pointer &nbsp; to &nbsp; the &nbsp; dialog &nbsp; box &nbsp; resource &nbsp; data. &nbsp; &nbsp; <br>&nbsp; Use &nbsp; the &nbsp; BeginUpdateResource &nbsp; function &nbsp; to &nbsp; open &nbsp; an &nbsp; update &nbsp; handle &nbsp; to &nbsp; Foot.exe. &nbsp; &nbsp; <br>&nbsp; Use &nbsp; the &nbsp; UpdateResource &nbsp; function &nbsp; to &nbsp; copy &nbsp; the &nbsp; dialog &nbsp; box &nbsp; resource &nbsp; from &nbsp; Hand.exe &nbsp; to &nbsp; Foot.exe. &nbsp; &nbsp; <br>&nbsp; Use &nbsp; the &nbsp; EndUpdateResource &nbsp; function &nbsp; to &nbsp; complete &nbsp; the &nbsp; update. &nbsp; &nbsp; <br>&nbsp; The &nbsp; following &nbsp; code &nbsp; implements &nbsp; these &nbsp; steps. &nbsp; &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; HRSRC &nbsp; hResLoad; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // &nbsp; handle &nbsp; to &nbsp; loaded &nbsp; resource &nbsp; &nbsp; <br>&nbsp; HANDLE &nbsp; hExe; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // &nbsp; handle &nbsp; to &nbsp; existing &nbsp; .EXE &nbsp; file &nbsp; &nbsp; <br>&nbsp; HRSRC &nbsp; hRes; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // &nbsp; handle/ptr. &nbsp; to &nbsp; res. &nbsp; info. &nbsp; in &nbsp; hExe &nbsp; &nbsp; <br>&nbsp; HANDLE &nbsp; hUpdateRes; &nbsp; &nbsp; // &nbsp; update &nbsp; resource &nbsp; handle &nbsp; &nbsp; <br>&nbsp; char &nbsp; *lpResLock; &nbsp; &nbsp; &nbsp; &nbsp; // &nbsp; pointer &nbsp; to &nbsp; resource &nbsp; data &nbsp; &nbsp; <br>&nbsp; BOOL &nbsp; result; &nbsp; &nbsp; <br>&nbsp; // &nbsp; Load &nbsp; the &nbsp; .EXE &nbsp; file &nbsp; that &nbsp; contains &nbsp; the &nbsp; dialog &nbsp; box &nbsp; you &nbsp; want &nbsp; to &nbsp; copy. &nbsp; &nbsp; <br>&nbsp; hExe &nbsp; = &nbsp; LoadLibrary("hand.exe"); &nbsp; &nbsp; <br>&nbsp; if &nbsp; (hExe &nbsp; == &nbsp; NULL) &nbsp; &nbsp; <br>&nbsp; { &nbsp; &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ErrorHandler("Could &nbsp; not &nbsp; load &nbsp; exe."); &nbsp; &nbsp; <br>&nbsp; } &nbsp; &nbsp; <br>&nbsp; &nbsp; &nbsp; <br>&nbsp; // &nbsp; Locate &nbsp; the &nbsp; dialog &nbsp; box &nbsp; resource &nbsp; in &nbsp; the &nbsp; .EXE &nbsp; file. &nbsp; &nbsp; <br>&nbsp; hRes &nbsp; = &nbsp; FindResource(hExe, &nbsp; "AboutBox", &nbsp; RT_DIALOG); &nbsp; &nbsp; <br>&nbsp; if &nbsp; (hRes &nbsp; == &nbsp; NULL) &nbsp; &nbsp; <br>&nbsp; { &nbsp; &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ErrorHandler("Could &nbsp; not &nbsp; locate &nbsp; dialog &nbsp; box."); &nbsp; &nbsp; <br>&nbsp; } &nbsp; &nbsp; <br>&nbsp; &nbsp; &nbsp; <br>&nbsp; // &nbsp; Load &nbsp; the &nbsp; dialog &nbsp; box &nbsp; into &nbsp; global &nbsp; memory. &nbsp; &nbsp; <br>&nbsp; hResLoad &nbsp; = &nbsp; LoadResource(hExe, &nbsp; hRes); &nbsp; &nbsp; <br>&nbsp; if &nbsp; (hResLoad &nbsp; == &nbsp; NULL) &nbsp; &nbsp; <br>&nbsp; { &nbsp; &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ErrorHandler("Could &nbsp; not &nbsp; load &nbsp; dialog &nbsp; box."); &nbsp; &nbsp; <br>&nbsp; } &nbsp; &nbsp; <br>&nbsp; &nbsp; &nbsp; <br>&nbsp; // &nbsp; Lock &nbsp; the &nbsp; dialog &nbsp; box &nbsp; into &nbsp; global &nbsp; memory. &nbsp; &nbsp; <br>&nbsp; lpResLock &nbsp; = &nbsp; LockResource(hResLoad); &nbsp; &nbsp; <br>&nbsp; if &nbsp; (lpResLock &nbsp; == &nbsp; NULL) &nbsp; &nbsp; <br>&nbsp; { &nbsp; &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ErrorHandler("Could &nbsp; not &nbsp; lock &nbsp; dialog &nbsp; box."); &nbsp; &nbsp; <br>&nbsp; } &nbsp; &nbsp; <br>&nbsp; &nbsp; &nbsp; <br>&nbsp; // &nbsp; Open &nbsp; the &nbsp; file &nbsp; to &nbsp; which &nbsp; you &nbsp; want &nbsp; to &nbsp; add &nbsp; the &nbsp; dialog &nbsp; box &nbsp; resource. &nbsp; &nbsp; <br>&nbsp; hUpdateRes &nbsp; = &nbsp; BeginUpdateResource("foot.exe", &nbsp; FALSE); &nbsp; &nbsp; <br>&nbsp; if &nbsp; (hUpdateRes &nbsp; == &nbsp; NULL) &nbsp; &nbsp; <br>&nbsp; { &nbsp; &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ErrorHandler("Could &nbsp; not &nbsp; open &nbsp; file &nbsp; for &nbsp; writing."); &nbsp; &nbsp; <br>&nbsp; } &nbsp; &nbsp; <br>&nbsp; &nbsp; &nbsp; <br>&nbsp; // &nbsp; Add &nbsp; the &nbsp; dialog &nbsp; box &nbsp; resource &nbsp; to &nbsp; the &nbsp; update &nbsp; list. &nbsp; &nbsp; <br>&nbsp; result &nbsp; = &nbsp; UpdateResource(hUpdateRes, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // &nbsp; update &nbsp; resource &nbsp; handle &nbsp; &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RT_DIALOG, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // &nbsp; change &nbsp; dialog &nbsp; box &nbsp; resource &nbsp; &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "AboutBox", &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // &nbsp; dialog &nbsp; box &nbsp; name &nbsp; &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MAKELANGID(LANG_NEUTRAL, &nbsp; SUBLANG_NEUTRAL), &nbsp; &nbsp; // &nbsp; neutral &nbsp; language &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lpResLock, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // &nbsp; ptr &nbsp; to &nbsp; resource &nbsp; info &nbsp; &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SizeofResource(hExe, &nbsp; hRes)); &nbsp; // &nbsp; size &nbsp; of &nbsp; resource &nbsp; info. &nbsp; &nbsp; <br>&nbsp; if &nbsp; (result &nbsp; == &nbsp; FALSE) &nbsp; &nbsp; <br>&nbsp; { &nbsp; &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ErrorHandler("Could &nbsp; not &nbsp; add &nbsp; resource."); &nbsp; &nbsp; <br>&nbsp; } &nbsp; &nbsp; <br>&nbsp; &nbsp; &nbsp; <br>&nbsp; // &nbsp; Write &nbsp; changes &nbsp; to &nbsp; FOOT.EXE &nbsp; and &nbsp; then &nbsp; close &nbsp; it. &nbsp; &nbsp; <br>&nbsp; if &nbsp; (!EndUpdateResource(hUpdateRes, &nbsp; FALSE)) &nbsp; &nbsp; <br>&nbsp; { &nbsp; &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ErrorHandler("Could &nbsp; not &nbsp; write &nbsp; changes &nbsp; to &nbsp; file."); &nbsp; &nbsp; <br>&nbsp; } &nbsp; &nbsp; <br>&nbsp; &nbsp; &nbsp; <br>&nbsp; // &nbsp; Clean &nbsp; up. &nbsp; &nbsp; <br>&nbsp; if &nbsp; (!FreeLibrary(hExe)) &nbsp; &nbsp; <br>&nbsp; { &nbsp; &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ErrorHandler("Could &nbsp; not &nbsp; free &nbsp; executable."); &nbsp; &nbsp; <br>&nbsp; }
 
wr960204: 翻译软件,我自行定义语言库就行了,你可以实现吗? 留个联系方式! 我的联系方式cqcredit@163.com
 
楼主是不是想要这种效果:程序后台运行,打开其他外文软件,自动显示出翻译后中文菜单、按钮。<br>如果是这样的话,是不是应该考虑修改其他软件的内存,或者通过消息控制其他进程?
 
问题还是没有解决!
 
后退
顶部