背景:
由于平时看代码或者浏览网页的时候有很多单词不明白意思,只有通过网页去查询翻译,很是麻烦,之前有下过一个有道划词翻译,感觉吧也是不太好用,后来就突然想用ahk来模仿有道划词翻译,编码了一周多终于完成了,不能说一样,只能说一模一样吧,嘻嘻 (#^.^#)
原理:
利用粘贴板获取选中(不会干扰粘贴板)调用搜狗翻译嵌套进入GUI的activeX控件中渲染出结果,可以这样理解就是把搜狗翻译网页界面的部分区域扣下来放到自己的GUI中,
搜狗翻译:年轻人不讲武德!!!
适用范围:
可以翻译基本所有页面上的单词,短语,句子,翻译多种语言,中英韩日等语言。为了降低划词灵敏度,设置了鼠标左键按下为工形,弹起为工形才触发划词,如果有特殊需求可以自行修改代码,代码会在下面贴出。
优点:
- 不调用第三方云接口
- 不依赖外部ahk文件
- 可以翻译任何界面的选中目标,界面还不错
- 可以支持多种语言中英韩日等,反正搜狗翻译网页能翻译啥它就能翻译啥,官方说的是支持50多种语言
不足:
- 由于ie版本限制 无法发出语音,(ie11也不行,实际activeX中的ie版本更低) 用其他浏览器都行
- 搜狗翻译网页有个机器人限制,但是频次不是很高,基本触发不了,如果触发了,到网页中输入验证码即可
- 由于是网络爬虫,如果哪天搜狗翻译把网页结构改了可能要重新编写代码
使用方法:
使用ahk1.x u32版本运行
划词翻译:在需要翻译的目标上划词选中(鼠标为工形) 或者是双击选中目标(鼠标为工形),这时会弹出一个红桃♠ (可以替换),点击红桃即可对选中目标进行翻译
快捷键翻译:选中目标(不管是怎么选中按shift选中也行) ,然后按ctlr+1 执行翻译。
tip:
可以通过通过设置(在代码中修改use_shortcut_trans=1默认是0)来关闭划词翻译只是用快捷键翻译!
我在代码中准备了很多图标,可供选择,如果不够可以到网上搜索图形符号然后转码成unicode。 图标的大小,形状,颜色都是可以修改的。
效果:
直接上效果
快捷键翻译效果
可能是录制帧数的问题,实际是没有黑框的,效果是很丝滑的。
完整代码:
;==========================================================================================================
;author tmz 2023年1月8日19:17:10 ahk_v1.x U32版本
;类似有道的划词翻译,支持双击.支持划词选中 后弹出小图标(可以自定义形状大小颜色)点击即可得到翻译结果
;可以翻译一些单词,短语,短句
;原理 :利用粘贴板获取选中(不会干扰粘贴板)调用搜狗翻译嵌套进入gui的activeX控件中渲染出结果
;优点:①.不调用第三方云接口 ②不依赖外部ahk文件 ③.界面是真的好看,哈哈 ~~④.可以支持多种语言中英韩日等.
;不足:由于ie版本限制 无法发出语音...大无语 ,(ie11也不行,实际activeX中的ie版本更低) 用其他浏览器都行
;搜狗翻译网页有个机器人限制,但是频次不是很高,基本触发不了,如果触发了,到网页中输入验证码即可
;如果搜狗翻译网页变动可能导致翻译不出来,但是改改代码照样用。
;注意请用U32版本运行!!!
;==========================================================================================================
#InstallMouseHook
#InstallKeybdHook
#KeyHistory 499
CoordMode,Mouse,Screen ;全局获取模式
OnMessage(0x100 , "keyboard_message_callback") ;键盘事件
;移动选框
WM_LBUTTONDOWN(){
Static init:=OnMessage(0x0201, "WM_LBUTTONDOWN")
if(A_Cursor="Arrow")
PostMessage, 0xA1, 2
return ;
}
;键盘事件的回调函数
keyboard_message_callback(wparam,lparma,msg)
{
WinGetActiveTitle, active_title
; tooltip ,% active_title ":" wParam
if((wparam=13 || wparam=27) && active_title=SoGouTrans.html_title ) ;响应回车事件和esc事件
{
Gui Translate2:destroy
}
}
;设置快捷键打开,我还是喜欢点击图标打开,快捷键自己改,改了之后设置use_shortcut_trans=1即可
$^1::
MouseGetPos, xpos, ypos
; tooltip , CN, % xpos, % ypos+20
select_str:=SoGouTrans.create_ico_gui(xpos,ypos) ;创建ico
if(!select_str)
{
; setTimer ,label_destroy_ico,off ;关闭定时器
Gui ,translate:destroy
return
}
try SoGouTrans.init_transhtml_gui(0) ;创建翻译结果
return ;
;Translate.create_trans_result_ui(800,600)
~LButton::
if(SoGouTrans.use_shortcut_trans)
return ;
; tooltip % A_PriorHotkey "," A_TimeSincePriorHotkey
;判断gui是否存在,存在就摧毁
; gui ,translate:Destroy
SoGouTrans.LB_down_cursor:=A_Cursor
if(A_PriorHotkey="~LButton up" && A_TimeSincePriorHotkey<=SoGouTrans.cursor_dbclick_gaptime && A_Cursor="IBeam" && SoGouTrans.trans_doubclick_on) ;判断鼠标双击事件
{
; tooltip % A_PriorHotkey "," A_TimeSincePriorHotkey
WinGetActiveTitle, active_title
if(active_title=SoGouTrans.html_title)
return
MouseGetPos, xpos, ypos
; tooltip , CN, % xpos, % ypos+20
SoGouTrans.create_ico_gui(xpos,ypos) ;创建ico
}
return ;
~LButton up::
WinGetActiveTitle, active_title
if(active_title=SoGouTrans.html_title)
return ;
else
gui ,translate2:destroy
if(SoGouTrans.use_shortcut_trans)
return ;
WinGetClass, active_class ,% active_title
; tooltip % active_title
if(active_title=SoGouTrans.ico_title)
return ;A_TimeSincePriorHotkey 当点击到ico上面的时候这个玩意就不准了、所以要这样返回防止重新创建ico
; tooltip % A_PriorHotkey "," A_TimeSincePriorHotkey
if(A_PriorHotkey="~LButton" && A_TimeSincePriorHotkey>=SoGouTrans.cursor_drag_gaptime ) ;判断鼠标拖动事件
{
if((SoGouTrans.LB_down_cursor="IBeam" && A_Cursor="IBeam") || active_class="TXGuiFoundation") ; 让它支持在qq中翻译
{
MouseGetPos, xpos, ypos
SoGouTrans.create_ico_gui(xpos,ypos) ;创建ico
}
return
}
; if(active_title!=SoGouTrans.ico_title)
; {
; gui ,translate:destroy
; }
return
GuiEscape:
msgBox ok
Gui Translate2:Destroy
return
;ico点击动画
label_ico_click_animate:
{
SoGouTrans.animate_timer_count:=SoGouTrans.animate_timer_count+1
if(SoGouTrans.html_ready || SoGouTrans.ico_new|| SoGouTrans.animate_timer_count*SoGouTrans.animate_timer_gap>SoGouTrans.animate_out_time)
{
setTimer ,label_ico_click_animate,off ; 关闭定时器
GuiControl,translate:hide ,Ico_wait_text1 ;停止显示动画
GuiControl,translate:hide ,Ico_wait_text2 ;停止显示动画
GuiControl,translate:hide ,Ico_wait_text3 ;停止显示动画
return
}
ico_wait_shape :=Util.decodeUtf8(SoGouTrans.ico_wait_shape)
ico_wait_shape :=SoGouTrans.ico_wait_shape
ico_size:=SoGouTrans.ico_size
wait1_offset_x:=1.5*ico_size
wait2_offset_x:=2*ico_size
wait3_offset_x:=2.5*ico_size
ico_color:=SoGouTrans.ico_color
i:=SoGouTrans.animate_timer_count ;INDEX 从1开始
if(i=1)
{
global Ico_wait_text1
global Ico_wait_text2
global Ico_wait_text3
}
if(i<=3)
{
offset_x:=(0.46*i+1)*ico_size-SoGouTrans.point_to_ico
Gui ,translate:Add, Text, vIco_wait_text%i% x%offset_x% y0 c%ico_color%, % ico_wait_shape ; label_gui_event标签处理gui事件
}else
{
loop ,% mod(i,4) ;显示
{
; tooltip loop1=Ico_wait_text%A_index%
GuiControl,translate:show ,Ico_wait_text%A_index%
}
loop ,% 3-(mod(i,4)) ;隐藏
{
hide_index:=4-A_index
GuiControl,translate:hide ,Ico_wait_text%hide_index%
}
}
; MouseGetPos ,x ,y
; toolTip % "x:" x " y:" y
return
}
;gui事件处理 https://ahkcn.sourceforge.net/docs/Variables.htm#GuiEvent
label_gui_event:
{
if(A_GuiControl="Ico_text" && A_GuiControlEvent="Normal") ;点击翻译图标时触发
{
;初始化并渲染翻译结果GUI
try SoGouTrans.init_transhtml_gui(1)
; msgBox ok
}
return ;
}
;延时后去掉ico
label_destroy_ico:
{
SoGouTrans.ico_timer_count:=SoGouTrans.ico_timer_count+1
IfWinNotExist ,% SoGouTrans.html_title
{
if(SoGouTrans.ico_timer_count*50>=SoGouTrans.ico_destroy_time)
{
Gui, Translate:destroy
setTimer ,label_destroy_ico,off
setTimer, label_ico_click_animate ,off
}
}
return ;
}
;搜狗翻译
class SoGouTrans
{
; static ico_shape :="H"
; static ico_shape :="\u2742" ;❂
; static ico_shape :="\u2664" ;♤
; static ico_shape :="\u2B1B" ;⬛
; static ico_shape :="\u2693" ;⚓
; static ico_shape :="\u2693" ;⚓
; static ico_shape :="\uD83D\uDC10" ;?
; static ico_shape :="\uD83C\uDF51" ;?
; static ico_shape :="\uD83C\uDFEF" ;?
; static ico_shape :="\u2764" ;❤
; static ico_shape :="\u265E" ;♞
; static ico_shape :="\u2663" ;♣
; static ico_shape :="\u265C" ;♜
; static ico_shape :="\u2602" ;☂
static ico_shape :="\u2660" ;♠ ;图形字符对应的unicode编码
; static ico_wait_shape :="\u25CF" ;● 等待的图标
static ico_wait_shape :="." ;● 等待的图标
static ico_size:= 15 ;图标大小, 对象变量必须在new中初始化
static ico_offset_x:= 10 ;翻译图标偏离鼠标点击位置x轴的距离
static ico_offset_y:= 6 ;翻译图标偏离鼠标点击位置y轴的距离
static ico_color:= "ff0000" ;翻译图标颜色,只支持16进制ffffff,不支持颜色单词
static ico_title:="ahk_translate_ico_v1" ;翻译的小图标
static html_title:="ahk_translate_result_v1" ;翻译的小图标
static html_scala:=0.8 ;缩放 范围(0-1] (0最小,1最大)
static ico_hwnd ;小图标的句柄
static html_hwnd ;html的句柄
static select_word ;选中字符
static ico_x ;图标所在x位置
static ico_y ;图标所在y位置
static hide_flag ;当前图标在单击其它区域后后影藏,除非是
static trans_doubclick_on:=1 ;是否支持双击选词 0不支持,1支持
static cursor_drag_gaptime:=300 ;判断鼠标按下到弹起时间差单位ms 来判断拖动
static cursor_dbclick_gaptime:=100 ;判断鼠标双击时间差单位ms 来判断双击
static html_head ;缓存头部
static html_foot ;缓存尾部
static gui_width:=520 ;显示html的宽度,缩放之前
static ignore_title ;忽略翻译的
static grid_width:=15 ;背景取样格子大小,单位像素
static LB_down_cursor ; 左键按下时鼠标形状
static timer_flag ; 判断当前是否还在定时器中执行
static ico_destroy_time :=3000 ;ico在多少ms内不点击的情况下消失
static ico_timer_count:=0 ;消失ico的timer执行的次数
static ico_new ;是否新建ico ,1是,0否
static html_ready :=0 ;当前html页面是否加载完成
static animate_timer_count:=0 ;当前动画计时器执行次数
static animate_timer_gap:=200 ;定时器周期时长 单位ms
static animate_out_time :=10000 ;动画超时时间 (超过时间关闭定时器),单位ms
static click_down_posx ;
static cursor_row_min_dist :=6 ;横向距离 单位px
static use_shortcut_trans :=0 ;是否使用快捷键翻译 ,1使用快捷键翻译,0使用图标翻译。
static point_to_ico := 5 ;点到ico的距离会减去该值
;在鼠标滑动位置创建一个图标
create_ico_gui(obs_x,obs_y)
{
SoGouTrans.ico_x :=obs_x+SoGouTrans.ico_offset_x+3
SoGouTrans.ico_y :=obs_y+SoGouTrans.ico_offset_y+13
obs_x:=obs_x+SoGouTrans.ico_offset_x
obs_y:=obs_y+SoGouTrans.ico_offset_y
ico_shape :=Util.decodeUtf8(SoGouTrans.ico_shape)
global Ico_text
bg_color :=SoGouTrans.calculate_bg_color(obs_x,obs_y,SoGouTrans.ico_size) ;取点分析背景颜色
; bg_color :=2b2b2b
ico_size:=SoGouTrans.ico_size
ico_color:=SoGouTrans.ico_color
gui_w:=ico_size>16?(2*ico_size-16)+8:ico_size+8
gui_h:=gui_w
gui_title:=SoGouTrans.ico_title
wait3_offset_x:=2.5*ico_size
gui_w:=wait3_offset_x+10
Gui ,translate:New, ,% gui_title
Gui, translate:Color, %bg_color%
; Gui, translate:Color, ffffff
Gui ,translate:+LastFound +HwndMenuHwnd +AlwaysOnTop -Caption +ToolWindow
SoGouTrans.ico_hwnd:=MenuHwnd
Gui, translate:Font, c%ico_color% q1 thin s%ico_size% , Verdana
Gui ,translate:Add, Text, vIco_text x0 y0 c%ico_color% glabel_gui_event, % ico_shape ; label_gui_event标签处理gui事件
WinSet, TransColor, %bg_color% 250 ;设置颜色透明
Gui ,translate:Show, x%obs_x% y%obs_y% w%gui_w% h%gui_h% NoActivate ;NoActivate 让当前活动窗口继续保持活动状态.
WinSet, AlwaysOnTop, Off, % gui_title ;去掉总在最上面限制,在切换窗口的时候可以隐藏,但是并不会关闭
GuiControl,hide ,Ico_wait_text1
GuiControl,hide ,Ico_wait_text2
GuiControl,hide ,Ico_wait_text3
select_str:=Util.getSelectStr() ;获取光标选中字符
StringReplace, select_str,select_str, `r,, All
StringReplace, select_str,select_str, `n,, All
StringReplace, select_str,select_str, `t,, All
SoGouTrans.select_word:= select_str
setTimer ,label_destroy_ico,off ;去掉之前的定时器
setTimer ,label_destroy_ico ,50 ;延时后去掉ico
SoGouTrans.ico_timer_count:=0
SoGOuTrans.ico_new:=1
; fileappend ,% SoGouTrans.select_word,C:\Users\Administrator\Desktop\select.txt
; msgBox % strlen(trim(SoGouTrans.select_word,OmitChars = "`r`n"))
; msgBox % strLen(select_str)
if(strLen(select_str)=0) ;数据为空
{
gui ,translate:destroy ;不显示图标了
return 0
}
return 1
}
;显示翻译结果gui
create_transhtml_gui(obs_x,obs_y)
{
html_page:=SoGouTrans.get_sogou_word_htmlreuslt(SoGouTrans.select_word,"en")
html_page:=html_page?html_page:SoGouTrans.get_sougou_sentence_htmlresult(SoGouTrans.select_word,"zh-CHS")
; msgBox ~ok2
if(!html_page)
return
global WB ;浏览器对象
global MenuHwnd2 ;句柄
gui_width:=SoGouTrans.gui_width*SoGouTrans.html_scala
; gui_width:=830*SoGouTrans.html_scala
gui_title:=SoGouTrans.html_title ;ahk翻译
Gui ,translate2:New,,% gui_title
; sleep ,100
Gui ,translate2:Add, ActiveX,x0 y0 w%gui_width% h1080 vWB, Shell.Explorer ; 最后一个参数是ActiveX组件的名称。
; Gui ,translate2:Add, ActiveX,x0 y0 w600 h1080 vWB, Shell.Explorer ; 最后一个参数是ActiveX组件的名称。
Gui, translate2:Color, 30f0ca
; tooltip % "xx2:" WB.readystate
Gui ,translate2:+LastFound +HwndMenuHwnd2 +AlwaysOnTop -Caption +ToolWindow
SoGouTrans.html_hwnd:=MenuHwnd2
WB.silent := true ;Surpress JS Error boxes
; msgBox % SoGouTrans.select_word
; msgBox % html_page
; html_page:="<h1>hello world!</h1>"
SoGouTrans.Display(WB,html_page)
while WB.readystate != 4 or WB.busy
sleep 10
; div_w:=WB.document.getElementById("mainDiv").offsetWidth
div_h:=WB.document.getElementById("mainDiv").offsetHeight
div_h:=(div_h-20)*SoGouTrans.html_scala-17
div_w:=gui_width-16
; msgBox % div_w
; Gui translate2:Show ,x%obs_x% y%obs_y% w%div_w%h%div_h% NoActivate
SoGouTrans.show_transhtml_gui(obs_x,obs_y,div_w,div_h)
; WinSet, TransColor, 000000 250
Util.FrameShadow(MenuHwnd2) ;窗口阴影
WinSet, AlwaysOnTop, Off, % gui_title ;去掉总在最上面限制,在切换窗口的时候可以隐藏,但是并不会关闭
}
; 初始化并调用翻译结果的gui
init_transhtml_gui(keep_ico)
{
SoGouTrans.html_ready:=0 ;加载完成变成1
SoGouTrans.ico_new:=0 ;创建新的ico变成1
SoGouTrans.animate_timer_count:=0 ;执行一次加一次
SetTimer,label_ico_click_animate,% SoGouTrans.animate_timer_gap ;timer后面必须是一个timer不然无法异步执行
SoGouTrans.create_transhtml_gui(SoGouTrans.ico_x,SoGouTrans.ico_y)
SoGouTrans.html_ready:=1
if(!keep_ico)
Gui ,translate:destroy
}
;调整gui显示的位置,对边界进行处理,gui_w,gui_h是窗口缩放后的宽度高度,x,y是绝对位置
show_transhtml_gui(obs_x,obs_y,div_w,div_h)
{
line_height:=32
screen_w:=A_ScreenWidth ;屏幕宽度
screen_h:=A_ScreenHeight ;屏幕高度
;处理右边界
if(obs_x+div_w>screen_w)
{
obs_x:=screen_w-div_w
}
;处理下边界
if(obs_y+div_h>screen_h)
{
obs_y:=obs_y-line_height-div_h
gui ,translate:destroy ;不显示图标了
}
; Gui translate2:Show ,x%obs_x% y%obs_y% w%div_w%h%div_h% NoActivate
Gui translate2:Show ,x%obs_x% y%obs_y% w%div_w% h%div_h%
}
;展示html
Display(WB,html_str) {
Count:=0
while % FileExist(f:=A_Temp "\" A_TickCount A_NowUTC "-tmp" Count ".DELETEME.html")
Count+=1
FileAppend,%html_str%,%f%,UTF-8
; f=C:\Users\Administrator\Desktop\xx4.html
WB.Navigate("file://" . f)
; msgBox % WB.readystate
}
;获取搜狗输翻译html片段,keyword 要翻译的词汇,language 要翻译成的语言(翻译句子)
get_sougou_sentence_htmlresult(keyword,language)
{
WebRequest := ComObjCreate("WinHttp.WinHttpRequest.5.1") ;创建http对象
uri=https://fanyi.sogou.com/text?keyword=%keyword%&transfrom=auto&transto=%language%&model=general
uri:=Util.urlEncode(uri)
WebRequest.Open("GET", uri) ;必须有http://
WebRequest.Send()
result := WebRequest.ResponseText
ObjRelease(WebRequest) ;释放内存
start_element=<div class="trans-to-bar"> ;搜索结果只有一个
end_element=<div class="operate-box"> ;搜索结果有两个以上,必须以上面一个变量开始搜索
StringReplace, result, result, "//,"https:// ,All ;把路径转换为绝对路径
if(SoGouTrans.get_resulthtml_headfoot(result))
{
html_head_frag:=SoGouTrans.html_head ;
html_foot_frag:=SoGouTrans.html_foot ;
}else {
return ;
}
start_pos:=instr(result,start_element,1,1) ;参数依次是1.目标字符,2.要匹配的字符,3.是否大小写敏感,4.起始位置
if(!start_pos)
return ;
end_pos:= instr(result,end_element,1,start_word_post) ;参数依次是1.目标字符,2.要匹配的字符,3.是否大小写消息敏感,4.起始位置
if(!end_pos)
return
sentence_resulthtml_frag:= subStr(result,start_pos,end_pos-start_pos)
border_color:= SoGouTrans.ico_color
html_scala:=SoGouTrans.html_scala
div_w:= SoGouTrans.gui_width "px"
; StringReplace, sentence_resulthtml_frag, sentence_resulthtml_frag, <div class="trans-box" >, <div class="trans-box" style="width:%div_w%">
left_div_html=<div id="mainDiv" style="zoom:%html_scala%;border-top:5px solid #%border_color%;width:%div_w%"><div class="trans-box"><div id="trans-to" class="trans-to"><div class="trans-con">
result_html=%html_head_frag% %left_div_html% %sentence_resulthtml_frag% </div></div></div></div>%html_foot_frag% ;加入div用于计算html的size
; fileAppend ,% result_html ,C:\Users\Administrator\Desktop\sentence.html,Utf-8
return result_html
}
;获取搜狗输翻译html片段,keyword 要翻译的词汇,language 要翻译成的语言(翻译单词或者短语)
get_sogou_word_htmlreuslt(keyword,language)
{
WebRequest := ComObjCreate("WinHttp.WinHttpRequest.5.1") ;创建http对象
uri=https://fanyi.sogou.com/text?keyword=%keyword%&transfrom=auto&transto=%language%&model=general
uri:=Util.urlEncode(uri)
WebRequest.Open("GET", uri) ;必须有http://
WebRequest.Send()
result := WebRequest.ResponseText
ObjRelease(WebRequest) ;释放内存
StringReplace, result, result, "//,"https:// ,All ;把路径转换为绝对路径
; msgBox ~ok3
; fileAppend ,% result ,C:\Users\Administrator\Desktop\xx.html,Utf-8
start_word=<div class="word-details-card
end_word=<div class="dictionary-list">
if(SoGouTrans.get_resulthtml_headfoot(result))
{
html_head_frag:=SoGouTrans.html_head ;
html_foot_frag:=SoGouTrans.html_foot ;
}else {
return ;
}
start_word_post:=instr(result,start_word,1,1)
if(!start_word_post)
return
; msgBox ~3
end_word_post:=instr(result,end_word,1,start_word_post)
if(!end_word_post || end_word_post<start_word_post)
return
; msgBox ~4
key_word_frag:=subStr(result,start_word_post,end_word_post-start_word_post)
border_color:= SoGouTrans.ico_color
html_scala:=SoGouTrans.html_scala
left_div_html=<div id="mainDiv" style="zoom:%html_scala%;border-top:5px solid #%border_color%"><div class="container" style="width: 50`%"><div class="trans-main" style="width: 200`%"><div class="main-left">
result_html=%html_head_frag% %left_div_html% %key_word_frag% </div></div></div></div>%html_foot_frag% ;加入div用于计算html的size
; fileAppend ,% result_html ,C:\Users\Administrator\Desktop\xx4.html,Utf-8
; fileAppend ,% key_word_frag ,C:\Users\Administrator\Desktop\key_word_frag.html,Utf-8
return result_html
}
;获取翻译结果的html的头尾,并保存
get_resulthtml_headfoot(html)
{
result:=html
body_start=<!--[if lte IE 9]>
body_end=</div><script>
if(SoGouTrans.html_head&&SoGouTrans.html_foot)
{
return 1
}else
{
body_start_post:=instr(result,body_start,1,1)
if(!body_start_post)
return
; msgBox ~1
body_end_post:=instr(result,body_end,1,body_start_post)
if(!body_end_post ||body_end_post<body_start_post )
return
; msgBox ~2
html_head_frag:=subStr(result,1,body_start_post-1)
html_foot_frag:=subStr(result,body_end_post+strLen("</div>"))
SoGouTrans.html_head:= html_head_frag
SoGouTrans.html_foot:= html_foot_frag
return 1
}
}
;计算背景颜色,采集20个点,判断颜色最多的,去掉背景会残留只有融入背景才能让图形更圆滑
calculate_bg_color(obs_x,obs_y,font_size)
{
grid_width:=SoGouTrans.grid_width ;取样格子宽度
x:=obs_x+font_size+10
y:=obs_y+font_size+10
color_map:={}
loop , 5
{
i:=A_Index
loop 4
{
j:=A_Index
PixelGetColor,current_color, % x+j*grid_width,% obs_y+i*grid_width ,RGB
; msgBox % x+j*grid_width "," y+i*grid_width " color:" current_color
if(!color_map[current_color])
color_map[current_color]:=1
else
color_map[current_color]:=color_map[current_color]+1
}
}
tmp_count:=0
tmp_color:=0
for key,value in color_map
{
if(color_map[key]>tmp_count)
{
tmp_count:=color_map[key]
tmp_color:=key
}
}
; msgBox % msg "color:" Util.ToBase(tmp_color,16)
return Util.ToBase(tmp_color,16)
}
}
class Util
{
;解码unicode
decodeUtf8(value)
{
i := 0
while (i := InStr(value, "\",, i+1)) {
if !(SubStr(value, i+1, 1) == "u")
SoGouTrans.ParseError("\", text, pos - StrLen(SubStr(value, i+1)))
uffff := Abs("0x" . SubStr(value, i+2, 4))
if (A_IsUnicode || uffff < 0x100)
value := SubStr(value, 1, i-1) . Chr(uffff) . SubStr(value, i+6)
}
Return,value
}
ToBase(n,b)
{
return (n < b ? "" : Util.ToBase(n//b,b)) . ((d:=Mod(n,b)) < 10 ? d : Chr(d+55))
}
;利用js对url编码
urlEncode(url)
{
oSC := ComObjCreate("ScriptControl")
oSC.Language := "JScript"
Script := "var Encoded = encodeURI(""" . url . """)"
oSC.ExecuteStatement(Script)
Return, oSC.Eval("Encoded")
}
;获取光标选中的字符串,使用系统粘贴板,但是不会给粘贴板留下任何数据
getSelectStr()
{
ClipboardOld = %ClipboardAll%
Clipboard = ; 必须清空, 才能检测是否有效.
Send ^c
ClipWait, 3 ;等待粘贴板数据,3s超时
if ErrorLevel ; ClipWait 超时.
return
clip_select:=Clipboard
Clipboard = %ClipboardOld% ; 恢复剪贴板之前的内容.
return clip_select
}
;窗口加上阴影
FrameShadow(HGui) {
DllCall("dwmapi\DwmIsCompositionEnabled","IntP",_ISENABLED) ; Get if DWM Manager is Enabled
if !_ISENABLED ; if DWM is not enabled, Make Basic Shadow
DllCall("SetClassLong","UInt",HGui,"Int",-26,"Int",DllCall("GetClassLong","UInt",HGui,"Int",-26)|0x20000)
else
VarSetCapacity(_MARGINS,16)
, NumPut(0,&_MARGINS,0,"UInt")
, NumPut(0,&_MARGINS,4,"UInt")
, NumPut(1,&_MARGINS,8,"UInt")
, NumPut(0,&_MARGINS,12,"UInt")
, DllCall("dwmapi\DwmSetWindowAttribute", "Ptr", HGui, "UInt", 2, "Int*", 2, "UInt", 4)
, DllCall("dwmapi\DwmExtendFrameIntoClientArea", "Ptr", HGui, "Ptr", &_MARGINS)
}
}
最后:
感谢群里面各位大佬的答疑解惑,才让我看到了实现这个划词翻译的可行性。由于时间仓促,可能代码还存在bug和不足,各位大佬用了后可以在评论区提出不足,如果有时间我改进改进。
——————–
完!
非常厉害?,无论是功能还是界面做的都很完美
界面得益于搜狗翻译对低版本ie的适配,不然渲染不出来,不足之处ie无法读语音?
实在厉害!!!???
提示错误
修复了,同时新增了esc和enter退出、
弹出红桃♠ 后,点击红桃怎么没有反应呢?
可能是没网
这界面好看
学习一下~
我整个直接好家伙,发现了新世界,真的真的太酷了。