;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)
    }
}

 

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