Plain text
复制到剪贴板
Open code in new window
EnlighterJS 3 Syntax Highlighter
;author tmz 2023年1月8日19:17:10 ahk_v1.x U32版本
;类似有道的划词翻译,支持双击.支持划词选中 后弹出小图标(可以自定义形状大小颜色)点击即可得到翻译结果
;可以翻译一些单词,短语,短句
;原理 :利用粘贴板获取选中(不会干扰粘贴板)调用搜狗翻译嵌套进入gui的activeX控件中渲染出结果
;优点:①.不调用第三方云接口 ②不依赖外部ahk文件 ③.界面是真的好看,哈哈 ~~④.可以支持多种语言中英韩日等.
;不足:由于ie版本限制 无法发出语音...大无语 ,(ie11也不行,实际activeX中的ie版本更低) 用其他浏览器都行
;搜狗翻译网页有个机器人限制,但是频次不是很高,基本触发不了,如果触发了,到网页中输入验证码即可
;如果搜狗翻译网页变动可能导致翻译不出来,但是改改代码照样用。
;注意请用U32版本运行!!!示例为:选词之后,按F1键可调出翻译
#NoEnv
#InstallMouseHook
#InstallKeybdHook
#KeyHistory 499
SetBatchLines -1
CoordMode, Mouse, Screen ;全局获取模式
; 强制使用32位运行
if !(A_IsUnicode=1 and A_PtrSize=4)
RunWait *RunAs %A_AhkPath%\..\AutoHotkeyU32.exe "%A_ScriptFullPath%"
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即可
F1::
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)
}
}
;author tmz 2023年1月8日19:17:10 ahk_v1.x U32版本 ;类似有道的划词翻译,支持双击.支持划词选中 后弹出小图标(可以自定义形状大小颜色)点击即可得到翻译结果 ;可以翻译一些单词,短语,短句 ;原理 :利用粘贴板获取选中(不会干扰粘贴板)调用搜狗翻译嵌套进入gui的activeX控件中渲染出结果 ;优点:①.不调用第三方云接口 ②不依赖外部ahk文件 ③.界面是真的好看,哈哈 ~~④.可以支持多种语言中英韩日等. ;不足:由于ie版本限制 无法发出语音...大无语 ,(ie11也不行,实际activeX中的ie版本更低) 用其他浏览器都行 ;搜狗翻译网页有个机器人限制,但是频次不是很高,基本触发不了,如果触发了,到网页中输入验证码即可 ;如果搜狗翻译网页变动可能导致翻译不出来,但是改改代码照样用。 ;注意请用U32版本运行!!!示例为:选词之后,按F1键可调出翻译 #NoEnv #InstallMouseHook #InstallKeybdHook #KeyHistory 499 SetBatchLines -1 CoordMode, Mouse, Screen ;全局获取模式 ; 强制使用32位运行 if !(A_IsUnicode=1 and A_PtrSize=4) RunWait *RunAs %A_AhkPath%\..\AutoHotkeyU32.exe "%A_ScriptFullPath%" 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即可 F1:: 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) } }
;author tmz 20231819:17:10 ahk_v1.x U32版本
;类似有道的划词翻译,支持双击.支持划词选中 后弹出小图标(可以自定义形状大小颜色)点击即可得到翻译结果
;可以翻译一些单词,短语,短句
;原理 :利用粘贴板获取选中(不会干扰粘贴板)调用搜狗翻译嵌套进入gui的activeX控件中渲染出结果
;优点:①.不调用第三方云接口 ②不依赖外部ahk文件 ③.界面是真的好看,哈哈 ~~④.可以支持多种语言中英韩日等.
;不足:由于ie版本限制 无法发出语音...大无语 ,(ie11也不行,实际activeX中的ie版本更低) 用其他浏览器都行
;搜狗翻译网页有个机器人限制,但是频次不是很高,基本触发不了,如果触发了,到网页中输入验证码即可
;如果搜狗翻译网页变动可能导致翻译不出来,但是改改代码照样用

;注意请用U32版本运行!!!示例为:选词之后,按F1键可调出翻译
#NoEnv
#InstallMouseHook
#InstallKeybdHook
#KeyHistory 499
SetBatchLines -1
CoordMode, Mouse, Screen ;全局获取模式

; 强制使用32位运行
if !(A_IsUnicode=1 and A_PtrSize=4)
  RunWait *RunAs %A_AhkPath%\..\AutoHotkeyU32.exe "%A_ScriptFullPath%"

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即可
F1::
  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 ;INDEX1开始
  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是,0static 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)
    }
}

 

声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。