✨ 点击图片换一张(老婆/猫/狗/二次元) ✨
;/*
;===========================================
; FindText - 屏幕抓字生成字库工具与找字函数
; https://www.autohotkey.com/boards/viewtopic.php?f=6&t=17834
;
; 脚本作者 : FeiYue
; 最新版本 : 10.2
; 更新时间 : 2026-02-22
;
; 用法: (需要最新版本 AHK v1.1.34+)
; 1. 将本脚本保存为“FindText.ahk”并复制到AHK执行程序的Lib子目录中(手动建立目录)
; 2. 抓图并生成调用FindText()的代码
; 2.1 方式一:直接点击“抓图”按钮
; 2.2 方式二:先设定截屏热键,使用热键截屏,再点击“截屏抓图”按钮
; 3. 测试一下调用的代码是否成功:直接点击“测试”按钮
; 4. 复制调用的代码到自己的脚本中
; 4.1 方式一:打勾“附加FindText()函数”的选框,然后点击“复制”按钮(不推荐)
; 4.2 方式二:取消“附加FindText()函数”的选框,然后点击“复制”按钮,
; 然后粘贴到自己的脚本中,然后在自己的脚本开头加上一行:
; #Include
if (!A_IsCompiled && A_LineFile=A_ScriptFullPath) FindText().Gui(“Show”)
;===== 复制下面的函数和类到你的代码中仅仅一次 =====
FindText(ByRef x:=””, ByRef y:=””, args) { static init, obj if !VarSetCapacity(init) && (init:=”1”) obj:=new FindTextClass() return !args.Length() ? obj : obj.FindText(x, y, args) }
Class FindTextClass { ;// Class Begin
Floor(i) { if i is number return i+0 else return 0 }
__New() { this.bits:={ Scan0: 0, hBM: 0, oldzw: 0, oldzh: 0 } this.bind:={ id: 0, mode: 0, oldStyle: 0 } this.Lib:=[] this.Cursor:=0 }
__Delete() { Try if (this.bits.hBM) DllCall(“DeleteObject”, “Ptr”,this.bits.hBM) }
New() { return new FindTextClass() }
help()
{
return “
(
;——————————–
; FindText - 屏幕找字函数
; 版本 : 10.2 (2026-02-22)
;——————————–
; 返回变量:=FindText(
; OutputX –> 保存返回的X坐标的变量名称
; , OutputY –> 保存返回的Y坐标的变量名称
; , X1 –> 查找范围的左上角X坐标
; , Y1 –> 查找范围的左上角Y坐标
; , X2 –> 查找范围的右下角X坐标
; , Y2 –> 查找范围的右下角Y坐标
; , err1 –> 文字的黑点容错百分率(0.1=10%)
; , err0 –> 背景的白点容错百分率(0.1=10%)
; 设置 err1<0 或 err0<0 可以打开左右膨胀算法
; 忽略文字线条的轻微错位,此时容错值应该非常小
; 在找图模式中,err0 可以设置要跳过的行列数,加快速度
; , Text –> 由工具生成的查找图像的数据,可以一次查找多个,用“|”分隔
; , ScreenShot –> 是否截屏,为0则使用上一次的截屏数据
; , FindAll –> 是否搜索所有位置,为0则找到一个位置就返回
; , JoinText –> 如果想组合查找,可以为1,或者是要查找单词的数组
; , offsetX –> 组合图像的每个字和前一个字的最大横向间隔
; , offsetY –> 组合图像的每个字和前一个字的最大高低间隔
; , dir –> 查找的方向,有上、下、左、右、中心9种
; 默认 dir=0,这种返回的结果将按最小误差排序,
; 即使设置了较大的容错,第一个结果也是误差最小的
; , zoomW –> 图像宽度的缩放百分率(1.0=100%)
; , zoomH –> 图像高度的缩放百分率(1.0=100%)
; )
;
; 返回变量 –> 如果没找到结果会返回0。否则返回一个二级数组,
; 第一级是每个结果对象,第二级是结果对象的具体信息对象:
; { 1:左上角X, 2:左上角Y, 3:图像宽度W, 4:图像高度H
; , x:中心点X, y:中心点Y, id:图像识别文本 }
; 所有坐标都是相对于屏幕,颜色使用RGB格式
; 所有 RRGGBB 可以使用 Black、White、Red、Green、Blue 代替,
; 所有 DRDGDB 可以使用相似度 1.0(100%) 代替,它是浮点数
;
; 如果 OutputX 等于 ‘wait’ 或 ‘wait1’ 意味着等待图像出现,
; 如果 OutputX 等于 ‘wait0’ 意味着等待图像消失
; 此时 OutputY 设置等待时间的秒数,如果小于0则无限等待
; OutputY 也可以添加找到后的稳定时间:’等待时间,稳定时间’
; 如果超时则返回0,意味着失败,如果等待图像出现成功,则返回位置数组
; 如果等待图像消失成功,则返回 1
; 例1: FindText(X:=’wait’, Y:=3, 0,0,0,0,0,0,Text) ; 等待3秒等图像出现
; 例2: FindText(X:=’wait0’, Y:=-1, 0,0,0,0,0,0,Text) ; 无限等待等图像消失
;
;
FindText(ByRef OutputX:=””, ByRef OutputY:=”” , x1:=0, y1:=0, x2:=0, y2:=0, err1:=0, err0:=0, text:=”” , ScreenShot:=1, FindAll:=1, JoinText:=0, offsetX:=20, offsetY:=10 , dir:=0, zoomW:=1, zoomH:=1) { local if (OutputX ~= “i)^\swait[10]?\s$”) { found:=!InStr(OutputX,”0”), v:=StrSplit(OutputY “,”, “,”) , time:=this.Floor(v[1]), StableTime:=this.Floor(v[2]) , timeout:=A_TickCount+Round(time1000), OutputX:=”” Loop { ok:=this.FindText(,, x1, y1, x2, y2, err1, err0, text, ScreenShot , FindAll, JoinText, offsetX, offsetY, dir, zoomW, zoomH) if (found && ok) { if (StableTime) { Sleep % StableTime1000 if !this.FindText(,, (v:=ok[1]).1, v.2, v.1+v.3-1, v.2+v.4-1, err1, err0 , text, ScreenShot, FindAll, JoinText, offsetX, offsetY, dir, zoomW, zoomH) Continue } OutputX:=ok[1].x, OutputY:=ok[1].y, this.ok:=ok return ok } if (!found && !ok) return 1 if (time>=0 && A_TickCount>=timeout) Break Sleep 50 } return 0 } SetBatchLines % (bch:=A_BatchLines)?”-1”:”-1” x1:=this.Floor(x1), y1:=this.Floor(y1), x2:=this.Floor(x2), y2:=this.Floor(y2) if (x1=0 && y1=0 && x2=0 && y2=0) n:=150000, x:=y:=-n, w:=h:=2n else x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x2-x1)+1, h:=Abs(y2-y1)+1 bits:=this.GetBitsFromScreen(x,y,w,h,ScreenShot,zx,zy), x-=zx, y-=zy , this.ok:=0, info:=[] Loop Parse, text, | if IsObject(j:=this.PicInfo(A_LoopField)) info.Push(j) if (w<1 || h<1 || !(num:=info.Length()) || !bits.Scan0) { SetBatchLines % bch return 0 } arr:=[], info2:=[], k:=0, s:=”” , mode:=(IsObject(JoinText) ? 2 : JoinText ? 1 : 0) For i,j in info { k:=Max(k, (j[7]=5 && j[8]!=2 ? j[9] : j[2]j[3])) if (mode) v:=(mode=1 ? i : j[10]) . “”, s.=”|” v , (v!=””) && ((!info2.HasKey(v) && info2[v]:=[]), info2[v].Push(j)) } sx:=x, sy:=y, sw:=w, sh:=h, (mode=1 && JoinText:=[s]) , allpos_max:=(FindAll || JoinText ? 10000:1) , VarSetCapacity(s1,k4), VarSetCapacity(s0,k4) , VarSetCapacity(ss,(sw+2)(sh+4)), VarSetCapacity(allpos,allpos_max8) , ini:={ sx:sx, sy:sy, sw:sw, sh:sh, zx:zx, zy:zy , mode:mode, bits:bits, ss:&ss, s1:&s1, s0:&s0 , allpos:&allpos, allpos_max:allpos_max , err1:err1, err0:err0, zoomW:zoomW, zoomH:zoomH } Loop 2 { if (err1=0 && err0=0) && (num>1 || A_Index>1) ini.err1:=err1:=0.05, ini.err0:=err0:=0.05 if (!JoinText) { For i,j in info Loop % this.PicFind(ini, j, dir, sx, sy, sw, sh) { v:=NumGet(allpos,4A_Index-4,”uint”), x:=(v&0xFFFF)+zx, y:=(v»16)+zy , w:=Floor(j[2]zoomW), h:=Floor(j[3]zoomH) , arr.Push({1:x, 2:y, 3:w, 4:h, x:x+w//2, y:y+h//2, id:j[10]}) if (!FindAll) Break 3 } } else For k,v in JoinText { v:=StrSplit(Trim(RegExReplace(v, “\s|[|\s]*”, “|”), “|”) , (InStr(v,”|”)?”|”:””), “ `t”) , this.JoinText(arr, ini, info2, v, 1, offsetX, offsetY , FindAll, dir, 0, 0, 0, sx, sy, sw, sh) if (!FindAll && arr.Length()) Break 2 } if (err1!=0 || err0!=0 || arr.Length() || info[1][4] || info[1][7]=5) Break } SetBatchLines % bch if (arr.Length()) { OutputX:=arr[1].x, OutputY:=arr[1].y, this.ok:=arr return arr } return 0 }
| ; the join text object use [ “abc”, “xyz”, “a1 | a2 | a3” ] |
PicFind(ini, j, dir, sx, sy, sw, sh) { local static init, MyFunc if !VarSetCapacity(init) && (init:=”1”) { x32:=”VVdWU4HsmAAAAIuEJAABAACLtCQEAQAAg7wkrAAAAAWNBLCJRCRAD4QqBQAAi4Qk” . “8AAAAIXAD46wEQAAMf@HRCQIAAAAADHtiTwki7wk7AAAAMdEJBgAAAAAx0QkDAAA” . “AACLhCToAAAAi0wkDDH2MdsByIX@iUQkBH876Y4AAAAPr4Qk1AAAAInBifCZ9@8B” . “wYtEJASAPBgxdEyLhCTkAAAAg8MBA7QkCAEAAIkMqIPFATnfdFSLBCSZ97wk8AAA” . “AIO8JKwAAAAEdbUPr4QkwAAAAInBifCZ9@+NDIGLRCQEgDwYMXW0i0QkGIuUJOAA” . “AACDwwEDtCQIAQAAiQyCg8ABOd+JRCQYdawBfCQMg0QkCAGLjCQMAQAAi0QkCAEM” . “JDmEJPAAAAAPhTT@@@+LRCQYiWwkOA+vhCT0AAAAwfgKiUQkMIuEJPgAAAAPr8XB” . “+AqJRCREg7wkrAAAAAQPhPQEAACLhCTcAAAAA4Qk1AAAAIu0JMwAAACJRCQoi4Qk” . “wAAAAA+vhCTQAAAAjSywi4Qk1AAAAIu0JMAAAAD32IO8JKwAAAABjQSGiUQkNA+E” . “7wQAAIO8JKwAAAACD4TnCQAAg7wkrAAAAAMPhH0NAACLrCT8AAAAhe0PhWYHAACL” . “RCQoiYQk3AAAAIt0JBiLTCQwuAAAAAA5zg9Pxot0JEQ5dCQ4iUQkGH8Ix0QkOAAA” . “AACLvCTUAAAAi6wk2AAAACu8JAgBAAArrCQMAQAAg7wkuAAAAAkPhJQAAACLhCS4” . “AAAAg+gBg@gHD4flAgAAg@gDiUQkXA+O4AIAAMdEJEwAAAAAx0QkDAAAAAA7fCRM” . “x0QkVAAAAAAPjOAAAAA7bCRUD4yvEAAAi0wkTIt0JFyJ+CnI98YCAAAAD0TBi0wk” . “VInCiegpyPfGAQAAAA9EwYP+A4nRD0@ID0@CiUwkCIlEJATpfA8AAJCNtCYAAAAA” . “ifiNVQHHRCRwAAAAAMHoH8dEJGwBAAAAx0QkWAAAAAAB+MdEJGQAAAAAx0QkDAAA” . “AADR+IlEJASJ6MHoHwHo0fiJRCQIjUcBicYPr@I50A9MwoPACIm0JIgAAACJxg+v” . “8Im0JIwAAACLtCSIAAAAOXQkcH0Zi7QkjAAAADl0JGTHRCRoAAAAAA+MuQUAAIuc” . “JAABAACF2w+EKwgAAIuEJAwBAAAPr4QkCAEAAIP4AQ+EEwgAAIuMJLgAAACFyQ+F” . “cAEAAItEJAyD+AEPjmMBAACLdCRAi5wkAAEAAIPoATHtiUQkEMdEJAQAAAAAiSwk” . “jX4Ei0QkBIsMJIs3i0QDBIXJiUQkCInIeDeLT@w5zg+DmQgAAIn6jWv86w6NdCYA” . “g+oEi0r8Oc5zF4kKi0yFBIlMgwSD6AGD+P915Lj@@@@@i0wkQIPAAYMEJAGDxwSD” . “RCQEBIk0gYt0JAiJNIOLBCQ7RCQQdYyLhCQIAQAAD6@AwfgCicWLhCQMAQAAD6@A” . “wfgCiUQkBIu0JAABAADHRCQIAAAAADHAkI20JgAAAACLfCQIiwy+iUwkEA+3+cHp” . “EIXAiQwkdC0x2422AAAAAIsMng+30Sn6D6@SOep9D8HpECsMJA+vyTtMJAR8EYPD” . “ATnDdduLfCQQiTyGg8ABg0QkCAGLfCQIO3wkDHWigcSYAAAAW15fXcJkAItEJAw5” . “hCQEAQAAD4@vDQAAi4QkDAEAAA+vhCQIAQAAg@gBD4SUBgAAi4QkCAEAAItUJAwP” . “r8DB+AKJxYuEJAwBAAAPr8DB+AKJRCQEMcCF0g+PJf@@@+uax0QkXAAAAACJ6MdE” . “JEwAAAAAif3HRCQMAAAAAInH6RX9@@8xwIO8JLAAAAACD5TAiUQkdA+EGAcAADHA” . “g7wksAAAAAEPlMCJRCR4i4QktAAAAIXAD4RDDwAAi7Qk4AAAAIuMJLQAAAAx7Yuc” . “JOgAAACLvCTkAAAAjQSOiUQkBIsLg8YEg8NYg8cEicjB6BAPr4QkDAEAAJn3vCTw” . “AAAAD6+EJMAAAACJBCQPt8EPr4QkCAEAAJn3vCTsAAAAixQkjQSCiUb8i0OsjURF” . “AIPFFolH@Dt0JAR1pouEJLQAAACJjCSwAAAAiUQkGIuEJPQAAAAPr4QktAAAAMH4” . “ColEJDCLhCToAAAAx0QkRAAAAADHRCQ4AAAAAIPACIlEJBDpkvv@@4uEJLAAAADB” . “6BAPr4QkDAEAAJn3vCTwAAAAD6+EJMAAAACJwQ+3hCSwAAAAD6+EJAgBAACZ97wk” . “7AAAAI0EgYmEJLAAAADpR@v@@4uEJPAAAADRpCS0AAAAD6+EJOwAAAADhCToAAAA” . “gTj@@@8AiUQkEA+WwA+2wIlEJCSLhCTYAAAAhcAPju36@@+LhCTUAAAAieqLbCQQ” . “x0QkLAAAAADHRCQ8AAAAAMHgAolEJFAxwIu8JNQAAACF@w+OKAEAAIu0JLwAAAAB” . “1gNUJFCJdCQUi3QkKAN0JDyJVCRIA5QkvAAAAIl0JByJVCQgi3wkFA+2dwIPtk8B” . “D7Y@iTQkiUwkBDH2iXwkCDm0JLQAAAAPhpkAAACLXLUAg8YCi0y1@InYD7bXD7bb” . “wegQK1QkBInfD7bAK3wkCCsEJIH5@@@@P3c4ixwkD6@SjRxYweILiVwkDIHDAAQA” . “AA+v2A+vw40cELj+BQAAK0QkDA+vxw+vxwHYOcFzMjHA642Jy8HrEA+22w+vwA+v” . “2znYd+oPtt0Pr9IPr9s52nfdD7bJifgPr8cPr8k5yHfOuAEAAAA7RCQki3QkHA+U” . “woNEJBQEg8YBg8IBi0wkFIhW@zlMJCCJdCQcD4UT@@@@i7wk1AAAAAF8JDyLVCRI” . “g0QkLAEDVCQ0i3QkLDm0JNgAAAAPha@+@@+LhCT8AAAAhcAPhHb5@@+DhCTMAAAA” . “AYuEJNQAAAAx7ccEJAAAAACJbCQEjXj@icaNtgAAAACF9n5Ni0QkBItcJCgxyYus” . “JNwAAAAx0gHDAcUPtgPrEoXJD7ZDAQ+EQA0AAA+2E4PDAQnQOfkPhBoMAAAPtlMB” . “CdCIRA0Ag8EBOc510wF0JASDBCQBiwQkOYQk2AAAAH+f6fT4@@+J+InvicWLdCRY” . “hfYPhRMKAACDbCQIAYNEJGgBg0QkZAGLVCRsOVQkaA+M7AgAAIt0JFiJ8IPgAQHC” . “ifCDwAGJVCRsg+ADiUQkWOnz+f@@i7wk2AAAAIOEJMwAAAABhf8PjxX@@@@pifj@” . “@4tcJHSJRCQohdsPhZILAACLRCQQi0wkFDHSiUQkNItEJDCFyYkEJA+EhQEAAIl8” . “JCCJbCQcideLtCTgAAAAi0QkKAMEvou0JLwAAAAPtnQGAol0JEiLtCS8AAAAD7ZM” . “BgEPtgQGa@cWiXQkJIt0JDSITCRQiEQkYImEJJQAAACLFon1D7bxibQkkAAAAIlU” . “JCyLlCTkAAAAixS6iZQktAAAAOs3jTRxD6@AifKBxgAEAAAPr@HB4AsPr86LdCQ8” . “AcG4@gUAACnQD6@GD6@GAcg5ww+DpAAAAIPFCItEJCQ7hCS0AAAAD4OjCgAAi0Qk” . “eINEJCQCi1UAi10EhcB0D4X@D4SbCwAAi5QksAAAAInRD7bGi3QkSA+20iuUJJQA” . “AADB6RAPtskrhCSQAAAAKfGB+@@@@z+JVCQ8D4Zk@@@@id7B7hCJ8g+28g+vyQ+v” . “9jnxd4QPts8Pr8APr8k5yA+Hc@@@@4tEJDwPttsPr9uJwg+v0DnaD4dc@@@@gXwk” . “LP@@@wB2EoX@D4TVCQAAgywkAQ+IywkAAIPHAYNEJDRYOXwkFA+Fjf7@@4tsJByL” . “fCQgi4QkAAEAAINEJAwBi3QkDIXAD4SwBwAAi1QkCAOUJNAAAACNjv@@@z+LRCQE” . “A4QkzAAAAMHiEAnQi5QkAAEAAIkEiouEJLgAAACFwA+Fdvn@@4tEJDArBCQ5tCQE” . “AQAAi1QkQIkEig+PaQcAAIuEJAwBAAAPr4QkCAEAAIP4AQ+F@Pf@@4tEJAyBxJgA” . “AABbXl9dwmQAi4QksAAAAIu0JNgAAADHBCQAAAAAx0QkBAAAAACDwAHB4AeJhCSw” . “AAAAi4Qk1AAAAMHgAoX2iUQkDInoi6wksAAAAA+O3vX@@4ucJNQAAACF235ki4wk” . “vAAAAItcJCiLvCS8AAAAA1wkBAHBA0QkDIlEJAgBx5APtlECD7ZBAQ+2MWvAS2vS” . “JgHCifDB4AQp8AHQOegZwIPBBIPDAffQg8ACiEP@Ofl1zouUJNQAAAABVCQEi0Qk” . “CIMEJAEDRCQ0izQkObQk2AAAAA+Fef@@@+nc+@@@iwQk6Yv3@@+LhCTwAAAAi7Qk” . “6AAAAA+vhCTsAAAA0aQktAAAAMdEJDABAAAAjQSGicaJRCQQi4Qk+AAAAMH4CoPA” . “AYO8JLQAAAACiUQkLHYRgX4I@@@@AA+WwA+2wIlEJDCLRCQQi0AEicIPtswPtsDB” . “6hAPttKJ1g+v8ol0JHyJzg+v8Ym0JIAAAACJxg+v8IuEJPAAAACFwIm0JIQAAAAP” . “jroIAACLdCQsi4QkDAEAADHtx0QkPAAAAADHRCQYAAAAAA+vxolEJFCLhCTsAAAA” . “D6@GweACiUQkYIuEJOgAAACDwAKJRCREifCNNLUAAAAAiXQkOInGD6+EJAgBAACJ” . “dCRIiUQkNIuEJOwAAACFwA+OhwEAAItEJETHRCQgAAAAAIlEJBSLRCQsiUQkHGaQ” . “i0QkFA+2MIl0JASJxg+2QP8Ptk7+vgIAAACIRCQkiUQkCA+2wYhMJCiJRCQMjXYA” . “ObQktAAAAA+GmwAAAItMJBCLfCQEiwSxg8YCi1yx@InCD7bMK0wkCMHqEA+2wCtE” . “JAwPttIp+oH7@@@@P4kMJHcujSx6D6@Jjb0ABAAAD6@6weELD6@XAcq5@gUAACnp” . “D6@ID6@BAdA5w3M3Me3rkInfwe8QifkPtvkPr9IPr@85+nfoixQkD7b@D6@@idEP” . “r8o5+XfWD7bbD6@AD6@bOdh3yb0BAAAAO2wkMHRji0QkPIt0JBiLvCTgAAAAmY0c” . “tQAAAAD3vCTwAAAAD6+EJMAAAACJwYtEJCCZ97wk7AAAAItUJATB4hCNBIGJBLcP” . “tkQkJIPGAYl0JBiLtCTkAAAAweAICdAPtlQkKAnQiQQei3QkHItEJCyLfCQ4i0wk” . “NAF8JBQBTCQgAfA5tCTsAAAAfgmJRCQc6ZP+@@+LdCRIi0QkLItUJFCLTCRgAVQk” . “PAFMJEQB8Dm0JPAAAAAPjq8DAACJRCRI6Tr+@@8rrCTAAAAAi0QkKAOEJNQAAACJ” . “RCQUjUX8iUQkCItEJDSD6AiJRCQgi4Qk1AAAAIPAAolEJByLhCTQAAAAg+gBicaJ” . “BCSLhCTQAAAAA4Qk2AAAADnGD48fAQAAi7QkzAAAAIPAAcdEJAwAAAAAiUQkJIuE” . “JNQAAACD7gGJdCQsi7QkzAAAAAHwi7Qk1AAAAIlEJDSNeAErhCTMAAAAjTS1CAAA” . “AIPAAol0JDyJRCRIi0QkLIt0JDQ58A+PogAAAInBiwQki3QkDCu0JMwAAACLXCQI” . “A3QkFAOcJLwAAAD30MHoH4lEJATrVI12AI28JwAAAAA5jCTEAAAAfkWAfCQEAHQ+” . “iwQkOYQkyAAAAH4yD7ZTAg+2QwGDwwQPtmv8a8BLa9ImAcKJ6MHgBCnoAdDB6AeI” . “RA4Bg8EBOc90FIXJebIxwIPDBIhEDgGDwQE5z3Xsi3QkPAF0JAiLdCRIAXQkDIME” . “JAGLVCQgiwQkAVQkCDlEJCQPhTX@@@+LjCTYAAAAhckPjvrw@@+LhCTYAAAAi2wk” . “FANsJBzHRCQIAQAAAMdEJAwAAAAAg8ABiUQkFIuEJNQAAACJbCQEg8AEiUQkIIuE” . “JLQAAACLlCTUAAAAhdIPjqEAAACLVCQEi1wkKIt0JCADXCQMidErjCTUAAAAAdaJ” . “DCQPtkIBD7YqvwIAAAADhCSwAAAAOehyRw+2agI56HI@iwwkD7Zp@jnocjQPtmn@” . “OehyLA+2KTnociUPtm7+OehyHQ+2bv856HIVD7Y+OfgZ@@fXg8cCifaNvCcAAAAA” . “ifmDBCQBg8IBiAuDxgGDwwGLPCQ5fCQEdYiLvCTUAAAAAXwkDINEJAgBi0wkHIt0” . “JAgBTCQEOXQkFA+FNf@@@4mEJLQAAADpbvb@@8dEJEQAAAAAx0QkMAAAAADHRCQ4” . “AAAAAMdEJBgAAAAA6UXv@@+LRCQEhcAPiN@2@@85+A+P1@b@@4tEJAiFwA+Iy@b@” . “@znoD4@D9v@@g0QkcAGJ6In9iceLdCQ4i0QkGDnGD03Gg7wkrAAAAAOJxolEJBSL” . “RCQID4@nAAAAD6+EJNQAAAADRCQEhfYPhEwDAAADhCTcAAAAi3QkMDHSi1wkRIk0” . “JInB6yk5VCQ4fhaLtCTkAAAAiwSWAcj2AAF1BYPrAXgqg8IBOVQkFA+EVfj@@zlU” . “JBh+0Yu0JOAAAACLBJYByIA4AXfAgywkAXm6g7wkuAAAAAkPhA32@@+DRCRUAemL” . “7@@@i0QkGMdEJEQAAAAAD6+EJPQAAADHRCQ4AAAAAMH4ColEJDDpz+7@@4N8JFgB” . “dB+DfCRYAg+EqAIAAINsJAQB6db1@@+DRCRMAekr7@@@g0QkBAHpwvX@@5CNdCYA” . “A4Qk0AAAAItUJAQPr4QkwAAAAAOUJMwAAACDvCSsAAAABY0EkA+E5vX@@4lEJCQD” . “hCSwAAAAi7QkvAAAAA+2dAYCiXQkKIu0JLwAAAAPtnQGAYl0JCyLtCS8AAAAD7YE” . “BolEJDSLRCQUhcAPhAgCAACLRCREiWwkHIn1iXwkIIlEJDyLRCQwiQQkMcCJx+t1” . “OXwkOH5ii4Qk5AAAAItUJCSLXCQoAxS4D7ZMFQIPtkQVAStEJCwPtlQVACtUJDSJ” . “zgHZKd6NmQAEAAAPr8APr97B4AsPr94Bw7j+BQAAKcgPr8IPr8IB2DmEJLQAAABy” . “B4NsJDwBeHyDxwE5fCQUD4S29v@@OXwkGH6Fi4Qk4AAAAItUJCSLXCQoAxS4D7ZM” . “FQIPtkQVAStEJCwPtlQVACtUJDSJzgHZKd6NmQAEAAAPr8APr97B4AsPr94Bw7j+” . “BQAAKcgPr8IPr8IB2DmEJLQAAAAPgyb@@@+DLCQBD4kc@@@@i2wkHIt8JCDpCv7@” . “@8dEJDAAAAAAx0QkGAAAAADpT@H@@zHS6ePz@@+NdgCBfCQs@@@@AA+H+@X@@+nk” . “9f@@i1QkFItEJDCF0okEJA+E@fX@@zHb6xONtgAAAACDwwE5XCQUD4SQAAAAi7Qk” . “4AAAAItEJCgDBJ6LtCTkAAAAiwyei7QkvAAAAA+2dAYCicrB6hAp1ouUJLwAAAAP” . “r@Y7dCR8D7ZUAgGIVCQci5QkvAAAAA+2BAJ@Kw+2VCQcD7b1KfIPr9I7lCSAAAAA” . “fxUPttEp0A+vwDuEJIQAAAAPjnn@@@+DLCQBD4lv@@@@iYwksAAAAOke@f@@iYwk” . “sAAAAOlK9f@@i0QkMIkEJOk+9f@@g0QkCAHpLvP@@8dEJDAAAAAAx0QkRAAAAADH” . “RCQYAAAAAOkO7P@@MdLpvPL@@w+2VCRQi0QkSMHgEMHiCAnQD7ZUJGAJ0ImEJLAA” . “AADp0vT@@5CQkJCQkJCQkA==” x64:=”QVdBVkFVQVRVV1ZTSIHsqAAAAEhjhCSgAQAASIu0JJgBAACD+QWJjCTwAAAAiZQk” . “+AAAAEWJxESJjCQIAQAATIu0JGgBAACLrCRwAQAAi7wkeAEAAEiNBIZIiUQkUA+E” . “EQUAAIX@D44TEQAAMdsx9kyJtCRoAQAAiRwkiXQkFDHAi5wk8AAAAESLrCRAAQAA” . “RTHSTIu0JGABAACLtCSoAQAARTH@RImEJAABAABBicRMY1wkFEUxyUUxwEwDnCRo” . “AQAAhe1@Net6Dx+AAAAAAEEPr8WJwUSJyJn3@QHBQ4A8AzF0PEmDwAFJY8dBAfFB” . “g8cBRDnFQYkMhn5DRInQmff@g@sEdckPr4QkGAEAAInBRInImff9Q4A8AzGNDIF1” . “xEiLlCRYAQAASYPAAUljxEEB8UGDxAFEOcWJDIJ@vQFsJBSDBCQBRAOUJLABAACL” . “BCQ5xw+FVv@@@0SJ4ESJZCQUTIu0JGgBAAAPr4QkgAEAAESLpCQAAQAAwfgKiUQk” . “OIuEJIgBAABBD6@HwfgKiUQkQIO8JPAAAAAED4TIBAAATGOsJEABAACLtCQwAQAA” . “TInoSAOEJFABAABIiUQkKIuEJBgBAAAPr4QkOAEAAI0EsIu0JBgBAACJRCQgi4Qk” . “QAEAAPfYg7wk8AAAAAGNBIaJRCQwD4SvBAAAg7wk8AAAAAIPhJQJAACDvCTwAAAA” . “Aw+E8gwAAIuUJJABAACF0g+FHgcAAEiLRCQoSImEJFABAACLfCQUi3QkOLgAAAAA” . “OfcPT8dEO3wkQIlEJBR@A0Ux@0SLtCRAAQAARIuUJEgBAABEK7QkqAEAAEQrlCSw” . “AQAAg7wkCAEAAAkPhI8AAACLhCQIAQAAg+gBg@gHD4e8AgAAg@gDiUQkYA+OtwIA” . “AMdEJEgAAAAAxwQkAAAAAEQ7dCRIx0QkWAAAAAAPjN0AAABEO1QkWA+M+A8AAIt0” . “JEiLfCRgRInwKfBA9scCD0TGi3QkWInCRInQidUp8ED2xwEPRMaD@wMPT+gPT8JB” . “icXpyQ4AAGYPH4QAAAAAAESJ8EGNUgHHRCR8AAAAAMHoH8dEJHgBAAAAx0QkXAAA” . “AABEAfDHRCRwAAAAAMcEJAAAAADR+EGJxUSJ0MHoH0QB0NH4icVBjUYBiccPr@o5” . “0A9MwoPACIm8JJQAAACJxw+v+Im8JJgAAACLvCSUAAAAOXwkfH0Zi7wkmAAAADl8” . “JHDHRCR0AAAAAA+MdgUAAEiDvCSYAQAAAA+E5gcAAIuEJLABAAAPr4QkqAEAAIP4” . “AQ+EzgcAAIuMJAgBAACFyQ+FRQEAAIsEJIP4AQ+OOQEAAIPoAkyLRCRQTIucJJgB” . “AABIjRyFBAAAAEUxyUUx0kOLdAgEQ4sUCESJ0UOLfAsETInQOdZyFOlJCAAADx8A” . “SIPoAUGLFIA51nMdQYlUgARBixSDg+kBg@n@QYlUgwR13kjHwP@@@@9Jg8EESIPA” . “AUmDwgFJOdlBiTSAQYk8g3WeRIuMJKgBAABEi5wksAEAAEUPr8lFD6@bQcH5AkHB” . “+wJEiyQkTIuUJJgBAAAx9jHAQYsssonvD7fdwe8QhcB0KkUxwEOLDIIPt9Ep2g+v” . “0kQ5yn0NwekQKfkPr8lBOct@E0mDwAFEOcB@2Uhj0IPAAUGJLJJIg8YBQTn0f7NI” . “gcSoAAAAW15fXUFcQV1BXkFfw4sEJDmEJKABAAAPj20NAACLhCSwAQAAD6+EJKgB” . “AACD+AEPhHoGAABEi4wkqAEAAESLnCSwAQAAMcCLFCRFD6@JRQ+v20HB+QJBwfsC” . “hdIPjzr@@@@rlWYPH0QAAMdEJGAAAAAARInQx0QkSAAAAABFifLHBCQAAAAAQYnG” . “6Tv9@@8xwIO8JPgAAAACD5TAiYQkgAAAAA+E3wYAADHAg7wk+AAAAAEPlMBFhcCJ” . “hCSEAAAAD4TkDgAATYnxTIm0JGgBAACLnCQYAQAASIu0JFgBAABMi6wkYAEAAEUx” . “wESLtCSoAQAARIu8JLABAABFMdJFixlJg8FYRInYwegQQQ+vx5n3@w+vw4nBQQ+3” . “w0EPr8aZ9@2NBIFCiQSGQYtBrEGNBEJBg8IWQ4lEhQBJg8ABRTnEd7uLhCSAAQAA” . “TIu0JGgBAABEiZwk+AAAAESJZCQUQQ+vxMH4ColEJDhJjUYIx0QkQAAAAABFMf9I” . “iUQkCOnK+@@@i4Qk+AAAAMHoEA+vhCSwAQAAmff@D6+EJBgBAACJwQ+3hCT4AAAA” . “D6+EJKgBAACZ9@2NBIGJhCT4AAAA6Yn7@@+J+EUB5ESLnCRIAQAAD6@FSJhMAfCB” . “OP@@@wBIiUQkCA+WwEWF2w+2wIlEJBgPjjr7@@+LvCRAAQAAx0QkJAAAAAAxwMdE” . “JDwAAAAAQb7+BQAARIl8JGTB5wKJfCRMRIuUJEABAABFhdIPjhwBAABIY1QkIEiL” . “vCQQAQAARTH@TI1sFwJIY1QkPEgDVCQoSIkUJA8fQABBD7Z1AEyLTCQIRTHbQQ+2” . “bf9BD7Z9@us@Dx+AAAAAAESNBHAPr8lFjZAABAAARA+v0MHhC0EPr8IBwUSJ8EQp” . “wEGJwEQPr8JBD6@QAco503NjSYPBCDHARTnjc11BixFBi1kEQYPDAonQD7bOD7bS” . “wegQKekp+g+2wCnwgfv@@@8@dpxBidhBwegQRQ+2wA+vwEUPr8BEOcB3tw+2xw+v” . “yQ+vwDnBd6oPttsPr9IPr9s52neduAEAAAA7RCQYSIs8JA+UwkmDxQSDwgFCiBQ@” . “SYPHAUQ5vCRAAQAAD48e@@@@i3QkTAF0JCCLtCRAAQAAAXQkPINEJCQBi1wkMIt8” . “JCQBXCQgObwkSAEAAA+Ftf7@@0SLfCRki4QkkAEAAIXAD4S@+f@@g4QkMAEAAAGL” . “hCRAAQAASIt8JChFMduLrCRIAQAATIusJFABAAAx20SNUP+JxoX2fk1IY9MxyQ+2” . “BBdNjUwVAEyNRBcBMdLrGYXJQQ+2AA+E8wwAAEEPtlD@SYPBAUmDwAEJ0EQ50Q+E” . “0QsAAEEPthCDwQEJ0DnOQYgBdcwB80GDwwFEOd1@puk@+f@@RInwRYnWQYnCi0Qk” . “XIXAD4WiCQAAg+0Bg0QkdAGDRCRwAYt0JHg5dCR0D4x7CAAAi3wkXIn4g+ABAcaJ” . “+IPAAYl0JHiD4AOJRCRc6Tb6@@+LhCRIAQAAg4QkMAEAAAGFwA+PFP@@@+nT+P@@” . “jQSQiUQkJIuEJIAAAACFwA+FTQsAAEiLRCQIRTHbi3wkOEiJRCQwi0QkGIXAD4R4” . “AQAARIlUJCBIi7QkWAEAAItEJCRIi4wkEAEAAEiLnCQQAQAARWvTFkIDBJ5Ii7Qk” . “EAEAAI1QAkhj0g+2NBaNUAFImA+2BAFIi0wkMEhj0g+2HBOLEUmJyYhEJEyJhCSc” . “AAAAiVQkKEiLlCRgAQAAiFwkPIlcJGhGiySa6z1EjQRxD6@ARIlEJGRBgcAABAAA” . “RA+vwcHgC0EPr8gByLn+BQAAK0wkZA+vyg+v0QHQOcMPg48AAABJg8EIRTniD4Nd” . “CgAAi4QkhAAAAEGDwgJBixFBi1kEhcB0EE2F2w+ERAsAAIuUJPgAAACJ0Q+2xg+2” . “0sHpECtEJGgrlCScAAAAD7bJKfGB+@@@@z8Phm3@@@9BidhBwegQRQ+2wA+vyUUP” . “r8BEOcF3jw+2zw+vwA+vyTnId4IPttsPr9IPr9s52g+Hcf@@@4F8JCj@@@8AdhJN” . “hdsPhJwJAACD7wEPiJMJAABJg8MBSINEJDBYRDlcJBgPj5L+@@9Ei1QkIIMEJAFI” . “g7wkmAEAAACLNCQPhE8HAABIY8aLlCQ4AQAARIuEJAgBAABIjQyFAAAAAIuEJDAB” . “AABIi5wkmAEAAAHqweIQRAHoCdBFhcCJRAv8D4WS+f@@i0QkOCn4ObQkoAEAAEiL” . “fCRQiUQP@A+PAQcAAIuEJLABAAAPr4QkqAEAAIP4AQ+FQfj@@4sEJOlC+f@@i4Qk” . “+AAAAESLjCRIAQAARTHbMduDwAHB4AdFhcmJhCT4AAAAi4QkQAEAAI00hQAAAAAP” . “jkL2@@9Ei2wkIIusJPgAAABMi7QkEAEAAIu8JEABAACF@35aTGPTTANUJChJY8VJ” . “jUwGAkUxwGYPH4QAAAAAAA+2EQ+2Qf9ED7ZJ@mvAS2vSJgHCRInIweAERCnIAdA5” . “6BnASIPBBPfQg8ACQ4gEAkmDwAFEOcd@x0EB9QH7QYPDAUQDbCQwRDmcJEgBAAB1” . “j+ny+@@@TInQ6dv3@@+J+EUB5MdEJCQBAAAAD6@FweACSJhMAfBIicZIiUQkCIuE” . “JIgBAADB+AqDwAFBg@wCiUQkIHYRgX4I@@@@AA+WwA+2wIlEJCRIi0QkCItABInC” . “D7bMD7bAweoQD7bSidYPr@KJtCSIAAAAic4Pr@GJtCSMAAAAicYPr@CF@4m0JJAA” . “AAAPjpoIAACLdCQgi4QksAEAADHJTIl0JEDHRCQ8AAAAAMdEJBQAAAAAiawkcAEA” . “AA+vxol0JEyJvCR4AQAAiUQkZInwD6@FweACSJhIiUQkaInwweACSJhIiUQkKIuE” . “JKgBAAAPr8aJRCQ4SItEJAhIg8AISIlEJDCLnCRwAQAAhdsPjl4BAACLRCQgTIts” . “JEDHBCQAAAAAicUPH0QAAEUPtn0BRQ+2dQBBuwIAAABBD7Z1AkyLTCQwRIn@RIh0” . “JBjrOkSNBHAPr8lFjZAABAAARA+v0MHhC0EPr8IBwbj+BQAARCnAQYnARA+vwkEP” . “r9AByjnTc2VJg8EIMclFOdx2X0GLEUGLWQRBg8MCidAPts4PttLB6BBEKflEKfIP” . “tsAp8IH7@@@@P3aYQYnYQcHoEEUPtsAPr8BFD6@ARDnAd7UPtscPr8kPr8A5wXeo” . “D7bbD6@SD6@bOdp3m7kBAAAAO0wkJHRdi0QkPItcJBTB5wjB5hAJ@g+2fCQYmUxj” . “y@e8JHgBAAAJ@g+vhCQYAQAAQYnAiwQkmfe8JHABAABIi5QkWAEAAEGNBIBCiQSK” . “idiDwAGJRCQUSIuEJGABAABCiTSIi0QkIEwDbCQoi3QkOAE0JAHoOawkcAEAAH4H” . “icXpuf7@@4t8JEyLRCQgi1wkZAFcJDxIi1wkaEgBXCRAAfg5vCR4AQAAD46IAwAA” . “iUQkTOlh@v@@SItEJChMAehIiQQki0QkICuEJBgBAACNePyLRCQwg+gIiUQkGIuE” . “JEABAACDwAKJRCRMi4QkOAEAAI1w@wOEJEgBAAA5xg+P@AAAAIPAAYucJDABAABE” . “iXwkZIlEJCCLhCRAAQAARTH2RIucJCABAABEi7wkKAEAAI1r@0yJbCRoAdiLnCRA” . “AQAAiUQkJESNUAErhCQwAQAAjRydCAAAAIPAAolcJDCJRCQ8O2wkJH98SIucJBAB” . “AABIY8dNY8aJ6UwDBCRMjUwDAonz99PB6x@rSQ8fQABBOct+RITbdEBBOfd+O0EP” . “thFBD7ZB@0UPtmn+a8BLa9ImAcJEiejB4AREKegB0MHoB4PBAUGIAEmDwQRJg8AB” . “RDnRdAiFyXm3McDr5QN8JDBEA3QkPIPGAQN8JBg5dCQgD4Vt@@@@RIt8JGRMi2wk” . “aESLhCRIAQAARYXAD4618f@@SGNsJExIiwQkTY11A0SJfCQgRIu8JPgAAAC+AQAA” . “ADH@SffVSI1cKAGLhCRIAQAAg8ABiQQki4QkQAEAAIPoAUiDwAFIiUQkGIuMJEAB” . “AACFyQ+OrAAAAEiLRCQYSGPXSANUJChNjQQeSY1MHQBMjRwYSInYZg8fhAAAAAAA” . “RA+2IEQPtlD@QbkCAAAARQH8RTnUckxED7ZQAUU51HJCRA+2Uf5FOdRyOEQPtlH@” . “RTnUci5ED7YRRTnUciVFD7ZQ@kU51HIbRQ+2UP9FOdRyEUUPtghFOcxFGclB99FB” . “g8ECSIPAAUSICkmDwAFIg8IBSIPBAUw52A+Fgf@@@wO8JEABAACDxgFIAes5NCQP” . “hTb@@@9Ei3wkIOnZ9v@@x0QkQAAAAADHRCQ4AAAAAEUx@8dEJBQAAAAA6fTv@@9F” . “he0PiFX3@@9FOfUPj0z3@@+F7Q+IRPf@@0Q51Q+PO@f@@4NEJHwBRInQRYnyQYnG” . “i0QkFEE5x0EPTceDvCTwAAAAA4nHiUQkGInoD4@vAAAAD6+EJEABAACF@0aNBCgP” . “hHwDAABEi0wkQIt8JDgxyUiLhCRQAQAA6zNmDx9EAABBOdd+GkiLtCRgAQAARInC” . “AxSO9gQQAXUGQYPpAXgxSIPBATlMJBgPjr74@@87TCQUicp9y0iLtCRYAQAARYnD” . “RAMcjkKAPBgBd7WD7wF5sIO8JAgBAAAJD4R29v@@g0QkWAHpO@D@@4tEJBTHRCRA” . “AAAAAEUx@w+vhCSAAQAAwfgKiUQkOOmI7@@@g3wkXAF0HoN8JFwCD4TNAgAAQYPt” . “AelG9v@@g0QkSAHp4O@@@0GDxQHpM@b@@w8fgAAAAACLlCQwAQAAA4QkOAEAAA+v” . “hCQYAQAARAHqg7wk8AAAAAUPhFn2@@+NNJCLhCT4AAAASIu8JBABAABEi0wkGAHw” . “jVACRYXJSGPSD7YcF41QAUiYSGPSD7Y8F4l8JCRIi7wkEAEAAA+2BAeJRCQoD4Qu” . “AgAAi0QkQESJVCQgRTHbi3wkOEyLlCQQAQAAiUQkMOmMAAAARDt8JDx+dkiLhCRg” . “AQAAQosUmAHyjUICSJhBD7YMAo1CAUhj0kEPthQSSJgrVCQoQQ+2BAJBickB2StE” . “JCREjYEABAAAQSnZRQ+vwQ+vwEUPr8FBuf4FAADB4AtBKclEickPr8pEAcAPr9EB” . “0EE5xHILg2wkMAEPiJMAAABJg8MBRDlcJBgPjgb3@@9EO1wkFESJXCQ8D41k@@@@” . “SIuEJFgBAABCixSYAfKNQgJImEEPtgwCjUIBSGPSQQ+2FBJImCtUJChBD7YEAkGJ” . “yQHZK0QkJESNgQAEAABBKdlFD6@BD6@ARQ+vwcHgC0EBwLj+BQAAKcgPr8IPr8JE” . “AcBBOcQPg@n+@@+D7wEPifD+@@9Ei1QkIOni@f@@ZpDHRCQ4AAAAAMdEJBQAAAAA” . “6avx@@8x0uks9P@@Dx9AAIF8JCj@@@8AD4cz9v@@6Rz2@@+LRCQYi3wkOIXAD4Q4” . “9v@@RTHATIuMJBABAADrD0mDwAFEOUQkGA+OhgAAAEiLtCRYAQAAi0QkJEIDBIZI” . “i7QkYAEAAEKLDIaNUAJIY9JFD7YcEYnKweoQQSnTjVABSJhFD6@bRDmcJIgAAABB” . “D7YEAUhj0kEPthQRfCIPtt0p2g+v0jmUJIwAAAB8EQ+20SnQD6@AO4QkkAAAAH6A” . “g+8BD4l3@@@@iYwk+AAAAOn7@P@@iYwk+AAAAOmK9f@@i3wkOOmB9f@@g8UB6Xrz” . “@@@HRCQ4AAAAAMdEJEAAAAAAx0QkFAAAAADpoez@@zHS6Qvz@@8PtkQkPA+2VCRM” . “weYQweAICfAJ0ImEJPgAAADpG@X@@5CQkJCQkJCQkJA=” MyFunc:=this.MCode(StrReplace((A_PtrSize=8?x64:x32),”@”,”/”)) } text:=j[1], w:=j[2], h:=j[3] , err1:=this.Floor(j[4] ? j[5] : ini.err1) , err0:=this.Floor(j[4] ? j[6] : ini.err0) , mode:=j[7], color:=j[8], n:=j[9] ok:=(!ini.bits.Scan0 || mode<1 || mode>5) ? 0 : DllCall(MyFunc.Ptr, “int”,mode, “uint”,color, “uint”,n, “int”,dir , “Ptr”,ini.bits.Scan0, “int”,ini.bits.Stride , “int”,ini.bits.zw, “int”,ini.bits.zh , “int”,sx, “int”,sy, “int”,sw, “int”,sh , “Ptr”,ini.ss, “Ptr”,ini.s1, “Ptr”,ini.s0 , “Ptr”,text, “int”,w, “int”,h , “int”,Floor(Abs(err1)1024), “int”,Floor(Abs(err0)1024) , “int”,(err1<0||err0<0), “Ptr”,ini.allpos, “int”,ini.allpos_max , “int”,Floor(wini.zoomW), “int”,Floor(hini.zoomH)) return ok }
code() { return “ (
//*** C source code of machine code *** // gcc.exe -m32/-m64 -O2
int attribute((stdcall)) PicFind( int mode, unsigned int c, unsigned int n, int dir , unsigned char * Bmp, int Stride, int zw, int zh , int sx, int sy, int sw, int sh , unsigned char * ss, unsigned int * s1, unsigned int * s0 , unsigned char * text, int w, int h , int err1, int err0, int more_err , unsigned int * allpos, int allpos_max , int new_w, int new_h ) { int ok, o, i, j, k, v, t, e1, e0, len1, len0, max, pic, shape, dir1; int x, y, x1, y1, x2, y2, x3, y3, r, g, b, rr, gg, bb, dR, dG, dB; int ii, jj, RunDir, DirCount, RunCount, AllCount1, AllCount2; unsigned int c1, c2, cors, *arr; unsigned char *ts, *gs; ok=o=v=len1=len0=0; ts=ss+sw; gs=ts+sw; arr=allpos+allpos_max; //———————- if (mode==5) { if (pic=(c==2)) // FindPic { cors=(unsigned int *)(text+wh4); j=(err0»10)+1; n=2; k=n<=2||cors[2]<0x1000000; c2=cors[1]; r=(c2»16)&0xFF; g=(c2»8)&0xFF; b=c2&0xFF; dR=rr; dG=gg; dB=bb; for (y=0; y<h; y+=j) for (x=0; x<w; x+=j) { o=(yw+x)4; rr=text[2+o]; gg=text[1+o]; bb=text[o]; for (i=2; i<n;) { c1=cors[i++]; c2=cors[i++]; r=((c1»16)&0xFF)-rr; g=((c1»8)&0xFF)-gg; b=(c1&0xFF)-bb; v=(c2<0x40000000) ? ((1024+(r+rr+rr))rr+2048gg+(1534-(r+rr+rr))bb<=c2) : (rr<=((c2»16)&0xFF)((c2»16)&0xFF) && gg<=((c2»8)&0xFF)((c2»8)&0xFF) && bb<=(c2&0xFF)(c2&0xFF)); if (v) break; } if (v==k) continue; s1[len1]=(ynew_h/h)Stride+(xnew_w/w)4; s0[len1++]=rr«16|gg«8|bb; } } else // FindMultiColor or FindColor { shape=(c==1); // FindShape cors=(unsigned int *)text; for (i=0; i<n; i++, o+=22) { c=cors[o]; y=c»16; x=c&0xFFFF; s1[len1]=(ynew_h/h)Stride+(xnew_w/w)4; s0[len1++]=o+cors[o+1]2; } cors+=2; } goto StartLookUp; } //———————- // Generate Lookup Table for (y=0; y<h; y++) { for (x=0; x<w; x++) { i=(mode==4) ? (ynew_h/h)Stride+(xnew_w/w)4 : (ynew_h/h)sw+(xnew_w/w); if (text[o++]==’1’) s1[len1++]=i; else s0[len0++]=i; } } //———————- // Color Position Mode // only used to recognize multicolored Verification Code if (mode==4) { y=c»16; x=c&0xFFFF; c=(ynew_h/h)Stride+(xnew_w/w)4; goto StartLookUp; } //———————- // Generate Two Value Image o=syStride+sx4; j=Stride-sw4; i=0; if (mode==1) // Color Mode { cors=(unsigned int )(text+wh); n=2; k=cors[0]<0x1000000; for (y=0; y<sh; y++, o+=j) for (x=0; x<sw; x++, o+=4, i++) { rr=Bmp[2+o]; gg=Bmp[1+o]; bb=Bmp[o]; for (t=0; t<n;) { c1=cors[t++]; c2=cors[t++]; r=((c1»16)&0xFF)-rr; g=((c1»8)&0xFF)-gg; b=(c1&0xFF)-bb; v=(c2<0x40000000) ? ((1024+(r+rr+rr))rr+2048gg+(1534-(r+rr+rr))bb<=c2) : (rr<=((c2»16)&0xFF)((c2»16)&0xFF) && gg<=((c2»8)&0xFF)((c2»8)&0xFF) && bb<=(c2&0xFF)(c2&0xFF)); if (v) break; } ts[i]=(v==k) ? 2:1; } } else if (mode==2) // Gray Threshold Mode { c=(c+1)«7; for (y=0; y<sh; y++, o+=j) for (x=0; x<sw; x++, o+=4, i++) ts[i]=(Bmp[2+o]38+Bmp[1+o]75+Bmp[o]15<c) ? 2:1; } else if (mode==3) // Gray Difference Mode { o-=Stride+4; j-=8; k=sw+2; for (y=sy-1; y<=sy+sh; y++, o+=j) { for (x=sx-1; x<=sx+sw; x++, o+=4, i++) gs[i]=(x<0||x>=zw||y<0||y>=zh)?0:(Bmp[2+o]38+Bmp[1+o]75+Bmp[o]15)»7; } for (i=0, y=1; y<=sh; y++) for (x=1; x<=sw; x++, i++) { o=yk+x; n=gs[o]+c; ts[i]=(gs[o-1]>n || gs[o+1]>n || gs[o-k-1]>n || gs[o-k]>n || gs[o-k+1]>n || gs[o+k-1]>n || gs[o+k]>n || gs[o+k+1]>n) ? 2:1; } } if (more_err) { for (sx++, i=0, y=0; y<sh; y++) for (x=0; x<sw; x++, i++) ss[i]=ts[i]|(x==0?0:ts[i-1])|(x==sw-1?0:ts[i+1]); } else ss=ts; //———————- StartLookUp: err1=(len1err1)»10; err0=(len0err0)»10; if (err1>=len1) len1=0; if (err0>=len0) len0=0; max=(len1>len0) ? len1 : len0; w=new_w; h=new_h; x1=0; y1=0; x2=sw-w; y2=sh-h; // 1 ==> ( Left to Right ) Top to Bottom // 2 ==> ( Right to Left ) Top to Bottom // 3 ==> ( Left to Right ) Bottom to Top // 4 ==> ( Right to Left ) Bottom to Top // 5 ==> ( Top to Bottom ) Left to Right // 6 ==> ( Bottom to Top ) Left to Right // 7 ==> ( Top to Bottom ) Right to Left // 8 ==> ( Bottom to Top ) Right to Left // 9 ==> Center to Four Sides if (dir==9) { x=(x1+x2)/2; y=(y1+y2)/2; i=x2-x1+1; j=y2-y1+1; AllCount1=ij; i=(i>j?i:j)+8; AllCount2=ii; RunCount=0; DirCount=1; RunDir=0; for (ii=0; RunCount<AllCount1 && ii<AllCount2;) { for(jj=0; jj<DirCount; jj++, ii++) { if(x>=x1 && x<=x2 && y>=y1 && y<=y2) { RunCount++; goto FindPos; FindPos_GoBak:; } if (RunDir==0) y–; else if (RunDir==1) x++; else if (RunDir==2) y++; else x–; } if (RunDir & 1) DirCount++; RunDir = (++RunDir) & 3; } goto Return1; } dir1=(dir<1 || dir>8) ? 0 : dir-1; if (dir1>3) { r=y1; y1=x1; x1=r; r=y2; y2=x2; x2=r; } for (y3=y1; y3<=y2; y3++) { for (x3=x1; x3<=x2; x3++) { y=(dir1 & 2) ? y1+y2-y3 : y3; x=(dir1 & 1) ? x1+x2-x3 : x3; if (dir1>3) { r=y; y=x; x=r; } //———————- FindPos: e1=err1; e0=err0; if (mode<4) { o=ysw+x; for (i=0; i<max; i++) { if (i<len1 && ss[o+s1[i]]<2 && (–e1)<0) goto NoMatch; if (i<len0 && (ss[o+s0[i]]&1)==0 && (–e0)<0) goto NoMatch; } } else if (mode==5) { o=(sy+y)Stride+(sx+x)4; if (pic) { for (i=0; i<max; i++) { j=o+s1[i]; c=s0[i]; r=Bmp[2+j]-(c»16); g=Bmp[1+j]-((c»8)&0xFF); b=Bmp[j]-(c&0xFF); if ((rr>dR || gg>dG || bb>dB) && (–e1)<0) goto NoMatch; } } else { for (i=0; i<max; i++) { j=o+s1[i]; rr=Bmp[2+j]; gg=Bmp[1+j]; bb=Bmp[j]; for (j=i22, k=cors[j]>0xFFFFFF, n=s0[i]; j<n;) { c1=cors[j++]; c2=cors[j++]; if (shape) { if (i==0) { c=rr«16|gg«8|bb; goto MatchOK; } c1=c; } r=((c1»16)&0xFF)-rr; g=((c1»8)&0xFF)-gg; b=(c1&0xFF)-bb; v=(c2<0x40000000) ? ((1024+(r+rr+rr))rr+2048gg+(1534-(r+rr+rr))bb<=c2) : (rr<=((c2»16)&0xFF)((c2»16)&0xFF) && gg<=((c2»8)&0xFF)((c2»8)&0xFF) && bb<=(c2&0xFF)(c2&0xFF)); if (v) { if (k) goto NoMatch2; goto MatchOK; } } if (k) goto MatchOK; NoMatch2: if (i==0 || (–e1)<0) goto NoMatch; MatchOK:; } } } else // mode==4 { o=(sy+y)Stride+(sx+x)4; j=o+c; rr=Bmp[2+j]; gg=Bmp[1+j]; bb=Bmp[j]; for (i=0; i<max; i++) { if (i<len1) { j=o+s1[i]; r=Bmp[2+j]-rr; g=Bmp[1+j]-gg; b=Bmp[j]-bb; if ((1024+(r+rr+rr))rr+2048gg+(1534-(r+rr+rr))bb>n && (–e1)<0) goto NoMatch; } if (i<len0) { j=o+s0[i]; r=Bmp[2+j]-rr; g=Bmp[1+j]-gg; b=Bmp[j]-bb; if ((1024+(r+rr+rr))rr+2048gg+(1534-(r+rr+rr))bb<=n && (–e0)<0) goto NoMatch; } } } ok++; if (allpos) { allpos[ok-1]=(sy+y)«16|(sx+x); if (dir==0) arr[ok-1]=err1-e1; if (ok>=allpos_max) goto Return1; } NoMatch: if (dir==9) goto FindPos_GoBak; } } //———————- Return1: if (!allpos || wh==1) return ok; // Sort by smallest error if (dir==0) { for (i=1; i<ok; i++) { k=arr[i]; v=allpos[i]; for (j=i-1; j>=0 && arr[j]>k; j–) { arr[j+1]=arr[j]; allpos[j+1]=allpos[j]; } arr[j+1]=k; allpos[j+1]=v; } } // Clean up overlapping results w=(ww)»2; h=(hh)»2; k=ok; ok=0; for (i=0; i<k; i++) { c1=allpos[i]; x1=c1&0xFFFF; y1=c1»16; for (j=0; j<ok; j++) { c2=allpos[j]; x=(c2&0xFFFF)-x1; y=(c2»16)-y1; if (xx<w && yy<h) goto NoMatch3; } allpos[ok++]=c1; NoMatch3:; } return ok; }
)” }
PicInfo(text)
{
local
if !InStr(text, “$”)
return
static init, info, bmp
if !VarSetCapacity(init) && (init:=”1”)
info:=[], bmp:=[]
key:=(r:=StrLen(v:=Trim(text,”|”)))<10000 ? v
: DllCall(“ntdll\RtlComputeCrc32”, “uint”,0
, “Ptr”,&v, “uint”,r(1+!!A_IsUnicode), “uint”)
if info.HasKey(key)
return info[key]
comment:=””, seterr:=err1:=err0:=0
; You Can Add Comment Text within The <>
if RegExMatch(v, “O)<([^>\n])>”, r)
v:=StrReplace(v,r[0]), comment:=Trim(r[1])
; You can Add two fault-tolerant in the [], separated by commas
if RegExMatch(v, “O)[([^]\n])]”, r)
{
v:=StrReplace(v,r[0]), r:=StrSplit(r[1] “,”, “,”)
, seterr:=1, err1:=r[1], err0:=r[2]
}
color:=SubStr(v,1,InStr(v,”$”)-1), v:=Trim(SubStr(v,InStr(v,”$”)+1))
mode:=InStr(color,”##”) ? 5 : InStr(color,”#”) ? 4
: InStr(color,”**”) ? 3 : InStr(color,””) ? 2 : 1
color:=RegExReplace(StrReplace(color,”@”,”-“), “[*#\s]”)
(mode=1 || mode=5) && color:=StrReplace(color,”0x”)
if (mode=5)
{
if !(v~=”^[\s-\w.]+/[\s-\w.]+/[\s-\w./,]+$”) ;
ToRGB(color, f:=0) ; color can use: RRGGBB, Red, Yellow, Black, White { static init, tab if !VarSetCapacity(init) && (init:=”1”) tab:=Object(“Black”, “000000”, “White”, “FFFFFF” , “Red”, “FF0000”, “Green”, “008000”, “Blue”, “0000FF” , “Yellow”, “FFFF00”, “Silver”, “C0C0C0”, “Gray”, “808080” , “Teal”, “008080”, “Navy”, “000080”, “Aqua”, “00FFFF” , “Olive”, “808000”, “Lime”, “00FF00”, “Fuchsia”, “FF00FF” , “Purple”, “800080”, “Maroon”, “800000”) return this.Floor(“0x” (tab.HasKey(color)?tab[color]:color))&0xFFFFFF|(f?0x1000000:0) }
Buffer(size, FillByte:=””) { local buf:={}, buf.SetCapacity(“_key”, size), p:=buf.GetAddress(“_key”) , (FillByte!=”” && DllCall(“RtlFillMemory”,”Ptr”,p,”Ptr”,size,”uchar”,FillByte)) , buf.Ptr:=p, buf.Size:=size return buf }
GetBitsFromScreen(ByRef x:=0, ByRef y:=0, ByRef w:=0, ByRef h:=0 , ScreenShot:=1, ByRef zx:=0, ByRef zy:=0, ByRef zw:=0, ByRef zh:=0) { local static init, CAPTUREBLT if !VarSetCapacity(init) && (init:=”1”) ; thanks Descolada { DllCall(“Dwmapi\DwmIsCompositionEnabled”, “Int“,i:=0) CAPTUREBLT:=i ? 0 : 0x40000000 } if InStr(A_OSVersion, “.”) ; thanks QQ:349029755 Try DllCall(“SetThreadDpiAwarenessContext”, “Ptr”,-3) (!IsObject(this.bits) && this.bits:={Scan0:0, hBM:0, oldzw:0, oldzh:0}) , bits:=this.bits if (!ScreenShot && bits.Scan0) { zx:=bits.zx, zy:=bits.zy, zw:=bits.zw, zh:=bits.zh , w:=Min(x+w,zx+zw), x:=Max(x,zx), w-=x , h:=Min(y+h,zy+zh), y:=Max(y,zy), h-=y return bits } bch:=A_BatchLines, cri:=A_IsCritical Critical bits.BindWindow:=id:=this.BindWindow(0,0,1) if (id) { WinGet, id, ID, ahk_id %id% WinGetPos, zx, zy, zw, zh, ahk_id %id% } if (!id) { SysGet, zx, 76 SysGet, zy, 77 SysGet, zw, 78 SysGet, zh, 79 } this.UpdateBits(bits, zx, zy, zw, zh) , w:=Min(x+w,zx+zw), x:=Max(x,zx), w-=x , h:=Min(y+h,zy+zh), y:=Max(y,zy), h-=y if (!ScreenShot || w<1 || h<1 || !bits.hBM) { Critical % cri SetBatchLines % bch return bits } sx:=x, sy:=y, sw:=w, sh:=h, x–, y–, w+=2, h+=2 , w:=Min(x+w,zx+zw), x:=Max(x,zx), w-=x , h:=Min(y+h,zy+zh), y:=Max(y,zy), h-=y if IsFunc(k:=”GetBitsFromScreen2”) && %k%(bits, x-zx, y-zy, w, h) { ; Get the bind window use bits.BindWindow ; Each small range of data obtained from DXGI must be ; copied to the screenshot cache using FindText().CopyBits() zx:=bits.zx, zy:=bits.zy, zw:=bits.zw, zh:=bits.zh x:=sx, y:=sy, w:=sw, h:=sh Critical % cri SetBatchLines % bch return bits } mDC:=DllCall(“CreateCompatibleDC”, “Ptr”,0, “Ptr”) oBM:=DllCall(“SelectObject”, “Ptr”,mDC, “Ptr”,bits.hBM, “Ptr”) if (id) { if (mode:=this.BindWindow(0,0,0,1))<2 { hDC:=DllCall(“GetDCEx”, “Ptr”,id, “Ptr”,0, “int”,3, “Ptr”) DllCall(“BitBlt”,”Ptr”,mDC,”int”,x-zx,”int”,y-zy,”int”,w,”int”,h , “Ptr”,hDC, “int”,x-zx, “int”,y-zy, “uint”,0xCC0020|CAPTUREBLT) DllCall(“ReleaseDC”, “Ptr”,id, “Ptr”,hDC) } else { hBM2:=this.CreateDIBSection(zw, zh) mDC2:=DllCall(“CreateCompatibleDC”, “Ptr”,0, “Ptr”) oBM2:=DllCall(“SelectObject”, “Ptr”,mDC2, “Ptr”,hBM2, “Ptr”) DllCall(“UpdateWindow”, “Ptr”,id) ; RDW_INVALIDATE=0x1|RDW_ERASE=0x4|RDW_ALLCHILDREN=0x80|RDW_FRAME=0x400 ; DllCall(“RedrawWindow”, “Ptr”,id, “Ptr”,0, “Ptr”,0, “uint”, 0x485) DllCall(“PrintWindow”, “Ptr”,id, “Ptr”,mDC2, “uint”,(mode>3)3) DllCall(“BitBlt”,”Ptr”,mDC,”int”,x-zx,”int”,y-zy,”int”,w,”int”,h , “Ptr”,mDC2, “int”,x-zx, “int”,y-zy, “uint”,0xCC0020) DllCall(“SelectObject”, “Ptr”,mDC2, “Ptr”,oBM2) DllCall(“DeleteDC”, “Ptr”,mDC2) DllCall(“DeleteObject”, “Ptr”,hBM2) } } else { hDC:=DllCall(“GetWindowDC”,”Ptr”,id:=DllCall(“GetDesktopWindow”,”Ptr”),”Ptr”) DllCall(“BitBlt”,”Ptr”,mDC,”int”,x-zx,”int”,y-zy,”int”,w,”int”,h , “Ptr”,hDC, “int”,x, “int”,y, “uint”,0xCC0020|CAPTUREBLT) DllCall(“ReleaseDC”, “Ptr”,id, “Ptr”,hDC) } if this.CaptureCursor(0,0,0,0,0,1) this.CaptureCursor(mDC, zx, zy, zw, zh) DllCall(“SelectObject”, “Ptr”,mDC, “Ptr”,oBM) DllCall(“DeleteDC”, “Ptr”,mDC) x:=sx, y:=sy, w:=sw, h:=sh Critical % cri SetBatchLines % bch return bits }
UpdateBits(bits, zx, zy, zw, zh) { local if (zw>bits.oldzw || zh>bits.oldzh || !bits.hBM) { Try DllCall(“DeleteObject”, “Ptr”,bits.hBM) bits.hBM:=this.CreateDIBSection(zw, zh, bpp:=32, ppvBits) , bits.Scan0:=(!bits.hBM ? 0:ppvBits) , bits.Stride:=((zwbpp+31)//32)4 , bits.oldzw:=zw, bits.oldzh:=zh } bits.zx:=zx, bits.zy:=zy, bits.zw:=zw, bits.zh:=zh }
CreateDIBSection(w, h, bpp:=32, ByRef ppvBits:=0) { local VarSetCapacity(bi, 40, 0), NumPut(40, bi, 0, “int”) , NumPut(w, bi, 4, “int”), NumPut(-h, bi, 8, “int”) , NumPut(1, bi, 12, “short”), NumPut(bpp, bi, 14, “short”) return DllCall(“CreateDIBSection”, “Ptr”,0, “Ptr”,&bi , “int”,0, “Ptr*“,ppvBits:=0, “Ptr”,0, “int”,0, “Ptr”) }
GetBitmapWH(hBM, ByRef w, ByRef h) { local VarSetCapacity(bm, size:=(A_PtrSize=8 ? 32:24), 0) , DllCall(“GetObject”, “Ptr”,hBM, “int”,size, “Ptr”,&bm) , w:=NumGet(bm,4,”int”), h:=Abs(NumGet(bm,8,”int”)) }
CopyHBM(hBM1, x1, y1, hBM2, x2, y2, w, h, Clear:=0) { local if (w<1 || h<1 || !hBM1 || !hBM2) return mDC1:=DllCall(“CreateCompatibleDC”, “Ptr”,0, “Ptr”) oBM1:=DllCall(“SelectObject”, “Ptr”,mDC1, “Ptr”,hBM1, “Ptr”) mDC2:=DllCall(“CreateCompatibleDC”, “Ptr”,0, “Ptr”) oBM2:=DllCall(“SelectObject”, “Ptr”,mDC2, “Ptr”,hBM2, “Ptr”) DllCall(“BitBlt”, “Ptr”,mDC1, “int”,x1, “int”,y1, “int”,w, “int”,h , “Ptr”,mDC2, “int”,x2, “int”,y2, “uint”,0xCC0020) if (Clear) DllCall(“BitBlt”, “Ptr”,mDC1, “int”,x1, “int”,y1, “int”,w, “int”,h , “Ptr”,mDC1, “int”,x1, “int”,y1, “uint”,MERGECOPY:=0xC000CA) DllCall(“SelectObject”, “Ptr”,mDC1, “Ptr”,oBM1) DllCall(“DeleteDC”, “Ptr”,mDC1) DllCall(“SelectObject”, “Ptr”,mDC2, “Ptr”,oBM2) DllCall(“DeleteDC”, “Ptr”,mDC2) }
CopyBits(Scan01,Stride1,x1,y1,Scan02,Stride2,x2,y2,w,h,Reverse:=0) { local if (w<1 || h<1 || !Scan01 || !Scan02) return static init, MFCopyImage if !VarSetCapacity(init) && (init:=”1”) { MFCopyImage:=DllCall(“GetProcAddress”, “Ptr” , DllCall(“LoadLibrary”, “Str”,”Mfplat.dll”, “Ptr”) , “AStr”,”MFCopyImage”, “Ptr”) } if (MFCopyImage && !Reverse) ; thanks QQ:121507989 { return DllCall(MFCopyImage , “Ptr”,Scan01+y1Stride1+x14, “int”,Stride1 , “Ptr”,Scan02+y2Stride2+x24, “int”,Stride2 , “uint”,w4, “uint”,h) } ListLines % (lls:=A_ListLines)?0:0 SetBatchLines % (bch:=A_BatchLines)?”-1”:”-1” p1:=Scan01+(y1-1)Stride1+x14 , p2:=Scan02+(y2-1)Stride2+x24, w=4 , (Reverse) && (p2+=(h+1)*Stride2, Stride2:=-Stride2) Loop % h DllCall(“RtlMoveMemory”,”Ptr”,p1+=Stride1,”Ptr”,p2+=Stride2,”Ptr”,w) SetBatchLines % bch ListLines % lls }
DrawHBM(hBM, lines) { local mDC:=DllCall(“CreateCompatibleDC”, “Ptr”,0, “Ptr”) oBM:=DllCall(“SelectObject”, “Ptr”,mDC, “Ptr”,hBM, “Ptr”) oldc:=””, brush:=0, VarSetCapacity(rect, 16) For k,v in lines ; [ [x, y, w, h, color] ] if IsObject(v) { if (oldc!=v[5]) { oldc:=v[5], BGR:=(oldc&0xFF)«16|oldc&0xFF00|(oldc»16)&0xFF DllCall(“DeleteObject”, “Ptr”,brush) brush:=DllCall(“CreateSolidBrush”, “uint”,BGR, “Ptr”) } DllCall(“SetRect”, “Ptr”,&rect, “int”,v[1], “int”,v[2] , “int”,v[1]+v[3], “int”,v[2]+v[4]) DllCall(“FillRect”, “Ptr”,mDC, “Ptr”,&rect, “Ptr”,brush) } DllCall(“DeleteObject”, “Ptr”,brush) DllCall(“SelectObject”, “Ptr”,mDC, “Ptr”,oBM) DllCall(“DeleteObject”, “Ptr”,mDC) }
; 绑定窗口从而可以后台查找这个窗口的图像 ; 相当于始终在前台。解绑窗口使用 FindText().BindWindow(0)
BindWindow(bind_id:=0, bind_mode:=0, get_id:=0, get_mode:=0) { local (!IsObject(this.bind) && this.bind:={id:0, mode:0, oldStyle:0}) , bind:=this.bind if (get_id) return bind.id if (get_mode) return bind.mode if (bind_id) { bind.id:=bind_id:=this.Floor(bind_id) , bind.mode:=bind_mode, bind.oldStyle:=0 if (bind_mode & 1) { WinGet, i, ExStyle, ahk_id %bind_id% bind.oldStyle:=i WinSet, Transparent, 255, ahk_id %bind_id% Loop 30 { Sleep 100 WinGet, i, Transparent, ahk_id %bind_id% } Until (i=255) } } else { bind_id:=bind.id if (bind.mode & 1) WinSet, ExStyle, % bind.oldStyle, ahk_id %bind_id% bind.id:=0, bind.mode:=0, bind.oldStyle:=0 } }
; 使用 FindText().CaptureCursor(1) 设置抓图时捕获鼠标 ; 使用 FindText().CaptureCursor(0) 取消抓图时捕获鼠标
CaptureCursor(hDC:=0, zx:=0, zy:=0, zw:=0, zh:=0, get_cursor:=0) { local if (get_cursor) return this.Cursor if (hDC=1 || hDC=0) && (zw=0) { this.Cursor:=hDC return } VarSetCapacity(mi, 40, 0), NumPut(16+A_PtrSize, mi, “int”) DllCall(“GetCursorInfo”, “Ptr”,&mi) bShow:=NumGet(mi, 4, “int”) hCursor:=NumGet(mi, 8, “Ptr”) x:=NumGet(mi, 8+A_PtrSize, “int”) y:=NumGet(mi, 12+A_PtrSize, “int”) if (!bShow) || (x<zx || y<zy || x>=zx+zw || y>=zy+zh) return VarSetCapacity(ni, 40, 0) DllCall(“GetIconInfo”, “Ptr”,hCursor, “Ptr”,&ni) xCenter:=NumGet(ni, 4, “int”) yCenter:=NumGet(ni, 8, “int”) hBMMask:=NumGet(ni, (A_PtrSize=8?16:12), “Ptr”) hBMColor:=NumGet(ni, (A_PtrSize=8?24:16), “Ptr”) DllCall(“DrawIconEx”, “Ptr”,hDC , “int”,x-xCenter-zx, “int”,y-yCenter-zy, “Ptr”,hCursor , “int”,0, “int”,0, “int”,0, “int”,0, “int”,3) DllCall(“DeleteObject”, “Ptr”,hBMMask) DllCall(“DeleteObject”, “Ptr”,hBMColor) }
MCode(hex) { local flag:=((hex~=”[^A-Fa-f\d\s]”) ? 1:4), len:=0 Loop 2 if !DllCall(“crypt32\CryptStringToBinary”, “Str”,hex, “uint”,0, “uint”,flag , “Ptr”,(A_Index=1?0:(p:=this.Buffer(len)).Ptr), “uint“,len, “Ptr”,0, “Ptr”,0) return if DllCall(“VirtualProtect”, “Ptr”,p.Ptr, “Ptr”,len, “uint”,0x40, “uint“,0) return p }
bin2hex(addr, size, base64:=0) { local flag:=(base64 ? 1:4)|0x40000000, len:=0 Loop 2 DllCall(“crypt32\CryptBinaryToString”, “Ptr”,addr, “uint”,size, “uint”,flag , “Ptr”,(A_Index=1?0:(p:=this.Buffer(len2)).Ptr), “uint“,len) return RegExReplace(StrGet(p.Ptr, len), “\s+”) }
base64tobit(s) { local ListLines % (lls:=A_ListLines)?0:0 Chars:=”0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz” SetFormat, IntegerFast, d Loop Parse, Chars if InStr(s, A_LoopField, 1) s:=RegExReplace(s, “[” A_LoopField “]”, ((i:=A_Index-1)»5&1) . (i»4&1) . (i»3&1) . (i»2&1) . (i»1&1) . (i&1)) s:=RegExReplace(RegExReplace(s,”[^01]+”),”10*$”) ListLines % lls return s }
bit2base64(s) { local ListLines % (lls:=A_ListLines)?0:0 s:=RegExReplace(s,”[^01]+”) s.=SubStr(“100000”,1,6-Mod(StrLen(s),6)) s:=RegExReplace(s,”.{6}”,”|$0”) Chars:=”0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz” SetFormat, IntegerFast, d Loop Parse, Chars s:=StrReplace(s, “|” . ((i:=A_Index-1)»5&1) . (i»4&1) . (i»3&1) . (i»2&1) . (i»1&1) . (i&1), A_LoopField) ListLines % lls return s }
ASCII(s) { local if RegExMatch(s, “O)$(\d+).([\w+/]+)”, r) { s:=RegExReplace(this.base64tobit(r[2]),”.{“ r[1] “}”,”$0`n”) s:=StrReplace(StrReplace(s,”0”,”_”),”1”,”0”) } else s:=”” return s }
; 可以在脚本的开头用 FindText().PicLib(Text,1) 导入字库, ; 然后使用 FindText().PicLib(“说明文字1|说明文字2|…”) 获取字库中的数据
PicLib(comments, add_to_Lib:=0, index:=1) { local (!IsObject(this.Lib) && this.Lib:=[]), Lib:=this.Lib , (!Lib.HasKey(index) && Lib[index]:=[]), Lib:=Lib[index] if (add_to_Lib) { re:=”O)<([^>\n]*)>[^$\n]+$[^”“\r\n]+” Loop Parse, comments, | if RegExMatch(A_LoopField, re, r) { s1:=Trim(r[1]), s2:=”” Loop Parse, s1 s2.=Format(“{:d}”, Ord(A_LoopField)) (s2!=””) && Lib[s2]:=r[0] } } else { Text:=”” Loop Parse, comments, | { s1:=Trim(A_LoopField), s2:=”” Loop Parse, s1 s2.=Format(“”, Ord(A_LoopField)) (Lib.HasKey(s2)) && Text.=”|” Lib[s2] } return Text } }
; 分割字符串为单个文字并获取数据
PicN(Number, index:=1) { return this.PicLib(RegExReplace(Number,”.”,”|$0”), 0, index) }
; 使用 FindText().PicX(Text) 可以将文字分割成多个单字的组合,从而适应间隔变化 ; 但是不能用于“颜色位置二值化”模式, 因为位置是与整体图像相关的
PicX(Text)
{
local
if !RegExMatch(Text, “O)(<[^$\n]+)$(\d+).([\w+/]+)”, r)
return Text
v:=this.base64tobit(r[3]), Text:=””
c:=StrLen(StrReplace(v,”0”))<=StrLen(v)//2 ? “1”:”0”
txt:=RegExReplace(v,”.{“ r[2] “}”,”$0n")
While InStr(txt,c)
{
While !(txt~="mn)^” c)
txt:=RegExReplace(txt,”mn)^.")
i:=0
While (txt~="mn)^.{“ i “}” c)
i:=Format(““,i+1)
v:=RegExReplace(txt,”mn)^(.{" i "}).*","$1")
txt:=RegExReplace(txt,"mn)^.{“ i “}”)
if (v!=””)
Text.=”|” r[1] “$” i “.” this.bit2base64(v)
}
return Text
}
; 截屏,作为后续操作要用的“上一次的截屏”
ScreenShot(x1:=0, y1:=0, x2:=0, y2:=0) { this.FindText(,, x1, y1, x2, y2) }
; 从“上一次的截屏”中快速获取指定坐标的RGB颜色 ; 如果坐标超出了屏幕范围,将返回白色
GetColor(x, y, fmt:=1) { local bits:=this.GetBitsFromScreen(,,,,0,zx,zy,zw,zh), x-=zx, y-=zy , c:=(x>=0 && x<zw && y>=0 && y<zh && bits.Scan0) ? NumGet(bits.Scan0+ybits.Stride+x4,”uint”) : 0xFFFFFF return (fmt ? Format(“0x{:06X}”,c&0xFFFFFF) : c) }
; 在“上一次的截屏”中设置点的RGB颜色
SetColor(x, y, color:=0x000000) { local bits:=this.GetBitsFromScreen(,,,,0,zx,zy,zw,zh), x-=zx, y-=zy if (x>=0 && x<zw && y>=0 && y<zh && bits.Scan0) NumPut(color, bits.Scan0+ybits.Stride+x4, “uint”) }
; 根据 FindText() 的结果识别一行文字或验证码 ; offsetX 为两个文字的最大间隔,超过会插入*号 ; offsetY 为两个文字的最大高度差 ; overlapW 用于设置覆盖的宽度 ; 最后返回数组:{text:识别结果, x:结果左上角X, y:结果左上角Y, w:宽, h:高}
Ocr(ok, offsetX:=20, offsetY:=20, overlapW:=0) { local ocr_Text:=ocr_X:=ocr_Y:=min_X:=dx:=”” For k,v in ok x:=v.1 , min_X:=(A_Index=1 || x<min_X ? x : min_X) , max_X:=(A_Index=1 || x>max_X ? x : max_X) While (min_X!=”” && min_X<=max_X) { LeftX:=”” For k,v in ok { x:=v.1, y:=v.2 if (x<min_X) || (ocr_Y!=”” && Abs(y-ocr_Y)>offsetY) Continue ; Get the leftmost X coordinates if (LeftX=”” || x<LeftX) LeftX:=x, LeftY:=y, LeftW:=v.3, LeftH:=v.4, LeftOCR:=v.id } if (LeftX=””) Break if (ocr_X=””) ocr_X:=LeftX, min_Y:=LeftY, max_Y:=LeftY+LeftH ; If the interval exceeds the set value, add “” to the result ocr_Text.=(ocr_Text!=”” && LeftX>dx ? “”:””) . LeftOCR ; Update for next search min_X:=LeftX+LeftW-(overlapW>LeftW//2 ? LeftW//2:overlapW) , dx:=LeftX+LeftW+offsetX, ocr_Y:=LeftY , (LeftY<min_Y && min_Y:=LeftY) , (LeftY+LeftH>max_Y && max_Y:=LeftY+LeftH) } (ocr_X=””) && ocr_X:=min_Y:=min_X:=max_Y:=0 return {text:ocr_Text, x:ocr_X, y:min_Y, w:min_X-ocr_X, h:max_Y-min_Y} }
; 按照从左到右、从上到下的顺序排序FindText()的结果 ; 忽略轻微的Y坐标差距,返回排序后的数组对象
Sort(ok, dy:=10) { local if !IsObject(ok) return ok s:=””, n:=150000, ypos:=[] For k,v in ok { x:=v.x, y:=v.y, add:=1 For k1,v1 in ypos if Abs(y-v1)<=dy { y:=v1, add:=0 Break } if (add) ypos.Push(y) s.=(y*n+x) “.” k “|” } s:=Trim(s,”|”) Sort, s, N D| ok2:=[] For k,v in StrSplit(s,”|”) ok2.Push(ok[SubStr(v,InStr(v,”.”)+1)]) return ok2 }
; 以指定点为中心,按从近到远排序FindText()的结果,返回排序后的数组
Sort2(ok, px, py) { local if !IsObject(ok) return ok s:=”” For k,v in ok s.=((v.x-px)2+(v.y-py)2) “.” k “|” s:=Trim(s,”|”) Sort, s, N D| ok2:=[] For k,v in StrSplit(s,”|”) ok2.Push(ok[SubStr(v,InStr(v,”.”)+1)]) return ok2 }
; 按指定的查找方向,排序FindText()的结果,返回排序后的数组
Sort3(ok, dir:=1) { local if !IsObject(ok) return ok s:=””, n:=150000 For k,v in ok x:=v.1, y:=v.2 , s.=(dir=1 ? yn+x : dir=2 ? yn-x : dir=3 ? -yn+x : dir=4 ? -yn-x : dir=5 ? xn+y : dir=6 ? xn-y : dir=7 ? -xn+y : dir=8 ? -xn-y : y*n+x) “.” k “|” s:=Trim(s,”|”) Sort, s, N D| ok2:=[] For k,v in StrSplit(s,”|”) ok2.Push(ok[SubStr(v,InStr(v,”.”)+1)]) return ok2 }
; 提示某个坐标的位置,或远程控制中当前鼠标的位置
MouseTip(x:=””, y:=””, w:=10, h:=10, d:=3) { local if (x=””) { VarSetCapacity(pt,16,0), DllCall(“GetCursorPos”,”Ptr”,&pt) x:=NumGet(pt,0,”uint”), y:=NumGet(pt,4,”uint”) } Loop 4 { this.RangeTip(x-w, y-h, 2w+1, 2h+1, (A_Index & 1 ? “Red”:”Blue”), d) Sleep 500 } this.RangeTip() }
; 显示范围的边框,类似于 ToolTip
RangeTip(x:=””, y:=””, w:=””, h:=””, color:=”Red”, d:=3, num:=1) { local ListLines % (lls:=A_ListLines)?0:0 static init, tab if !VarSetCapacity(init) && (init:=”1”) tab:=[] (!tab.HasKey(num) && tab[num]:=[0,0,0,0]), Range:=tab[num] if (x=””) { if (Range[1]) Loop 4 { Gui, % Range[A_Index] “:Destroy” Range[A_Index]:=0 } ListLines % lls return } if !(Range[1]) { Loop 4 { Gui, New, +Hwndid +AlwaysOnTop -Caption +ToolWindow -DPIScale +E0x08000000 Range[A_Index]:=id } } x:=Floor(x), y:=Floor(y), w:=Floor(w), h:=Floor(h), d:=Floor(d) Loop 4 { i:=A_Index , x1:=(i=2 ? x+w : x-d) , y1:=(i=3 ? y+h : y-d) , w1:=(i=1 || i=3 ? w+2d : d) , h1:=(i=2 || i=4 ? h+2d : d) Gui, % Range[i] “:Color”, %color% Gui, % Range[i] “:Show”, NA x%x1% y%y1% w%w1% h%h1% } ListLines % lls }
State(key) { return GetKeyState(key,”P”) || GetKeyState(key) }
; 用鼠标左右键选取屏幕范围
GetRange(ww:=25, hh:=8, key:=”RButton”) { local static init, KeyOff, hk if !VarSetCapacity(init) && (init:=”1”) KeyOff:=this.GetRange.Bind(this, “Off”) if (ww==”Off”) return hk:=Trim(A_ThisHotkey, “”) ;——————— GetRange_HotkeyIf:=_Gui:=this.GuiNew() _Gui.Opt(“-Caption +ToolWindow +E0x80000”) _Gui.Title:=”GetRange_HotkeyIf” _Gui.Show(“NA x0 y0 w0 h0”) ;——————— if GetKeyState(“Ctrl”) Send {Ctrl Up} Hotkey, IfWinExist, GetRange_HotkeyIf keys:=key “|Up|Down|Left|Right” For k,v in StrSplit(keys, “|”) { if GetKeyState(v) Send {%v% Up} Hotkey, *%v%, %KeyOff%, On UseErrorLevel } Hotkey, IfWinExist ;——————— Critical % (cri:=A_IsCritical)?”Off”:”Off” CoordMode, Mouse tip:=this.Lang(“s5”) hk:=””, oldx:=oldy:=””, keydown:=0 Loop { Sleep 50 MouseGetPos, x2, y2 if (hk=key) || this.State(key) || this.State(“Ctrl”) { keydown++ if (keydown=1) MouseGetPos, x1, y1, Bind_ID timeout:=A_TickCount+3000 While (A_TickCount<timeout) && (this.State(key) || this.State(“Ctrl”)) Sleep 50 hk:=”” if (keydown>=2) Break } else if (hk=”Up”) || this.State(“Up”) (hh>1 && hh–), hk:=”” else if (hk=”Down”) || this.State(“Down”) hh++, hk:=”” else if (hk=”Left”) || this.State(“Left”) (ww>1 && ww–), hk:=”” else if (hk=”Right”) || this.State(“Right”) ww++, hk:=”” x:=(keydown?x1:x2), y:=(keydown?y1:y2) this.RangeTip(x-ww, y-hh, 2ww+1, 2*hh+1, (A_MSec<500?”Red”:”Blue”)) if (oldx=x2 && oldy=y2) Continue oldx:=x2, oldy:=y2 ToolTip % “x: “ x “ y: “ y “`n” tip } ToolTip this.RangeTip() Hotkey, IfWinExist, GetRange_HotkeyIf For k,v in StrSplit(keys, “|”) Hotkey, *%v%, %KeyOff%, Off UseErrorLevel Hotkey, IfWinExist GetRange_HotkeyIf.Destroy() Critical % cri return [x-ww, y-hh, x+ww, y+hh, Bind_ID] }
GetRange2(key:=”LButton”)
{
local
FindText_GetRange:=_Gui:=this.GuiNew()
_Gui.Opt(“+LastFound +AlwaysOnTop -Caption +ToolWindow -DPIScale +E0x08000000”)
_Gui.BackColor:=”White”
WinSet, Transparent, 10
this.GetBitsFromScreen(,,,,0,x,y,w,h)
_Gui.Title:=”FindText_GetRange”
_Gui.Show(“NA x” x “ y” y “ w” w “ h” h)
CoordMode, Mouse
tip:=this.Lang(“s7”), oldx:=oldy:=””
Loop
{
Sleep 50
MouseGetPos, x1, y1
if (oldx=x1 && oldy=y1)
Continue
oldx:=x1, oldy:=y1
ToolTip % “x: “ x1 “ y: “ y1 “ w: 0 h: 0n" tip
}
Until this.State(key) || this.State("Ctrl")
Loop
{
Sleep 50
MouseGetPos, x2, y2
x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x2-x1)+1, h:=Abs(y2-y1)+1
this.RangeTip(x, y, w, h, (A_MSec<500 ? "Red":"Blue"))
if (oldx=x2 && oldy=y2)
Continue
oldx:=x2, oldy:=y2
ToolTip % "x: " x " y: " y " w: " w " h: " h "n” tip
}
Until !(this.State(key) || this.State(“Ctrl”))
ToolTip
this.RangeTip()
FindText_GetRange.Destroy()
Clipboard:=x “,” y “,” (x+w-1) “,” (y+h-1)
return [x, y, x+w-1, y+h-1]
}
BitmapFromScreen(ByRef x:=0, ByRef y:=0, ByRef w:=0, ByRef h:=0 , ScreenShot:=1, ByRef zx:=0, ByRef zy:=0, ByRef zw:=0, ByRef zh:=0) { local bits:=this.GetBitsFromScreen(x,y,w,h,ScreenShot,zx,zy,zw,zh) if (w<1 || h<1 || !bits.hBM) return hBM:=this.CreateDIBSection(w, h) this.CopyHBM(hBM, 0, 0, bits.hBM, x-zx, y-zy, w, h, 1) return hBM }
; 快速保存截图为BMP文件,可用于调试 ; 如果 file=0 或 “” ,会保存到剪贴板
SavePic(file:=0, x1:=0, y1:=0, x2:=0, y2:=0, ScreenShot:=1) { local x1:=this.Floor(x1), y1:=this.Floor(y1), x2:=this.Floor(x2), y2:=this.Floor(y2) if (x1=0 && y1=0 && x2=0 && y2=0) n:=150000, x:=y:=-n, w:=h:=2*n else x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x2-x1)+1, h:=Abs(y2-y1)+1 hBM:=this.BitmapFromScreen(x, y, w, h, ScreenShot) this.SaveBitmapToFile(file, hBM) DllCall(“DeleteObject”, “Ptr”,hBM) }
; 保存图像到文件,如果 file=0 或者 ““,保存到剪贴板 ; 参数可以是位图句柄或者文件路径,例如: “c:\a.bmp”
SaveBitmapToFile(file, hBM_or_file, x:=0, y:=0, w:=0, h:=0) { local if hBM_or_file is number hBM_or_file:=”HBITMAP:” hBM_or_file if !hBM:=DllCall(“CopyImage”, “Ptr”,LoadPicture(hBM_or_file) , “int”,0, “int”,0, “int”,0, “uint”,0x2008) return if (file) || (w!=0 && h!=0) { (w=0 || h=0) && this.GetBitmapWH(hBM, w, h) hBM2:=this.CreateDIBSection(w, -h, bpp:=(file ? 24 : 32)) this.CopyHBM(hBM2, 0, 0, hBM, x, y, w, h) DllCall(“DeleteObject”, “Ptr”,hBM), hBM:=hBM2 } VarSetCapacity(dib, dib_size:=(A_PtrSize=8 ? 104:84), 0) , DllCall(“GetObject”, “Ptr”,hBM, “int”,dib_size, “Ptr”,&dib) , pbi:=&dib+(bitmap_size:=A_PtrSize=8 ? 32:24) , size:=NumGet(pbi+20, “uint”), pBits:=NumGet(pbi-A_PtrSize, “Ptr”) if (!file) { hdib:=DllCall(“GlobalAlloc”, “uint”,2, “Ptr”,40+size, “Ptr”) pdib:=DllCall(“GlobalLock”, “Ptr”,hdib, “Ptr”) DllCall(“RtlMoveMemory”, “Ptr”,pdib, “Ptr”,pbi, “Ptr”,40) DllCall(“RtlMoveMemory”, “Ptr”,pdib+40, “Ptr”,pBits, “Ptr”,size) DllCall(“GlobalUnlock”, “Ptr”,hdib) DllCall(“OpenClipboard”, “Ptr”,0) DllCall(“EmptyClipboard”) DllCall(“SetClipboardData”, “uint”,8, “Ptr”,hdib) DllCall(“CloseClipboard”) } else { if InStr(file,”") && !FileExist(dir:=RegExReplace(file,”[^\]$”)) Try FileCreateDir, % dir VarSetCapacity(bf, 14, 0), NumPut(0x4D42, bf, “short”) NumPut(54+size, bf, 2, “uint”), NumPut(54, bf, 10, “uint”) f:=FileOpen(file, “w”), f.RawWrite(bf, 14) , f.RawWrite(pbi+0, 40), f.RawWrite(pBits+0, size), f.Close() } DllCall(“DeleteObject”, “Ptr”,hBM) }
; 显示保存的图像
ShowPic(file:=””, show:=1, ByRef x:=””, ByRef y:=””, ByRef w:=””, ByRef h:=””) { local if (file=””) { this.ShowScreenShot() return } if !(hBM:=LoadPicture(file)) return this.GetBitmapWH(hBM, w, h) bits:=this.GetBitsFromScreen(,,,,0,x,y,zw,zh) this.UpdateBits(bits, x, y, Max(w,zw), Max(h,zh)) this.CopyHBM(bits.hBM, 0, 0, hBM, 0, 0, w, h) DllCall(“DeleteObject”, “Ptr”,hBM) if (show) this.ShowScreenShot(x, y, x+w-1, y+h-1, 0) return 1 }
; 显示内存中的屏幕截图用于调试
ShowScreenShot(x1:=0, y1:=0, x2:=0, y2:=0, ScreenShot:=1) { local static init, hPic, oldx, oldy, oldw, oldh, FindText_Screen if !VarSetCapacity(init) && (init:=”1”) FindText_Screen:=”” x1:=this.Floor(x1), y1:=this.Floor(y1), x2:=this.Floor(x2), y2:=this.Floor(y2) if (x1=0 && y1=0 && x2=0 && y2=0) { if (FindText_Screen) FindText_Screen.Destroy(), FindText_Screen:=”” return } x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x2-x1)+1, h:=Abs(y2-y1)+1 if !hBM:=this.BitmapFromScreen(x,y,w,h,ScreenShot) return ;————— if (!FindText_Screen) { FindText_Screen:=_Gui:=this.GuiNew() ; WS_EX_NOACTIVATE:=0x08000000 _Gui.Opt(“+AlwaysOnTop -Caption +ToolWindow -DPIScale +E0x08000000”) _Gui.MarginX:=0, _Gui.MarginY:=0 id:=_Gui.Add(“Pic”, “w” w “ h” h), hPic:=id.Hwnd _Gui.Title:=”Show Pic” _Gui.Show(“NA x” x “ y” y “ w” w “ h” h) oldx:=x, oldy:=y, oldw:=w, oldh:=h } else if (oldx!=x || oldy!=y || oldw!=w || oldh!=h) { if (oldw!=w || oldh!=h) FindText_Screen[hPic].Move(,, w, h) FindText_Screen.Show(“NA x” x “ y” y “ w” w “ h” h) oldx:=x, oldy:=y, oldw:=w, oldh:=h } this.BitmapToWindow(hPic, 0, 0, hBM, 0, 0, w, h) DllCall(“DeleteObject”, “Ptr”,hBM) }
BitmapToWindow(hwnd, x1, y1, hBM, x2, y2, w, h) { local mDC:=DllCall(“CreateCompatibleDC”, “Ptr”,0, “Ptr”) oBM:=DllCall(“SelectObject”, “Ptr”,mDC, “Ptr”,hBM, “Ptr”) hDC:=DllCall(“GetDC”, “Ptr”,hwnd, “Ptr”) DllCall(“BitBlt”, “Ptr”,hDC, “int”,x1, “int”,y1, “int”,w, “int”,h , “Ptr”,mDC, “int”,x2, “int”,y2, “uint”,0xCC0020) DllCall(“ReleaseDC”, “Ptr”,hwnd, “Ptr”,hDC) DllCall(“SelectObject”, “Ptr”,mDC, “Ptr”,oBM) DllCall(“DeleteDC”, “Ptr”,mDC) }
; 快速获取屏幕图像的搜索文本数据
GetTextFromScreen(x1:=0, y1:=0, x2:=0, y2:=0, Threshold:=”” , ScreenShot:=1, ByRef rx:=””, ByRef ry:=””, cut:=1) { local if (x1=0 && y1=0 && x2=0 && y2=0) return this.Gui(“CaptureS”, ScreenShot) SetBatchLines % (bch:=A_BatchLines)?”-1”:”-1” x1:=this.Floor(x1), y1:=this.Floor(y1), x2:=this.Floor(x2), y2:=this.Floor(y2) x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x2-x1)+1, h:=Abs(y2-y1)+1 bits:=this.GetBitsFromScreen(x,y,w,h,ScreenShot,zx,zy) if (w<1 || h<1 || !bits.Scan0) { SetBatchLines % bch return } ListLines % (lls:=A_ListLines)?0:0 gs:=[] j:=bits.Stride-w4, p:=bits.Scan0+(y-zy)bits.Stride+(x-zx)4-j-4 Loop % h + 0(k:=0) Loop % w + 0(p+=j) c:=NumGet(0|p+=4,”uint”) , gs[++k]:=(((c»16)&0xFF)38+((c»8)&0xFF)75+(c&0xFF)15)»7 if InStr(Threshold,”*”) { Threshold:=Trim(Threshold,” “), (Threshold=”” && Threshold:=50) s:=””, sw:=w, w-=2, h-=2, x++, y++ Loop % h + 0(y1:=0) Loop % w + 0(y1++) i:=y1sw+A_Index+1, j:=gs[i]+Threshold , s.=( gs[i-1]>j || gs[i+1]>j || gs[i-sw]>j || gs[i+sw]>j || gs[i-sw-1]>j || gs[i-sw+1]>j || gs[i+sw-1]>j || gs[i+sw+1]>j ) ? “1”:”0” Threshold:=”**” Threshold } else { Threshold:=Trim(Threshold,” “) if (Threshold=””) { pp:=[] Loop 256 pp[A_Index-1]:=0 Loop % wh pp[gs[A_Index]]++ IP0:=IS0:=0 Loop 256 k:=A_Index-1, IP0+=kpp[k], IS0+=pp[k] Threshold:=Floor(IP0/IS0) Loop 20 { LastThreshold:=Threshold IP1:=IS1:=0 Loop % LastThreshold+1 k:=A_Index-1, IP1+=kpp[k], IS1+=pp[k] IP2:=IP0-IP1, IS2:=IS0-IS1 if (IS1!=0 && IS2!=0) Threshold:=Floor((IP1/IS1+IP2/IS2)/2) if (Threshold=LastThreshold) Break } } s:=”” Loop % wh s.=gs[A_Index]<=Threshold ? “1”:”0” Threshold:=”*” Threshold } ListLines % lls ;——————– w:=Format(““,w), CutUp:=CutDown:=0 if (cut=1) { re1:=”(^0{“ w “}|^1{“ w “})” re2:=”(0{“ w “}$|1{“ w “}$)” While (s~=re1) s:=RegExReplace(s,re1), CutUp++ While (s~=re2) s:=RegExReplace(s,re2), CutDown++ } rx:=x+w//2, ry:=y+CutUp+(h-CutUp-CutDown)//2 s:=”|<>” Threshold “$” w “.” this.bit2base64(s) ;——————– SetBatchLines % bch return s }
; 等待几秒钟直到屏幕图像改变,需要先调用FindText().ScreenShot()
WaitChange(time:=-1, x1:=0, y1:=0, x2:=0, y2:=0) { local hash:=this.GetPicHash(x1, y1, x2, y2, 0) time:=this.Floor(time), timeout:=A_TickCount+Round(time*1000) Loop { if (hash!=this.GetPicHash(x1, y1, x2, y2, 1)) return 1 if (time>=0 && A_TickCount>=timeout) Break Sleep 10 } return 0 }
; 等待屏幕图像稳定下来
WaitNotChange(time:=1, timeout:=30, x1:=0, y1:=0, x2:=0, y2:=0) { local oldhash:=””, time:=this.Floor(time) , timeout:=A_TickCount+Round(this.Floor(timeout)1000) Loop { hash:=this.GetPicHash(x1, y1, x2, y2, 1), t:=A_TickCount if (hash!=oldhash) oldhash:=hash, timeout2:=t+Round(time1000) if (t>=timeout2) return 1 if (t>=timeout) return 0 Sleep 100 } }
GetPicHash(x1:=0, y1:=0, x2:=0, y2:=0, ScreenShot:=1) { local static init:=DllCall(“LoadLibrary”, “Str”,”ntdll”, “Ptr”) x1:=this.Floor(x1), y1:=this.Floor(y1), x2:=this.Floor(x2), y2:=this.Floor(y2) if (x1=0 && y1=0 && x2=0 && y2=0) n:=150000, x:=y:=-n, w:=h:=2n else x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x2-x1)+1, h:=Abs(y2-y1)+1 bits:=this.GetBitsFromScreen(x,y,w,h,ScreenShot,zx,zy), x-=zx, y-=zy if (w<1 || h<1 || !bits.Scan0) return 0 hash:=0, Stride:=bits.Stride, p:=bits.Scan0+(y-1)Stride+x4, w=4 ListLines % (lls:=A_ListLines)?0:0 Loop % h hash:=(hash*31+DllCall(“ntdll\RtlComputeCrc32”, “uint”,0 , “Ptr”,p+=Stride, “uint”,w, “uint”))&0xFFFFFFFF ListLines % lls return hash }
WindowToScreen(ByRef x, ByRef y, x1, y1, id:=””) { local if (!id) WinGet, id, ID, A VarSetCapacity(rect, 16, 0) , DllCall(“GetWindowRect”, “Ptr”,id, “Ptr”,&rect) , x:=x1+NumGet(rect,”int”), y:=y1+NumGet(rect,4,”int”) }
ScreenToWindow(ByRef x, ByRef y, x1, y1, id:=””) { local this.WindowToScreen(dx, dy, 0, 0, id), x:=x1-dx, y:=y1-dy }
ClientToScreen(ByRef x, ByRef y, x1, y1, id:=””) { local if (!id) WinGet, id, ID, A VarSetCapacity(pt, 8, 0), NumPut(0, pt, “int64”) , DllCall(“ClientToScreen”, “Ptr”,id, “Ptr”,&pt) , x:=x1+NumGet(pt,”int”), y:=y1+NumGet(pt,4,”int”) }
ScreenToClient(ByRef x, ByRef y, x1, y1, id:=””) { local this.ClientToScreen(dx, dy, 0, 0, id), x:=x1-dx, y:=y1-dy }
; 不像 FindText 总是使用屏幕坐标,它使用与内置命令 ; PixelGetColor 一样的 CoordMode 设置的坐标模式
PixelGetColor(x, y, ScreenShot:=1, id:=””) { if (A_CoordModePixel=”Window”) this.WindowToScreen(x, y, x, y, id) else if (A_CoordModePixel=”Client”) this.ClientToScreen(x, y, x, y, id) if (ScreenShot) this.ScreenShot(x, y, x, y) return this.GetColor(x, y) }
; 不像 FindText 总是使用屏幕坐标,它使用与内置命令 ; ImageSearch 一样的 CoordMode 设置的坐标模式 ; 图片文件参数可以使用 “*n *TransBlack/White/RRGGBB-DRDGDB… d:\a.bmp”
ImageSearch(ByRef rx:=””, ByRef ry:=””, x1:=0, y1:=0, x2:=0, y2:=0 , ImageFile:=””, ScreenShot:=1, FindAll:=0, dir:=1) { local dx:=dy:=0 if (A_CoordModePixel=”Window”) this.WindowToScreen(dx, dy, 0, 0) else if (A_CoordModePixel=”Client”) this.ClientToScreen(dx, dy, 0, 0) text:=”” Loop Parse, ImageFile, | if (v:=Trim(A_LoopField))!=”” { text.=InStr(v,”$”) ? “|” v : Format(“|##{:06X}”,RegExMatch(v,”O)(^|\s)*(\d+)\s”,r)?r[2]*0x010101:0) . (RegExMatch(v, “Oi)(^|\s)*Trans(\S+)\s”, r) ? “/” Trim(r[2],”/”):””) . “$” Trim(RegExReplace(v,”(^|\s)*\S+”)) } x1:=this.Floor(x1), y1:=this.Floor(y1), x2:=this.Floor(x2), y2:=this.Floor(y2) if (x1=0 && y1=0 && x2=0 && y2=0) n:=150000, x1:=y1:=-n, x2:=y2:=n if (ok:=this.FindText(,, x1+dx, y1+dy, x2+dx, y2+dy , 0, 0, text, ScreenShot, FindAll,,,, dir)) { For k,v in ok ; you can use ok:=FindText().ok v.1-=dx, v.2-=dy, v.x-=dx, v.y-=dy rx:=ok[1].1, ry:=ok[1].2, ErrorLevel:=0 return ok } else { rx:=ry:=””, ErrorLevel:=1 return 0 } }
; 不像 FindText 总是使用屏幕坐标,它使用与内置命令 ; PixelSearch 一样的 CoordMode 设置的坐标模式 ; 颜色参数可以是 “RRGGBB-DRDGDB|RRGGBB-DRDGDB”, Variation 取值 0-255
PixelSearch(ByRef rx:=””, ByRef ry:=””, x1:=0, y1:=0, x2:=0, y2:=0 , ColorID:=””, Variation:=0, ScreenShot:=1, FindAll:=0, dir:=1) { local text:=Format(“##{:06X}$0/0/”, this.Floor(Variation)*0x010101) . Trim(StrReplace(ColorID, “|”, “/”), “ /”) return this.ImageSearch(rx, ry, x1, y1, x2, y2, text, ScreenShot, FindAll, dir) }
; 屏幕坐标指示的范围内的某些颜色的像素计数 ; 颜色参数可以是 “RRGGBB-DRDGDB|RRGGBB-DRDGDB”, Variation 取值 0-255
PixelCount(x1:=0, y1:=0, x2:=0, y2:=0, ColorID:=””, Variation:=0, ScreenShot:=1) { local x1:=this.Floor(x1), y1:=this.Floor(y1), x2:=this.Floor(x2), y2:=this.Floor(y2) if (x1=0 && y1=0 && x2=0 && y2=0) n:=150000, x:=y:=-n, w:=h:=2n else x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x2-x1)+1, h:=Abs(y2-y1)+1 bits:=this.GetBitsFromScreen(x,y,w,h,ScreenShot,zx,zy), x-=zx, y-=zy sum:=0, VarSetCapacity(s1,4), VarSetCapacity(s0,4) ini:={ bits:bits, ss:0, s1:&s1, s0:&s0, allpos:0, allpos_max:0 , err1:0, err0:0, zoomW:1, zoomH:1 } text:=Format(“##{:06X}$0/0/”, this.Floor(Variation)0x010101) . Trim(StrReplace(StrSplit(ColorID “,”, “,”)[1], “|”, “/”), “ /”) if IsObject(j:=this.PicInfo(text)) sum:=this.PicFind(ini, j, 1, x, y, w, h) return sum }
; 创建包含特定颜色的色块,可以限定这个色块中符合颜色的数量 ; ColorID 可以使用 “RRGGBB-DRDGDB|RRGGBB-DRDGDB”, “*128”, “**50” ; Count1, Count0 是这个色块二值化后黑点和白点的数量最小值
ColorBlock(ColorID, w, h, Count1:=0, Count0:=0) { local (Count0>0 && Count1:=0) Text:=”|<>[” (1-Count1/(wh)) “,” (1-Count0/(wh)) “]” . Trim(StrReplace(ColorID,”|”,”/”),” /”) . Format(“${:d}.”,w) . this.bit2base64(StrReplace(Format(Format(“{{}:0{:d}d{}}”,w*h),0),”0” , (Count0>0 ? “0”:”1”))) return Text }
Click(x:=””, y:=””, other1:=””, other2:=””, GoBack:=0) { local CoordMode, Mouse, % (bak:=A_CoordModeMouse)?”Screen”:”Screen” if GoBack MouseGetPos, oldx, oldy MouseMove, x, y, 0 Sleep 30 Click % x “,” y “,” other1 “,” other2 if GoBack MouseMove, oldx, oldy, 0 CoordMode, Mouse, %bak% return 1 }
; 动态运行AHK代码作为新线程
Class Thread
{
__New(args)
{
this.pid:=this.Exec(args)
}
__Delete()
{
Process, Close, % this.pid
}
Exec(s, Ahk:=””, args:=””) ; required AHK v1.1.34+ and Ahk2Exe Use .exe
{
local
Ahk:=Ahk ? Ahk : A_IsCompiled ? A_ScriptFullPath : A_AhkPath
s:=”nDllCall(""SetWindowText"",""Ptr"",A_ScriptHwnd,""Str"",""<AHK>"")n”
. “nSetBatchLines,-1n” . s, s:=RegExReplace(s, “\R”, “rn”)
Try
{
shell:=ComObjCreate(“WScript.Shell”)
oExec:=shell.Exec(“””” Ahk “”” /script /force /CP0 * “ args)
oExec.StdIn.Write(s)
oExec.StdIn.Close(), pid:=oExec.ProcessID
}
Catch
{
f:=A_Temp “~ahk.tmp”
s:=”rnTry FileDelete “ f “rn” s
Try FileDelete % f
FileAppend % s, % f
r:=this.Clear.Bind(this)
SetTimer % r, -3000
Run “%Ahk%” /script /force /CP0 “%f%” %args%,, UseErrorLevel, pid
}
return pid
}
Clear()
{
Try FileDelete % A_Temp “~ahk.tmp”
SetTimer,, Off
}
}
; FindText().QPC() 用法类似于 A_TickCount
QPC() { static init, f, c if !VarSetCapacity(init) && (init:=”1”) f:=0, c:=DllCall(“QueryPerformanceFrequency”, “Int64“,f)+(f/=1000) return (!DllCall(“QueryPerformanceCounter”,”Int64“,c))*0+(c/f) }
; FindText().ToolTip() 用法类似于 ToolTip
ToolTip(s:=””, x:=””, y:=””, num:=1, arg:=””) { local static init, ini, tip, timer if !VarSetCapacity(init) && (init:=”1”) ini:=[], tip:=[], timer:=[] f:=”ToolTip_” . this.Floor(num) if (s=””) { Try tip[f].Destroy() ini[f]:=””, tip[f]:=”” return } ;—————– r1:=A_CoordModeToolTip r2:=A_CoordModeMouse CoordMode Mouse, Screen MouseGetPos x1, y1 CoordMode Mouse, %r1% MouseGetPos x2, y2 CoordMode Mouse, %r2% (x!=”” && x:=”x” (this.Floor(x)+x1-x2)) , (y!=”” && y:=”y” (this.Floor(y)+y1-y2)) , (x=”” && y=”” && x:=”x” (x1+16) “ y” (y1+16)) ;—————– bgcolor:=arg.bgcolor!=”” ? arg.bgcolor : “FAFBFC” color:=arg.color!=”” ? arg.color : “Black” font:=arg.font ? arg.font : “Consolas” size:=arg.size ? arg.size : “10” bold:=arg.bold ? arg.bold : “” trans:=arg.trans!=”” ? arg.trans & 255 : 255 timeout:=arg.timeout!=”” ? arg.timeout : “” ;—————– r:=bgcolor “|” color “|” font “|” size “|” bold “|” trans “|” s if (!ini.HasKey(f) || ini[f]!=r) { ini[f]:=r Try tip[f].Destroy() tip[f]:=_Gui:=this.GuiNew() ; WS_EX_LAYERED:=0x80000, WS_EX_TRANSPARENT:=0x20 _Gui.Opt(“+LastFound +AlwaysOnTop -Caption +ToolWindow -DPIScale +E0x80020”) _Gui.MarginX:=2, _Gui.MarginY:=2 _Gui.BackColor:=bgcolor _Gui.SetFont(“c” color “ s” size “ “ bold, font) _Gui.Add(“Text”,, s) _Gui.Title:=f _Gui.Show(“Hide”) WinSet, Transparent, % trans } tip[f].Opt(“+AlwaysOnTop”) tip[f].Show(“NA “ x “ “ y) if (timeout) { (!timer.HasKey(f) && timer[f]:=this.ToolTip.Bind(this,””,””,”“,num)) , r:=timer[f] SetTimer % r, % -Round(Abs(this.Floor(timeout)*1000))-1 } }
; FindText().ObjView() 查看对象的值用于调试
ObjView(obj, keyname:=””) { local if IsObject(obj) ; thanks lexikos’s type(v) { s:=”” For k,v in obj s.=this.ObjView(v, keyname “[” (StrLen(k)>1000 || [k].GetCapacity(1) ? “””” k “””“:k) “]”) } else s:=keyname “: “ (StrLen(obj)>1000 || [obj].GetCapacity(1) ? “””” obj “””“:obj) “`n” if (keyname!=””) return s ;—————— _Gui:=this.GuiNew(“+AlwaysOnTop”) _Gui.Add(“Button”, “y270 w350 gCancel Default”, “OK”) _Gui.Add(“Edit”, “xp y10 w350 h250 -Wrap -WantReturn”) _Gui[“Edit1”].Value:=s _Gui.Title:=”Debug view object values” _Gui.Show() DetectHiddenWindows 0 WinWaitClose % “ahk_id “ _Gui.Hwnd _Gui.Destroy() }
EditScroll(hEdit, regex:=””, line:=0, pos:=0)
{
local
ControlGetText, s,, ahk_id %hEdit%
pos:=(regex!=””) ? InStr(SubStr(s,1,s~=regex) “ “,”n",0,-1)
: (line>1) ? InStr(s,"n”,0,1,line-1) : pos
SendMessage, 0xB1, pos, pos,, ahk_id %hEdit%
SendMessage, 0xB7,,,, ahk_id %hEdit%
}
LastCtrl() { local return (G:=this.GuiFromHwnd(WinExist()))[G.LastHwnd] }
Hide(args*) { WinMinimize WinHide ToolTip DetectHiddenWindows 0 WinWaitClose % “ahk_id “ WinExist() }
SC(RGB, hwnd) { SendMessage,0x2001,0,(RGB&0xFF)«16|RGB&0xFF00|(RGB»16)&0xFF,,% “ahk_id “ hwnd }
;==== Optional GUI interface ====
Gui(cmd, arg1:=””, args)
{
local
static
local bch, cri, lls, _Gui
ListLines % InStr(“MouseMove|ToolTipOff”,cmd)?0:A_ListLines
static init
if !VarSetCapacity(init) && (init:=”1”)
{
SavePicDir:=A_Temp “\Ahk_ScreenShot"
G_ := this.Gui.Bind(this)
G_G := this.Gui.Bind(this, “G”)
G_Run := this.Gui.Bind(this, “Run”)
G_Show := this.Gui.Bind(this, “Show”)
G_KeyDown := this.Gui.Bind(this, “KeyDown”)
G_LButtonDown := this.Gui.Bind(this, “LButtonDown”)
G_RButtonDown := this.Gui.Bind(this, “RButtonDown”)
G_MouseMove := this.Gui.Bind(this, “MouseMove”)
G_ScreenShot := this.Gui.Bind(this, “ScreenShot”)
G_ShowPic := this.Gui.Bind(this, “ShowPic”)
G_Slider := this.Gui.Bind(this, “Slider”)
G_ToolTip := this.Gui.Bind(this, “ToolTip”)
G_ToolTipOff := this.Gui.Bind(this, “ToolTipOff”)
G_SaveScr := this.Gui.Bind(this, “SaveScr”)
G_PicShowOK := this.Gui.Bind(this, “PicShowOK”)
G_Drag := this.Gui.Bind(this, “Drag”)
FindText_Capture:=FindText_Main:=””
PrevControl:=x:=y:=oldx:=oldy:=””
Pics:=[], hBM_old:=dx:=dy:=0
bch:=A_BatchLines, cri:=A_IsCritical
Critical
#NoEnv
Lang:=this.Lang(,1), Tip_Text:=this.Lang(,2)
G_.Call(“MakeCaptureWindow”)
G_.Call(“MakeMainWindow”)
OnMessage(0x100, G_KeyDown)
OnMessage(0x201, G_LButtonDown)
OnMessage(0x204, G_RButtonDown)
OnMessage(0x200, G_MouseMove)
Menu, Tray, Add
Menu, Tray, Add, % Lang[“s1”], % G_Show
if (!A_IsCompiled && A_LineFile=A_ScriptFullPath)
{
Menu, Tray, Default, % Lang[“s1”]
Menu, Tray, Click, 1
Menu, Tray, Icon, Shell32.dll, 23
}
Critical % cri
SetBatchLines % bch
this.GuiNew(“+LastFound”).Destroy()
}
Switch cmd
{
Case “G”:
id:=this.LastCtrl()
Try id.OnEvent(“Click”, G_Run)
Catch
Try id.OnEvent(“Change”, G_Run)
return
Case “Run”:
Critical
G_.Call(arg1.Name)
return
Case “Show”:
FindText_Main.Show(arg1 ? “Center” : “”)
ControlFocus,, % “ahk_id “ hscr
return
Case “Cancel”, “Cancel2”:
WinHide
return
Case “MakeCaptureWindow”:
WindowColor:=”0xDDEEFF”
Try FindText_Capture.Destroy()
FindText_Capture:=_Gui:=this.GuiNew()
_Gui.Opt(“+LastFound +AlwaysOnTop -DPIScale”)
_Gui.MarginX:=15, _Gui.MarginY:=10
_Gui.BackColor:=WindowColor
_Gui.SetFont(“s12”, “Verdana”)
Tab:=_Gui.Add(“Tab3”, “vMyTab1 -Wrap”, StrSplit(Lang[“s18”],”|”))
Tab.UseTab(1)
C_:=[], Cid_:=[]
, nW:=71, nH:=25, w:=h:=12, pW:=nW(w+1)-1, pH:=(nH+1)(h+1)-1
id:=_Gui.Add(“Text”, “w” pW “ h” pH), Cid_[id.Hwnd]:=-1
_Gui.Opt(“-Theme”)
ListLines % (lls:=A_ListLines)?0:0
Loop % nW(nH+1)
{
i:=A_Index, j:=i=1 ? “xp yp Section” : Mod(i,nW)=1 ? “xs y+1”:”x+1”
id:=Gui.Add(“Progress”, j “ w” w “ h” h “ -E0x20000 Smooth”)
C[i]:=id.Hwnd, Cid_[id.Hwnd]:=i
}
ListLines % lls
Gui.Opt(“+Theme”)
_Gui.Add(“Slider”, “xs w” pW “ vMySlider1 +Center Page20 Line10 NoTicks AltSubmit”)
G_G.Call()
_Gui.Add(“Slider”, “ys h” pH “ vMySlider2 +Center Page20 Line10 NoTicks AltSubmit +Vertical”)
G_G.Call()
Tab.UseTab(2)
id:=_Gui.Add(“Pic”, “w” (pW-135) “ h” pH “ +Border -Background Section”), hPic:=id.Hwnd
Pic_hBM:=this.CreateDIBSection(Pic_w:=(pW-135), Pic_h:=pH)
_Gui.Add(“Slider”, “xs wp vMySlider3 +Center Page20 Line10 NoTicks AltSubmit”)
G_G.Call()
_Gui.Add(“Slider”, “ys h” pH “ vMySlider4 +Center Page20 Line10 NoTicks AltSubmit +Vertical”)
G_G.Call()
_Gui.Add(“ListBox”, “ys w120 h200 vSelectBox AltSubmit 0x100”)
G_G.Call()
_Gui.Add(“Button”, “y+0 wp vClearAll”, Lang[“ClearAll”])
G_G.Call()
_Gui.Add(“Button”, “y+0 wp vOpenDir”, Lang[“OpenDir”])
G_G.Call()
_Gui.Add(“Button”, “y+0 wp vLoadPic”, Lang[“LoadPic”])
G_G.Call()
_Gui.Add(“Button”, “y+0 wp vSavePic”, Lang[“SavePic”])
G_G.Call()
Tab.UseTab()
;————–
_Gui.Add(“Text”, “xm Section”, Lang[“SelGray”])
_Gui.Add(“Edit”, “x+5 yp-3 w80 vSelGray ReadOnly”)
_Gui.Add(“Text”, “x+15 ys”, Lang[“SelColor”])
_Gui.Add(“Edit”, “x+5 yp-3 w150 vSelColor ReadOnly”)
_Gui.Add(“Text”, “x+15 ys”, Lang[“SelR”])
_Gui.Add(“Edit”, “x+5 yp-3 w80 vSelR ReadOnly”)
_Gui.Add(“Text”, “x+5 ys”, Lang[“SelG”])
_Gui.Add(“Edit”, “x+5 yp-3 w80 vSelG ReadOnly”)
_Gui.Add(“Text”, “x+5 ys”, Lang[“SelB”])
_Gui.Add(“Edit”, “x+5 yp-3 w80 vSelB ReadOnly”)
;————–
id:=_Gui.Add(“Button”, “xm Hidden Section”, Lang[“Auto”])
id.GetPos(pX, pY, pW, pH)
w:=Round(pW*0.75), i:=Round(w*3+15+pW*0.5-w*1.5)
_Gui.Add(“Button”, “xm+” i “ yp w” w “ hp -Wrap vRepU”, Lang[“RepU”])
G_G.Call()
_Gui.Add(“Button”, “x+0 wp hp -Wrap vCutU”, Lang[“CutU”])
G_G.Call()
_Gui.Add(“Button”, “x+0 wp hp -Wrap vCutU3”, Lang[“CutU3”])
G_G.Call()
_Gui.Add(“Button”, “xm wp hp -Wrap vRepL”, Lang[“RepL”])
G_G.Call()
_Gui.Add(“Button”, “x+0 wp hp -Wrap vCutL”, Lang[“CutL”])
G_G.Call()
_Gui.Add(“Button”, “x+0 wp hp -Wrap vCutL3”, Lang[“CutL3”])
G_G.Call()
_Gui.Add(“Button”, “x+15 w” pW “ hp -Wrap vAuto”, Lang[“Auto”])
G_G.Call()
_Gui.Add(“Button”, “x+15 w” w “ hp -Wrap vRepR”, Lang[“RepR”])
G_G.Call()
_Gui.Add(“Button”, “x+0 wp hp -Wrap vCutR”, Lang[“CutR”])
G_G.Call()
_Gui.Add(“Button”, “x+0 wp hp -Wrap vCutR3”, Lang[“CutR3”])
G_G.Call()
_Gui.Add(“Button”, “xm+” i “ wp hp -Wrap vRepD”, Lang[“RepD”])
G_G.Call()
_Gui.Add(“Button”, “x+0 wp hp -Wrap vCutD”, Lang[“CutD”])
G_G.Call()
_Gui.Add(“Button”, “x+0 wp hp -Wrap vCutD3”, Lang[“CutD3”])
G_G.Call()
;————–
Tab:=_Gui.Add(“Tab3”, “ys -Wrap”, StrSplit(Lang[“s2”],”|”))
Tab.UseTab(1)
_Gui.Add(“Text”, “x+30 y+35”, Lang[“Threshold”])
_Gui.Add(“Edit”, “x+15 w100 vThreshold”)
_Gui.Add(“Button”, “x+15 yp-3 vGray2Two”, Lang[“Gray2Two”])
G_G.Call()
Tab.UseTab(2)
_Gui.Add(“Text”, “x+30 y+35”, Lang[“GrayDiff”])
_Gui.Add(“Edit”, “x+15 w100 vGrayDiff”, “50”)
_Gui.Add(“Button”, “x+15 yp-3 vGrayDiff2Two”, Lang[“GrayDiff2Two”])
G_G.Call()
Tab.UseTab(3)
_Gui.Add(“Text”, “x+10 y+15 Section”, Lang[“Similar1”] “ 0”)
_Gui.Add(“Slider”, “x+0 w100 vSimilar1 +Center Page1 NoTicks ToolTip”)
G_G.Call()
_Gui.Add(“Text”, “x+0”, “100”)
_Gui.Add(“Button”, “x+10 ys-2 vAddColorSim”, Lang[“AddColorSim”])
G_G.Call()
_Gui.Add(“Text”, “x+25 ys+4”, Lang[“DiffRGB2”])
_Gui.Add(“Edit”, “x+5 ys w80 vDiffRGB2 Limit3”)
_Gui.Add(“UpDown”, “vdRGB2 Range0-255 Wrap”, 50)
_Gui.Add(“Button”, “x+10 ys-2 vAddColorDiff”, Lang[“AddColorDiff”])
G_G.Call()
_Gui.Add(“Button”, “xs vUndo2”, Lang[“Undo2”])
G_G.Call()
_Gui.Add(“Edit”, “x+10 yp+2 w340 vColorList”)
_Gui.Add(“Button”, “x+10 yp-2 vColor2Two”, Lang[“Color2Two”])
G_G.Call()
Tab.UseTab(4)
_Gui.Add(“Text”, “x+30 y+35”, Lang[“Similar2”] “ 0”)
_Gui.Add(“Slider”, “x+0 w120 vSimilar2 +Center Page1 NoTicks ToolTip”)
G_G.Call()
_Gui.Add(“Text”, “x+0”, “100”)
_Gui.Add(“Button”, “x+15 yp-3 vColorPos2Two”, Lang[“ColorPos2Two”])
G_G.Call()
Tab.UseTab(5)
_Gui.Add(“Text”, “x+30 y+15 Section”, Lang[“Similar3”] “ 0”)
_Gui.Add(“Slider”, “x+0 w120 vSimilar3 +Center Page1 NoTicks ToolTip”)
G_G.Call()
_Gui.Add(“Text”, “x+0”, “100”)
_Gui.Add(“Button”, “x+15 ys-2 vUndo”, Lang[“Undo”])
G_G.Call()
_Gui.Add(“Checkbox”, “xs vMultiColor”, Lang[“MultiColor”])
G_G.Call()
_Gui.Add(“Checkbox”, “x+50 vFindShape”, Lang[“FindShape”])
G_G.Call()
Tab.UseTab()
;————–
_Gui.Add(“Button”, “xm vReset”, Lang[“Reset”])
G_G.Call()
_Gui.Add(“Checkbox”, “x+15 yp+5 vModify”, Lang[“Modify”])
G_G.Call()
_Gui.Add(“Text”, “x+30”, Lang[“Comment”])
_Gui.Add(“Edit”, “x+5 yp-2 w250 vComment”)
_Gui.Add(“Button”, “x+10 yp-3 vSplitAdd”, Lang[“SplitAdd”])
G_G.Call()
_Gui.Add(“Button”, “x+10 vAllAdd”, Lang[“AllAdd”])
G_G.Call()
_Gui.Add(“Button”, “x+30 wp vOK”, Lang[“OK”])
G_G.Call()
_Gui.Add(“Button”, “x+15 wp vCancel”, Lang[“Cancel”])
G_G.Call()
_Gui.Add(“Button”, “xm vBind0”, Lang[“Bind0”])
G_G.Call()
_Gui.Add(“Button”, “x+10 vBind1”, Lang[“Bind1”])
G_G.Call()
_Gui.Add(“Button”, “x+10 vBind2”, Lang[“Bind2”])
G_G.Call()
_Gui.Add(“Button”, “x+10 vBind3”, Lang[“Bind3”])
G_G.Call()
_Gui.Add(“Button”, “x+10 vBind4”, Lang[“Bind4”])
G_G.Call()
_Gui.Add(“Button”, “x+30 vSavePic2”, Lang[“SavePic2”])
G_G.Call()
_Gui.Title:=Lang[“s3”]
_Gui.Show(“Hide”)
_Gui.OnEvent(“DropFiles”, G_Drag)
return
Case “Drag”:
Try G.Call(“LoadPic”, args[2][1])
return
Case “MakeMainWindow”:
Try FindText_Main.Destroy()
FindText_Main:=Gui:=this.GuiNew()
_Gui.Opt(“+LastFound +AlwaysOnTop -DPIScale”)
_Gui.MarginX:=15, _Gui.MarginY:=10
_Gui.BackColor:=WindowColor
_Gui.SetFont(“s12”, “Verdana”)
_Gui.Add(“Text”, “xm”, Lang[“NowHotkey”])
_Gui.Add(“Edit”, “x+5 w160 vNowHotkey ReadOnly”)
_Gui.Add(“Hotkey”, “x+5 w160 vSetHotkey1”)
s:=”F1|F2|F3|F4|F5|F6|F7|F8|F9|F10|F11|F12|LWin|Ctrl|Shift|Space|MButton”
. “|ScrollLock|CapsLock|Ins|Esc|BS|Del|Tab|Home|End|PgUp|PgDn”
. “|NumpadDot|NumpadSub|NumpadAdd|NumpadDiv|NumpadMult”
_Gui.Add(“DDL”, “x+5 w160 vSetHotkey2”, StrSplit(s,”|”))
_Gui.Add(“Button”, “x+15 vApply”, Lang[“Apply”])
G_G.Call()
_Gui.Add(“GroupBox”, “xm y+0 w280 h55 vMyGroup cBlack”)
_Gui.Add(“Text”, “xp+15 yp+20 Section”, Lang[“Myww”] “: “)
_Gui.Add(“Text”, “x+0 w80”, nW//2)
_Gui.Add(“UpDown”, “vMyww Range1-100”, nW//2)
_Gui.Add(“Text”, “x+15 ys”, Lang[“Myhh”] “: “)
_Gui.Add(“Text”, “x+0 w80”, nH//2)
id:=_Gui.Add(“UpDown”, “vMyhh Range1-100”, nH//2)
id.GetPos(pX, pY, pW, pH)
_Gui[“MyGroup”].Move(,, pX+pW, pH+30)
id:=_Gui.Add(“Checkbox”, “x+100 ys vAddFunc”, Lang[“AddFunc”] “ FindText()”)
id.GetPos(pX, pY, pW, pH)
pW:=pX+pW-15, pW:=(pW<720?720:pW), w:=pW//5
_Gui.Add(“Button”, “xm y+18 w” w “ vCutL2”, Lang[“CutL2”])
G_G.Call()
_Gui.Add(“Button”, “x+0 wp vCutR2”, Lang[“CutR2”])
G_G.Call()
_Gui.Add(“Button”, “x+0 wp vCutU2”, Lang[“CutU2”])
G_G.Call()
_Gui.Add(“Button”, “x+0 wp vCutD2”, Lang[“CutD2”])
G_G.Call()
_Gui.Add(“Button”, “x+0 wp vUpdate”, Lang[“Update”])
G_G.Call()
_Gui.SetFont(“s6 bold”, “Verdana”)
_Gui.Add(“Edit”, “xm y+10 w” pW “ h260 vMyPic -Wrap HScroll”)
_Gui.SetFont(“s12 norm”, “Verdana”)
w:=pW//3
_Gui.Add(“Button”, “xm w” w “ vCapture”, Lang[“Capture”])
G_G.Call()
_Gui.Add(“Button”, “x+0 wp vTest”, Lang[“Test”])
G_G.Call()
_Gui.Add(“Button”, “x+0 wp vCopy”, Lang[“Copy”])
G_G.Call()
_Gui.Add(“Button”, “xm y+0 wp vCaptureS”, Lang[“CaptureS”])
G_G.Call()
_Gui.Add(“Button”, “x+0 wp vGetRange”, Lang[“GetRange”])
G_G.Call()
_Gui.Add(“Button”, “x+0 wp vGetOffset”, Lang[“GetOffset”])
G_G.Call()
_Gui.Add(“Edit”, “xm y+10 w130 hp vClipText”)
_Gui.Add(“Button”, “x+0 vPaste”, Lang[“Paste”])
G_G.Call()
_Gui.Add(“Button”, “x+0 vTestClip”, Lang[“TestClip”])
G_G.Call()
id:=_Gui.Add(“Button”, “x+0 vGetClipOffset”, Lang[“GetClipOffset”])
G_G.Call()
id.GetPos(x,, w)
w:=((pW+15)-(x+w))//2
_Gui.Add(“Edit”, “x+0 w” w “ hp vOffset”)
_Gui.Add(“Button”, “x+0 wp vCopyOffset”, Lang[“CopyOffset”])
G_G.Call()
_Gui.SetFont(“cBlue”)
id:=_Gui.Add(“Edit”, “xm w” pW “ h250 vscr -Wrap HScroll”), hscr:=id.Hwnd
_Gui.Title:=Lang[“s4”]
_Gui.Show(“Hide”)
G.Call(“LoadScr”)
OnExit(G_SaveScr)
return
Case “LoadScr”:
f:=A_Temp “~scr1.tmp”
FileRead, s, % f
FindText_Main[“scr”].Value:=s
return
Case “SaveScr”:
f:=A_Temp “~scr1.tmp”
s:=FindText_Main[“scr”].Value
Try FileDelete % f
FileAppend % s, % f
return
Case “Capture”, “CaptureS”:
Gui:=FindText_Main
if show_gui:=WinExist(“ahk_id “ _Gui.Hwnd)
this.Hide()
if (cmd=”Capture”)
{
w:=_Gui[“Myww”].Value
h:=_Gui[“Myhh”].Value
p:=this.GetRange(w, h)
sx:=p[1], sy:=p[2], sw:=p[3]-p[1]+1, sh:=p[4]-p[2]+1
, Bind_ID:=p[5], bind_mode:=””
_Gui:=FindText_Capture
_Gui[“MyTab1”].Choose(1)
}
else
{
sx:=0, sy:=0, sw:=1, sh:=1, Bind_ID:=WinExist(“A”), bind_mode:=””
_Gui:=FindText_Capture
_Gui[“MyTab1”].Choose(2)
}
n:=150000, x:=y:=-n, w:=h:=2*n
hBM:=this.BitmapFromScreen(x,y,w,h,(arg1=0?0:1))
Pics:=[], Pics[hBM]:=1, hBM_x:=hBM_y:=0
G.Call(“CaptureUpdate”)
G_.Call(“PicUpdate”)
Names:=[“HBITMAP:*” hBM], s:=”
Lang(text:=””, getLang:=0)
{
local
static init, Lang1, Lang2
if !VarSetCapacity(init) && (init:=”1”)
{
s:=”
(
Myww = 宽度 = 调整抓图范围的宽度
Myhh = 高度 = 调整抓图范围的高度
AddFunc = 附加 = 复制时带 FindText() 函数
NowHotkey = 截屏热键 = 当前的截屏热键
SetHotkey1 = = 第一优先级的截屏热键
SetHotkey2 = = 第二优先级的截屏热键
Apply = 应用 = 应用新的截屏热键
CutU2 = 上删 = 裁剪下面编辑框中文字的上边缘
CutL2 = 左删 = 裁剪下面编辑框中文字的左边缘
CutR2 = 右删 = 裁剪下面编辑框中文字的右边缘
CutD2 = 下删 = 裁剪下面编辑框中文字的下边缘
Update = 更新 = 更新下面编辑框中文字到代码行中
GetRange = 获取屏幕范围 = 获取屏幕范围到剪贴板并替换代码中的范围参数
GetOffset = 获取相对坐标 = 获取相对图像位置的偏移坐标并替换代码中的点击坐标
GetClipOffset = 获取相对坐标2 = 获取相对左边编辑框的图像的偏移坐标
Capture = 抓图 = 开始屏幕抓图
CaptureS = 截屏抓图 = 先截屏,然后显示截屏图像,再手动选择图像内的范围抓图
Test = 测试 = 测试生成的代码是否可以查找成功
TestClip = 测试2 = 测试左边文本框中的文字是否可以查找成功,结果复制到剪贴板
Paste = 粘贴 = 粘贴剪贴板的文字数据
CopyOffset = 复制2 = 复制左边的偏移坐标到剪贴板
Copy = 复制 = 复制代码到剪贴板
Reset = 重读 = 重新读取原来的彩色图像
SplitAdd = 分割添加 = 点击黄色的标签来分割图像为多个图像数据,添加到旧代码中
AllAdd = 整体添加 = 将文字数据整体添加到旧代码中
Gray2Two = 灰度阈值二值化 = 灰度小于阈值的为黑色其余白色
GrayDiff2Two = 灰度差值二值化 = 某点与周围灰度之差大于差值的为黑色其余白色
Color2Two = 颜色二值化 = 通过颜色列表来转换图像为黑白图
ColorPos2Two = 颜色位置二值化 = 指定颜色及相似色为黑色其余白色,但是记录该色的位置
SelGray = 灰度 = 选定颜色的灰度值 (0-255)
SelColor = 颜色 = 选定颜色的RGB颜色值
SelR = 红 = 选定颜色的红色分量
SelG = 绿 = 选定颜色的绿色分量
SelB = 蓝 = 选定颜色的蓝色分量
RepU = -上 = 撤销裁剪上边缘1个像素
CutU = 上 = 裁剪上边缘1个像素
CutU3 = 上3 = 裁剪上边缘3个像素
RepL = -左 = 撤销裁剪左边缘1个像素
CutL = 左 = 裁剪左边缘1个像素
CutL3 = 左3 = 裁剪左边缘3个像素
Auto = 自动 = 二值化之后自动裁剪空白边缘
RepR = -右 = 撤销裁剪右边缘1个像素
CutR = 右 = 裁剪右边缘1个像素
CutR3 = 右3 = 裁剪右边缘3个像素
RepD = -下 = 撤销裁剪下边缘1个像素
CutD = 下 = 裁剪下边缘1个像素
CutD3 = 下3 = 裁剪下边缘3个像素
Modify = 修改 = 二值化后可以用鼠标在预览区点击手动修改黑白点
MultiColor = 多点找色 = 鼠标选择多种颜色,之后点击“确定”按钮
FindShape = 找形状 = 鼠标选择多种颜色,会基于第一点的颜色二值化
Undo = 撤销 = 撤销上一次选择的颜色
Undo2 = 撤销 = 撤销上一次添加到颜色列表的颜色
Comment = 识别文字 = 识别文本 (包含在<>中),分割添加时也会分解成单个文字
Threshold = 灰度阈值 = 灰度阈值 (0-255)
GrayDiff = 灰度差值 = 灰度差值 (0-255)
Similar1 = 相似度 = 与选定颜色的相似度
Similar2 = 相似度 = 与选定颜色的相似度
Similar3 = 相似度 = 与选定颜色的相似度
AddColorSim = 添加 = 颜色相似模式添加到颜色列表中再运行颜色二值化
AddColorDiff = 添加 = 颜色偏色模式添加到颜色列表中再运行颜色二值化
ColorList = = 颜色列表用于转换图像为二值图
DiffRGB = 红/绿/蓝 = 多色查找时各分量允许的偏差 (0-255)
DiffRGB2 = 红/绿/蓝 = 多色查找时各分量允许的偏差 (0-255)
Bind0 = 绑定窗口1 = 绑定窗口使用GetDCEx()获取后台窗口图像
Bind1 = 绑定窗口1+ = 绑定窗口使用GetDCEx()并修改窗口透明度
Bind2 = 绑定窗口2 = 绑定窗口使用PrintWindow()获取后台窗口图像
Bind3 = 绑定窗口2+ = 绑定窗口使用PrintWindow()并修改窗口透明度
Bind4 = 绑定窗口3 = 绑定窗口使用PrintWindow(,,3)获取后台窗口图像
OK = 确定 = 生成全新的代码替换旧代码
OK2 = 确定 = 恢复截屏到屏幕然后再抓图
Cancel = 取消 = 关闭窗口不做任何事
Cancel2 = 取消 = 关闭窗口不做任何事
ClearAll = 清空 = 清空所有保存的截图
OpenDir = 打开目录 = 打开保存屏幕截图的目录
SavePic = 保存图片 = 选择一个范围保存为图片
SavePic2 = 保存图片 = 将修剪后的原始图像保存为图片
LoadPic = 载入图片 = 载入一张图片作为抓取的图像
ClipText = = 显示粘贴的文字数据
Offset = = 显示“获取相对坐标2”或者“获取屏幕范围”的结果
SelectBox = = 选择截图显示到屏幕左上角
s1 = FindText找字工具
s2 = 灰度阈值|灰度差值|颜色|颜色位置|多色查找
s3 = 图像二值化及分割
s4 = 抓图生成字库及找字代码
s5 = 方向键微调选框\n先点击右键(Ctrl)一次\n把鼠标移开\n再点击右键(Ctrl)一次
s6 = 解绑窗口使用
s7 = 左键(Ctrl)拖动选择范围\n坐标复制到剪贴板
s8 = 找到|时间|毫秒|位置|结果|值可以这样获取|等待3秒等图像出现|无限等待等图像消失
s9 = 截屏成功
s10 = 鼠标位置|穿透显示绑定窗口\n点击右键完成抓图
s11 = 请先设定灰度差值!
s12 = 请先选择核心颜色!
s13 = 请先将图像二值化!
s14 = 不能用于颜色位置二值化模式, 因为分割后会导致位置错误
s15 = 你确定选择的范围吗?\n\n如果不确定,可以重新选择
s16 = 请先添加颜色到颜色列表!
s17 = 你想打开的图片没有找到!
s18 = 捕获|截图
s19 = 你确定要删除所有的截图吗?
)”
Lang1:=[], Lang2:=[]
Loop Parse, s, n, r
if InStr(v:=A_LoopField, “=”)
r:=StrSplit(StrReplace(v “==”,”\n”,”n"), "=", "t “)
, Lang1[r[1]]:=r[2], Lang2[r[1]]:=r[3]
}
return getLang=1 ? Lang1 : getLang=2 ? Lang2 : Lang1[text]
}
;——————————— ; Gui-V1-V2 Compatibility Library By FeiYue ;———————————
GuiNew(args) { return new this.GuiCreate(args) }
GuiFromHwnd(hwnd:=”AllGuiObj”, RecurseParent:=0) { static init, AllGuiObj if !VarSetCapacity(init) && (init:=”1”) AllGuiObj:=[] if (hwnd==”AllGuiObj”) return AllGuiObj if (RecurseParent) While hwnd && !AllGuiObj.HasKey(hwnd) hwnd:=DllCall(“GetParent”, “Ptr”,hwnd, “Ptr”) return AllGuiObj[hwnd] }
GuiCtrlFromHwnd(hwnd) { return this.GuiFromHwnd(hwnd,1)[hwnd] }
GuiOnEvent(EventName, args) { return this.GuiFromHwnd(WinExist())[“_” EventName].Call(0,args) }
GuiClose(args) { return FindText().GuiOnEvent(“Close”,args) }
GuiEscape(args) { return FindText().GuiOnEvent(“Escape”,args) }
GuiSize(args) { return FindText().GuiOnEvent(“Size”,args) }
GuiContextMenu(args) { return FindText().GuiOnEvent(“ContextMenu”,args) }
GuiDropFiles(args) { return FindText().GuiOnEvent(“DropFiles”,0,args) }
Class GuiCreate { ;// GuiCreate Class Begin
__New(opts:=””, title:=””, args*) { local Gui, New, % opts “ +Hwndhwnd +LabelFindTextClass.Gui”, % title this.Hwnd:=hwnd, this.ClassNN:=[] FindText().GuiFromHwnd()[hwnd]:=this }
__Delete() { this.Destroy() }
Destroy() { local if !(hwnd:=this.Hwnd) return this.Hwnd:=””, FindText().GuiFromHwnd().Delete(hwnd) Try Gui, % hwnd “:Destroy” For k,v in this (v.Hwnd && v.Hwnd:=””), this[k]:=”” }
OnEvent(EventName, Callback, AddRemove:=1) { if IsObject(Callback) this[“_” EventName]:=Callback }
Opt(opts) { Gui, % this.Hwnd “:” RegExReplace(opts,”i)[+-\s]Label\S*”) }
Add(type, opts:=””, text:=””) { local static init, type2class if !VarSetCapacity(init) && (init:=”1”) type2class:=[] type:=(type=”DropDownList”?”DDL”:type=”Picture”?”Pic”:type) name:=RegExMatch(opts,”i)(^|[+-\s])V(?!Scroll\b|ertical\b)\K\S“,r)?r:”” opts:=RegExReplace(opts,”i)(^|[+-\s])V(?!Scroll\b|ertical\b)\S”) if IsObject(text) { s:=”” For k,v in text s.=”|” v text:=Trim(s, “|”) } Gui, % this.Hwnd “:Add”, % type, % opts “ +Hwndhwnd”, % text this.LastHwnd:=hwnd if type2class.HasKey(type) s:=type2class[type] else { WinGetClass, s, ahk_id %hwnd% type2class[type]:=s } this.ClassNN[s]:=n:=Floor(this.ClassNN[s])+1, classnn:=s . n obj:= new this.Control(this.Hwnd, hwnd, type, classnn, name) this[hwnd]:=obj, this[classnn]:=obj if (name) && !(name~=”i)^(Destroy|OnEvent|Opt|Add” . “|SetFont|Show|Hide|Move|GetClientPos|GetPos|Maximize” . “|Minimize|Restore|Flash|Submit|Hwnd|Name|Title” . “|BackColor|MarginX|MarginY|MenuBar|FocusedCtrl)$”) this[name]:=obj return obj }
SetFont(opts:=””, FontName:=””) { Gui, % this.Hwnd “:Font”, % opts, % FontName }
Show(opts:=””, args*) { Gui, % this.Hwnd “:Show”, % opts }
Hide() { Gui, % this.Hwnd “:Hide” }
Move(x:=””, y:=””, w:=””, h:=””) { local this.GetPos(pX, pY, pW, pH) x:=(x=”“?pX:x), y:=(y=”“?pY:y), w:=(w=”“?pW:w), h:=(h=”“?pH:h) DllCall(“MoveWindow”, “Ptr”,this.Hwnd, “int”,x, “int”,y, “int”,w, “int”,h, “int”,1) }
GetClientPos(ByRef x:=””, ByRef y:=””, ByRef w:=””, ByRef h:=””) { local VarSetCapacity(rect, 16, 0) , DllCall(“GetClientRect”, “Ptr”,this.Hwnd, “Ptr”,&rect) , DllCall(“ClientToScreen”, “Ptr”,this.Hwnd, “Ptr”,&rect) , x:=NumGet(rect, 0, “int”), y:=NumGet(rect, 4, “int”) , w:=NumGet(rect, 8, “int”)-x, h:=NumGet(rect, 12, “int”)-y }
GetPos(ByRef x:=””, ByRef y:=””, ByRef w:=””, ByRef h:=””) { local VarSetCapacity(rect, 16, 0) , DllCall(“GetWindowRect”, “Ptr”,this.Hwnd, “Ptr”,&rect) , x:=NumGet(rect, 0, “int”), y:=NumGet(rect, 4, “int”) , w:=NumGet(rect, 8, “int”)-x, h:=NumGet(rect, 12, “int”)-y }
Maximize() { Gui, % this.Hwnd “:Maximize” }
Minimize() { Gui, % this.Hwnd “:Minimize” }
Restore() { Gui, % this.Hwnd “:Restore” }
Flash(k:=1) { Gui, % this.Hwnd “:Flash”, % k ? “”:”Off” }
Submit(hide:=1) { local (hide && this.Hide()), arr:=[] For k,v in this if k is number if (v.Name!=””) arr[v.Name]:=v.Value return arr }
BackColor { get { return this._BackColor } set { this._BackColor:=value Gui, % this.Hwnd “:Color”, % value return value } }
MarginX { get { return this._MarginX } set { this._MarginX:=value Gui, % this.Hwnd “:Margin”, % value return value } }
MarginY { get { return this._MarginY } set { this._MarginY:=value Gui, % this.Hwnd “:Margin”,, % value return value } }
MenuBar { get { return this._MenuBar } set { this._MenuBar:=value Gui, % this.Hwnd “:Menu”, % value return value } }
Title { get { local VarSetCapacity(v, 260*2) DllCall(“GetWindowText”, “Ptr”,this.Hwnd, “Str”,v, “Int”,260) return v } set { DllCall(“SetWindowText”, “Ptr”,this.Hwnd, “Str”,value) return value } }
FocusedCtrl { get { local GuiControlGet, v, % this.Hwnd “:Focus” return this[v] } }
Class Control { ;// Control Class Begin
__New(GuiHwnd, hwnd, type, classnn, name) { this.GuiHwnd:=GuiHwnd, this.Hwnd:=hwnd this.Type:=type, this.ClassNN:=classnn, this.Name:=name }
Opt(opts) { GuiControl, % opts, % this.Hwnd }
OnEvent(EventName, Callback, AddRemove:=1) { local r:=this.OnEvent_G.Bind(this, Callback) GuiControl, +g, % this.Hwnd, % r }
OnEvent_G(Callback, args) { if IsObject(Callback) return %Callback%(this, args) }
GetPos(ByRef x:=””, ByRef y:=””, ByRef w:=””, ByRef h:=””) { local GuiControlGet, p, Pos, % this.Hwnd x:=Floor(pX), y:=Floor(pY), w:=Floor(pW), h:=Floor(pH) }
Move(x:=””, y:=””, w:=””, h:=””) { local s:=(x=””?””:” x” x) (y=””?””:” y” y) (w=””?””:” w” w) (h=””?””:” h” h) GuiControl, Move, % this.Hwnd, % s }
Redraw() { GuiControl, MoveDraw, % this.Hwnd }
Focus() { Try GuiControl, Focus, % this.Hwnd }
UseTab(Name:=””, Exact:=””, index:=””) { Gui, % this.GuiHwnd “:Tab”, % Name, % index, % Exact?”Exact”:”” }
SetFont(opts:=””, FontName:=””) { Gui, % this.GuiHwnd “:Font”, % opts, % FontName GuiControl, Font, % this.Hwnd }
Add(text) { local if IsObject(text) { s:=”” For k,v in text s.=”|” v text:=Trim(s, “|”) } GuiControl,, % this.Hwnd, % text }
Delete(N:=””) { if (N=””) GuiControl,, % this.Hwnd, | else this.Choose(N), this.Choose(0) }
Choose(N) { if N is number GuiControl, Choose, % this.Hwnd, % N else GuiControl, ChooseString, % this.Hwnd, % N }
Gui { get { return FindText().GuiFromHwnd(this.GuiHwnd) } }
Enabled { get { local GuiControlGet, v, Enabled, % this.Hwnd return v } set { GuiControl, % “Enable” (!!value), % this.Hwnd return value } }
Visible { get { local GuiControlGet, v, Visible, % this.Hwnd return v } set { GuiControl, % “Show” (!!value), % this.Hwnd return value } }
Focused { get { local GuiControlGet, v, % this.GuiHwnd “:Focus” return (v=this.ClassNN) } }
Value { get { local if (this.Type~=”i)^(ListBox|DDL|ComboBox|Tab)$”) this.Opt(“+AltSubmit”) GuiControlGet, v,, % this.Hwnd return v } set { if (this.Type~=”i)^(ListBox|DDL|ComboBox|Tab)$”) GuiControl, Choose, % this.Hwnd, % value else GuiControl,, % this.Hwnd, % value return value } }
Text { get { local if (this.Type~=”i)^(ListBox|DDL|ComboBox|Tab)$”) this.Opt(“-AltSubmit”) GuiControlGet, v,, % this.Hwnd return v } set { if (this.Type~=”i)^(ListBox|DDL|ComboBox|Tab)$”) GuiControl, ChooseString, % this.Hwnd, % value else GuiControl,, % this.Hwnd, % value return value } }
} ;// Control Class End
} ;// GuiCreate Class End
Script_End() { }
} ;// Class End
;================= The End =================
;