FindText.ahk 122 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715
  1. ;/*
  2. ;===========================================
  3. ; FindText - 屏幕抓字生成字库工具与找字函数
  4. ; https://www.autohotkey.com/boards/viewtopic.php?f=83&t=116471
  5. ;
  6. ; 脚本作者 : FeiYue
  7. ; 最新版本 : 9.4
  8. ; 更新时间 : 2023-12-18
  9. ;
  10. ; 用法: (需要最新版本 AHK v2.02)
  11. ; 1. 将本脚本保存为“FindText.ahk”并复制到AHK执行程序的Lib子目录中(手动建立目录)
  12. ; 2. 抓图并生成调用FindText()的代码
  13. ; 2.1 方式一:直接点击“抓图”按钮
  14. ; 2.2 方式二:先设定截屏热键,使用热键截屏,再点击“截屏抓图”按钮
  15. ; 3. 测试一下调用的代码是否成功:直接点击“测试”按钮
  16. ; 4. 复制调用的代码到自己的脚本中
  17. ; 4.1 方式一:打勾“附加FindText()函数”的选框,然后点击“复制”按钮(不推荐)
  18. ; 4.2 方式二:取消“附加FindText()函数”的选框,然后点击“复制”按钮,
  19. ; 然后粘贴到自己的脚本中,然后在自己的脚本开头加上一行:
  20. ; #Include <FindText> ; Lib目录中必须有FindText.ahk
  21. ; 5. 多色查找模式可以一定程度上适应图像的放大缩小,常用于游戏中找图
  22. ; 6. 这个库还可以用于快速截屏、获取颜色、写入颜色、编辑后另存图片
  23. ; 7. 如果要调用FindTextClass类中的函数,请用无参数的FindText()获取类实例对象
  24. ;
  25. ;===========================================
  26. ;*/
  27. if (!A_IsCompiled && A_LineFile=A_ScriptFullPath)
  28. FindText().Gui("Show")
  29. ;===== 复制下面的函数和类到你的代码中仅仅一次 =====
  30. FindText(args*)
  31. {
  32. static obj:=FindTextClass()
  33. return !args.Length ? obj : obj.FindText(args*)
  34. }
  35. Class FindTextClass
  36. { ;// Class Begin
  37. Floor(i) => IsNumber(i) ? i+0 : 0
  38. __New()
  39. {
  40. this.bits:={ Scan0: 0, hBM: 0, oldzw: 0, oldzh: 0 }
  41. this.bind:={ id: 0, mode: 0, oldStyle: 0 }
  42. this.Lib:=Map()
  43. this.Cursor:=0
  44. }
  45. __Delete()
  46. {
  47. if (this.bits.hBM)
  48. DllCall("DeleteObject", "Ptr",this.bits.hBM)
  49. }
  50. New()
  51. {
  52. return FindTextClass()
  53. }
  54. help()
  55. {
  56. return "
  57. (
  58. ;--------------------------------
  59. ; FindText - 屏幕找字函数
  60. ; 版本 : 9.4 (2023-12-18)
  61. ;--------------------------------
  62. ; 返回变量:=FindText(
  63. ; &OutputX --> 保存返回的X坐标的变量名称
  64. ; , &OutputY --> 保存返回的Y坐标的变量名称
  65. ; , X1 --> 查找范围的左上角X坐标
  66. ; , Y1 --> 查找范围的左上角Y坐标
  67. ; , X2 --> 查找范围的右下角X坐标
  68. ; , Y2 --> 查找范围的右下角Y坐标
  69. ; , err1 --> 文字的黑点容错百分率(0.1=10%)
  70. ; , err0 --> 背景的白点容错百分率(0.1=10%)
  71. ; , Text --> 由工具生成的查找图像的数据,可以一次查找多个,用“|”分隔
  72. ; , ScreenShot --> 是否截屏,为0则使用上一次的截屏数据
  73. ; , FindAll --> 是否搜索所有位置,为0则找到一个位置就返回
  74. ; , JoinText --> 如果想组合查找,可以为1,或者是要查找单词的数组
  75. ; , offsetX --> 组合图像的每个字和前一个字的最大横向间隔
  76. ; , offsetY --> 组合图像的每个字和前一个字的最大高低间隔
  77. ; , dir --> 查找的方向,有上、下、左、右、中心9种
  78. ; , zoomW --> 图像宽度的缩放百分率(1.0=100%)
  79. ; , zoomH --> 图像高度的缩放百分率(1.0=100%)
  80. ; )
  81. ;
  82. ; 返回变量 --> 如果没找到结果会返回0。否则返回一个二级数组,
  83. ; 第一级是每个结果对象,第二级是结果对象的具体信息对象:
  84. ; { 1:左上角X, 2:左上角Y, 3:图像宽度W, 4:图像高度H
  85. ; , x:中心点X, y:中心点Y, id:图像识别文本 }
  86. ; 坐标都是相对于屏幕,颜色使用RGB格式
  87. ;
  88. ; 如果 OutputX 等于 'wait' 或 'wait1' 意味着等待图像出现,
  89. ; 如果 OutputX 等于 'wait0' 意味着等待图像消失
  90. ; 此时 OutputY 设置等待时间的秒数,如果小于0则无限等待
  91. ; 如果超时则返回0,意味着失败,如果等待图像出现成功,则返回位置数组
  92. ; 如果等待图像消失成功,则返回 1(注意这里的等待功能仅适用于静态图像)
  93. ; 例1: FindText(&X:='wait', &Y:=3, 0,0,0,0,0,0,Text) ; 等待3秒等图像出现
  94. ; 例2: FindText(&X:='wait0', &Y:=-1, 0,0,0,0,0,0,Text) ; 无限等待等图像消失
  95. ;
  96. ; <FindMultiColor> <FindColor> : 找色 是仅有一个点的 找多色
  97. ; Text:='|<>##DRDGDB $ 0/0/RRGGBB1-DRDGDB1/RRGGBB2/-RRGGBB3/-RRGGBB4, xn/yn/...'
  98. ; '##'之后的颜色 (0xDRDGDB) 是所有颜色的默认偏色(各个分量允许的变化值)
  99. ; 初始点 (0,0) 匹配 0xRRGGBB1(+/-0xDRDGDB1) 或者 0xRRGGBB2(+/-0xDRDGDB)
  100. ; 或者 非 0xRRGGBB3(+/-0xDRDGDB) 或者 非 0xRRGGBB4(+/-0xDRDGDB)
  101. ; 以 '-' 开头的颜色,表示除了这种颜色的其他的任何颜色都匹配
  102. ; 每个点可以允许匹配10组颜色 (xn/yn/RRGGBB1/.../RRGGBB10)
  103. ;
  104. ; <FindPic> : Text 参数需要手动输入
  105. ; Text:='|<>##DRDGDB-RRGGBB1-RRGGBB2... $ d:\a.bmp'
  106. ; 0xRRGGBB1(+/-0xDRDGDB)... 都是透明色,不参与匹配
  107. ;
  108. ;--------------------------------
  109. )"
  110. }
  111. FindText(OutputX:="", OutputY:=""
  112. , x1:=0, y1:=0, x2:=0, y2:=0, err1:=0, err0:=0, text:=""
  113. , ScreenShot:=1, FindAll:=1, JoinText:=0, offsetX:=20, offsetY:=10
  114. , dir:=1, zoomW:=1, zoomH:=1)
  115. {
  116. wait:=(OutputX is VarRef) && IsSetRef(OutputX) ? %OutputX% : OutputX
  117. if !IsObject(wait) && (wait ~= "i)^\s*wait[10]?\s*$")
  118. {
  119. time:=(OutputY is VarRef) && IsSetRef(OutputY) ? %OutputY% : OutputY
  120. found:=!InStr(wait,"0"), time:=this.Floor(time)
  121. , timeout:=A_TickCount+Round(time*1000)
  122. Loop
  123. {
  124. ok:=this.FindText(,, x1, y1, x2, y2, err1, err0, text, ScreenShot
  125. , FindAll, JoinText, offsetX, offsetY, dir, zoomW, zoomH)
  126. if (found && ok)
  127. {
  128. (OutputX is VarRef) && (%OutputX%:=ok[1].x)
  129. , (OutputY is VarRef) && (%OutputY%:=ok[1].y)
  130. return ok
  131. }
  132. if (!found && !ok)
  133. return 1
  134. if (time>=0 && A_TickCount>=timeout)
  135. Break
  136. Sleep 50
  137. }
  138. return 0
  139. }
  140. x1:=this.Floor(x1), y1:=this.Floor(y1), x2:=this.Floor(x2), y2:=this.Floor(y2)
  141. if (x1=0 && y1=0 && x2=0 && y2=0)
  142. n:=150000, x:=y:=-n, w:=h:=2*n
  143. else
  144. x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x2-x1)+1, h:=Abs(y2-y1)+1
  145. bits:=this.GetBitsFromScreen(&x,&y,&w,&h,ScreenShot,&zx,&zy), x-=zx, y-=zy
  146. , this.ok:=0, info:=[]
  147. Loop Parse, text, "|"
  148. if IsObject(j:=this.PicInfo(A_LoopField))
  149. info.Push(j)
  150. if (w<1 || h<1 || !(num:=info.Length) || !bits.Scan0)
  151. {
  152. return 0
  153. }
  154. arr:=[], info2:=Map(), info2.Default:=[], k:=0, s:=""
  155. , mode:=(IsObject(JoinText) ? 2 : JoinText ? 1 : 0)
  156. For i,j in info
  157. {
  158. k:=Max(k, (j[7]=5 && j[8]=0 ? j[9] : j[2]*j[3]))
  159. if (mode)
  160. v:=(mode=2 ? j[10] : i) . "", s.="|" v
  161. , (!info2.Has(v) && info2[v]:=[]), (v!="" && info2[v].Push(j))
  162. }
  163. sx:=x, sy:=y, sw:=w, sh:=h
  164. , JoinText:=(mode=1 ? [s] : JoinText)
  165. , s1:=Buffer(k*4), s0:=Buffer(k*4)
  166. , ss:=Buffer(sw*(sh+2))
  167. , FindAll:=(dir=9 ? 1 : FindAll)
  168. , allpos_max:=(FindAll || JoinText ? 10240 : 1)
  169. , ini:={ sx:sx, sy:sy, sw:sw, sh:sh, zx:zx, zy:zy
  170. , mode:mode, bits:bits, ss:ss.Ptr, s1:s1.Ptr, s0:s0.Ptr
  171. , err1:err1, err0:err0, allpos_max:allpos_max
  172. , zoomW:zoomW, zoomH:zoomH }
  173. Loop 2
  174. {
  175. if (err1=0 && err0=0) && (num>1 || A_Index>1)
  176. ini.err1:=err1:=0.05, ini.err0:=err0:=0.05
  177. if (!JoinText)
  178. {
  179. allpos:=Buffer(allpos_max*4), allpos_ptr:=allpos.Ptr
  180. For i,j in info
  181. Loop this.PicFind(ini, j, dir, sx, sy, sw, sh, allpos_ptr)
  182. {
  183. pos:=NumGet(allpos, 4*(A_Index-1), "uint")
  184. , x:=(pos&0xFFFF)+zx, y:=(pos>>16)+zy
  185. , w:=Floor(j[2]*zoomW), h:=Floor(j[3]*zoomH), comment:=j[10]
  186. , arr.Push({1:x, 2:y, 3:w, 4:h, x:x+w//2, y:y+h//2, id:comment})
  187. if (!FindAll)
  188. Break 3
  189. }
  190. }
  191. else
  192. For k,v in JoinText
  193. {
  194. v:=StrSplit(Trim(RegExReplace(v, "\s*\|[|\s]*", "|"), "|")
  195. , (InStr(v,"|")?"|":""), " `t")
  196. , this.JoinText(arr, ini, info2, v, 1, offsetX, offsetY
  197. , FindAll, dir, 0, 0, 0, sx, sy, sw, sh)
  198. if (!FindAll && arr.Length)
  199. Break 2
  200. }
  201. if (err1!=0 || err0!=0 || arr.Length || info[1][4] || info[1][7]=5)
  202. Break
  203. }
  204. if (dir=9 && arr.Length)
  205. arr:=this.Sort2(arr, (x1+x2)//2, (y1+y2)//2)
  206. if (arr.Length)
  207. {
  208. (OutputX is VarRef) && (%OutputX%:=arr[1].x)
  209. , (OutputY is VarRef) && (%OutputY%:=arr[1].y)
  210. , this.ok:=arr
  211. return arr
  212. }
  213. return 0
  214. }
  215. ; 组合文本参数可以用数组 <==> [ "abc", "xyz", "a1|a2|a3" ]
  216. JoinText(arr, ini, info2, text, index, offsetX, offsetY
  217. , FindAll, dir, minX, minY, maxY, sx, sy, sw, sh)
  218. {
  219. if !(Len:=text.Length)
  220. return 0
  221. allpos:=Buffer(ini.allpos_max*4), allpos_ptr:=allpos.Ptr
  222. , zoomW:=ini.zoomW, zoomH:=ini.zoomH, mode:=ini.mode
  223. For i,j in info2[text[index]]
  224. if (mode!=2 || text[index]==j[10])
  225. Loop this.PicFind(ini, j, dir, sx, sy, (index=1 ? sw
  226. : Min(sx+offsetX+Floor(j[2]*zoomW),ini.sx+ini.sw)-sx), sh, allpos_ptr)
  227. {
  228. pos:=NumGet(allpos, 4*(A_Index-1), "uint")
  229. , x:=pos&0xFFFF, y:=pos>>16
  230. , w:=Floor(j[2]*zoomW), h:=Floor(j[3]*zoomH)
  231. , (index=1 && (minX:=x, minY:=y, maxY:=y+h))
  232. , minY1:=Min(y, minY), maxY1:=Max(y+h, maxY), sx1:=x+w
  233. if (index<Len)
  234. {
  235. sy1:=Max(minY1-offsetY, ini.sy)
  236. , sh1:=Min(maxY1+offsetY, ini.sy+ini.sh)-sy1
  237. if this.JoinText(arr, ini, info2, text, index+1, offsetX, offsetY
  238. , FindAll, 5, minX, minY1, maxY1, sx1, sy1, 0, sh1)
  239. && (index>1 || !FindAll)
  240. return 1
  241. }
  242. else
  243. {
  244. comment:=""
  245. For k,v in text
  246. comment.=(mode=2 ? v : info2[v][1][10])
  247. x:=minX+ini.zx, y:=minY1+ini.zy, w:=sx1-minX, h:=maxY1-minY1
  248. , arr.Push({1:x, 2:y, 3:w, 4:h, x:x+w//2, y:y+h//2, id:comment})
  249. if (index>1 || !FindAll)
  250. return 1
  251. }
  252. }
  253. return 0
  254. }
  255. PicFind(ini, j, dir, sx, sy, sw, sh, allpos_ptr)
  256. {
  257. static MyFunc:=""
  258. if (!MyFunc)
  259. {
  260. x32:="VVdWU4PEgIO8JJQAAAAFi6wkzAAAAA+EoAoAAIu8JNAAAACF@w+O7RAAAMcEJAAA"
  261. . "AADHRCQQAAAAADH@x0QkHAAAAADHRCQUAAAAAIuEJMgAAACLTCQUMfYx2wHIhe2J"
  262. . "RCQMf0HplAAAAI22AAAAAA+vhCS0AAAAicGJ8Jn3@QHBi0QkDIA8GDF0TIuEJMQA"
  263. . "AACDwwEDtCTkAAAAiQy4g8cBOd10VIsEJJn3vCTQAAAAg7wklAAAAAR1tQ+vhCSo"
  264. . "AAAAicGJ8Jn3@Y0MgYtEJAyAPBgxdbSLRCQci5QkwAAAAIPDAQO0JOQAAACJDIKD"
  265. . "wAE53YlEJBx1rAFsJBSDRCQQAYuMJOgAAACLRCQQAQwkOYQk0AAAAA+FLv@@@4tM"
  266. . "JBy7rYvbaIl8JCQPr4wk1AAAAInIwfkf9+vB+gwpyouMJNgAAACJVCQYD6@PicjB"
  267. . "+R@368H6DCnKiVQkKIO8JJQAAAAED4RNCgAAi4QkqAAAAIu0JKwAAAAPr4QksAAA"
  268. . "AIuMJKgAAACNPLCLhCS0AAAA99iNBIGJRCQwi4QklAAAAIXAD4VWAwAAi4QkmAAA"
  269. . "AIusJLgAAADHRCQsAAAAAMdEJDQAAAAAwegQD7bAiUQkDIuEJJgAAAAPtsSJRCQQ"
  270. . "D7aEJJgAAACJRCQUi4QktAAAAMHgAoXtiUQkPA+OvQAAAIu0JLQAAACF9g+OlAAA"
  271. . "AIu0JKQAAACLbCQ0A6wkvAAAAAH+A3wkPIl8JDgDvCSkAAAAiTwkifaNvCcAAAAA"
  272. . "D7ZOAotcJAwPtkYBD7YWK0QkECtUJBSJzwHZKd+NmQAEAAAPr8APr9@B4AsPr98B"
  273. . "w7j+BQAAKcgPr8IPr9AB0zmcJJwAAAAPk0UAg8YEg8UBOzQkdaqLjCS0AAAAAUwk"
  274. . "NIt8JDiDRCQsAQN8JDCLRCQsOYQkuAAAAA+FQ@@@@4tEJBiJRCREi0QkKIlEJFyL"
  275. . "dCQci0wkRDHAOc6LTCRcD07wiXQkHIt0JCQ5zg9PxolEJCSLdCQki0QkHDnGD03G"
  276. . "iUQkFIuEJJQAAACD6ASD+AEPhnQHAADHRCRkAAAAAMdEJHAAAAAAi0QkcAOEJLQA"
  277. . "AAArhCTkAAAAiUQkdItEJGQDhCS4AAAAK4Qk6AAAAIlEJEyLhCSgAAAAg+gBg@gH"
  278. . "D4fpBgAAg@gDiUQkVA+O5AYAAIt0JGSLRCRwiXQkcIlEJGSLdCR0OXQkZA+P5AYA"
  279. . "AItEJHSLTCQci3QkVMdEJDwAAAAAiUQkeIuEJMAAAACNBIiJRCRgifCD4AGJRCRY"
  280. . "ifCD4AOJRCR8i0QkcIt0JEw58A+PAQEAAIN8JHwBi0wkZA9PTCR4iXQkQIlEJCyJ"
  281. . "TCRQi0QkWIXAi0QkQA9ERCQsg3wkVAOJRCQ0D49PAgAAg7wklAAAAAWLRCRQiUQk"
  282. . "OItEJDgPhFcCAACDvCSUAAAABA+EKwQAAA+vhCS0AAAAi0wkFIt0JDSFyY0sMA+E"
  283. . "4AMAAIt0JFyLXCREMcCLlCS8AAAAiWwkEItMJByLfCQkiRwkiXQkDAHqi2wkFOsL"
  284. . "g8ABOcUPhKUDAAA5yH0Xi5wkwAAAAIs0gwHWgD4AdQaDLCQBeBw5x37Wi5wkxAAA"
  285. . "AIs0gwHWgD4BdcWDbCQMAXm+g0QkLAGDbCRAAYtEJCw5RCRMD40Z@@@@g0QkZAGD"
  286. . "bCR4AYtEJGQ5RCR0D43X@v@@i0QkPIPsgFteX13CWACDvCSUAAAAAQ+EQgsAAIO8"
  287. . "JJQAAAACD4QtCQAAi4QkmAAAAA+2jCScAAAAx0QkFAAAAADHRCQsAAAAAMHoEA+2"
  288. . "wIkEJIuEJJgAAAAPtsSJRCQMD7aEJJgAAACJRCQQi4QknAAAAMHoEA+26IuEJJwA"
  289. . "AACJ7g+v9Q+2xIl0JCCJxg+v8InID6@BiXQkCIlEJASLhCS0AAAAweACiUQkNIuE"
  290. . "JLgAAACFwA+OEv3@@4uEJLQAAACFwA+OfgAAAIuUJKQAAACLXCQsA5wkvAAAAAH6"
  291. . "A3wkNIl8JDgDvCSkAAAAif0PtkICMf8PtkoBKwQkD7YyD6@AOUQkIHwiK0wkDA+v"
  292. . "yTlMJAh8FYnwD7bwK3QkEA+v9jl0JAQPncCJx4n4g8IEg8MBiEP@Oep1touMJLQA"
  293. . "AAABTCQsi3wkOINEJBQBA3wkMItEJBQ5hCS4AAAAD4VZ@@@@6Wb8@@+NtCYAAAAA"
  294. . "i0QkNIO8JJQAAAAFiUQkOItEJFCJRCQ0i0QkOA+Fqf3@@w+vhCSoAAAAi0wkNIts"
  295. . "JGiF7Y0EiIlEJDAPhQUDAACLRCRsi3wkFMdEJBgAAAAAiUQkKItEJESF@4lEJEgP"
  296. . "hBsBAACLfCQgjbQmAAAAAItMJBiLtCTAAAAAi0QkMAMEjou0JMQAAACNFImNHJGL"
  297. . "VCQoizSOi4wkpAAAAIkUJIm0JJwAAACLtCSkAAAAD7Z0BgKJdCQMi7QkpAAAAA+2"
  298. . "dAYBD7YEAYl0JBCJRCQgid7reYsEJIPGAosIi1gEiciJ38HoEMHvEA+2wCtEJAyJ"
  299. . "+g+2+g+21w+224n9iVwkBDHbD6@viVQkCA+vwDnofysPtsUrRCQQidUPr+oPr8A5"
  300. . "6H8Yi1QkBA+2wStEJCCJ0w+v2g+vwDnYD57DgwQkCIH5@@@@AA+XwDjYdRg5tCSc"
  301. . "AAAAD4d6@@@@g2wkSAEPiIICAACDRCQYAYNEJChUi0QkGDlEJBQPhfT+@@+JfCQg"
  302. . "i4Qk3AAAAINEJDwBi0wkPIXAD4TK@P@@i1QkOAOUJLAAAACLRCQ0A4QkrAAAAIu0"
  303. . "JNwAAADB4hAJ0DuMJOAAAACJRI78D4yX@P@@6cL8@@+LbCQQi1QkHIXSdKSLtCS8"
  304. . "AAAAi4QkwAAAAItcJGCNDC6LEIPABAHKOdjGAgB18ul8@@@@D6+EJKgAAACLdCQ0"
  305. . "i1wkFI0EsIu0JKQAAACJBCQDhCSYAAAAhduJ8Q+2bAYCD7Z0BgEPtgQBiXQkDIlE"
  306. . "JBAPhDj@@@+LRCRcMduJbCQYiUQkMItEJESJRCQoZpA7XCQcfWSLhCTAAAAAixQk"
  307. . "i3wkGAMUmA+2dBECD7ZEEQErRCQMD7YUEStUJBCJ9QH+Kf2NvgAEAAAPr8APr@3B"
  308. . "4AsPr@0Bx7j+BQAAKfAPr8IPr9AB1zu8JJwAAAB2C4NsJCgBD4iY+@@@OVwkJH5k"
  309. . "i4QkxAAAAIsUJIt8JBgDFJgPtnQRAg+2RBEBK0QkDA+2FBErVCQQifUB@in9jb4A"
  310. . "BAAAD6@AD6@9weALD6@9Ace4@gUAACnwD6@CD6@QAdc7vCScAAAAdwuDbCQwAQ+I"
  311. . "Lvv@@4PDATlcJBQPhR@@@@@pOv7@@4t0JBSF9g+ELv7@@4t0JESLnCSkAAAAMdKQ"
  312. . "i4QkwAAAAIt8JDADPJCLhCTEAAAAiyyQD7ZEOwKJ6cHpEA+2ySnID7ZMOwEPtjw7"
  313. . "D6@AO0QkIH8niegPtsQpwQ+vyTtMJAh@F4n4D7b4iegPtsApxw+v@zt8JAR+B2aQ"
  314. . "g+4BeBWDwgE5VCQUdZKJrCSYAAAA6ab9@@+JrCSYAAAA6Xz6@@+JfCQg6XP6@@@H"
  315. . "RCRUAAAAAIt0JHSLRCRMiXQkTIlEJHSLdCR0OXQkZA+OHPn@@8dEJDwAAAAAi0Qk"
  316. . "PIPsgFteX13CWACLhCSwAAAAx4QksAAAAAAAAACJRCRki4QkrAAAAMeEJKwAAAAA"
  317. . "AAAAiUQkcOlr+P@@i7QkmAAAADHAhfYPlcCJRCRoD4U6AQAAi5wknAAAAIXbD4R@"
  318. . "BgAAi7QknAAAAIu8JMAAAACLnCTEAAAAjQS3MfaJBCSLhCTIAAAAMdKDxwSDwwSL"
  319. . "BLCJhCSYAAAAwegE9@UPr4Qk6AAAAIlUJAyZ97wk0AAAAA+vhCSoAAAAicGLRCQM"
  320. . "D6+EJOQAAACZ9@2NBIGJR@yLhCSYAAAAg+APjQRGg8YViUP8OzwkdZeLhCScAAAA"
  321. . "i4wk1AAAALqti9toD6@IiUQkHInIwfkf9+qJ0MH4DCnIi7QkyAAAAIlEJETHRCRc"
  322. . "AAAAAMdEJCQAAAAAg8YEiXQkbOkX9@@@i4QkmAAAAMHoEA+vhCToAAAAmfe8JNAA"
  323. . "AAAPr4QkqAAAAInBD7eEJJgAAAAPr4Qk5AAAAJn3@Y0EgYmEJJgAAACLRCQYiUQk"
  324. . "RItEJCiJRCRc6cH2@@+LhCTQAAAAi7QkyAAAAA+2lCSYAAAAD6@FjQSGiUQkbIuE"
  325. . "JJgAAADB6BAPtsiLhCSYAAAAic4Pr@GLjCTQAAAAD7bEiXQkIInGD6@widAPr8KF"
  326. . "yYl0JAiJRCQED47OBAAAi3QkbI0ErQAAAACJrCTMAAAAi5wkmAAAAIu8JJwAAACL"
  327. . "bCQgiUQkNDHAx0QkLAAAAADHRCQwAAAAAMdEJBwAAAAAiTQki5QkzAAAAIXSD44a"
  328. . "AQAAi4wkyAAAAIs0JMdEJBQAAAAAiVwkKAHBA0QkNIlMJBCJRCQ4A4QkyAAAAIlE"
  329. . "JCSLRCQQhf8PtlABD7ZIAg+2AIkUJIlEJAx0RjHSZpCLHJaJ2MHoEA+2wCnID6@A"
  330. . "OcV8Iw+2xysEJA+vwDlEJAh8FA+2wytEJAwPr8A5RCQED435AAAAg8IBOfp1wolc"
  331. . "JCiLRCQcweEQweACiUQkGItEJCyZ97wk0AAAAA+vhCSoAAAAicOLRCQUmfe8JMwA"
  332. . "AACLVCQcjQSDi5wkwAAAAIkEk4sEJIPCAYucJMQAAACJVCQcweAICcELTCQMi0Qk"
  333. . "GIkMA4NEJBAEi5Qk5AAAAItEJBABVCQUO0QkJA+FIP@@@4tcJCiLRCQ4iTQkg0Qk"
  334. . "MAGLtCToAAAAi0wkMAF0JCw5jCTQAAAAD4W2@v@@i0wkHLqti9toiZwkmAAAAA+v"
  335. . "jCTUAAAAx0QkXAAAAADHRCQkAAAAAInIwfkf9+rB+gwpyolUJETplPT@@5CNdCYA"
  336. . "iVwkKOlr@@@@i4wktAAAAIuEJLwAAAAx7YuUJLgAAADHBCQAAAAAjQRIiUQkNInI"
  337. . "weAChdKJRCQMD45A9P@@i4QktAAAAIXAfleLjCSkAAAAi0QkNAH5A3wkDI0cKIl8"
  338. . "JBADvCSkAAAAD7ZRAg+2QQGDwQQPtnH8g8MBa8BLa9ImAcKJ8MHgBCnwAdDB+AeI"
  339. . "Q@85+XXTA6wktAAAAIt8JBCDBCQBA3wkMIsEJDmEJLgAAAB1iouEJLQAAACLvCSc"
  340. . "AAAAMfbHRCQMAAAAAIPoAYlEJCyLhCS4AAAAg+gBiUQkMIuEJLQAAACFwA+O7QAA"
  341. . "AItEJAyLjCS0AAAAi6wkvAAAAIXAi0QkNA+URCQUAfGJTCQ4icONFDABy4nxK4wk"
  342. . "tAAAAAHuiXQkEAHBMcCJDCTpkgAAAIB8JBQAD4WPAAAAOUQkLA+EhQAAAItMJAw5"
  343. . "TCQwdHsPtjoPtmr@vgEAAAADvCSYAAAAOe9yPA+2agE573I0iwwkD7YpOe9yKg+2"
  344. . "KznvciMPtmn@Oe9yGw+2aQE573ITD7Zr@znvcgsPtnMBOfcPksGJzotsJBCJ8YhM"
  345. . "BQCDwAGDwgGDwwGDBCQBOYQktAAAAHQShcAPhWb@@@+LdCQQxgQGAuvYi3QkOINE"
  346. . "JAwBi0QkDDmEJLgAAAAPhe7+@@+LRCQYibwknAAAAIlEJESLRCQoiUQkXOl@8v@@"
  347. . "i4QkmAAAAIucJLgAAAAx7ccEJAAAAACDwAHB4AeJhCSYAAAAi4QktAAAAMHgAoXb"
  348. . "iUQkDA+ONfL@@4uMJLQAAACFyX5mi4wkpAAAAIucJLwAAACJbCQUAfkDfCQMAeuL"
  349. . "rCSYAAAAiXwkEAO8JKQAAAAPtlECD7ZBAQ+2MWvAS2vSJgHCifDB4AQp8AHCOdUP"
  350. . "lwODwQSDwwE5+XXVi2wkFAOsJLQAAACLfCQQgwQkAQN8JDCLBCQ5hCS4AAAAD4V3"
  351. . "@@@@6afx@@@HRCQoAAAAAMdEJBgAAAAAx0QkJAAAAADHRCQcAAAAAOkg8P@@x0Qk"
  352. . "RAAAAADHRCQcAAAAAMdEJFwAAAAAx0QkJAAAAADpkfH@@zHAx0QkHAAAAADpIPr@"
  353. . "@5CQkJCQkJCQkJCQkJCQkA=="
  354. x64:="QVdBVkFVQVRVV1ZTSIHsuAAAAEiLtCQgAQAAi5wkcAEAAIP5BYmMJAABAACJ1UWJ"
  355. . "xUSJjCQYAQAARIu8JHgBAAAPhDIMAABFhf8PjlASAABEiXQkEIl8JBgxwIu8JAAB"
  356. . "AABEi6wkQAEAAEUx0kyLtCRgAQAAi6wkoAEAAEUx20SJZCQgx0QkCAAAAABBicTH"
  357. . "RCQoAAAAAImUJAgBAABEiYQkEAEAAEiJtCQgAQAASGN0JChFMclFMcBIA7QkaAEA"
  358. . "AIXbfzfrfWYPH4QAAAAAAEEPr8WJwUSJyJn3+wHBQoA8BjF0PUmDwAFJY8NBAelB"
  359. . "g8MBRDnDQYkMhn5ERInQmUH3@4P@BHXID6+EJCgBAACJwUSJyJn3+0KAPAYxjQyB"
  360. . "dcNIi5QkWAEAAEmDwAFJY8RBAelBg8QBRDnDiQyCf7wBXCQog0QkCAFEA5QkqAEA"
  361. . "AItEJAhBOccPhVD@@@9EieFBuK2L22hEi3QkEA+vjCSAAQAARIlkJFSLrCQIAQAA"
  362. . "RItkJCBEi6wkEAEAAEiLtCQgAQAAi3wkGESJXCQIicjB+R9B9+jB+gwpyouMJIgB"
  363. . "AACJVCQQQQ+vy4nIwfkfQffowfoMKcqJVCQYg7wkAAEAAAQPhIMLAACLhCQoAQAA"
  364. . "i5wkMAEAAA+vhCQ4AQAAjQSYi5wkKAEAAIlEJCiLhCRAAQAA99iNBIOLnCQAAQAA"
  365. . "iUQkLIXbD4X6AwAAiehEi5wkSAEAAMHoEA+22EiJ6A+2xEWF24nBQA+2xYnCD44X"
  366. . "BQAAi4QkQAEAAImsJAgBAABEi3wkKIusJEABAABEiXQkQESJZCRIQYnWweACx0Qk"
  367. . "IAAAAADHRCQwAAAAAIlEJDiJfCRQQYnMhe0PjooAAABIY3wkMEljx0Ux20gDvCRQ"
  368. . "AQAATI1UBgIPH4QAAAAAAEEPtlL+RQ+2CkEPtkL@RCnyRInJQYnQQo0UCynZRCng"
  369. . "RI2KAAQAAA+vwEQPr8nB4AtED6@Juf4FAAAp0YnKQQ+v0EGNBAFBD6@QAdBBOcVC"
  370. . "D5MEH0mDwwFJg8IERDndf59EA3wkOAFsJDCDRCQgAUQDfCQsi0QkIDmEJEgBAAAP"
  371. . "hVP@@@+LRCQQRIt0JECLfCRQRItkJEiLrCQIAQAAiUQkWItEJBiJhCSAAAAAi1wk"
  372. . "VItMJFgxwDnLi4wkgAAAAA9O2IlcJFSLXCQIOcsPT8OJRCQIi1wkCItEJFQ5ww9N"
  373. . "w0GJw4uEJAABAACD6ASD+AEPhpsIAADHhCSMAAAAAAAAAMeEJKAAAAAAAAAAi4Qk"
  374. . "oAAAAAOEJEABAAArhCSgAQAAiYQkpAAAAIuEJIwAAAADhCRIAQAAK4QkqAEAAIlE"
  375. . "JGCLhCQYAQAAg+gBg@gHD4f+BwAAg@gDiUQkaA+O+QcAAIucJIwAAACLhCSgAAAA"
  376. . "iZwkoAAAAImEJIwAAACLnCSkAAAAOZwkjAAAAA+P8wcAAIuEJKQAAABIi5wkWAEA"
  377. . "AImsJAgBAABEieVFidxEibQkhAAAAMdEJEAAAAAARYnuiYQkqAAAAItEJFSJvCSI"
  378. . "AAAAg+gBSI1EgwRIiUQkeEGNQ@9JifNIi7QkUAEAAEiNRIMEi1wkaEiJRCRIidiD"
  379. . "4AGJRCRsidiD4AOJhCSsAAAAi4QkoAAAAIt8JGA5+A+PBQEAAIO8JKwAAAABi5wk"
  380. . "jAAAAA9PnCSoAAAAiXwkUIlEJCCJXCRkDx+EAAAAAACLTCRsi0QkUIXJD0REJCCD"
  381. . "fCRoA4lEJCwPj1QCAACDvCQAAQAABYtEJGSJRCQwD4RcAgAAg7wkAAEAAAQPhFQE"
  382. . "AACLTCQwD6+MJEABAAADTCQsRYXkD4QJBAAARIuUJIAAAABEi0wkWDHARItEJFSL"
  383. . "fCQITIusJFgBAABMi7wkYAEAAOsNSIPAAUE5xA+O0gMAAEE5wInCfhOJy0EDXIUA"
  384. . "gDweAHUGQYPpAXgWOdd+1YnKQQMUh4A8FgF1yUGD6gF5w4NEJCABg2wkUAGLRCQg"
  385. . "OUQkYA+NJv@@@4OEJIwAAAABg6wkqAAAAAGLhCSMAAAAOYQkpAAAAA+NxP7@@4tE"
  386. . "JEBIgcS4AAAAW15fXUFcQV1BXkFfw4O8JAABAAABD4S3CwAAg7wkAAEAAAIPhIcJ"
  387. . "AABIiehEi4QkSAEAAEEPts0PtsSJ60GJzEGJw0APtsXB6xCJRCQgRInoD7bbwegQ"
  388. . "x0QkMAAAAADHRCQ4AAAAAA+20EyJ6A+2xEGJ1onHD6@4i4QkQAEAAEQPr@JEjTyF"
  389. . "AAAAAEQPr+FFhcAPjrkAAACJrCQIAQAAi6wkQAEAAESJrCQQAQAARYndhe1+b0hj"
  390. . "RCQoTGNcJDhFMcBMA5wkUAEAAEiNVAYCDx+EAAAAAAAPtgJFMdIPtkr@RA+2Sv4p"
  391. . "2A+vwEE5xnwaRCnpD6@JOc98EEQrTCQgRQ+vyUU5zEEPncJHiBQDSYPAAUiDwgRE"
  392. . "OcV@vEQBfCQoAWwkOItUJCyDRCQwAQFUJCiLRCQwOYQkSAEAAA+Fb@@@@4usJAgB"
  393. . "AABEi6wkEAEAAItEJBCJRCRYi0QkGImEJIAAAADp6@v@@4tEJCyDvCQAAQAABYlE"
  394. . "JDCLRCRkiUQkLA+FpP3@@4tEJDCLfCQsD6+EJCgBAACLlCSQAAAAhdKNBLiJRCQ4"
  395. . "D4VVAwAARYXkD4RRAQAASIu8JGABAABIi4QkWAEAAESLrCSEAAAASIm0JJgAAADH"
  396. . "RCQoAAAAAESJpCSUAAAASIl8JBBIi3wkcEiJxkiJfCQYi3wkWIl8JFyLvCSIAAAA"
  397. . "i0QkOAMGSItcJBBEi0QkKEiLVCQYjUgBRIszRI1IAkiYSGPJTWPJRQ+2JANBD7Yc"
  398. . "C0cPthQLQYnZ63QPH0QAAItKBIsaQYPAAkGJzYnYD7b9wegQQcHtEA+26UUPtu0P"
  399. . "tsAxyUQp0EWJ7w+vwEUPr@1EOfh@KA+2x0GJ@0QpyA+vwEQPr@9EOfh@Ew+2w4np"
  400. . "RCngD6@ND6@AOcgPnsFIg8IIgfv@@@8AD5fAOMh1EEU5xneMg2wkXAEPiBADAABI"
  401. . "g8YESINEJBAEg0QkKBVIg0QkGFRIO3QkSA+FIf@@@0SLpCSUAAAASIu0JJgAAABE"
  402. . "iawkhAAAAIm8JIgAAABmkINEJEABSIO8JJABAAAAi3wkQA+Emvz@@4tEJDADhCQ4"
  403. . "AQAASGPXi0wkLAOMJDABAABIi5wkkAEAAMHgEAnIO7wkmAEAAIlEk@wPjGP8@@@p"
  404. . "mvz@@4tEJFSFwHSkSIuEJFgBAABMi0QkeA8fgAAAAACJygMQSIPABEw5wMYEFgB1"
  405. . "7+l6@@@@i0QkMIt8JCwPr4QkKAEAAI0EuInBA4QkCAEAAEWF5I1QAkhj0kEPthwT"
  406. . "jVABSJhBD7YEA0hj0kEPtjwTQYn9D4Q1@@@@i7wkgAAAAIlsJBhFMcmJzUGJx0iJ"
  407. . "dCQ4iXwkEIt8JFiJfCQoi3wkVEQ5z0WJyn5uSIuEJFgBAABCixSIAeqNQgJImEEP"
  408. . "tgwDjUIBSGPSQQ+2FBNImEEPtgQDic4B2USNgQAEAAAp3kQp+kQPr8ZEKegPr8BE"
  409. . "D6@GweALQQHAuP4FAAApyA+vwg+v0EEB0EU58HYLg2wkKAEPiEcBAABEOVQkCH5w"
  410. . "SIuEJGABAABCixSIAeqNQgJImEEPtgwDjUIBSGPSQQ+2FBNImEEPtgQDQYnKAdlE"
  411. . "jYEABAAAQSnaRCn6RQ+vwkQp6A+vwEUPr8LB4AtBAcC4@gUAACnID6@CD6@QQQHQ"
  412. . "RTnwdwuDbCQQAQ+I0AAAAEmDwQFFOcwPjwb@@@+LbCQYSIt0JDjpBf7@@0WF5A+E"
  413. . "@P3@@0SJdCQoRItMJFgxyUSLrCSEAAAAi7wkiAAAAESLVCQ4TIu0JFgBAABMi7wk"
  414. . "YAEAAEGLFI5BixyPRAHSQYnYjUICQcHoEEUPtsBImEEPtgQDRCnARI1CAUhj0g+v"
  415. . "wEEPthQTTWPARw+2BANEOeh@HQ+2x0EpwEUPr8BBOfh@Dg+2wynCD6@SOep+CGaQ"
  416. . "QYPpAXgoSIPBAUE5zH+ViZwkCAEAAESLdCQo6VD9@@+LbCQYSIt0JDjp9Pn@@4mc"
  417. . "JAgBAABEi3QkKOnj+f@@RImsJIQAAACJvCSIAAAARIukJJQAAABIi7QkmAAAAOm@"
  418. . "+f@@x0QkaAAAAACLnCSkAAAAi0QkYIlcJGCJhCSkAAAAi5wkpAAAADmcJIwAAAAP"
  419. . "jg34@@@HRCRAAAAAAOm8+f@@i4QkOAEAAMeEJDgBAAAAAAAAiYQkjAAAAIuEJDAB"
  420. . "AADHhCQwAQAAAAAAAImEJKAAAADpRPf@@zHAhdIPlcCJhCSQAAAAD4UTAQAARTHJ"
  421. . "RTHbRYXATIuUJGgBAAAPhEkGAABBiyox0kmDwlSJ6MHoBPfzD6+EJKgBAACJ0ZlB"
  422. . "9@8Pr4QkKAEAAEGJwIuEJKABAAAPr8FIi4wkWAEAAJn3+0GNBIBCiQSJiehIi4wk"
  423. . "YAEAAIPgD0GNBENBg8MVQokEiUmDwQFFOc13mIuMJIABAAC6rYvbaESJbCRUQQ+v"
  424. . "zYnIwfkf9+qJ0MH4DCnISIucJGgBAACJRCRYx4QkgAAAAAAAAADHRCQIAAAAAEiD"
  425. . "wwRIiVwkcOkB9v@@iejB6BAPr4QkqAEAAJlB9@8Pr4QkKAEAAInBD7fFD6+EJKAB"
  426. . "AACZ9@uNLIGLRCQQiUQkWItEJBiJhCSAAAAA6b31@@+J2EEPr8fB4AJImEgDhCRo"
  427. . "AQAASIlEJHCJ0A+20sHoEEGJ1A+2yEiJ6A+2xEGJzonHRA+v8Q+v+EQPr+JFhf8P"
  428. . "juAEAACNQ@9Ii0wkcEGNUP@HRCQoAAAAAMdEJBAAAAAASI0EhQYAAADHRCQYAAAA"
  429. . "AESJhCQQAQAATI1UkQQx0onpSIlEJCCNBJ0AAAAAQYnVSIm0JCABAACJnCRwAQAA"
  430. . "iUQkLESJvCR4AQAAi7QkcAEAAIX2D47tAAAASGNEJBhIi7QkaAEAAEiNXAYCSANE"
  431. . "JCBIAfAx9kiJRCQIDx9AAIusJBABAABED7YDRA+2S@9ED7Zb@oXtdEBIi1QkcGaQ"
  432. . "iwqJyMHoEA+2wEQpwA+vwEE5xnwbD7bFRCnID6@AOcd8Dg+2wUQp2A+vwEE5xH1a"
  433. . "SIPCBEw50nXHi0QkKE1j@UHB4BBBweEIQYPFAUUJyJlFCdj3vCR4AQAAD6+EJCgB"
  434. . "AACJxYnwmfe8JHABAABIi5QkWAEAAI1EhQBCiQS6SIuEJGABAABGiQS4SIPDBAO0"
  435. . "JKABAABIOVwkCA+FQP@@@4t0JCwBdCQYg0QkEAGLnCSoAQAAi0QkEAFcJCg5hCR4"
  436. . "AQAAD4Xj@v@@RIlsJFSJzYtMJFQPr4wkgAEAALqti9toRIusJBABAABIi7QkIAEA"
  437. . "AMeEJIAAAAAAAAAAx0QkCAAAAACJyMH5H@fqwfoMKcqJVCRY6aTz@@+LhCRAAQAA"
  438. . "RIuMJEgBAABFMdsx2wHASJhIA4QkUAEAAEWFyUiJRCQwi4QkQAEAAESNPIUAAAAA"
  439. . "D45k9@@@iXwkIIu8JEABAACF@35PSGNEJChMY9NMA1QkMEUxwEiNTAYCD7YRD7ZB"
  440. . "@0iDwQRED7ZJ+mvAS2vSJgHCRInIweAERCnIAdDB+AdDiAQCSYPAAUQ5x3@NRAF8"
  441. . "JCgB+0GDwwGLTCQsAUwkKEQ5nCRIAQAAdZdIY4QkQAEAALoBAAAASIm0JCABAACL"
  442. . "tCRAAQAAi3wkIEUx28dEJCwAAAAASI1YAUgpwouEJEABAABIiVQkQEiJXCQ4g+gB"
  443. . "iUQkKIuEJEgBAACD6AGJRCQghfYPjt8AAABMY0wkLEiLTCQ4RYXbSItEJDBMi5Qk"
  444. . "UAEAAA+Uw06NBAlIi0wkQEqNVAgBTQHKSQHATAHJSAHBMcDpjgAAAITbD4WOAAAA"
  445. . "OUQkKA+EhAAAAEQ5XCQgdH1ED7Zq@0QPtnr+QbkBAAAAQQHtRTn9ckVED7Y6RTn9"
  446. . "cjxED7Z5@0U5@XIyRQ+2eP9FOf1yKEQPtnn+RTn9ch5ED7Y5RTn9chVFD7Z4@kU5"
  447. . "@XILRQ+2CEU5zUEPksFFiAwCSIPAAUiDwgFJg8ABSIPBATnGfg+FwA+Fav@@@0HG"
  448. . "BAIC690BdCQsQYPDAUQ5nCRIAQAAD4UH@@@@i0QkEEiLtCQgAQAAiUQkWItEJBiJ"
  449. . "hCSAAAAA6YLx@@+NRQFEi5QkSAEAAEUx2zHbweAHicWLhCRAAQAARYXSRI08hQAA"
  450. . "AAAPjlL1@@9EiXQkIESLtCRAAQAARYX2flNIY0QkKExj00wDlCRQAQAARTHASI1M"
  451. . "BgIPthEPtkH@RA+2Sf5rwEtr0iYBwkSJyMHgBEQpyAHQOcVDD5cEAkmDwAFIg8EE"
  452. . "RTnGf81EAXwkKEQB80GDwwGLTCQsAUwkKEQ5nCRIAQAAdZKLRCQQRIt0JCCJRCRY"
  453. . "i0QkGImEJIAAAADpvfD@@8dEJBgAAAAAx0QkEAAAAADHRCQIAAAAAMdEJFQAAAAA"
  454. . "6Qbv@@@HRCRYAAAAAMeEJIAAAAAAAAAAx0QkVAAAAADHRCQIAAAAAOmX8P@@McDH"
  455. . "RCRUAAAAAOkz+v@@kJCQkA=="
  456. this.MCode(&MyFunc, StrReplace((A_PtrSize=8?x64:x32),"@","/"))
  457. }
  458. text:=j[1], w:=j[2], h:=j[3]
  459. , err1:=this.Floor(j[4] ? j[5] : ini.err1)
  460. , err0:=this.Floor(j[4] ? j[6] : ini.err0)
  461. , mode:=j[7], color:=j[8], n:=j[9]
  462. return (!ini.bits.Scan0) ? 0 : DllCall(MyFunc.Ptr
  463. , "int",mode, "uint",color, "uint",n, "int",dir
  464. , "Ptr",ini.bits.Scan0, "int",ini.bits.Stride
  465. , "int",sx, "int",sy, "int",sw, "int",sh
  466. , "Ptr",ini.ss, "Ptr",ini.s1, "Ptr",ini.s0
  467. , (mode=5 ? "Ptr":"AStr"),text, "int",w, "int",h
  468. , "int",Floor(err1*10000), "int",Floor(err0*10000)
  469. , "Ptr",allpos_ptr, "int",ini.allpos_max
  470. , "int",Floor(w*ini.zoomW), "int",Floor(h*ini.zoomH))
  471. }
  472. code()
  473. {
  474. return "
  475. (
  476. //***** 机器码的 C语言 源代码 *****
  477. int __attribute__((__stdcall__)) PicFind(
  478. int mode, unsigned int c, unsigned int n, int dir
  479. , unsigned char * Bmp, int Stride
  480. , int sx, int sy, int sw, int sh
  481. , unsigned char * ss, unsigned int * s1, unsigned int * s0
  482. , unsigned char * text, int w, int h, int err1, int err0
  483. , unsigned int * allpos, int allpos_max
  484. , int new_w, int new_h )
  485. {
  486. int ok, o, i, j, k, v, e1, e0, len1, len0, max;
  487. int x, y, x1, y1, x2, y2, x3, y3;
  488. int r, g, b, rr, gg, bb, dR, dG, dB;
  489. unsigned int c1, c2;
  490. unsigned char * gs;
  491. unsigned int * cors;
  492. ok=0; o=0; len1=0; len0=0;
  493. //----------------------
  494. // 找多色、找单色、搜图模式
  495. if (mode==5)
  496. {
  497. if (k=(c!=0)) // FindPic
  498. {
  499. cors=(unsigned int *)(text+w*h*4);
  500. r=(c>>16)&0xFF; g=(c>>8)&0xFF; b=c&0xFF;
  501. dR=r*r; dG=g*g; dB=b*b;
  502. for (y=0; y<h; y++)
  503. {
  504. for (x=0; x<w; x++, o+=4)
  505. {
  506. rr=text[2+o]; gg=text[1+o]; bb=text[o];
  507. for (i=0; i<n; i++)
  508. {
  509. c=cors[i]; r=((c>>16)&0xFF)-rr;
  510. g=((c>>8)&0xFF)-gg; b=(c&0xFF)-bb;
  511. if (r*r<=dR && g*g<=dG && b*b<=dB) goto NoMatch1;
  512. }
  513. s1[len1]=(y*new_h/h)*Stride+(x*new_w/w)*4;
  514. s0[len1++]=(rr<<16)|(gg<<8)|bb;
  515. NoMatch1:;
  516. }
  517. }
  518. }
  519. else // FindMultiColor or FindColor
  520. {
  521. cors=(unsigned int *)text;
  522. for (; len1<n; len1++, o+=21)
  523. {
  524. c=cors[o]; y=(c>>4)/w; x=(c>>4)%w;
  525. s1[len1]=(y*new_h/h)*Stride+(x*new_w/w)*4;
  526. s0[len1]=o+(c&0xF)*2;
  527. }
  528. cors++;
  529. }
  530. goto StartLookUp;
  531. }
  532. //----------------------
  533. // 生成查表需要的表格
  534. for (y=0; y<h; y++)
  535. {
  536. for (x=0; x<w; x++)
  537. {
  538. if (mode==4)
  539. i=(y*new_h/h)*Stride+(x*new_w/w)*4;
  540. else
  541. i=(y*new_h/h)*sw+(x*new_w/w);
  542. if (text[o++]=='1')
  543. s1[len1++]=i;
  544. else
  545. s0[len0++]=i;
  546. }
  547. }
  548. //----------------------
  549. // 颜色位置模式
  550. // 仅用于多色验证码的识别
  551. if (mode==4)
  552. {
  553. y=c>>16; x=c&0xFFFF;
  554. c=(y*new_h/h)*Stride+(x*new_w/w)*4;
  555. goto StartLookUp;
  556. }
  557. //----------------------
  558. // 生成二值化图像
  559. o=sy*Stride+sx*4; j=Stride-sw*4; i=0;
  560. if (mode==0) // 颜色相似二值化
  561. {
  562. rr=(c>>16)&0xFF; gg=(c>>8)&0xFF; bb=c&0xFF;
  563. for (y=0; y<sh; y++, o+=j)
  564. for (x=0; x<sw; x++, o+=4, i++)
  565. {
  566. r=Bmp[2+o]-rr; g=Bmp[1+o]-gg; b=Bmp[o]-bb; v=r+rr+rr;
  567. ss[i]=((1024+v)*r*r+2048*g*g+(1534-v)*b*b<=n) ? 1:0;
  568. }
  569. }
  570. else if (mode==1) // 灰度阈值二值化
  571. {
  572. c=(c+1)<<7;
  573. for (y=0; y<sh; y++, o+=j)
  574. for (x=0; x<sw; x++, o+=4, i++)
  575. ss[i]=(Bmp[2+o]*38+Bmp[1+o]*75+Bmp[o]*15<c) ? 1:0;
  576. }
  577. else if (mode==2) // 灰度差值二值化
  578. {
  579. gs=ss+sw*2;
  580. for (y=0; y<sh; y++, o+=j)
  581. {
  582. for (x=0; x<sw; x++, o+=4, i++)
  583. gs[i]=(Bmp[2+o]*38+Bmp[1+o]*75+Bmp[o]*15)>>7;
  584. }
  585. for (i=0, y=0; y<sh; y++)
  586. for (x=0; x<sw; x++, i++)
  587. {
  588. if (x==0 || y==0 || x==sw-1 || y==sh-1)
  589. ss[i]=2;
  590. else
  591. {
  592. n=gs[i]+c;
  593. ss[i]=(gs[i-1]>n || gs[i+1]>n
  594. || gs[i-sw]>n || gs[i+sw]>n
  595. || gs[i-sw-1]>n || gs[i-sw+1]>n
  596. || gs[i+sw-1]>n || gs[i+sw+1]>n) ? 1:0;
  597. }
  598. }
  599. }
  600. else // (mode==3) 颜色分量二值化
  601. {
  602. rr=(c>>16)&0xFF; gg=(c>>8)&0xFF; bb=c&0xFF;
  603. r=(n>>16)&0xFF; g=(n>>8)&0xFF; b=n&0xFF;
  604. dR=r*r; dG=g*g; dB=b*b;
  605. for (y=0; y<sh; y++, o+=j)
  606. for (x=0; x<sw; x++, o+=4, i++)
  607. {
  608. r=Bmp[2+o]-rr; g=Bmp[1+o]-gg; b=Bmp[o]-bb;
  609. ss[i]=(r*r<=dR && g*g<=dG && b*b<=dB) ? 1:0;
  610. }
  611. }
  612. //----------------------
  613. StartLookUp:
  614. err1=len1*err1/10000;
  615. err0=len0*err0/10000;
  616. if (err1>=len1) len1=0;
  617. if (err0>=len0) len0=0;
  618. max=(len1>len0) ? len1 : len0;
  619. if (mode==5 || mode==4)
  620. {
  621. x1=sx; y1=sy; sx=0; sy=0;
  622. }
  623. else
  624. {
  625. x1=0; y1=0;
  626. }
  627. x2=x1+sw-new_w; y2=y1+sh-new_h;
  628. // 1 ==> ( Left to Right ) Top to Bottom
  629. // 2 ==> ( Right to Left ) Top to Bottom
  630. // 3 ==> ( Left to Right ) Bottom to Top
  631. // 4 ==> ( Right to Left ) Bottom to Top
  632. // 5 ==> ( Top to Bottom ) Left to Right
  633. // 6 ==> ( Bottom to Top ) Left to Right
  634. // 7 ==> ( Top to Bottom ) Right to Left
  635. // 8 ==> ( Bottom to Top ) Right to Left
  636. if (dir<1 || dir>8) dir=1;
  637. if (--dir>3) { r=y1; y1=x1; x1=r; r=y2; y2=x2; x2=r; }
  638. for (y3=y1; y3<=y2; y3++)
  639. {
  640. for (x3=x1; x3<=x2; x3++)
  641. {
  642. y=((dir&3)>1) ? y1+y2-y3 : y3;
  643. x=(dir&1) ? x1+x2-x3 : x3;
  644. if (dir>3) { r=y; y=x; x=r; }
  645. //----------------------
  646. e1=err1; e0=err0;
  647. if (mode==5)
  648. {
  649. o=y*Stride+x*4;
  650. if (k)
  651. {
  652. for (i=0; i<max; i++)
  653. {
  654. j=o+s1[i]; c=s0[i]; r=Bmp[2+j]-((c>>16)&0xFF);
  655. g=Bmp[1+j]-((c>>8)&0xFF); b=Bmp[j]-(c&0xFF);
  656. if ((r*r>dR || g*g>dG || b*b>dB) && (--e1)<0) goto NoMatch;
  657. }
  658. }
  659. else
  660. {
  661. for (i=0; i<max; i++)
  662. {
  663. j=o+s1[i]; rr=Bmp[2+j]; gg=Bmp[1+j]; bb=Bmp[j];
  664. for (j=i*21, n=s0[i]; j<n;)
  665. {
  666. c1=cors[j++]; c2=cors[j++];
  667. r=((c1>>16)&0xFF)-rr; g=((c1>>8)&0xFF)-gg; b=(c1&0xFF)-bb;
  668. dR=(c2>>16)&0xFF; dG=(c2>>8)&0xFF; dB=c2&0xFF;
  669. if ((r*r<=dR*dR && g*g<=dG*dG && b*b<=dB*dB)^(c1>0xFFFFFF))
  670. goto MatchOK;
  671. }
  672. if ((--e1)<0) goto NoMatch;
  673. MatchOK:;
  674. }
  675. }
  676. }
  677. else if (mode==4)
  678. {
  679. o=y*Stride+x*4;
  680. j=o+c; rr=Bmp[2+j]; gg=Bmp[1+j]; bb=Bmp[j];
  681. for (i=0; i<max; i++)
  682. {
  683. if (i<len1)
  684. {
  685. j=o+s1[i]; r=Bmp[2+j]-rr; g=Bmp[1+j]-gg; b=Bmp[j]-bb; v=r+rr+rr;
  686. if ((1024+v)*r*r+2048*g*g+(1534-v)*b*b>n && (--e1)<0) goto NoMatch;
  687. }
  688. if (i<len0)
  689. {
  690. j=o+s0[i]; r=Bmp[2+j]-rr; g=Bmp[1+j]-gg; b=Bmp[j]-bb; v=r+rr+rr;
  691. if ((1024+v)*r*r+2048*g*g+(1534-v)*b*b<=n && (--e0)<0) goto NoMatch;
  692. }
  693. }
  694. }
  695. else
  696. {
  697. o=y*sw+x;
  698. for (i=0; i<max; i++)
  699. {
  700. if (i<len1 && ss[o+s1[i]]==0 && (--e1)<0) goto NoMatch;
  701. if (i<len0 && ss[o+s0[i]]==1 && (--e0)<0) goto NoMatch;
  702. }
  703. // 清空已经找到的图像
  704. for (i=0; i<len1; i++)
  705. ss[o+s1[i]]=0;
  706. }
  707. ok++;
  708. if (allpos!=0)
  709. {
  710. allpos[ok-1]=(sy+y)<<16|(sx+x);
  711. if (ok>=allpos_max) goto Return1;
  712. }
  713. NoMatch:;
  714. }
  715. }
  716. //----------------------
  717. Return1:
  718. return ok;
  719. }
  720. )"
  721. }
  722. PicInfo(text)
  723. {
  724. static info:=Map(), bmp:=[]
  725. if !InStr(text, "$")
  726. return
  727. key:=(r:=StrLen(text))<10000 ? text
  728. : DllCall("ntdll\RtlComputeCrc32", "uint",0
  729. , "Ptr",StrPtr(text), "uint",r*2, "uint")
  730. if info.Has(key)
  731. return info[key]
  732. v:=text, comment:="", seterr:=err1:=err0:=0
  733. ; You Can Add Comment Text within The <>
  734. if RegExMatch(v, "<([^>\n]*)>", &r)
  735. v:=StrReplace(v,r[0]), comment:=Trim(r[1])
  736. ; You can Add two fault-tolerant in the [], separated by commas
  737. if RegExMatch(v, "\[([^\]\n]*)]", &r)
  738. {
  739. v:=StrReplace(v,r[0]), r:=StrSplit(r[1] ",", ",")
  740. , seterr:=1, err1:=r[1], err0:=r[2]
  741. }
  742. color:=SubStr(v,1,InStr(v,"$")-1), v:=Trim(SubStr(v,InStr(v,"$")+1))
  743. mode:=InStr(color,"##") ? 5
  744. : InStr(color,"#") ? 4 : InStr(color,"-") ? 3
  745. : InStr(color,"**") ? 2 : InStr(color,"*") ? 1 : 0
  746. color:=RegExReplace(color, "[*#\s]")
  747. (mode=0 || mode=3 || mode=5) && color:=StrReplace(color,"0x")
  748. if (mode=5)
  749. {
  750. if !(v~="/[\s\-\w]+/[\s\-\w,/]+$") ; FindPic
  751. {
  752. ; 你可以使用 Text:="|<>##DRDGDB-RRGGBB1-RRGGBB2... $ d:\a.bmp"
  753. ; 那么 0xRRGGBB1(+/-0xDRDGDB)... 都是透明色
  754. if !(hBM:=LoadPicture(v))
  755. return
  756. this.GetBitmapWH(hBM, &w, &h)
  757. if (w<1 || h<1)
  758. return
  759. hBM2:=this.CreateDIBSection(w, h, 32, &Scan0)
  760. this.CopyHBM(hBM2, 0, 0, hBM, 0, 0, w, h)
  761. DllCall("DeleteObject", "Ptr",hBM)
  762. if (!Scan0)
  763. return
  764. ; 所有用于 ImageSearch 的图片都缓存了
  765. StrReplace(color, "-",,, &n)
  766. bmp.Push(buf:=Buffer(w*h*4+n*4)), v:=buf.Ptr
  767. DllCall("RtlMoveMemory", "Ptr",v, "Ptr",Scan0, "Ptr",w*h*4)
  768. DllCall("DeleteObject", "Ptr",hBM2)
  769. p:=v+w*h*4-4, tab:=Map(), tab.CaseSense:="Off"
  770. , tab.Set("Black", "000000", "White", "FFFFFF"
  771. , "Red", "FF0000", "Green", "008000", "Blue", "0000FF"
  772. , "Yellow", "FFFF00", "Silver", "C0C0C0", "Gray", "808080"
  773. , "Teal", "008080", "Navy", "000080", "Aqua", "00FFFF"
  774. , "Olive", "808000", "Lime", "00FF00", "Fuchsia", "FF00FF"
  775. , "Purple", "800080", "Maroon", "800000")
  776. For k1,v1 in StrSplit(color, "-")
  777. if (k1>1)
  778. NumPut("uint", this.Floor("0x" (tab.Has(v1)?tab[v1]:v1)), p+=4)
  779. color:=this.Floor("0x" StrSplit(color "-", "-")[1])|0x1000000
  780. }
  781. else ; FindMultiColor or FindColor
  782. {
  783. ; Text:='|<>##DRDGDB $ 0/0/RRGGBB1-DRDGDB1/RRGGBB2/-RRGGBB3/-RRGGBB4, xn/yn/...'
  784. ; '##'之后的颜色 (0xDRDGDB) 是所有颜色的默认偏色(各个分量允许的变化值)
  785. ; 初始点 (0,0) 匹配 0xRRGGBB1(+/-0xDRDGDB1) 或者 0xRRGGBB2(+/-0xDRDGDB)
  786. ; 或者 非 0xRRGGBB3(+/-0xDRDGDB) 或者 非 0xRRGGBB4(+/-0xDRDGDB)
  787. ; 以 '-' 开头的颜色,表示除了这种颜色的其他的任何颜色都匹配
  788. ; 每个点可以允许匹配10组颜色 (xn/yn/RRGGBB1/.../RRGGBB10)
  789. arr:=StrSplit(Trim(RegExReplace(v, "i)\s|0x"), ","), ",")
  790. if !(n:=arr.Length)
  791. return
  792. bmp.Push(buf:=Buffer(n*(1+10+10)*4)), v:=buf.Ptr
  793. , color:=StrSplit(color "-", "-")[1]
  794. For k1,v1 in arr
  795. {
  796. r:=StrSplit(v1 "/", "/")
  797. , x:=this.Floor(r[1]), y:=this.Floor(r[2])
  798. , (A_Index=1) ? (x1:=x2:=x, y1:=y2:=y)
  799. : (x1:=Min(x1,x), x2:=Max(x2,x)
  800. , y1:=Min(y1,y), y2:=Max(y2,y))
  801. }
  802. w:=x2-x1+1, h:=y2-y1+1
  803. For k1,v1 in arr
  804. {
  805. r:=StrSplit(v1 "/", "/")
  806. , x:=this.Floor(r[1])-x1, y:=this.Floor(r[2])-y1
  807. , n1:=Min(Max(r.Length-3, 0), 10)
  808. , NumPut("uint", (y*w+x)<<4|n1, p:=v+(A_Index-1)*84)
  809. Loop n1
  810. k1:=(InStr(v1:=r[2+A_Index], "-")=1 ? 0x1000000:0)
  811. , c:=StrSplit(Trim(v1,"-") "-" color, "-")
  812. , NumPut("uint", this.Floor("0x" c[1])&0xFFFFFF|k1, p+=4)
  813. , NumPut("uint", this.Floor("0x" c[2]), p+=4)
  814. }
  815. color:=0
  816. }
  817. }
  818. else
  819. {
  820. r:=StrSplit(v ".", "."), w:=this.Floor(r[1])
  821. , v:=this.base64tobit(r[2]), h:=StrLen(v)//w
  822. if (w<1 || h<1 || StrLen(v)!=w*h)
  823. return
  824. if (mode=3)
  825. {
  826. r:=StrSplit(color, "-")
  827. , color:=this.Floor("0x" r[1]), n:=this.Floor("0x" r[2])
  828. }
  829. else
  830. {
  831. r:=StrSplit(color "@1", "@")
  832. , color:=this.Floor((mode=0?"0x":"") r[1]), n:=this.Floor(r[2])
  833. , n:=(n<=0||n>1?1:n), n:=Floor(4606*255*255*(1-n)*(1-n))
  834. , (mode=4) && color:=((color-1)//w)<<16|Mod(color-1,w)
  835. }
  836. }
  837. return info[key]:=[v, w, h, seterr, err1, err0, mode, color, n, comment]
  838. }
  839. GetBitsFromScreen(&x:=0, &y:=0, &w:=0, &h:=0
  840. , ScreenShot:=1, &zx:=0, &zy:=0, &zw:=0, &zh:=0)
  841. {
  842. static CAPTUREBLT:=""
  843. (!IsObject(this.bits) && this.bits:={Scan0:0, hBM:0, oldzw:0, oldzh:0})
  844. , bits:=this.bits
  845. if (!ScreenShot && bits.Scan0)
  846. {
  847. zx:=bits.zx, zy:=bits.zy, zw:=bits.zw, zh:=bits.zh
  848. , w:=Min(x+w,zx+zw), x:=Max(x,zx), w-=x
  849. , h:=Min(y+h,zy+zh), y:=Max(y,zy), h-=y
  850. return bits
  851. }
  852. cri:=A_IsCritical
  853. Critical
  854. if (id:=this.BindWindow(0,0,1))
  855. {
  856. id:=WinGetID("ahk_id " id)
  857. WinGetPos &zx, &zy, &zw, &zh, id
  858. }
  859. if (!id)
  860. zx:=SysGet(76), zy:=SysGet(77), zw:=SysGet(78), zh:=SysGet(79)
  861. this.UpdateBits(bits, zx, zy, zw, zh)
  862. , w:=Min(x+w,zx+zw), x:=Max(x,zx), w-=x
  863. , h:=Min(y+h,zy+zh), y:=Max(y,zy), h-=y
  864. if (!ScreenShot || w<1 || h<1 || !bits.hBM)
  865. {
  866. Critical(cri)
  867. return bits
  868. }
  869. if IsSet(GetBitsFromScreen2) && (GetBitsFromScreen2 is Func)
  870. && GetBitsFromScreen2(bits, x-zx, y-zy, w, h)
  871. {
  872. ; Each small range of data obtained from DXGI must be
  873. ; copied to the screenshot cache using this.CopyBits()
  874. zx:=bits.zx, zy:=bits.zy, zw:=bits.zw, zh:=bits.zh
  875. Critical(cri)
  876. return bits
  877. }
  878. if (CAPTUREBLT="") ; thanks Descolada
  879. {
  880. DllCall("Dwmapi\DwmIsCompositionEnabled", "Int*", &i:=0)
  881. CAPTUREBLT:=i ? 0 : 0x40000000
  882. }
  883. mDC:=DllCall("CreateCompatibleDC", "Ptr",0, "Ptr")
  884. oBM:=DllCall("SelectObject", "Ptr",mDC, "Ptr",bits.hBM, "Ptr")
  885. if (id)
  886. {
  887. if (mode:=this.BindWindow(0,0,0,1))<2
  888. {
  889. hDC:=DllCall("GetDCEx", "Ptr",id, "Ptr",0, "int",3, "Ptr")
  890. DllCall("BitBlt","Ptr",mDC,"int",x-zx,"int",y-zy,"int",w,"int",h
  891. , "Ptr",hDC, "int",x-zx, "int",y-zy, "uint",0xCC0020|CAPTUREBLT)
  892. DllCall("ReleaseDC", "Ptr",id, "Ptr",hDC)
  893. }
  894. else
  895. {
  896. hBM2:=this.CreateDIBSection(zw, zh)
  897. mDC2:=DllCall("CreateCompatibleDC", "Ptr",0, "Ptr")
  898. oBM2:=DllCall("SelectObject", "Ptr",mDC2, "Ptr",hBM2, "Ptr")
  899. DllCall("PrintWindow", "Ptr",id, "Ptr",mDC2, "uint",(mode>3)*3)
  900. DllCall("BitBlt","Ptr",mDC,"int",x-zx,"int",y-zy,"int",w,"int",h
  901. , "Ptr",mDC2, "int",x-zx, "int",y-zy, "uint",0xCC0020)
  902. DllCall("SelectObject", "Ptr",mDC2, "Ptr",oBM2)
  903. DllCall("DeleteDC", "Ptr",mDC2)
  904. DllCall("DeleteObject", "Ptr",hBM2)
  905. }
  906. }
  907. else
  908. {
  909. hDC:=DllCall("GetWindowDC","Ptr",id:=DllCall("GetDesktopWindow","Ptr"),"Ptr")
  910. DllCall("BitBlt","Ptr",mDC,"int",x-zx,"int",y-zy,"int",w,"int",h
  911. , "Ptr",hDC, "int",x, "int",y, "uint",0xCC0020|CAPTUREBLT)
  912. DllCall("ReleaseDC", "Ptr",id, "Ptr",hDC)
  913. }
  914. if this.CaptureCursor(0,0,0,0,0,1)
  915. this.CaptureCursor(mDC, zx, zy, zw, zh)
  916. DllCall("SelectObject", "Ptr",mDC, "Ptr",oBM)
  917. DllCall("DeleteDC", "Ptr",mDC)
  918. Critical(cri)
  919. return bits
  920. }
  921. UpdateBits(bits, zx, zy, zw, zh)
  922. {
  923. if (zw>bits.oldzw || zh>bits.oldzh || !bits.hBM)
  924. {
  925. Try DllCall("DeleteObject", "Ptr",bits.hBM)
  926. bits.hBM:=this.CreateDIBSection(zw, zh, bpp:=32, &ppvBits)
  927. , bits.Scan0:=(!bits.hBM ? 0:ppvBits)
  928. , bits.Stride:=((zw*bpp+31)//32)*4
  929. , bits.oldzw:=zw, bits.oldzh:=zh
  930. }
  931. bits.zx:=zx, bits.zy:=zy, bits.zw:=zw, bits.zh:=zh
  932. }
  933. CreateDIBSection(w, h, bpp:=32, &ppvBits:=0)
  934. {
  935. NumPut("int",40, "int",w, "int",-h, "short",1, "short",bpp, bi:=Buffer(40,0))
  936. return DllCall("CreateDIBSection", "Ptr",0, "Ptr",bi
  937. , "int",0, "Ptr*",&ppvBits:=0, "Ptr",0, "int",0, "Ptr")
  938. }
  939. GetBitmapWH(hBM, &w, &h)
  940. {
  941. bm:=Buffer(size:=(A_PtrSize=8 ? 32:24))
  942. , DllCall("GetObject", "Ptr",hBM, "int",size, "Ptr",bm)
  943. , w:=NumGet(bm,4,"int"), h:=Abs(NumGet(bm,8,"int"))
  944. }
  945. CopyHBM(hBM1, x1, y1, hBM2, x2, y2, w, h, Clear:=0, trans:=0, alpha:=255)
  946. {
  947. if (w<1 || h<1 || !hBM1 || !hBM2)
  948. return
  949. mDC1:=DllCall("CreateCompatibleDC", "Ptr",0, "Ptr")
  950. oBM1:=DllCall("SelectObject", "Ptr",mDC1, "Ptr",hBM1, "Ptr")
  951. mDC2:=DllCall("CreateCompatibleDC", "Ptr",0, "Ptr")
  952. oBM2:=DllCall("SelectObject", "Ptr",mDC2, "Ptr",hBM2, "Ptr")
  953. if (trans)
  954. DllCall("GdiAlphaBlend", "Ptr",mDC1, "int",x1, "int",y1, "int",w, "int",h
  955. , "Ptr",mDC2, "int",x2, "int",y2, "int",w, "int",h, "uint",alpha<<16)
  956. else
  957. DllCall("BitBlt", "Ptr",mDC1, "int",x1, "int",y1, "int",w, "int",h
  958. , "Ptr",mDC2, "int",x2, "int",y2, "uint",0xCC0020)
  959. if (Clear)
  960. DllCall("BitBlt", "Ptr",mDC1, "int",x1, "int",y1, "int",w, "int",h
  961. , "Ptr",mDC1, "int",x1, "int",y1, "uint",MERGECOPY:=0xC000CA)
  962. DllCall("SelectObject", "Ptr",mDC1, "Ptr",oBM1)
  963. DllCall("DeleteDC", "Ptr",mDC1)
  964. DllCall("SelectObject", "Ptr",mDC2, "Ptr",oBM2)
  965. DllCall("DeleteDC", "Ptr",mDC2)
  966. }
  967. CopyBits(Scan01,Stride1,x1,y1,Scan02,Stride2,x2,y2,w,h,Reverse:=0)
  968. {
  969. if (w<1 || h<1 || !Scan01 || !Scan02)
  970. return
  971. static init:="", MFCopyImage
  972. if (!init && init:=1)
  973. {
  974. MFCopyImage:=DllCall("GetProcAddress", "Ptr"
  975. , DllCall("LoadLibrary", "Str","Mfplat.dll", "Ptr")
  976. , "AStr","MFCopyImage", "Ptr")
  977. }
  978. if (MFCopyImage && !Reverse) ; thanks QQ:任性
  979. {
  980. return DllCall(MFCopyImage
  981. , "Ptr",Scan01+y1*Stride1+x1*4, "int",Stride1
  982. , "Ptr",Scan02+y2*Stride2+x2*4, "int",Stride2
  983. , "uint",w*4, "uint",h)
  984. }
  985. ListLines (lls:=A_ListLines)?0:0
  986. p1:=Scan01+(y1-1)*Stride1+x1*4
  987. , p2:=Scan02+(y2-1)*Stride2+x2*4, w*=4
  988. if (Reverse)
  989. p2+=(h+1)*Stride2, Stride2:=-Stride2
  990. Loop h
  991. DllCall("RtlMoveMemory","Ptr",p1+=Stride1,"Ptr",p2+=Stride2,"Ptr",w)
  992. ListLines lls
  993. }
  994. DrawHBM(hBM, lines)
  995. {
  996. mDC:=DllCall("CreateCompatibleDC", "Ptr",0, "Ptr")
  997. oBM:=DllCall("SelectObject", "Ptr",mDC, "Ptr",hBM, "Ptr")
  998. oldc:="", brush:=0, rect:=Buffer(16)
  999. For k,v in lines ; [ [x, y, w, h, color] ]
  1000. if IsObject(v)
  1001. {
  1002. if (oldc!=v[5])
  1003. {
  1004. oldc:=v[5], BGR:=(oldc&0xFF)<<16|oldc&0xFF00|(oldc>>16)&0xFF
  1005. DllCall("DeleteObject", "Ptr",brush)
  1006. brush:=DllCall("CreateSolidBrush", "UInt",BGR, "Ptr")
  1007. }
  1008. DllCall("SetRect", "Ptr",rect, "int",v[1], "int",v[2]
  1009. , "int",v[1]+v[3], "int",v[2]+v[4])
  1010. DllCall("FillRect", "Ptr",mDC, "Ptr",rect, "Ptr",brush)
  1011. }
  1012. DllCall("DeleteObject", "Ptr",brush)
  1013. DllCall("SelectObject", "Ptr",mDC, "Ptr",oBM)
  1014. DllCall("DeleteObject", "Ptr",mDC)
  1015. }
  1016. ; 绑定窗口从而可以后台查找这个窗口的图像
  1017. ; 相当于始终在前台。解绑窗口使用 FindText().BindWindow(0)
  1018. BindWindow(bind_id:=0, bind_mode:=0, get_id:=0, get_mode:=0)
  1019. {
  1020. (!IsObject(this.bind) && this.bind:={id:0, mode:0, oldStyle:0})
  1021. , bind:=this.bind
  1022. if (get_id)
  1023. return bind.id
  1024. if (get_mode)
  1025. return bind.mode
  1026. if (bind_id)
  1027. {
  1028. bind.id:=bind_id:=this.Floor(bind_id)
  1029. , bind.mode:=bind_mode, bind.oldStyle:=0
  1030. if (bind_mode & 1)
  1031. {
  1032. i:=WinGetExStyle(bind_id)
  1033. bind.oldStyle:=i
  1034. WinSetTransparent(255, bind_id)
  1035. Loop 30
  1036. {
  1037. Sleep 100
  1038. i:=WinGetTransparent(bind_id)
  1039. }
  1040. Until (i=255)
  1041. }
  1042. }
  1043. else
  1044. {
  1045. bind_id:=bind.id
  1046. if (bind.mode & 1)
  1047. WinSetExStyle(bind.oldStyle, bind_id)
  1048. bind.id:=0, bind.mode:=0, bind.oldStyle:=0
  1049. }
  1050. }
  1051. ; 使用 FindText().CaptureCursor(1) 设置抓图时捕获鼠标
  1052. ; 使用 FindText().CaptureCursor(0) 取消抓图时捕获鼠标
  1053. CaptureCursor(hDC:=0, zx:=0, zy:=0, zw:=0, zh:=0, get_cursor:=0)
  1054. {
  1055. if (get_cursor)
  1056. return this.Cursor
  1057. if (hDC=1 || hDC=0) && (zw=0)
  1058. {
  1059. this.Cursor:=hDC
  1060. return
  1061. }
  1062. mi:=Buffer(40, 0), NumPut("int", 16+A_PtrSize, mi)
  1063. DllCall("GetCursorInfo", "Ptr",mi)
  1064. bShow:=NumGet(mi, 4, "int")
  1065. hCursor:=NumGet(mi, 8, "Ptr")
  1066. x:=NumGet(mi, 8+A_PtrSize, "int")
  1067. y:=NumGet(mi, 12+A_PtrSize, "int")
  1068. if (!bShow) || (x<zx || y<zy || x>=zx+zw || y>=zy+zh)
  1069. return
  1070. ni:=Buffer(40, 0)
  1071. DllCall("GetIconInfo", "Ptr",hCursor, "Ptr",ni)
  1072. xCenter:=NumGet(ni, 4, "int")
  1073. yCenter:=NumGet(ni, 8, "int")
  1074. hBMMask:=NumGet(ni, (A_PtrSize=8?16:12), "Ptr")
  1075. hBMColor:=NumGet(ni, (A_PtrSize=8?24:16), "Ptr")
  1076. DllCall("DrawIconEx", "Ptr",hDC
  1077. , "int",x-xCenter-zx, "int",y-yCenter-zy, "Ptr",hCursor
  1078. , "int",0, "int",0, "int",0, "int",0, "int",3)
  1079. DllCall("DeleteObject", "Ptr",hBMMask)
  1080. DllCall("DeleteObject", "Ptr",hBMColor)
  1081. }
  1082. MCode(&code, hex)
  1083. {
  1084. flag:=((hex~="[^\s\da-fA-F]")?1:4), hex:=RegExReplace(hex, "[\s=]")
  1085. , code:=Buffer(len:=(flag=1 ? StrLen(hex)//4*3+3 : StrLen(hex)//2))
  1086. DllCall("crypt32\CryptStringToBinary", "Str",hex, "uint",0
  1087. , "uint",flag, "Ptr",code, "uint*",&len, "Ptr",0, "Ptr",0)
  1088. DllCall("VirtualProtect", "Ptr",code, "Ptr",len, "uint",0x40, "Ptr*",0)
  1089. }
  1090. bin2hex(addr, size, base64:=1)
  1091. {
  1092. flag:=(base64 ? 1|0x40000000 : 4|0x0000000C)
  1093. Loop 2
  1094. p:=(A_Index=1 ? 0 : Buffer(len*2))
  1095. , DllCall("Crypt32\CryptBinaryToString", "Ptr",addr, "uint",size
  1096. , "uint",flag, "Ptr",p, "uint*",&len:=0)
  1097. return RegExReplace(StrGet(p, len), "\s+")
  1098. }
  1099. base64tobit(s)
  1100. {
  1101. ListLines (lls:=A_ListLines)?0:0
  1102. static Chars:="0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
  1103. Loop Parse, Chars
  1104. if InStr(s, A_LoopField, 1)
  1105. s:=StrReplace(s, A_LoopField, ((i:=A_Index-1)>>5&1)
  1106. . (i>>4&1) . (i>>3&1) . (i>>2&1) . (i>>1&1) . (i&1), 1)
  1107. s:=RegExReplace(RegExReplace(s,"[^01]+"),"10*$")
  1108. ListLines lls
  1109. return s
  1110. }
  1111. bit2base64(s)
  1112. {
  1113. ListLines (lls:=A_ListLines)?0:0
  1114. s:=RegExReplace(s,"[^01]+")
  1115. s.=SubStr("100000",1,6-Mod(StrLen(s),6))
  1116. s:=RegExReplace(s,".{6}","|$0")
  1117. Chars:="0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
  1118. Loop Parse, Chars
  1119. s:=StrReplace(s, "|" . ((i:=A_Index-1)>>5&1)
  1120. . (i>>4&1) . (i>>3&1) . (i>>2&1) . (i>>1&1) . (i&1), A_LoopField)
  1121. ListLines lls
  1122. return s
  1123. }
  1124. ASCII(s)
  1125. {
  1126. if RegExMatch(s, "\$(\d+)\.([\w+/]+)", &r)
  1127. {
  1128. s:=RegExReplace(this.base64tobit(r[2]),".{" r[1] "}","$0`n")
  1129. s:=StrReplace(StrReplace(s,"0","_"),"1","0")
  1130. }
  1131. else s:=""
  1132. return s
  1133. }
  1134. ; 可以在脚本的开头用 FindText().PicLib(Text,1) 导入字库,
  1135. ; 然后使用 FindText().PicLib("说明文字1|说明文字2|...") 获取字库中的数据
  1136. PicLib(comments, add_to_Lib:=0, index:=1)
  1137. {
  1138. (!IsObject(this.Lib) && this.Lib:=Map()), Lib:=this.Lib
  1139. , (!Lib.Has(index) && Lib[index]:=Map()), Lib:=Lib[index]
  1140. if (add_to_Lib)
  1141. {
  1142. re:="<([^>\n]*)>[^$\n]+\$[^`"'\r\n]+"
  1143. Loop Parse, comments, "|"
  1144. if RegExMatch(A_LoopField, re, &r)
  1145. {
  1146. s1:=Trim(r[1]), s2:=""
  1147. Loop Parse, s1
  1148. s2.="_" . Format("{:d}",Ord(A_LoopField))
  1149. Lib[s2]:=r[0]
  1150. }
  1151. Lib[""]:=""
  1152. }
  1153. else
  1154. {
  1155. Text:=""
  1156. Loop Parse, comments, "|"
  1157. {
  1158. s1:=Trim(A_LoopField), s2:=""
  1159. Loop Parse, s1
  1160. s2.="_" . Format("{:d}",Ord(A_LoopField))
  1161. if Lib.Has(s2)
  1162. Text.="|" . Lib[s2]
  1163. }
  1164. return Text
  1165. }
  1166. }
  1167. ; 分割字符串为单个文字并获取数据
  1168. PicN(Number, index:=1)
  1169. {
  1170. return this.PicLib(RegExReplace(Number,".","|$0"), 0, index)
  1171. }
  1172. ; 使用 FindText().PicX(Text) 可以将文字分割成多个单字的组合,从而适应间隔变化
  1173. ; 但是不能用于“颜色位置二值化”模式, 因为位置是与整体图像相关的
  1174. PicX(Text)
  1175. {
  1176. if !RegExMatch(Text, "(<[^$\n]+)\$(\d+)\.([\w+/]+)", &r)
  1177. return Text
  1178. v:=this.base64tobit(r[3]), Text:=""
  1179. c:=StrLen(StrReplace(v,"0"))<=StrLen(v)//2 ? "1":"0"
  1180. txt:=RegExReplace(v,".{" r[2] "}","$0`n")
  1181. While InStr(txt,c)
  1182. {
  1183. While !(txt~="m`n)^" c)
  1184. txt:=RegExReplace(txt,"m`n)^.")
  1185. i:=0
  1186. While (txt~="m`n)^.{" i "}" c)
  1187. i:=Format("{:d}",i+1)
  1188. v:=RegExReplace(txt,"m`n)^(.{" i "}).*","$1")
  1189. txt:=RegExReplace(txt,"m`n)^.{" i "}")
  1190. if (v!="")
  1191. Text.="|" r[1] "$" i "." this.bit2base64(v)
  1192. }
  1193. return Text
  1194. }
  1195. ; 截屏,作为后续操作要用的“上一次的截屏”
  1196. ScreenShot(x1:=0, y1:=0, x2:=0, y2:=0)
  1197. {
  1198. this.FindText(,, x1, y1, x2, y2)
  1199. }
  1200. ; 从“上一次的截屏”中快速获取指定坐标的RGB颜色
  1201. ; 如果坐标超出了屏幕范围,将返回白色
  1202. GetColor(x, y, fmt:=1)
  1203. {
  1204. bits:=this.GetBitsFromScreen(,,,,0,&zx,&zy,&zw,&zh)
  1205. , c:=(x<zx || x>=zx+zw || y<zy || y>=zy+zh || !bits.Scan0)
  1206. ? 0xFFFFFF : NumGet(bits.Scan0+(y-zy)*bits.Stride+(x-zx)*4,"uint")
  1207. return (fmt ? Format("0x{:06X}",c&0xFFFFFF) : c)
  1208. }
  1209. ; 在“上一次的截屏”中设置点的RGB颜色
  1210. SetColor(x, y, color:=0x000000)
  1211. {
  1212. bits:=this.GetBitsFromScreen(,,,,0,&zx,&zy,&zw,&zh)
  1213. if !(x<zx || x>=zx+zw || y<zy || y>=zy+zh || !bits.Scan0)
  1214. NumPut("uint", color, bits.Scan0+(y-zy)*bits.Stride+(x-zx)*4)
  1215. }
  1216. ; 根据 FindText() 的结果识别一行文字或验证码
  1217. ; offsetX 为两个文字的最大间隔,超过会插入*号
  1218. ; offsetY 为两个文字的最大高度差
  1219. ; overlapW 用于设置覆盖的宽度
  1220. ; 最后返回数组:{text:识别结果, x:结果左上角X, y:结果左上角Y, w:宽, h:高}
  1221. Ocr(ok, offsetX:=20, offsetY:=20, overlapW:=0)
  1222. {
  1223. ocr_Text:=ocr_X:=ocr_Y:=min_X:=dx:=""
  1224. For k,v in ok
  1225. x:=v.1
  1226. , min_X:=(A_Index=1 || x<min_X ? x : min_X)
  1227. , max_X:=(A_Index=1 || x>max_X ? x : max_X)
  1228. While (min_X!="" && min_X<=max_X)
  1229. {
  1230. LeftX:=""
  1231. For k,v in ok
  1232. {
  1233. x:=v.1, y:=v.2
  1234. if (x<min_X) || (ocr_Y!="" && Abs(y-ocr_Y)>offsetY)
  1235. Continue
  1236. ; Get the leftmost X coordinates
  1237. if (LeftX="" || x<LeftX)
  1238. LeftX:=x, LeftY:=y, LeftW:=v.3, LeftH:=v.4, LeftOCR:=v.id
  1239. }
  1240. if (LeftX="")
  1241. Break
  1242. if (ocr_X="")
  1243. ocr_X:=LeftX, min_Y:=LeftY, max_Y:=LeftY+LeftH
  1244. ; If the interval exceeds the set value, add "*" to the result
  1245. ocr_Text.=(ocr_Text!="" && LeftX>dx ? "*":"") . LeftOCR
  1246. ; Update for next search
  1247. min_X:=LeftX+LeftW-(overlapW>LeftW//2 ? LeftW//2:overlapW)
  1248. , dx:=LeftX+LeftW+offsetX, ocr_Y:=LeftY
  1249. , (LeftY<min_Y && min_Y:=LeftY)
  1250. , (LeftY+LeftH>max_Y && max_Y:=LeftY+LeftH)
  1251. }
  1252. if (ocr_X="")
  1253. ocr_X:=0, min_Y:=0, min_X:=0, max_Y:=0
  1254. return {text:ocr_Text, x:ocr_X, y:min_Y
  1255. , w: min_X-ocr_X, h: max_Y-min_Y}
  1256. }
  1257. ; 按照从左到右、从上到下的顺序排序FindText()的结果
  1258. ; 忽略轻微的Y坐标差距,返回排序后的数组对象
  1259. Sort(ok, dy:=10)
  1260. {
  1261. if !IsObject(ok)
  1262. return ok
  1263. s:="", n:=150000, ypos:=[]
  1264. For k,v in ok
  1265. {
  1266. x:=v.x, y:=v.y, add:=1
  1267. For k1,v1 in ypos
  1268. if Abs(y-v1)<=dy
  1269. {
  1270. y:=v1, add:=0
  1271. Break
  1272. }
  1273. if (add)
  1274. ypos.Push(y)
  1275. s.=(y*n+x) "." k "|"
  1276. }
  1277. s:=Sort(Trim(s,"|"), "N D|")
  1278. ok2:=[]
  1279. Loop Parse, s, "|"
  1280. ok2.Push( ok[StrSplit(A_LoopField,".")[2]] )
  1281. return ok2
  1282. }
  1283. ; 以指定点为中心,按从近到远排序FindText()的结果,返回排序后的数组
  1284. Sort2(ok, px, py)
  1285. {
  1286. if !IsObject(ok)
  1287. return ok
  1288. s:=""
  1289. For k,v in ok
  1290. s.=((v.x-px)**2+(v.y-py)**2) "." k "|"
  1291. s:=Sort(Trim(s,"|"), "N D|")
  1292. ok2:=[]
  1293. Loop Parse, s, "|"
  1294. ok2.Push( ok[StrSplit(A_LoopField,".")[2]] )
  1295. return ok2
  1296. }
  1297. ; 按指定的查找方向,排序FindText()的结果,返回排序后的数组
  1298. Sort3(ok, dir:=1)
  1299. {
  1300. if !IsObject(ok)
  1301. return ok
  1302. s:="", n:=150000
  1303. For k,v in ok
  1304. x:=v.1, y:=v.2
  1305. , s.=(dir=1 ? y*n+x
  1306. : dir=2 ? y*n-x
  1307. : dir=3 ? -y*n+x
  1308. : dir=4 ? -y*n-x
  1309. : dir=5 ? x*n+y
  1310. : dir=6 ? x*n-y
  1311. : dir=7 ? -x*n+y
  1312. : dir=8 ? -x*n-y : y*n+x) "." k "|"
  1313. s:=Sort(Trim(s,"|"), "N D|")
  1314. ok2:=[]
  1315. Loop Parse, s, "|"
  1316. ok2.Push( ok[StrSplit(A_LoopField,".")[2]] )
  1317. return ok2
  1318. }
  1319. ; 提示某个坐标的位置,或远程控制中当前鼠标的位置
  1320. MouseTip(x:="", y:="", w:=10, h:=10, d:=3)
  1321. {
  1322. if (x="")
  1323. {
  1324. pt:=Buffer(16,0), DllCall("GetCursorPos", "Ptr",pt)
  1325. x:=NumGet(pt,0,"uint"), y:=NumGet(pt,4,"uint")
  1326. }
  1327. Loop 4
  1328. {
  1329. this.RangeTip(x-w, y-h, 2*w+1, 2*h+1, (A_Index & 1 ? "Red":"Blue"), d)
  1330. Sleep 500
  1331. }
  1332. this.RangeTip()
  1333. }
  1334. ; 显示范围的边框,类似于 ToolTip
  1335. RangeTip(x:="", y:="", w:="", h:="", color:="Red", d:=3)
  1336. {
  1337. static Range:=Map()
  1338. if (x="")
  1339. {
  1340. Loop 4
  1341. if (Range.Has(i:=A_Index) && Range[i])
  1342. Range[i].Destroy(), Range[i]:=0
  1343. return
  1344. }
  1345. if !(Range.Has(1) && Range[1])
  1346. {
  1347. Loop 4
  1348. Range[A_Index]:=Gui("+AlwaysOnTop -Caption +ToolWindow -DPIScale +E0x08000000")
  1349. }
  1350. x:=(IsNumBer(x)?x:0), y:=(IsNumBer(y)?y:0)
  1351. , w:=(IsNumBer(w)?w:0), h:=(IsNumBer(h)?h:0), d:=(IsNumBer(d)?d:0)
  1352. Loop 4
  1353. {
  1354. i:=A_Index
  1355. , x1:=(i=2 ? x+w : x-d)
  1356. , y1:=(i=3 ? y+h : y-d)
  1357. , w1:=(i=1 || i=3 ? w+2*d : d)
  1358. , h1:=(i=2 || i=4 ? h+2*d : d)
  1359. Range[i].BackColor:=color
  1360. Range[i].Show("NA x" x1 " y" y1 " w" w1 " h" h1)
  1361. }
  1362. }
  1363. ; 用鼠标左右键选取屏幕范围
  1364. GetRange(ww:=25, hh:=8, key:="RButton")
  1365. {
  1366. static Gui_Off:="", hk, FindText_HotkeyIf:=""
  1367. if (!Gui_Off)
  1368. Gui_Off:=this.GetRange.Bind(this, "Off")
  1369. if (ww="Off")
  1370. return hk:=Trim(A_ThisHotkey, "*")
  1371. ;---------------------
  1372. Try FindText_HotkeyIf.Destroy()
  1373. FindText_HotkeyIf:=_Gui:=Gui()
  1374. _Gui.Opt "-Caption +ToolWindow +E0x80000"
  1375. _Gui.Title:="FindText_HotkeyIf"
  1376. _Gui.Show "NA x0 y0 w0 h0"
  1377. ;---------------------
  1378. HotIfWinExist "FindText_HotkeyIf"
  1379. keys:=key "|Up|Down|Left|Right"
  1380. For k,v in StrSplit(keys, "|")
  1381. {
  1382. KeyWait v
  1383. Try Hotkey "*" v, Gui_Off, "On"
  1384. }
  1385. KeyWait "Ctrl"
  1386. HotIfWinExist
  1387. ;---------------------
  1388. Critical (cri:=A_IsCritical)?"Off":"Off"
  1389. CoordMode "Mouse"
  1390. tip:=this.Lang("s5")
  1391. hk:="", oldx:=oldy:="", keydown:=0
  1392. Loop
  1393. {
  1394. Sleep 50
  1395. MouseGetPos &x, &y
  1396. if (hk=key) || GetKeyState(key,"P") || GetKeyState("Ctrl","P")
  1397. {
  1398. keydown++
  1399. if (keydown=1)
  1400. MouseGetPos &x1, &y1, &Bind_ID
  1401. KeyWait key
  1402. KeyWait "Ctrl"
  1403. hk:=""
  1404. if (keydown>1)
  1405. Break
  1406. }
  1407. else if (hk="Up") || GetKeyState("Up","P")
  1408. (hh>1 && hh--), hk:=""
  1409. else if (hk="Down") || GetKeyState("Down","P")
  1410. hh++, hk:=""
  1411. else if (hk="Left") || GetKeyState("Left","P")
  1412. (ww>1 && ww--), hk:=""
  1413. else if (hk="Right") || GetKeyState("Right","P")
  1414. ww++, hk:=""
  1415. this.RangeTip((keydown?x1:x)-ww, (keydown?y1:y)-hh
  1416. , 2*ww+1, 2*hh+1, (A_MSec<500?"Red":"Blue"))
  1417. if (oldx=x && oldy=y)
  1418. Continue
  1419. oldx:=x, oldy:=y
  1420. ToolTip "x: " (keydown?x1:x) " y: " (keydown?y1:y) "`n" tip
  1421. }
  1422. ToolTip
  1423. this.RangeTip()
  1424. HotIfWinExist "FindText_HotkeyIf"
  1425. For k,v in StrSplit(keys, "|")
  1426. Try Hotkey "*" v, Gui_Off, "Off"
  1427. HotIfWinExist
  1428. FindText_HotkeyIf.Destroy
  1429. Critical(cri)
  1430. return [x1-ww, y1-hh, x1+ww, y1+hh, Bind_ID]
  1431. }
  1432. ; 截屏到剪贴板或者文件,或者仅获取范围
  1433. SnapShot(ScreenShot:=1, key:="LButton")
  1434. {
  1435. static Gui_Off:="", hk, SnapShot_HotkeyIf:="", SnapShot_Box:=""
  1436. if (!Gui_Off)
  1437. Gui_Off:=this.SnapShot.Bind(this, "Off")
  1438. if (ScreenShot="Off")
  1439. return hk:=Trim(A_ThisHotkey, "*")
  1440. n:=150000, x:=y:=-n, w:=h:=2*n
  1441. hBM:=this.BitmapFromScreen(&x,&y,&w,&h,ScreenShot,&zx,&zy,&zw,&zh)
  1442. ;---------------
  1443. Try SnapShot_HotkeyIf.Destroy() ; WS_EX_NOACTIVATE:=0x08000000
  1444. SnapShot_HotkeyIf:=_Gui:=Gui()
  1445. _Gui.Opt "+AlwaysOnTop -Caption +ToolWindow -DPIScale +E0x08000000"
  1446. _Gui.MarginX:=0, _Gui.MarginY:=0
  1447. _Gui.Add "Pic", "w" zw " h" zh, "HBITMAP:*" hBM
  1448. _Gui.Title:="SnapShot_HotkeyIf"
  1449. _Gui.Show "NA x" zx " y" zy " w" zw " h" zh
  1450. ;---------------
  1451. Try SnapShot_Box.Destroy()
  1452. SnapShot_Box:=_Gui:=Gui()
  1453. _Gui.Opt "+AlwaysOnTop -Caption +ToolWindow -DPIScale +E0x08000000"
  1454. box_id:=_Gui.Hwnd
  1455. _Gui.MarginX:=0, _Gui.MarginY:=0
  1456. _Gui.SetFont "s12"
  1457. For k,v in StrSplit(this.Lang("s15"), "|")
  1458. id:=_Gui.Add("Button", (k=1?"":"x+0"), v)
  1459. id.GetPos(&pX, &pY, &pW, &pH)
  1460. box_w:=pX+pW+10, box_h:=pH+10
  1461. _Gui.Title:="SnapShot_Box"
  1462. _Gui.Show "Hide"
  1463. ;---------------
  1464. HotIfWinExist "SnapShot_HotkeyIf"
  1465. keys:=key "|RButton|Esc|Up|Down|Left|Right"
  1466. For k,v in StrSplit(keys, "|")
  1467. {
  1468. KeyWait v
  1469. Try Hotkey "*" v, Gui_Off, "On"
  1470. }
  1471. HotIfWinExist
  1472. ;---------------
  1473. Critical (cri:=A_IsCritical)?"Off":"Off"
  1474. CoordMode "Mouse"
  1475. Loop
  1476. { ;// For ReTry
  1477. tip:=this.Lang("s16")
  1478. hk:="", oldx:=oldy:="", ok:=0, d:=10, oldt:=0, oldf:=""
  1479. x:=y:=w:=h:=0
  1480. Loop
  1481. {
  1482. Sleep 50
  1483. if (hk="RButton") || (hk="Esc") || GetKeyState("RButton","P") || GetKeyState("Esc","P")
  1484. Break 2
  1485. MouseGetPos &x1, &y1
  1486. if (oldx=x1 && oldy=y1)
  1487. Continue
  1488. oldx:=x1, oldy:=y1
  1489. ToolTip "x: " x1 " y: " y1 " w: 0 h: 0`n" tip
  1490. }
  1491. Until (hk=key) || GetKeyState(key,"P")
  1492. Loop
  1493. {
  1494. Sleep 50
  1495. MouseGetPos &x2, &y2
  1496. x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x1-x2)+1, h:=Abs(y1-y2)+1
  1497. this.RangeTip(x, y, w, h, (A_MSec<500 ? "Red":"Blue"))
  1498. if (oldx=x2 && oldy=y2)
  1499. Continue
  1500. oldx:=x2, oldy:=y2
  1501. ToolTip "x: " x " y: " y " w: " w " h: " h "`n" tip
  1502. }
  1503. Until !GetKeyState(key,"P")
  1504. hk:=""
  1505. Loop
  1506. {
  1507. Sleep 50
  1508. MouseGetPos &x3, &y3
  1509. x1:=x, y1:=y, x2:=x+w-1, y2:=y+h-1
  1510. , d1:=Abs(x3-x1)<=d, d2:=Abs(x3-x2)<=d
  1511. , d3:=Abs(y3-y1)<=d, d4:=Abs(y3-y2)<=d
  1512. , d5:=x3>x1+d && x3<x2-d, d6:=y3>y1+d && y3<y2-d
  1513. , f:=(d1 && d3 ? 1 : d2 && d3 ? 2 : d1 && d4 ? 3
  1514. : d2 && d4 ? 4 : d5 && d3 ? 5 : d5 && d4 ? 6
  1515. : d6 && d1 ? 7 : d6 && d2 ? 8 : d5 && d6 ? 9 : 0)
  1516. if (oldf!=f)
  1517. oldf:=f, this.SetCursor(f=1 || f=4 ? "SIZENWSE"
  1518. : f=2 || f=3 ? "SIZENESW" : f=5 || f=6 ? "SIZENS"
  1519. : f=7 || f=8 ? "SIZEWE" : f=9 ? "SIZEALL" : "ARROW")
  1520. ;--------------
  1521. if (hk="Up") || GetKeyState("Up","P")
  1522. hk:="", y--
  1523. else if (hk="Down") || GetKeyState("Down","P")
  1524. hk:="", y++
  1525. else if (hk="Left") || GetKeyState("Left","P")
  1526. hk:="", x--
  1527. else if (hk="Right") || GetKeyState("Right","P")
  1528. hk:="", x++
  1529. else if (hk="RButton") || (hk="Esc") || GetKeyState("RButton","P") || GetKeyState("Esc","P")
  1530. Break
  1531. else if (hk=key) || GetKeyState(key,"P")
  1532. {
  1533. MouseGetPos(,, &id, &mc)
  1534. if (id=box_id) && (mc="Button1")
  1535. {
  1536. KeyWait key
  1537. this.RangeTip(), this.SetCursor()
  1538. SnapShot_Box.Hide
  1539. Continue 2
  1540. }
  1541. if (id=box_id) && (ok:=mc="Button2" ? 2 : mc="Button4" ? 1:100)
  1542. Break
  1543. SnapShot_Box.Hide
  1544. ToolTip
  1545. Loop
  1546. {
  1547. Sleep 50
  1548. MouseGetPos &x4, &y4
  1549. x1:=x, y1:=y, x2:=x+w-1, y2:=y+h-1, dx:=x4-x3, dy:=y4-y3
  1550. , (f=1 ? (x1+=dx, y1+=dy) : f=2 ? (x2+=dx, y1+=dy)
  1551. : f=3 ? (x1+=dx, y2+=dy) : f=4 ? (x2+=dx, y2+=dy)
  1552. : f=5 ? y1+=dy : f=6 ? y2+=dy : f=7 ? x1+=dx : f=8 ? x2+=dx
  1553. : f=9 ? (x1+=dx, y1+=dy, x2+=dx, y2+=dy) : 0)
  1554. , (f ? this.RangeTip(Min(x1,x2), Min(y1,y2), Abs(x1-x2)+1, Abs(y1-y2)+1
  1555. , (A_MSec<500 ? "Red":"Blue")) : 0)
  1556. }
  1557. Until !GetKeyState(key,"P")
  1558. hk:="", x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x1-x2)+1, h:=Abs(y1-y2)+1
  1559. if (f=9) && Abs(dx)<2 && Abs(dy)<2 && (ok:=(-oldt)+(oldt:=A_TickCount)<400)
  1560. Break
  1561. }
  1562. this.RangeTip(x, y, w, h, (A_MSec<500 ? "Red":"Blue"))
  1563. x1:=x+w-box_w, (x1<10 && x1:=10), (x1>zx+zw-box_w && x1:=zx+zw-box_w)
  1564. , y1:=y+h+10, (y1>zy+zh-box_h && y1:=y-box_h), (y1<10 && y1:=10)
  1565. SnapShot_Box.Show "NA x" x1 " y" y1
  1566. ;-------------
  1567. if (oldx=x3 && oldy=y3)
  1568. Continue
  1569. oldx:=x3, oldy:=y3
  1570. ToolTip "x: " x " y: " y " w: " w " h: " h "`n" tip
  1571. }
  1572. Break
  1573. } ;// For ReTry
  1574. HotIfWinExist "SnapShot_HotkeyIf"
  1575. For k,v in StrSplit(keys, "|")
  1576. {
  1577. KeyWait v
  1578. Try Hotkey "*" v, Gui_Off, "Off"
  1579. }
  1580. HotIfWinExist
  1581. ToolTip
  1582. this.RangeTip()
  1583. this.SetCursor()
  1584. SnapShot_Box.Destroy
  1585. SnapShot_HotkeyIf.Destroy
  1586. Critical(cri)
  1587. ;---------------
  1588. w:=Min(x+w,zx+zw), x:=Max(x,zx), w-=x
  1589. h:=Min(y+h,zy+zh), y:=Max(y,zy), h-=y
  1590. if (ok=1)
  1591. this.SaveBitmapToFile(0, hBM, x-zx, y-zy, w, h)
  1592. else if (ok=2)
  1593. {
  1594. f:=FileSelect("S18", A_Desktop "\1.bmp", "SaveAs", "Image (*.bmp)")
  1595. this.SaveBitmapToFile(f, hBM, x-zx, y-zy, w, h)
  1596. }
  1597. DllCall("DeleteObject", "Ptr",hBM)
  1598. return [x, y, x+w-1, y+h-1]
  1599. }
  1600. SetCursor(cursor:="", *)
  1601. {
  1602. static init:=0, tab:=Map()
  1603. if (!init && init:=1)
  1604. {
  1605. OnExit(this.SetCursor.Bind(this,"")), this.SetCursor()
  1606. s:="ARROW,32512, SIZENWSE,32642, SIZENESW,32643"
  1607. . ", SIZEWE,32644, SIZENS,32645, SIZEALL,32646"
  1608. . ", IBEAM,32513, WAIT,32514, CROSS,32515, UPARROW,32516"
  1609. . ", NO,32648, HAND,32649, APPSTARTING,32650, HELP,32651"
  1610. For i,v in StrSplit(s, ",", " ")
  1611. (i&1) ? (k:=v) : (tab[k]:=DllCall("CopyImage", "Ptr"
  1612. , DllCall("LoadCursor", "Ptr",0, "Ptr",v, "Ptr")
  1613. , "int",2, "int",0, "int",0, "int",0, "Ptr"))
  1614. }
  1615. if (cursor!="") && tab.Has(cursor)
  1616. DllCall("SetSystemCursor", "Ptr", DllCall("CopyImage", "Ptr",tab[cursor]
  1617. , "int",2, "int",0, "int",0, "int",0, "Ptr"), "int",32512)
  1618. else
  1619. DllCall("SystemParametersInfo", "int",0x57, "int",0, "Ptr",0, "int",0)
  1620. }
  1621. BitmapFromScreen(&x:=0, &y:=0, &w:=0, &h:=0
  1622. , ScreenShot:=1, &zx:=0, &zy:=0, &zw:=0, &zh:=0)
  1623. {
  1624. bits:=this.GetBitsFromScreen(&x,&y,&w,&h,ScreenShot,&zx,&zy,&zw,&zh)
  1625. if (w<1 || h<1 || !bits.hBM)
  1626. return
  1627. hBM:=this.CreateDIBSection(w, h)
  1628. this.CopyHBM(hBM, 0, 0, bits.hBM, x-zx, y-zy, w, h, 1)
  1629. return hBM
  1630. }
  1631. ; 快速保存截图为BMP文件,可用于调试
  1632. ; 如果 file = 0 或 "" ,会保存到剪贴板
  1633. SavePic(file:=0, x1:=0, y1:=0, x2:=0, y2:=0, ScreenShot:=1)
  1634. {
  1635. x1:=this.Floor(x1), y1:=this.Floor(y1), x2:=this.Floor(x2), y2:=this.Floor(y2)
  1636. if (x1=0 && y1=0 && x2=0 && y2=0)
  1637. n:=150000, x:=y:=-n, w:=h:=2*n
  1638. else
  1639. x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x2-x1)+1, h:=Abs(y2-y1)+1
  1640. hBM:=this.BitmapFromScreen(&x, &y, &w, &h, ScreenShot)
  1641. this.SaveBitmapToFile(file, hBM)
  1642. DllCall("DeleteObject", "Ptr",hBM)
  1643. }
  1644. ; 保存图像到文件,如果 file = 0 或者 "",保存到剪贴板
  1645. ; 参数可以是位图句柄或者文件路径,例如: "c:\a.bmp"
  1646. SaveBitmapToFile(file, hBM_or_file, x:=0, y:=0, w:=0, h:=0)
  1647. {
  1648. if IsNumber(hBM_or_file)
  1649. hBM_or_file:="HBITMAP:*" hBM_or_file
  1650. if !hBM:=DllCall("CopyImage", "Ptr",LoadPicture(hBM_or_file)
  1651. , "int",0, "int",0, "int",0, "uint",0x2008)
  1652. return
  1653. if (file) || (w!=0 && h!=0)
  1654. {
  1655. (w=0 || h=0) && this.GetBitmapWH(hBM, &w, &h)
  1656. hBM2:=this.CreateDIBSection(w, -h, bpp:=(file ? 24 : 32))
  1657. this.CopyHBM(hBM2, 0, 0, hBM, x, y, w, h)
  1658. DllCall("DeleteObject", "Ptr",hBM), hBM:=hBM2
  1659. }
  1660. dib:=Buffer(dib_size:=(A_PtrSize=8 ? 104:84))
  1661. , DllCall("GetObject", "Ptr",hBM, "int",dib_size, "Ptr",dib)
  1662. , pbi:=dib.Ptr+(bitmap_size:=A_PtrSize=8 ? 32:24)
  1663. , size:=NumGet(pbi+20, "uint"), pBits:=NumGet(pbi-A_PtrSize, "Ptr")
  1664. if (!file)
  1665. {
  1666. hdib:=DllCall("GlobalAlloc", "uint",2, "Ptr",40+size, "Ptr")
  1667. pdib:=DllCall("GlobalLock", "Ptr",hdib, "Ptr")
  1668. DllCall("RtlMoveMemory", "Ptr",pdib, "Ptr",pbi, "Ptr",40)
  1669. DllCall("RtlMoveMemory", "Ptr",pdib+40, "Ptr",pBits, "Ptr",size)
  1670. DllCall("GlobalUnlock", "Ptr",hdib)
  1671. DllCall("OpenClipboard", "Ptr",0)
  1672. DllCall("EmptyClipboard")
  1673. if !DllCall("SetClipboardData", "uint",8, "Ptr",hdib)
  1674. DllCall("GlobalFree", "Ptr",hdib)
  1675. DllCall("CloseClipboard")
  1676. }
  1677. else
  1678. {
  1679. if InStr(file,"\") && !FileExist(dir:=RegExReplace(file,"[^\\]*$"))
  1680. Try DirCreate(dir)
  1681. bf:=Buffer(14, 0), NumPut("short", 0x4D42, bf)
  1682. NumPut("uint", 54+size, bf, 2), NumPut("uint", 54, bf, 10)
  1683. f:=FileOpen(file, "w"), f.RawWrite(bf, 14)
  1684. , f.RawWrite(pbi+0, 40), f.RawWrite(pBits+0, size), f.Close()
  1685. }
  1686. DllCall("DeleteObject", "Ptr",hBM)
  1687. }
  1688. ; 显示保存的图像
  1689. ShowPic(file:="", show:=1, &x:="", &y:="", &w:="", &h:="")
  1690. {
  1691. if (file="")
  1692. {
  1693. this.ShowScreenShot()
  1694. return
  1695. }
  1696. if !(hBM:=LoadPicture(file))
  1697. return
  1698. this.GetBitmapWH(hBM, &w, &h)
  1699. this.GetBitsFromScreen(,,,,0,&x,&y)
  1700. bits:=this.GetBitsFromScreen(&x,&y,&w,&h,0)
  1701. this.CopyHBM(bits.hBM, 0, 0, hBM, 0, 0, w, h)
  1702. DllCall("DeleteObject", "Ptr",hBM)
  1703. if (show)
  1704. this.ShowScreenShot(x, y, x+w-1, y+h-1, 0)
  1705. }
  1706. ; 显示内存中的屏幕截图用于调试
  1707. ShowScreenShot(x1:=0, y1:=0, x2:=0, y2:=0, ScreenShot:=1)
  1708. {
  1709. static hPic, oldx, oldy, oldw, oldh, FindText_Screen:=""
  1710. x1:=this.Floor(x1), y1:=this.Floor(y1), x2:=this.Floor(x2), y2:=this.Floor(y2)
  1711. if (x1=0 && y1=0 && x2=0 && y2=0)
  1712. {
  1713. if (FindText_Screen)
  1714. FindText_Screen.Destroy(), FindText_Screen:=""
  1715. return
  1716. }
  1717. x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x2-x1)+1, h:=Abs(y2-y1)+1
  1718. if !hBM:=this.BitmapFromScreen(&x,&y,&w,&h,ScreenShot)
  1719. return
  1720. ;---------------
  1721. if (!FindText_Screen)
  1722. {
  1723. FindText_Screen:=_Gui:=Gui() ; WS_EX_NOACTIVATE:=0x08000000
  1724. _Gui.Opt "+AlwaysOnTop -Caption +ToolWindow -DPIScale +E0x08000000"
  1725. _Gui.Name:="FindText_Screen"
  1726. _Gui.MarginX:=0, _Gui.MarginY:=0
  1727. id:=_Gui.Add("Pic", "w" w " h" h), hPic:=id.Hwnd
  1728. _Gui.Title:="Show Pic"
  1729. _Gui.Show "NA x" x " y" y " w" w " h" h
  1730. oldx:=x, oldy:=y, oldw:=w, oldh:=h
  1731. }
  1732. else if (oldx!=x || oldy!=y || oldw!=w || oldh!=h)
  1733. {
  1734. if (oldw!=w || oldh!=h)
  1735. FindText_Screen[hPic].Move(,, w, h)
  1736. FindText_Screen.Show "NA x" x " y" y " w" w " h" h
  1737. oldx:=x, oldy:=y, oldw:=w, oldh:=h
  1738. }
  1739. this.BitmapToWindow(hPic, 0, 0, hBM, 0, 0, w, h)
  1740. DllCall("DeleteObject", "Ptr",hBM)
  1741. }
  1742. BitmapToWindow(hwnd, x1, y1, hBM, x2, y2, w, h)
  1743. {
  1744. mDC:=DllCall("CreateCompatibleDC", "Ptr",0, "Ptr")
  1745. oBM:=DllCall("SelectObject", "Ptr",mDC, "Ptr",hBM, "Ptr")
  1746. hDC:=DllCall("GetDC", "Ptr",hwnd, "Ptr")
  1747. DllCall("BitBlt", "Ptr",hDC, "int",x1, "int",y1, "int",w, "int",h
  1748. , "Ptr",mDC, "int",x2, "int",y2, "uint",0xCC0020)
  1749. DllCall("ReleaseDC", "Ptr",hwnd, "Ptr",hDC)
  1750. DllCall("SelectObject", "Ptr",mDC, "Ptr",oBM)
  1751. DllCall("DeleteDC", "Ptr",mDC)
  1752. }
  1753. ; 快速获取屏幕图像的搜索文本数据
  1754. GetTextFromScreen(x1, y1, x2, y2, Threshold:=""
  1755. , ScreenShot:=1, &rx:="", &ry:="", cut:=1)
  1756. {
  1757. x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x2-x1)+1, h:=Abs(y2-y1)+1
  1758. bits:=this.GetBitsFromScreen(&x,&y,&w,&h,ScreenShot,&zx,&zy)
  1759. Scan0:=bits.Scan0, Stride:=bits.Stride
  1760. if (w<1 || h<1 || !Scan0)
  1761. {
  1762. return
  1763. }
  1764. ListLines (lls:=A_ListLines)?0:0
  1765. gray:=Map(), gray.Default:=0
  1766. Loop h + 0*(j:=y-zy-1)*(k:=0)
  1767. Loop w + 0*(i:=x-zx-1)*(j++)
  1768. c:=NumGet(Scan0+j*Stride+(++i)*4,"uint")
  1769. , gray[++k]:=(((c>>16)&0xFF)*38+((c>>8)&0xFF)*75+(c&0xFF)*15)>>7
  1770. if InStr(Threshold,"**")
  1771. {
  1772. Threshold:=StrReplace(Threshold,"*")
  1773. if (Threshold="")
  1774. Threshold:=50
  1775. s:="", sw:=w, w-=2, h-=2, x++, y++
  1776. Loop h + 0*(y1:=0)
  1777. Loop w + 0*(y1++)
  1778. i:=y1*sw+A_Index+1, j:=gray[i]+Threshold
  1779. , s.=( gray[i-1]>j || gray[i+1]>j
  1780. || gray[i-sw]>j || gray[i+sw]>j
  1781. || gray[i-sw-1]>j || gray[i-sw+1]>j
  1782. || gray[i+sw-1]>j || gray[i+sw+1]>j ) ? "1":"0"
  1783. Threshold:="**" Threshold
  1784. }
  1785. else
  1786. {
  1787. Threshold:=StrReplace(Threshold,"*")
  1788. if (Threshold="")
  1789. {
  1790. pp:=Map(), pp.Default:=0
  1791. Loop 256
  1792. pp[A_Index-1]:=0
  1793. Loop w*h
  1794. pp[gray[A_Index]]++
  1795. IP0:=IS0:=0
  1796. Loop 256
  1797. k:=A_Index-1, IP0+=k*pp[k], IS0+=pp[k]
  1798. Threshold:=Floor(IP0/IS0)
  1799. Loop 20
  1800. {
  1801. LastThreshold:=Threshold
  1802. IP1:=IS1:=0
  1803. Loop LastThreshold+1
  1804. k:=A_Index-1, IP1+=k*pp[k], IS1+=pp[k]
  1805. IP2:=IP0-IP1, IS2:=IS0-IS1
  1806. if (IS1!=0 && IS2!=0)
  1807. Threshold:=Floor((IP1/IS1+IP2/IS2)/2)
  1808. if (Threshold=LastThreshold)
  1809. Break
  1810. }
  1811. }
  1812. s:=""
  1813. Loop w*h
  1814. s.=gray[A_Index]<=Threshold ? "1":"0"
  1815. Threshold:="*" Threshold
  1816. }
  1817. ListLines lls
  1818. ;--------------------
  1819. w:=Format("{:d}",w), CutUp:=CutDown:=0
  1820. if (cut=1)
  1821. {
  1822. re1:="(^0{" w "}|^1{" w "})"
  1823. re2:="(0{" w "}$|1{" w "}$)"
  1824. While (s~=re1)
  1825. s:=RegExReplace(s,re1), CutUp++
  1826. While (s~=re2)
  1827. s:=RegExReplace(s,re2), CutDown++
  1828. }
  1829. rx:=x+w//2, ry:=y+CutUp+(h-CutUp-CutDown)//2
  1830. s:="|<>" Threshold "$" w "." this.bit2base64(s)
  1831. ;--------------------
  1832. return s
  1833. }
  1834. ; 等待几秒钟直到屏幕图像改变,需要先调用FindText().ScreenShot()
  1835. WaitChange(time:=-1, x1:=0, y1:=0, x2:=0, y2:=0)
  1836. {
  1837. hash:=this.GetPicHash(x1, y1, x2, y2, 0)
  1838. time:=this.Floor(time), timeout:=A_TickCount+Round(time*1000)
  1839. Loop
  1840. {
  1841. if (hash!=this.GetPicHash(x1, y1, x2, y2, 1))
  1842. return 1
  1843. if (time>=0 && A_TickCount>=timeout)
  1844. Break
  1845. Sleep 10
  1846. }
  1847. return 0
  1848. }
  1849. ; 等待屏幕图像稳定下来
  1850. WaitNotChange(time:=1, timeout:=30, x1:=0, y1:=0, x2:=0, y2:=0)
  1851. {
  1852. oldhash:="", timeout:=A_TickCount+Round(this.Floor(timeout)*1000)
  1853. Loop
  1854. {
  1855. hash:=this.GetPicHash(x1, y1, x2, y2, 1), t:=A_TickCount
  1856. if (hash!=oldhash)
  1857. oldhash:=hash, timeout2:=t+Round(this.Floor(time)*1000)
  1858. if (t>=timeout2)
  1859. return 1
  1860. if (t>=timeout)
  1861. return 0
  1862. Sleep 10
  1863. }
  1864. }
  1865. GetPicHash(x1:=0, y1:=0, x2:=0, y2:=0, ScreenShot:=1)
  1866. {
  1867. static init:=DllCall("LoadLibrary", "Str","ntdll", "Ptr")
  1868. x1:=this.Floor(x1), y1:=this.Floor(y1), x2:=this.Floor(x2), y2:=this.Floor(y2)
  1869. if (x1=0 && y1=0 && x2=0 && y2=0)
  1870. n:=150000, x:=y:=-n, w:=h:=2*n
  1871. else
  1872. x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x2-x1)+1, h:=Abs(y2-y1)+1
  1873. bits:=this.GetBitsFromScreen(&x,&y,&w,&h,ScreenShot,&zx,&zy), x-=zx, y-=zy
  1874. if (w<1 || h<1 || !bits.Scan0)
  1875. return 0
  1876. hash:=0, Stride:=bits.Stride, p:=bits.Scan0+(y-1)*Stride+x*4, w*=4
  1877. Loop h
  1878. hash:=(hash*31+DllCall("ntdll\RtlComputeCrc32", "uint",0
  1879. , "Ptr",p+=Stride, "uint",w, "uint"))&0xFFFFFFFF
  1880. return hash
  1881. }
  1882. WindowToScreen(&x, &y, x1, y1, id:="")
  1883. {
  1884. if (!id)
  1885. id:=WinGetID("A")
  1886. rect:=Buffer(16, 0)
  1887. , DllCall("GetWindowRect", "Ptr",id, "Ptr",rect)
  1888. , x:=x1+NumGet(rect,"int"), y:=y1+NumGet(rect,4,"int")
  1889. }
  1890. ScreenToWindow(&x, &y, x1, y1, id:="")
  1891. {
  1892. this.WindowToScreen(&dx, &dy, 0, 0, id), x:=x1-dx, y:=y1-dy
  1893. }
  1894. ClientToScreen(&x, &y, x1, y1, id:="")
  1895. {
  1896. if (!id)
  1897. id:=WinGetID("A")
  1898. pt:=Buffer(8, 0), NumPut("int64", 0, pt)
  1899. , DllCall("ClientToScreen", "Ptr",id, "Ptr",pt)
  1900. , x:=x1+NumGet(pt,"int"), y:=y1+NumGet(pt,4,"int")
  1901. }
  1902. ScreenToClient(&x, &y, x1, y1, id:="")
  1903. {
  1904. this.ClientToScreen(&dx, &dy, 0, 0, id), x:=x1-dx, y:=y1-dy
  1905. }
  1906. ; 不像 FindText 总是使用屏幕坐标,它使用与内置命令
  1907. ; ImageSearch 一样的 CoordMode 设置的坐标模式
  1908. ; 图片文件参数可以使用 "*n *TransRRGGBB-RRGGBB-White... d:\a.bmp"
  1909. ImageSearch(&rx:="", &ry:="", x1:=0, y1:=0, x2:=0, y2:=0
  1910. , ImageFile:="", ScreenShot:=1, FindAll:=0)
  1911. {
  1912. dx:=dy:=0
  1913. if (A_CoordModePixel="Window")
  1914. this.WindowToScreen(&dx, &dy, 0, 0)
  1915. else if (A_CoordModePixel="Client")
  1916. this.ClientToScreen(&dx, &dy, 0, 0)
  1917. text:=""
  1918. Loop Parse, ImageFile, "|"
  1919. if (v:=Trim(A_LoopField))!=""
  1920. {
  1921. text.=InStr(v,"$") ? "|" v : "|##"
  1922. . (RegExMatch(v, "(^|\s)\*(\d+)\s", &r)
  1923. ? Format("{:06X}", r[2]<<16|r[2]<<8|r[2]) : "000000")
  1924. . (RegExMatch(v, "i)(^|\s)\*Trans([\-\w]+)\s", &r)
  1925. ? "-" . Trim(r[2],"-") : "") . "$"
  1926. . Trim(RegExReplace(v, "(?<=^|\s)\*\S+"))
  1927. }
  1928. x1:=this.Floor(x1), y1:=this.Floor(y1), x2:=this.Floor(x2), y2:=this.Floor(y2)
  1929. if (x1=0 && y1=0 && x2=0 && y2=0)
  1930. n:=150000, x1:=y1:=-n, x2:=y2:=n
  1931. if (ok:=this.FindText(,, x1+dx, y1+dy, x2+dx, y2+dy
  1932. , 0, 0, text, ScreenShot, FindAll))
  1933. {
  1934. For k,v in ok ; you can use ok:=FindText().ok
  1935. v.1-=dx, v.2-=dy, v.x-=dx, v.y-=dy
  1936. rx:=ok[1].1, ry:=ok[1].2
  1937. return ok
  1938. }
  1939. else
  1940. {
  1941. rx:=ry:=""
  1942. return 0
  1943. }
  1944. }
  1945. ; 不像 FindText 总是使用屏幕坐标,它使用与内置命令
  1946. ; PixelSearch 一样的 CoordMode 设置的坐标模式
  1947. ; 颜色参数可以是 "RRGGBB-DRDGDB|RRGGBB-DRDGDB", Variation 取值 0-255
  1948. PixelSearch(&rx:="", &ry:="", x1:=0, y1:=0, x2:=0, y2:=0
  1949. , ColorID:="", Variation:=0, ScreenShot:=1, FindAll:=0)
  1950. {
  1951. n:=this.Floor(Variation), text:=Format("##{:06X}$0/0", n<<16|n<<8|n)
  1952. Loop Parse, ColorID, "|"
  1953. if (v:=Trim(A_LoopField))!=""
  1954. text.="/" v
  1955. return this.ImageSearch(&rx, &ry, x1, y1, x2, y2, text, ScreenShot, FindAll)
  1956. }
  1957. ; 屏幕坐标指示的范围内的某些颜色的像素计数
  1958. ; 颜色参数可以是 "RRGGBB-DRDGDB|RRGGBB-DRDGDB", Variation 取值 0-255
  1959. PixelCount(x1:=0, y1:=0, x2:=0, y2:=0, ColorID:="", Variation:=0, ScreenShot:=1)
  1960. {
  1961. x1:=this.Floor(x1), y1:=this.Floor(y1), x2:=this.Floor(x2), y2:=this.Floor(y2)
  1962. if (x1=0 && y1=0 && x2=0 && y2=0)
  1963. n:=150000, x:=y:=-n, w:=h:=2*n
  1964. else
  1965. x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x2-x1)+1, h:=Abs(y2-y1)+1
  1966. bits:=this.GetBitsFromScreen(&x,&y,&w,&h,ScreenShot,&zx,&zy), x-=zx, y-=zy
  1967. sum:=0, s1:=Buffer(4), s0:=Buffer(4)
  1968. , ini:={ bits:bits, ss:0, s1:s1.Ptr, s0:s0.Ptr
  1969. , err1:0, err0:0, allpos_max:0, zoomW:1, zoomH:1 }
  1970. , n:=this.Floor(Variation), text:=Format("##{:06X}$0/0", n<<16|n<<8|n)
  1971. Loop Parse, ColorID, "|"
  1972. if (v:=Trim(A_LoopField))!=""
  1973. text.="/" v
  1974. if (w>0 && h>0 && bits.Scan0) && IsObject(j:=this.PicInfo(text))
  1975. sum:=this.PicFind(ini, j, 1, x, y, w, h, 0)
  1976. return sum
  1977. }
  1978. Click(x:="", y:="", other1:="", other2:="", GoBack:=0)
  1979. {
  1980. CoordMode "Mouse", (bak:=A_CoordModeMouse)?"Screen":"Screen"
  1981. if GoBack
  1982. MouseGetPos &oldx, &oldy
  1983. MouseMove x, y, 0
  1984. Click x "," y "," other1 "," other2
  1985. if GoBack
  1986. MouseMove oldx, oldy, 0
  1987. CoordMode "Mouse", bak
  1988. }
  1989. ; 使用 ControlClick 代替 Click, 使用屏幕坐标,如果用于后台请提供 hwnd
  1990. ControlClick(x, y, WhichButton:="", ClickCount:=1, Opt:="", hwnd:="")
  1991. {
  1992. if !hwnd
  1993. hwnd:=DllCall("WindowFromPoint", "int64",y<<32|x&0xFFFFFFFF, "Ptr")
  1994. pt:=Buffer(8,0), ScreenX:=x, ScreenY:=y
  1995. Loop
  1996. {
  1997. NumPut("int64",0,pt), DllCall("ClientToScreen", "Ptr",hwnd, "Ptr",pt)
  1998. , x:=ScreenX-NumGet(pt,"int"), y:=ScreenY-NumGet(pt,4,"int")
  1999. , id:=DllCall("ChildWindowFromPoint", "Ptr",hwnd, "int64",y<<32|x, "Ptr")
  2000. if (!id || id=hwnd)
  2001. Break
  2002. else hwnd:=id
  2003. }
  2004. DetectHiddenWindows (bak:=A_DetectHiddenWindows)?1:1
  2005. PostMessage 0x200, 0, y<<16|x, hwnd ; WM_MOUSEMOVE
  2006. SetControlDelay -1
  2007. ControlClick "x" x " y" y, hwnd,, WhichButton, ClickCount, "NA Pos " Opt
  2008. DetectHiddenWindows bak
  2009. }
  2010. ; 动态运行AHK代码作为新线程
  2011. Class Thread
  2012. {
  2013. __New(args*)
  2014. {
  2015. this.pid:=this.Exec(args*)
  2016. }
  2017. __Delete()
  2018. {
  2019. ProcessClose(this.pid)
  2020. }
  2021. Exec(s, Ahk:="", args:="")
  2022. {
  2023. Ahk:=Ahk ? Ahk : A_IsCompiled ? A_ScriptFullPath : A_AhkPath
  2024. add:=A_IsCompiled ? " /script " : ""
  2025. s:="`nDllCall(`"SetWindowText`",`"Ptr`",A_ScriptHwnd,`"Str`",`"<AHK>`")`n"
  2026. . "`n`n" . s, s:=RegExReplace(s, "\R", "`r`n")
  2027. Try
  2028. {
  2029. shell:=ComObject("WScript.Shell")
  2030. oExec:=shell.Exec("`"" Ahk "`"" add " /force /CP0 * " args)
  2031. oExec.StdIn.Write(s)
  2032. oExec.StdIn.Close(), pid:=oExec.ProcessID
  2033. }
  2034. Catch
  2035. {
  2036. f:=A_Temp "\~ahk.tmp"
  2037. s:="`r`nTry FileDelete(`"" f "`")`r`n" s
  2038. Try FileDelete(f)
  2039. FileAppend(s, f)
  2040. r:=this.Clear.Bind(this)
  2041. SetTimer(r, -3000)
  2042. Run "`"" Ahk "`"" add " /force /CP0 `"" f "`" " args,,, &pid
  2043. }
  2044. return pid
  2045. }
  2046. Clear()
  2047. {
  2048. Try FileDelete(A_Temp "\~ahk.tmp")
  2049. SetTimer(,0)
  2050. }
  2051. }
  2052. ; FindText().QPC() 用法类似于 A_TickCount
  2053. QPC()
  2054. {
  2055. static f:=0, c:=DllCall("QueryPerformanceFrequency", "Int*",&f)+(f/=1000)
  2056. return (!DllCall("QueryPerformanceCounter", "Int64*",&c))*0+(c/f)
  2057. }
  2058. ; FindText().ToolTip() 用法类似于 ToolTip
  2059. ToolTip(s:="", x:="", y:="", num:=1, arg:="")
  2060. {
  2061. static ini:=Map(), tip:=Map(), timer:=Map()
  2062. f:="ToolTip_" . this.Floor(num)
  2063. if (s="")
  2064. {
  2065. ini[f]:=""
  2066. Try tip[f].Destroy()
  2067. return
  2068. }
  2069. ;-----------------
  2070. r1:=A_CoordModeToolTip
  2071. r2:=A_CoordModeMouse
  2072. CoordMode "Mouse", "Screen"
  2073. MouseGetPos &x1, &y1
  2074. CoordMode "Mouse", r1
  2075. MouseGetPos &x2, &y2
  2076. CoordMode "Mouse", r2
  2077. (x!="" && x:="x" (this.Floor(x)+x1-x2))
  2078. , (y!="" && y:="y" (this.Floor(y)+y1-y2))
  2079. , (x="" && y="" && x:="x" (x1+16) " y" (y1+16))
  2080. ;-----------------
  2081. (!IsObject(arg) && arg:={})
  2082. bgcolor:=arg.HasOwnProp("bgcolor") ? arg.bgcolor : "FAFBFC"
  2083. color:=arg.HasOwnProp("color") ? arg.color : "Black"
  2084. font:=arg.HasOwnProp("font") ? arg.font : "Consolas"
  2085. size:=arg.HasOwnProp("size") ? arg.size : "10"
  2086. bold:=arg.HasOwnProp("bold") ? arg.bold : ""
  2087. trans:=arg.HasOwnProp("trans") ? arg.trans & 255 : 255
  2088. timeout:=arg.HasOwnProp("timeout") ? arg.timeout : ""
  2089. ;-----------------
  2090. r:=bgcolor "|" color "|" font "|" size "|" bold "|" trans "|" s
  2091. if (!ini.Has(f) || ini[f]!=r)
  2092. {
  2093. ini[f]:=r
  2094. Try tip[f].Destroy()
  2095. tip[f]:=_Gui:=Gui() ; WS_EX_LAYERED:=0x80000, WS_EX_TRANSPARENT:=0x20
  2096. _Gui.Opt "+AlwaysOnTop -Caption +ToolWindow -DPIScale +E0x80020"
  2097. _Gui.MarginX:=2, _Gui.MarginY:=2
  2098. _Gui.BackColor:=bgcolor
  2099. _Gui.SetFont "c" color " s" size " " bold, font
  2100. _Gui.Add "Text",, s
  2101. _Gui.Title:=f
  2102. _Gui.Show "Hide"
  2103. ;------------------
  2104. DetectHiddenWindows (bak:=A_DetectHiddenWindows)?1:1
  2105. WinSetTransparent(trans, _Gui.Hwnd)
  2106. DetectHiddenWindows bak
  2107. }
  2108. else _Gui:=tip[f]
  2109. _Gui.Opt "+AlwaysOnTop"
  2110. _Gui.Show "NA " x " " y
  2111. if (timeout)
  2112. {
  2113. (!timer.Has(f) && timer[f]:=this.ToolTip.Bind(this,"","","",num))
  2114. SetTimer(timer[f], -Round(Abs(this.Floor(timeout)*1000))-1)
  2115. }
  2116. }
  2117. ; FindText().ObjView() 查看对象的值用于调试
  2118. ObjView(obj, keyname:="")
  2119. {
  2120. static Gui_DeBug:=""
  2121. if IsObject(obj)
  2122. {
  2123. s:=""
  2124. For k,v in (HasMethod(obj,"__Enum") ? obj : obj.OwnProps())
  2125. s.=this.ObjView(v, keyname "[" (k is Number ? k : "`"" k "`"") "]")
  2126. }
  2127. else
  2128. s:=keyname ": " (obj is Number ? obj : "`"" obj "`"") "`n"
  2129. if (keyname!="")
  2130. return s
  2131. ;------------------
  2132. Try Gui_DeBug.Destroy()
  2133. Gui_DeBug:=_Gui:=Gui()
  2134. _Gui.Opt "+LastFound +AlwaysOnTop"
  2135. _Gui.Add("Button", "y270 w350 Default", "OK").OnEvent("Click", (*) => WinHide())
  2136. _Gui.Add "Edit", "xp y10 w350 h250 -Wrap -WantReturn"
  2137. _Gui["Edit1"].Value:=s
  2138. _Gui.Title:="Debug view object values"
  2139. _Gui.Show
  2140. DetectHiddenWindows(0)
  2141. WinWaitClose "ahk_id " WinExist()
  2142. _Gui.Destroy
  2143. }
  2144. EditScroll(hEdit, regex:="", line:=0, pos:=0)
  2145. {
  2146. s:=ControlGetText(hEdit)
  2147. pos:=(regex!="") ? InStr(SubStr(s,1,s~=regex),"`n",0,-1)
  2148. : (line>1) ? InStr(s,"`n",0,1,line-1) : pos
  2149. SendMessage 0xB1, pos, pos, hEdit
  2150. SendMessage 0xB7,,, hEdit
  2151. }
  2152. ; 从编译后的程序中获取脚本
  2153. GetScript() ; thanks TAC109
  2154. {
  2155. if (!A_IsCompiled)
  2156. return
  2157. For i,ahk in ["#1", ">AUTOHOTKEY SCRIPT<"]
  2158. if (rc:=DllCall("FindResource", "Ptr",0, "Str",ahk, "Ptr",10, "Ptr"))
  2159. && (sz:=DllCall("SizeofResource", "Ptr",0, "Ptr",rc, "Uint"))
  2160. && (pt:=DllCall("LoadResource", "Ptr",0, "Ptr",rc, "Ptr"))
  2161. && (pt:=DllCall("LockResource", "Ptr",pt, "Ptr"))
  2162. && (DllCall("VirtualProtect", "Ptr",pt, "Ptr",sz, "UInt",0x4, "UInt*",0))
  2163. && (InStr(StrGet(pt, 20, "utf-8"), "<COMPILER"))
  2164. return this.FormatScript(StrGet(pt, sz, "utf-8"))
  2165. }
  2166. FormatScript(s, space:="", tab:=" ")
  2167. {
  2168. ListLines (lls:=A_ListLines)?0:0
  2169. VarSetStrCapacity(&ss, StrLen(s)*2), n:=0, w:=StrLen(tab)
  2170. , space2:=StrReplace(Format("{:020d}",0), "0", tab)
  2171. Loop Parse, s, "`n", "`r"
  2172. {
  2173. v:=Trim(A_LoopField), n2:=n
  2174. if RegExMatch(v, "^\s*[{}][\s{}]*|\{\s*$|\{\s+;", &r)
  2175. n+=w*(StrLen(RegExReplace(r[0], "[^{]"))
  2176. -StrLen(RegExReplace(r[0], "[^}]"))), n2:=Min(n,n2)
  2177. ss.=Space . SubStr(space2,1,n2) . v . "`r`n"
  2178. }
  2179. ListLines lls
  2180. return SubStr(ss,1,-2)
  2181. }
  2182. ; 获取 Gui对象 通过 Gui名称
  2183. GuiFromName(GuiName:="")
  2184. {
  2185. DetectHiddenWindows (bak:=A_DetectHiddenWindows)?1:1
  2186. List:=WinGetList("ahk_class AutoHotkeyGUI ahk_pid " DllCall("GetCurrentProcessId"))
  2187. DetectHiddenWindows bak
  2188. For id in List
  2189. Try if (_Gui:=GuiFromHwnd(id)) && (_Gui.Name=GuiName)
  2190. return _Gui
  2191. }
  2192. ; 获取最后添加的Gui控件的对象,前提是 Gui +LastFound
  2193. LastCtrl()
  2194. {
  2195. For Ctrl in GuiFromHwnd(WinExist())
  2196. last:=Ctrl
  2197. return last
  2198. }
  2199. ; 隐藏窗口,前提是 Gui +LastFound
  2200. Hide(id:="")
  2201. {
  2202. if (id ? WinExist("ahk_id " id) : WinExist())
  2203. {
  2204. WinMinimize
  2205. WinHide
  2206. ToolTip
  2207. DetectHiddenWindows 0
  2208. WinWaitClose "ahk_id " WinExist()
  2209. }
  2210. }
  2211. ;==== Optional GUI interface ====
  2212. Gui(cmd, arg1:="", args*)
  2213. {
  2214. static
  2215. local _Gui, cri, lls
  2216. (InStr("MouseMove|ToolTipOff", cmd) && ListLines(0))
  2217. static init:=0
  2218. if (!init && init:=1)
  2219. {
  2220. SavePicDir:=A_Temp "\Ahk_ScreenShot\"
  2221. Gui_ := this.Gui.Bind(this)
  2222. Gui_G := this.Gui.Bind(this, "G")
  2223. Gui_Run := this.Gui.Bind(this, "Run")
  2224. Gui_Off := this.Gui.Bind(this, "Off")
  2225. Gui_Show := this.Gui.Bind(this, "Show")
  2226. Gui_KeyDown := this.Gui.Bind(this, "KeyDown")
  2227. Gui_LButtonDown := this.Gui.Bind(this, "LButtonDown")
  2228. Gui_RButtonDown := this.Gui.Bind(this, "RButtonDown")
  2229. Gui_MouseMove := this.Gui.Bind(this, "MouseMove")
  2230. Gui_ScreenShot := this.Gui.Bind(this, "ScreenShot")
  2231. Gui_ShowPic := this.Gui.Bind(this, "ShowPic")
  2232. Gui_Slider := this.Gui.Bind(this, "Slider")
  2233. Gui_ToolTip := this.Gui.Bind(this, "ToolTip")
  2234. Gui_ToolTipOff := this.Gui.Bind(this, "ToolTipOff")
  2235. Gui_SaveScr := this.Gui.Bind(this, "SaveScr")
  2236. FindText_Capture:=FindText_Main:=FindText_SubPic:=""
  2237. cri:=A_IsCritical
  2238. Critical
  2239. Lang:=this.Lang(,1), Tip_Text:=this.Lang(,2)
  2240. Gui_("MakeCaptureWindow")
  2241. Gui_("MakeMainWindow")
  2242. OnMessage(0x100, Gui_KeyDown)
  2243. OnMessage(0x201, Gui_LButtonDown)
  2244. OnMessage(0x204, Gui_RButtonDown)
  2245. OnMessage(0x200, Gui_MouseMove)
  2246. A_TrayMenu.Add
  2247. A_TrayMenu.Add Lang["s1"], Gui_Show
  2248. if (!A_IsCompiled && A_LineFile=A_ScriptFullPath)
  2249. {
  2250. A_TrayMenu.Default:=Lang["s1"]
  2251. A_TrayMenu.ClickCount:=1
  2252. TraySetIcon "Shell32.dll", 23
  2253. }
  2254. Critical(cri)
  2255. _Gui:=Gui("+LastFound")
  2256. _Gui.Destroy
  2257. ;-------------------
  2258. Pics:=PrevControl:=x:=y:=oldx:=oldy:="", oldt:=0
  2259. }
  2260. Switch cmd, 1
  2261. {
  2262. Case "Off":
  2263. return hk:=Trim(A_ThisHotkey, "*")
  2264. Case "G":
  2265. id:=this.LastCtrl()
  2266. Try id.OnEvent("Click", Gui_Run)
  2267. Try id.OnEvent("Change", Gui_Run)
  2268. return
  2269. Case "Run":
  2270. Critical
  2271. Gui_(arg1.Name)
  2272. return
  2273. Case "Show":
  2274. _Gui:=FindText_Main
  2275. _Gui.Show(arg1 ? "Center" : "")
  2276. ControlFocus(hscr)
  2277. return
  2278. Case "Cancel", "Cancel2":
  2279. WinHide
  2280. return
  2281. Case "MakeCaptureWindow":
  2282. WindowColor:="0xDDEEFF"
  2283. Try FindText_Capture.Destroy()
  2284. FindText_Capture:=_Gui:=Gui()
  2285. _Gui.Opt "+LastFound +AlwaysOnTop -DPIScale"
  2286. _Gui.MarginX:=15, _Gui.MarginY:=15
  2287. _Gui.BackColor:=WindowColor
  2288. _Gui.SetFont "s12", "Verdana"
  2289. Tab:=_Gui.Add("Tab3", "vMyTab1 -Wrap", StrSplit(Lang["s18"],"|"))
  2290. Tab.UseTab(1)
  2291. C_:=Map(), nW:=71, nH:=25, w:=h:=12, pW:=nW*(w+1)-1, pH:=(nH+1)*(h+1)-1
  2292. _Gui.Opt "-Theme"
  2293. ListLines (lls:=A_ListLines)?0:0
  2294. Loop nW*(nH+1)
  2295. {
  2296. i:=A_Index, j:=i=1 ? "Section" : Mod(i,nW)=1 ? "xs y+1":"x+1"
  2297. id:=_Gui.Add("Progress", j " w" w " h" h " -E0x20000 Smooth")
  2298. C_[i]:=id.Hwnd
  2299. }
  2300. ListLines lls
  2301. _Gui.Opt "+Theme"
  2302. _Gui.Add "Slider", "xs w" pW " vMySlider1 +Center Page20 Line10 NoTicks AltSubmit"
  2303. Gui_G()
  2304. _Gui.Add "Slider", "ys h" pH " vMySlider2 +Center Page20 Line10 NoTicks AltSubmit +Vertical"
  2305. Gui_G()
  2306. Tab.UseTab(2)
  2307. pW-=120+15
  2308. id:=_Gui.Add("Text", "w" pW " h" pH " +Border Section"), parent_id:=id.Hwnd
  2309. _Gui.Add "Slider", "xs w" pW " vMySlider3 +Center Page20 Line10 NoTicks AltSubmit"
  2310. Gui_G()
  2311. _Gui.Add "Slider", "ys h" pH " vMySlider4 +Center Page20 Line10 NoTicks AltSubmit +Vertical"
  2312. Gui_G()
  2313. _Gui.Add "ListBox", "ys w120 h200 vSelectBox AltSubmit 0x100"
  2314. Gui_G()
  2315. _Gui.Add "Button", "y+0 wp vClearAll", Lang["ClearAll"]
  2316. Gui_G()
  2317. _Gui.Add "Button", "y+0 wp vOpenDir", Lang["OpenDir"]
  2318. Gui_G()
  2319. _Gui.Add "Button", "y+0 wp vLoadPic", Lang["LoadPic"]
  2320. Gui_G()
  2321. _Gui.Add "Button", "y+0 wp vSavePic", Lang["SavePic"]
  2322. Gui_G()
  2323. Tab.UseTab()
  2324. MySlider1:=MySlider2:=MySlider3:=MySlider4:=dx:=dy:=0
  2325. ;--------------
  2326. _Gui.Add "Button", "xm Hidden Section", Lang["Auto"]
  2327. this.LastCtrl().GetPos(&pX, &pY, &pW, &pH)
  2328. w:=Round(pW*0.75), i:=Round(w*3+15+pW*0.5-w*1.5)
  2329. _Gui.Add "Button", "xm+" i " yp w" w " hp -Wrap vRepU", Lang["RepU"]
  2330. Gui_G()
  2331. _Gui.Add "Button", "x+0 wp hp -Wrap vCutU", Lang["CutU"]
  2332. Gui_G()
  2333. _Gui.Add "Button", "x+0 wp hp -Wrap vCutU3", Lang["CutU3"]
  2334. Gui_G()
  2335. _Gui.Add "Button", "xm wp hp -Wrap vRepL", Lang["RepL"]
  2336. Gui_G()
  2337. _Gui.Add "Button", "x+0 wp hp -Wrap vCutL", Lang["CutL"]
  2338. Gui_G()
  2339. _Gui.Add "Button", "x+0 wp hp -Wrap vCutL3", Lang["CutL3"]
  2340. Gui_G()
  2341. _Gui.Add "Button", "x+15 w" pW " hp -Wrap vAuto", Lang["Auto"]
  2342. Gui_G()
  2343. _Gui.Add "Button", "x+15 w" w " hp -Wrap vRepR", Lang["RepR"]
  2344. Gui_G()
  2345. _Gui.Add "Button", "x+0 wp hp -Wrap vCutR", Lang["CutR"]
  2346. Gui_G()
  2347. _Gui.Add "Button", "x+0 wp hp -Wrap vCutR3", Lang["CutR3"]
  2348. Gui_G()
  2349. _Gui.Add "Button", "xm+" i " wp hp -Wrap vRepD", Lang["RepD"]
  2350. Gui_G()
  2351. _Gui.Add "Button", "x+0 wp hp -Wrap vCutD", Lang["CutD"]
  2352. Gui_G()
  2353. _Gui.Add "Button", "x+0 wp hp -Wrap vCutD3", Lang["CutD3"]
  2354. Gui_G()
  2355. ;--------------
  2356. _Gui.Add "Text", "x+60 ys+3 Section", Lang["SelGray"]
  2357. _Gui.Add "Edit", "x+3 yp-3 w60 vSelGray ReadOnly"
  2358. _Gui.Add "Text", "x+15 ys", Lang["SelColor"]
  2359. _Gui.Add "Edit", "x+3 yp-3 w150 vSelColor ReadOnly"
  2360. _Gui.Add "Text", "x+15 ys", Lang["SelR"]
  2361. _Gui.Add "Edit", "x+3 yp-3 w60 vSelR ReadOnly"
  2362. _Gui.Add "Text", "x+5 ys", Lang["SelG"]
  2363. _Gui.Add "Edit", "x+3 yp-3 w60 vSelG ReadOnly"
  2364. _Gui.Add "Text", "x+5 ys", Lang["SelB"]
  2365. _Gui.Add "Edit", "x+3 yp-3 w60 vSelB ReadOnly"
  2366. ;--------------
  2367. x:=w*6+pW+15*4
  2368. Tab:=_Gui.Add("Tab3", "x" x " y+15 -Wrap", StrSplit(Lang["s2"],"|"))
  2369. Tab.UseTab(1)
  2370. _Gui.Add "Text", "x+15 y+15", Lang["Threshold"]
  2371. _Gui.Add "Edit", "x+15 w100 vThreshold"
  2372. _Gui.Add "Button", "x+15 yp-3 vGray2Two", Lang["Gray2Two"]
  2373. Gui_G()
  2374. Tab.UseTab(2)
  2375. _Gui.Add "Text", "x+15 y+15", Lang["GrayDiff"]
  2376. _Gui.Add "Edit", "x+15 w100 vGrayDiff", "50"
  2377. _Gui.Add "Button", "x+15 yp-3 vGrayDiff2Two", Lang["GrayDiff2Two"]
  2378. Gui_G()
  2379. Tab.UseTab(3)
  2380. _Gui.Add "Text", "x+15 y+15", Lang["Similar1"] " 0"
  2381. _Gui.Add "Slider", "x+0 w120 vSimilar1 +Center Page1 NoTicks ToolTip", 100
  2382. Gui_G()
  2383. _Gui.Add "Text", "x+0", "100"
  2384. _Gui.Add "Button", "x+15 yp-3 vColor2Two", Lang["Color2Two"]
  2385. Gui_G()
  2386. Tab.UseTab(4)
  2387. _Gui.Add "Text", "x+15 y+15", Lang["Similar2"] " 0"
  2388. _Gui.Add "Slider", "x+0 w120 vSimilar2 +Center Page1 NoTicks ToolTip", 100
  2389. Gui_G()
  2390. _Gui.Add "Text", "x+0", "100"
  2391. _Gui.Add "Button", "x+15 yp-3 vColorPos2Two", Lang["ColorPos2Two"]
  2392. Gui_G()
  2393. Tab.UseTab(5)
  2394. _Gui.Add "Text", "x+10 y+15", Lang["DiffR"]
  2395. _Gui.Add "Edit", "x+5 w80 vDiffR Limit3"
  2396. _Gui.Add "UpDown", "vdR Range0-255 Wrap"
  2397. _Gui.Add "Text", "x+5", Lang["DiffG"]
  2398. _Gui.Add "Edit", "x+5 w80 vDiffG Limit3"
  2399. _Gui.Add "UpDown", "vdG Range0-255 Wrap"
  2400. _Gui.Add "Text", "x+5", Lang["DiffB"]
  2401. _Gui.Add "Edit", "x+5 w80 vDiffB Limit3"
  2402. _Gui.Add "UpDown", "vdB Range0-255 Wrap"
  2403. _Gui.Add "Button", "x+15 yp-3 vColorDiff2Two", Lang["ColorDiff2Two"]
  2404. Gui_G()
  2405. Tab.UseTab(6)
  2406. _Gui.Add "Text", "x+10 y+15", Lang["DiffRGB"]
  2407. _Gui.Add "Edit", "x+5 w80 vDiffRGB Limit3"
  2408. _Gui.Add "UpDown", "vdRGB Range0-255 Wrap"
  2409. _Gui.Add "Checkbox", "x+15 yp+5 vMultiColor", Lang["MultiColor"]
  2410. Gui_G()
  2411. _Gui.Add "Button", "x+15 yp-5 vUndo", Lang["Undo"]
  2412. Gui_G()
  2413. Tab.UseTab()
  2414. ;--------------
  2415. _Gui.Add "Button", "xm vReset", Lang["Reset"]
  2416. Gui_G()
  2417. _Gui.Add "Checkbox", "x+15 yp+5 vModify", Lang["Modify"]
  2418. Gui_G()
  2419. _Gui.Add "Text", "x+30", Lang["Comment"]
  2420. _Gui.Add "Edit", "x+5 yp-2 w150 vComment"
  2421. _Gui.Add "Button", "x+10 yp-3 vSplitAdd", Lang["SplitAdd"]
  2422. Gui_G()
  2423. _Gui.Add "Button", "x+10 vAllAdd", Lang["AllAdd"]
  2424. Gui_G()
  2425. _Gui.Add "Button", "x+30 wp vOK", Lang["OK"]
  2426. Gui_G()
  2427. _Gui.Add "Button", "x+10 wp vCancel", Lang["Cancel"]
  2428. Gui_G()
  2429. _Gui.Add "Button", "xm vBind0", Lang["Bind0"]
  2430. Gui_G()
  2431. _Gui.Add "Button", "x+10 vBind1", Lang["Bind1"]
  2432. Gui_G()
  2433. _Gui.Add "Button", "x+10 vBind2", Lang["Bind2"]
  2434. Gui_G()
  2435. _Gui.Add "Button", "x+10 vBind3", Lang["Bind3"]
  2436. Gui_G()
  2437. _Gui.Add "Button", "x+10 vBind4", Lang["Bind4"]
  2438. Gui_G()
  2439. _Gui.Add "Button", "x+60 vSavePic2", Lang["SavePic2"]
  2440. Gui_G()
  2441. _Gui.Title:=Lang["s3"]
  2442. _Gui.Show "Hide"
  2443. ;--------------------
  2444. Try FindText_SubPic.Destroy()
  2445. FindText_SubPic:=_Gui:=Gui()
  2446. _Gui.Opt "+Parent" parent_id " +AlwaysOnTop -Caption +ToolWindow -DPIScale"
  2447. _Gui.MarginX:=0, _Gui.MarginY:=0
  2448. _Gui.BackColor:="White"
  2449. id:=_Gui.Add("Pic", "x0 y0 w500 h500"), sub_hpic:=id.Hwnd
  2450. _Gui.Title:="SubPic"
  2451. _Gui.Show "NA x0 y0"
  2452. return
  2453. Case "MakeMainWindow":
  2454. Try FindText_Main.Destroy()
  2455. FindText_Main:=_Gui:=Gui()
  2456. _Gui.Opt "+LastFound +AlwaysOnTop -DPIScale"
  2457. _Gui.MarginX:=15, _Gui.MarginY:=10
  2458. _Gui.BackColor:=WindowColor
  2459. _Gui.SetFont "s12", "Verdana"
  2460. _Gui.Add "Text", "xm", Lang["NowHotkey"]
  2461. _Gui.Add "Edit", "x+5 w160 vNowHotkey ReadOnly"
  2462. _Gui.Add "Hotkey", "x+5 w160 vSetHotkey1"
  2463. s:="F1|F2|F3|F4|F5|F6|F7|F8|F9|F10|F11|F12|LWin|MButton"
  2464. . "|ScrollLock|CapsLock|Ins|Esc|BS|Del|Tab|Home|End|PgUp|PgDn"
  2465. . "|NumpadDot|NumpadSub|NumpadAdd|NumpadDiv|NumpadMult"
  2466. _Gui.Add "DDL", "x+5 w160 vSetHotkey2", StrSplit(s,"|")
  2467. _Gui.Add "Button", "x+15 vApply", Lang["Apply"]
  2468. Gui_G()
  2469. _Gui.Add "GroupBox", "xm y+0 w280 h55 vMyGroup cBlack"
  2470. _Gui.Add "Text", "xp+15 yp+20 Section", Lang["Myww"] ": "
  2471. _Gui.Add "Text", "x+0 w80", nW//2
  2472. _Gui.Add "UpDown", "vMyww Range1-100", nW//2
  2473. _Gui.Add "Text", "x+15 ys", Lang["Myhh"] ": "
  2474. _Gui.Add "Text", "x+0 w80", nH//2
  2475. _Gui.Add "UpDown", "vMyhh Range1-100", nH//2
  2476. this.LastCtrl().GetPos(&pX, &pY, &pW, &pH)
  2477. _Gui["MyGroup"].Move(,, pX+pW, pH+30)
  2478. _Gui.Add "Checkbox", "x+100 ys vAddFunc", Lang["AddFunc"] " FindText()"
  2479. this.LastCtrl().GetPos(&pX, &pY, &pW, &pH)
  2480. pW:=pX+pW-15, pW:=(pW<720?720:pW), w:=pW//5
  2481. _Gui.Add "Button", "xm y+18 w" w " vCutL2", Lang["CutL2"]
  2482. Gui_G()
  2483. _Gui.Add "Button", "x+0 wp vCutR2", Lang["CutR2"]
  2484. Gui_G()
  2485. _Gui.Add "Button", "x+0 wp vCutU2", Lang["CutU2"]
  2486. Gui_G()
  2487. _Gui.Add "Button", "x+0 wp vCutD2", Lang["CutD2"]
  2488. Gui_G()
  2489. _Gui.Add "Button", "x+0 wp vUpdate", Lang["Update"]
  2490. Gui_G()
  2491. _Gui.SetFont "s6 bold", "Verdana"
  2492. _Gui.Add "Edit", "xm y+10 w" pW " h260 vMyPic -Wrap HScroll"
  2493. _Gui.SetFont "s12 norm", "Verdana"
  2494. w:=pW//3
  2495. _Gui.Add "Button", "xm w" w " vCapture", Lang["Capture"]
  2496. Gui_G()
  2497. _Gui.Add "Button", "x+0 wp vTest", Lang["Test"]
  2498. Gui_G()
  2499. _Gui.Add "Button", "x+0 wp vCopy", Lang["Copy"]
  2500. Gui_G()
  2501. _Gui.Add "Button", "xm y+0 wp vCaptureS", Lang["CaptureS"]
  2502. Gui_G()
  2503. _Gui.Add "Button", "x+0 wp vGetRange", Lang["GetRange"]
  2504. Gui_G()
  2505. _Gui.Add "Button", "x+0 wp vGetOffset", Lang["GetOffset"]
  2506. Gui_G()
  2507. _Gui.Add "Edit", "xm y+10 w130 hp vClipText"
  2508. _Gui.Add "Button", "x+0 vPaste", Lang["Paste"]
  2509. Gui_G()
  2510. _Gui.Add "Button", "x+0 vTestClip", Lang["TestClip"]
  2511. Gui_G()
  2512. _Gui.Add "Button", "x+0 vGetClipOffset", Lang["GetClipOffset"]
  2513. Gui_G()
  2514. r:=pW
  2515. this.LastCtrl().GetPos(&pX, &pY, &pW, &pH)
  2516. w:=((r+15)-(pX+pW))//2, pW:=r
  2517. _Gui.Add "Edit", "x+0 w" w " hp vOffset"
  2518. _Gui.Add "Button", "x+0 wp vCopyOffset", Lang["CopyOffset"]
  2519. Gui_G()
  2520. _Gui.SetFont "cBlue"
  2521. id:=_Gui.Add("Edit", "xm w" pW " h250 vscr -Wrap HScroll"), hscr:=id.Hwnd
  2522. _Gui.Title:=Lang["s4"]
  2523. _Gui.Show "Hide"
  2524. Gui_("LoadScr")
  2525. OnExit(Gui_SaveScr)
  2526. return
  2527. Case "LoadScr":
  2528. f:=A_Temp "\~scr2.tmp"
  2529. Try s:="", s:=FileRead(f)
  2530. _Gui:=FindText_Main
  2531. _Gui["scr"].Value:=s
  2532. return
  2533. Case "SaveScr":
  2534. f:=A_Temp "\~scr2.tmp"
  2535. _Gui:=FindText_Main
  2536. s:=_Gui["scr"].Value
  2537. Try FileDelete(f)
  2538. FileAppend(s, f)
  2539. return
  2540. Case "Capture", "CaptureS":
  2541. _Gui:=FindText_Main
  2542. if WinExist()!=_Gui.Hwnd
  2543. return this.GetRange()
  2544. this.Hide()
  2545. if !InStr(cmd, "CaptureS")
  2546. {
  2547. _Gui:=FindText_Main
  2548. w:=_Gui["Myww"].Value
  2549. h:=_Gui["Myhh"].Value
  2550. p:=this.GetRange(w, h)
  2551. sx:=p[1], sy:=p[2], sw:=p[3]-p[1]+1, sh:=p[4]-p[2]+1
  2552. , Bind_ID:=p[5], bind_mode:=""
  2553. _Gui:=FindText_Capture
  2554. _Gui["MyTab1"].Choose(1)
  2555. }
  2556. else
  2557. {
  2558. sx:=0, sy:=0, sw:=1, sh:=1, Bind_ID:=WinExist("A"), bind_mode:=""
  2559. _Gui:=FindText_Capture
  2560. _Gui["MyTab1"].Choose(2)
  2561. }
  2562. this.ScreenShot()
  2563. n:=150000, x:=y:=-n, w:=h:=2*n
  2564. hBM:=this.BitmapFromScreen(&x,&y,&w,&h,0)
  2565. Gui_("CaptureUpdate")
  2566. Gui_("PicUpdate")
  2567. Names:=[], s:=""
  2568. Loop Files, SavePicDir "*.bmp"
  2569. Names.Push(v:=A_LoopFileFullPath), s.="|" RegExReplace(v,"i)^.*\\|\.bmp$")
  2570. _Gui["SelectBox"].Delete()
  2571. _Gui["SelectBox"].Add(StrSplit(Trim(s,"|"),"|"))
  2572. ;------------------------
  2573. Loop Parse, "SelGray|SelColor|SelR|SelG|SelB|Threshold|Comment", "|"
  2574. _Gui[A_LoopField].Value:=""
  2575. _Gui["Modify"].Value:=Modify:=0
  2576. _Gui["MultiColor"].Value:=MultiColor:=0
  2577. _Gui["GrayDiff"].Value:=50
  2578. _Gui["Gray2Two"].Focus()
  2579. _Gui["Gray2Two"].Opt("+Default")
  2580. _Gui.Opt "+LastFound"
  2581. _Gui.Show "Center"
  2582. Event:=Result:=""
  2583. DetectHiddenWindows 0
  2584. Critical "Off"
  2585. WinWaitClose "ahk_id " WinExist()
  2586. Critical
  2587. ToolTip
  2588. _Gui:=FindText_Main
  2589. ;--------------------------------
  2590. if (bind_mode!="")
  2591. {
  2592. tt:=WinGetTitle(Bind_ID)
  2593. tc:=WinGetClass(Bind_ID)
  2594. tt:=Trim(SubStr(tt,1,30) (tc ? " ahk_class " tc:""))
  2595. tt:=StrReplace(RegExReplace(tt, "[;``]", "``$0"), "`"","```"")
  2596. Result:="`nSetTitleMatchMode 2`nid:=WinExist(`"" tt "`")"
  2597. . "`nFindText().BindWindow(id" (bind_mode=0 ? "":"," bind_mode)
  2598. . ") `; " Lang["s6"] " FindText().BindWindow(0)`n`n" Result
  2599. }
  2600. if (Event="OK")
  2601. {
  2602. if (!A_IsCompiled)
  2603. s:=FileRead(A_LineFile)
  2604. else
  2605. s:=this.GetScript()
  2606. re:="i)\n\s*FindText[^\n]+args\*[\s\S]*?Script_End[(){\s]+}"
  2607. if RegExMatch(s, re, &r)
  2608. s:="`n;==========`n" r[0] "`n"
  2609. _Gui["scr"].Value:=Result "`n" s
  2610. _Gui["MyPic"].Value:=Trim(this.ASCII(Result),"`n")
  2611. }
  2612. else if (Event="SplitAdd") || (Event="AllAdd")
  2613. {
  2614. s:=_Gui["scr"].Value
  2615. r:=SubStr(s, 1, InStr(s,"=FindText("))
  2616. i:=j:=0, re:="<[^>\n]*>[^$\n]+\$[^`"'\r\n]+"
  2617. While j:=RegExMatch(r, re,, j+1)
  2618. i:=InStr(r, "`n", 0, j)
  2619. _Gui["scr"].Value:=SubStr(s,1,i) . Result . SubStr(s,i+1)
  2620. _Gui["MyPic"].Value:=Trim(this.ASCII(Result),"`n")
  2621. }
  2622. if (Event) && RegExMatch(Result, "\$\d+\.[\w+/]{1,100}", &r)
  2623. this.EditScroll(hscr, "\Q" r[0] "\E")
  2624. Event:=Result:=s:=""
  2625. ;----------------------
  2626. Gui_Show()
  2627. return
  2628. Case "CaptureUpdate":
  2629. nX:=sx, nY:=sy, nW:=sw, nH:=sh
  2630. bits:=this.GetBitsFromScreen(&nX,&nY,&nW,&nH,0,&zx,&zy)
  2631. cors:=Map(), cors.Default:=0
  2632. , cut:=Map(), cut.Default:=0
  2633. , ascii:=Map(), ascii.Default:=0
  2634. bg:=color:="", dx:=dy:=CutLeft:=CutRight:=CutUp:=CutDown:=0
  2635. ListLines (lls:=A_ListLines)?0:0
  2636. if (nW>0 && nH>0 && bits.Scan0)
  2637. {
  2638. j:=bits.Stride-nW*4, p:=bits.Scan0+(nY-zy)*bits.Stride+(nX-zx)*4-4-j
  2639. Loop nH + 0*(k:=0)
  2640. Loop nW + 0*(p+=j)
  2641. cors[++k]:=NumGet(p+=4,"uint")
  2642. }
  2643. Loop 25 + 0*(ty:=dy-1)*(k:=0)
  2644. Loop 71 + 0*(tx:=dx-1)*(ty++)
  2645. {
  2646. c:=(++tx)<nW && ty<nH ? cors[ty*nW+tx+1] : WindowColor
  2647. SendMessage 0x2001,0,(c&0xFF)<<16|c&0xFF00|(c>>16)&0xFF,C_[++k]
  2648. }
  2649. Loop 71 + 0*(k:=71*25)
  2650. SendMessage 0x2001,0,0xAAFFFF,C_[++k]
  2651. ListLines lls
  2652. _Gui:=FindText_Capture
  2653. _Gui["MySlider1"].Enabled:=nW>71
  2654. _Gui["MySlider2"].Enabled:=nH>25
  2655. _Gui["MySlider1"].Value:=0
  2656. _Gui["MySlider2"].Value:=0
  2657. return
  2658. Case "PicUpdate":
  2659. FindText_SubPic[sub_hpic].Value:="*w0 *h0 HBITMAP:" hBM
  2660. _Gui:=FindText_Capture
  2661. _Gui["MySlider3"].Value:=0
  2662. _Gui["MySlider4"].Value:=0
  2663. Gui_("MySlider3")
  2664. return
  2665. Case "Reset":
  2666. Gui_("CaptureUpdate")
  2667. return
  2668. Case "LoadPic":
  2669. _Gui:=FindText_Capture
  2670. _Gui.Opt "+OwnDialogs"
  2671. f:=arg1
  2672. if (f="")
  2673. {
  2674. if !FileExist(SavePicDir)
  2675. DirCreate(SavePicDir)
  2676. f:=SavePicDir "*.bmp"
  2677. Loop Files, f
  2678. f:=A_LoopFileFullPath
  2679. f:=FileSelect(, f, "Select Picture")
  2680. }
  2681. if !FileExist(f)
  2682. {
  2683. MsgBox(Lang["s17"] " !", "Tip", "4096 T1")
  2684. return
  2685. }
  2686. this.ShowPic(f, 0, &sx, &sy, &sw, &sh)
  2687. hBM:=this.BitmapFromScreen(&sx, &sy, &sw, &sh, 0)
  2688. sw:=Min(sw,200), sh:=Min(sh,200)
  2689. Gui_("CaptureUpdate")
  2690. Gui_("PicUpdate")
  2691. return
  2692. Case "SavePic":
  2693. _Gui:=FindText_Capture
  2694. SelectBox:=_Gui["SelectBox"].Value
  2695. Try f:="", f:=Names[SelectBox]
  2696. _Gui.Hide
  2697. this.ShowPic(f)
  2698. pos:=this.SnapShot(0)
  2699. Gui_("ScreenShot", pos[1] "|" pos[2] "|" pos[3] "|" pos[4] "|0")
  2700. this.ShowPic()
  2701. return
  2702. Case "SelectBox":
  2703. _Gui:=FindText_Capture
  2704. SelectBox:=_Gui["SelectBox"].Value
  2705. Try f:="", f:=Names[SelectBox]
  2706. if (f!="")
  2707. Gui_("LoadPic", f)
  2708. return
  2709. Case "ClearAll":
  2710. FindText_Capture.Hide
  2711. Try FileDelete(SavePicDir "*.bmp")
  2712. return
  2713. Case "OpenDir":
  2714. FindText_Capture.Minimize
  2715. if !FileExist(SavePicDir)
  2716. DirCreate(SavePicDir)
  2717. Run SavePicDir
  2718. return
  2719. Case "GetRange":
  2720. _Gui:=FindText_Main
  2721. _Gui.Opt "+LastFound"
  2722. this.Hide()
  2723. p:=this.SnapShot(), v:=p[1] ", " p[2] ", " p[3] ", " p[4]
  2724. s:=_Gui["scr"].Value
  2725. re:="i)(=FindText\([^\n]*?)([^(,\n]*,){4}([^,\n]*,[^,\n]*,[^,\n]*Text)"
  2726. if SubStr(s,1,s~="i)\n\s*FindText[^\n]+args\*")~=re
  2727. {
  2728. s:=RegExReplace(s, re, "$1 " v ",$3",, 1)
  2729. _Gui["scr"].Value:=s
  2730. }
  2731. _Gui["Offset"].Value:=v
  2732. Gui_Show()
  2733. return
  2734. Case "Test", "TestClip":
  2735. _Gui:=FindText_Main
  2736. _Gui.Opt "+LastFound"
  2737. this.Hide()
  2738. ;----------------------
  2739. if (cmd="Test")
  2740. s:=_Gui["scr"].Value
  2741. else
  2742. s:=_Gui["ClipText"].Value
  2743. if (cmd="Test") && InStr(s, "MCode(")
  2744. {
  2745. s:="`nA_TrayMenu.ClickCount:=1`n" s "`nExitApp`n"
  2746. Thread1:=FindTextClass.Thread(s)
  2747. DetectHiddenWindows 1
  2748. if WinWait("ahk_class AutoHotkey ahk_pid " Thread1.pid,, 3)
  2749. WinWaitClose(,, 30)
  2750. ; Thread1:="" ; kill the Thread
  2751. }
  2752. else
  2753. {
  2754. t:=A_TickCount, v:=X:=Y:=""
  2755. if RegExMatch(s, "<[^>\n]*>[^$\n]+\$[^`"'\r\n]+", &r)
  2756. v:=this.FindText(&X, &Y, 0,0,0,0, 0,0, r[0])
  2757. r:=StrSplit(Lang["s8"] "||||", "|")
  2758. MsgBox(r[1] ":`t" (IsObject(v)?v.Length:v) "`n`n"
  2759. . r[2] ":`t" (A_TickCount-t) " " r[3] "`n`n"
  2760. . r[4] ":`t" X ", " Y "`n`n"
  2761. . r[5] ":`t<" (IsObject(v)?v[1].id:"") ">", "Tip", "4096 T3")
  2762. Try For i,j in v
  2763. if (i<=2)
  2764. this.MouseTip(j.x, j.y)
  2765. v:="", A_Clipboard:=X "," Y
  2766. }
  2767. ;----------------------
  2768. Gui_Show()
  2769. return
  2770. Case "GetOffset", "GetClipOffset":
  2771. FindText_Main.Hide
  2772. p:=this.GetRange()
  2773. _Gui:=FindText_Main
  2774. if (cmd="GetOffset")
  2775. s:=_Gui["scr"].Value
  2776. else
  2777. s:=_Gui["ClipText"].Value
  2778. if RegExMatch(s, "<[^>\n]*>[^$\n]+\$[^`"'\r\n]+", &r)
  2779. && this.FindText(&X, &Y, 0,0,0,0, 0,0, r[0])
  2780. {
  2781. r:=StrReplace("X+" ((p[1]+p[3])//2-X)
  2782. . ", Y+" ((p[2]+p[4])//2-Y), "+-", "-")
  2783. if (cmd="GetOffset")
  2784. {
  2785. re:="i)(\(\)\.\w*Click\w*\()[^,\n]*,[^,)\n]*"
  2786. if SubStr(s,1,s~="i)\n\s*FindText[^\n]+args\*")~=re
  2787. s:=RegExReplace(s, re, "$1" r,, 1)
  2788. _Gui["scr"].Value:=s
  2789. }
  2790. _Gui["Offset"].Value:=r
  2791. }
  2792. s:="", Gui_Show()
  2793. return
  2794. Case "Paste":
  2795. s:=A_Clipboard
  2796. if RegExMatch(s, "\|?<[^>\n]*>[^$\n]+\$[^`"'\r\n]+", &r)
  2797. {
  2798. _Gui:=FindText_Main
  2799. _Gui["ClipText"].Value:=r[0]
  2800. _Gui["MyPic"].Value:=Trim(this.ASCII(r[0]),"`n")
  2801. }
  2802. return
  2803. Case "CopyOffset":
  2804. _Gui:=FindText_Main
  2805. s:=_Gui["Offset"].Value
  2806. A_Clipboard:=s
  2807. return
  2808. Case "Copy":
  2809. _Gui:=FindText_Main
  2810. s:=EditGetSelectedText(hscr)
  2811. if (s="")
  2812. {
  2813. s:=_Gui["scr"].Value
  2814. r:=_Gui["AddFunc"].Value
  2815. if (r != 1)
  2816. s:=RegExReplace(s, "i)\n\s*FindText[^\n]+args\*[\s\S]*")
  2817. , s:=RegExReplace(s, "i)\n; ok:=FindText[\s\S]*")
  2818. , s:=SubStr(s, (s~="i)\n[ \t]*Text"))
  2819. }
  2820. A_Clipboard:=RegExReplace(s, "\R", "`r`n")
  2821. ControlFocus(hscr)
  2822. return
  2823. Case "Apply":
  2824. _Gui:=FindText_Main
  2825. NowHotkey:=_Gui["NowHotkey"].Value
  2826. SetHotkey1:=_Gui["SetHotkey1"].Value
  2827. SetHotkey2:=_Gui["SetHotkey2"].Text
  2828. if (NowHotkey!="")
  2829. Try Hotkey "*" NowHotkey,, "Off"
  2830. k:=SetHotkey1!="" ? SetHotkey1 : SetHotkey2
  2831. if (k!="")
  2832. Try Hotkey "*" k, Gui_ScreenShot, "On"
  2833. _Gui["NowHotkey"].Value:=k
  2834. _Gui["SetHotkey1"].Value:=""
  2835. _Gui["SetHotkey2"].Choose(0)
  2836. return
  2837. Case "ScreenShot":
  2838. Critical
  2839. if !FileExist(SavePicDir)
  2840. DirCreate(SavePicDir)
  2841. Loop
  2842. f:=SavePicDir . Format("{:03d}.bmp",A_Index)
  2843. Until !FileExist(f)
  2844. this.SavePic(f, StrSplit(arg1,"|")*)
  2845. CoordMode "ToolTip"
  2846. this.ToolTip(Lang["s9"],, 0,, { bgcolor:"Yellow", color:"Red"
  2847. , size:48, bold:"bold", trans:200, timeout:0.2 })
  2848. return
  2849. Case "Bind0", "Bind1", "Bind2", "Bind3", "Bind4":
  2850. this.BindWindow(Bind_ID, bind_mode:=SubStr(cmd,5))
  2851. n:=150000, x:=y:=-n, w:=h:=2*n
  2852. hBM:=this.BitmapFromScreen(&x,&y,&w,&h,1)
  2853. Gui_("PicUpdate")
  2854. FindText_Capture["MyTab1"].Choose(2)
  2855. this.BindWindow(0)
  2856. return
  2857. Case "MySlider1", "MySlider2":
  2858. SetTimer Gui_Slider, -10
  2859. return
  2860. Case "Slider":
  2861. Critical
  2862. _Gui:=FindText_Capture
  2863. MySlider1:=_Gui["MySlider1"].Value
  2864. MySlider2:=_Gui["MySlider2"].Value
  2865. dx:=nW>71 ? Round((nW-71)*MySlider1/100) : 0
  2866. dy:=nH>25 ? Round((nH-25)*MySlider2/100) : 0
  2867. if (oldx=dx && oldy=dy)
  2868. return
  2869. ListLines (lls:=A_ListLines)?0:0
  2870. Loop 25 + 0*(ty:=dy-1)*(k:=0)
  2871. Loop 71 + 0*(tx:=dx-1)*(ty++)
  2872. {
  2873. c:=((++tx)>=nW || ty>=nH || cut[i:=ty*nW+tx+1]
  2874. ? WindowColor : bg="" ? cors[i] : ascii[i])
  2875. SendMessage 0x2001,0,(c&0xFF)<<16|c&0xFF00|(c>>16)&0xFF,C_[++k]
  2876. }
  2877. Loop 71*(oldx!=dx) + 0*(i:=nW*nH+dx)*(k:=71*25)
  2878. SendMessage 0x2001,0,(cut[++i]?0x0000FF:0xAAFFFF),C_[++k]
  2879. ListLines lls
  2880. oldx:=dx, oldy:=dy
  2881. return
  2882. Case "MySlider3", "MySlider4":
  2883. _Gui:=FindText_Capture
  2884. _Gui[parent_id].GetPos(,, &pW, &pH)
  2885. MySlider3:=_Gui["MySlider3"].Value
  2886. MySlider4:=_Gui["MySlider4"].Value
  2887. w:=pW, h:=pH
  2888. FindText_SubPic[sub_hpic].GetPos(,, &pW, &pH)
  2889. x:=pW>w ? -Round((pW-w)*MySlider3/100) : 0
  2890. y:=pH>h ? -Round((pH-h)*MySlider4/100) : 0
  2891. FindText_SubPic.Show "NA x" x " y" y " w" pW " h" pH
  2892. return
  2893. Case "RepColor":
  2894. cut[k]:=0, c:=(bg="" ? cors[k] : ascii[k])
  2895. if (tx:=Mod(k-1,nW)-dx)>=0 && tx<71 && (ty:=(k-1)//nW-dy)>=0 && ty<25
  2896. SendMessage 0x2001,0,(c&0xFF)<<16|c&0xFF00|(c>>16)&0xFF,C_[ty*71+tx+1]
  2897. return
  2898. Case "CutColor":
  2899. cut[k]:=1, c:=WindowColor
  2900. if (tx:=Mod(k-1,nW)-dx)>=0 && tx<71 && (ty:=(k-1)//nW-dy)>=0 && ty<25
  2901. SendMessage 0x2001,0,(c&0xFF)<<16|c&0xFF00|(c>>16)&0xFF,C_[ty*71+tx+1]
  2902. return
  2903. Case "RepL":
  2904. if (CutLeft<=0) || (bg!="" && InStr(color,"**") && CutLeft=1)
  2905. return
  2906. k:=CutLeft-nW, CutLeft--
  2907. Loop nH
  2908. k+=nW, (A_Index>CutUp && A_Index<nH+1-CutDown && Gui_("RepColor"))
  2909. return
  2910. Case "CutL":
  2911. if (CutLeft+CutRight>=nW)
  2912. return
  2913. CutLeft++, k:=CutLeft-nW
  2914. Loop nH
  2915. k+=nW, (A_Index>CutUp && A_Index<nH+1-CutDown && Gui_("CutColor"))
  2916. return
  2917. Case "CutL3":
  2918. Loop 3
  2919. Gui_("CutL")
  2920. return
  2921. Case "RepR":
  2922. if (CutRight<=0) || (bg!="" && InStr(color,"**") && CutRight=1)
  2923. return
  2924. k:=1-CutRight, CutRight--
  2925. Loop nH
  2926. k+=nW, (A_Index>CutUp && A_Index<nH+1-CutDown && Gui_("RepColor"))
  2927. return
  2928. Case "CutR":
  2929. if (CutLeft+CutRight>=nW)
  2930. return
  2931. CutRight++, k:=1-CutRight
  2932. Loop nH
  2933. k+=nW, (A_Index>CutUp && A_Index<nH+1-CutDown && Gui_("CutColor"))
  2934. return
  2935. Case "CutR3":
  2936. Loop 3
  2937. Gui_("CutR")
  2938. return
  2939. Case "RepU":
  2940. if (CutUp<=0) || (bg!="" && InStr(color,"**") && CutUp=1)
  2941. return
  2942. k:=(CutUp-1)*nW, CutUp--
  2943. Loop nW
  2944. k++, (A_Index>CutLeft && A_Index<nW+1-CutRight && Gui_("RepColor"))
  2945. return
  2946. Case "CutU":
  2947. if (CutUp+CutDown>=nH)
  2948. return
  2949. CutUp++, k:=(CutUp-1)*nW
  2950. Loop nW
  2951. k++, (A_Index>CutLeft && A_Index<nW+1-CutRight && Gui_("CutColor"))
  2952. return
  2953. Case "CutU3":
  2954. Loop 3
  2955. Gui_("CutU")
  2956. return
  2957. Case "RepD":
  2958. if (CutDown<=0) || (bg!="" && InStr(color,"**") && CutDown=1)
  2959. return
  2960. k:=(nH-CutDown)*nW, CutDown--
  2961. Loop nW
  2962. k++, (A_Index>CutLeft && A_Index<nW+1-CutRight && Gui_("RepColor"))
  2963. return
  2964. Case "CutD":
  2965. if (CutUp+CutDown>=nH)
  2966. return
  2967. CutDown++, k:=(nH-CutDown)*nW
  2968. Loop nW
  2969. k++, (A_Index>CutLeft && A_Index<nW+1-CutRight && Gui_("CutColor"))
  2970. return
  2971. Case "CutD3":
  2972. Loop 3
  2973. Gui_("CutD")
  2974. return
  2975. Case "Gray2Two":
  2976. ListLines (lls:=A_ListLines)?0:0
  2977. gray:=Map(), gray.Default:=0, k:=0
  2978. Loop nW*nH
  2979. gray[++k]:=((((c:=cors[k])>>16)&0xFF)*38+((c>>8)&0xFF)*75+(c&0xFF)*15)>>7
  2980. _Gui:=FindText_Capture
  2981. _Gui["Threshold"].Focus()
  2982. Threshold:=_Gui["Threshold"].Value
  2983. if (Threshold="")
  2984. {
  2985. pp:=Map(), pp.Default:=0
  2986. Loop 256
  2987. pp[A_Index-1]:=0
  2988. Loop nW*nH
  2989. if (!cut[A_Index])
  2990. pp[gray[A_Index]]++
  2991. IP0:=IS0:=0
  2992. Loop 256
  2993. k:=A_Index-1, IP0+=k*pp[k], IS0+=pp[k]
  2994. Threshold:=Floor(IP0/IS0)
  2995. Loop 20
  2996. {
  2997. LastThreshold:=Threshold
  2998. IP1:=IS1:=0
  2999. Loop LastThreshold+1
  3000. k:=A_Index-1, IP1+=k*pp[k], IS1+=pp[k]
  3001. IP2:=IP0-IP1, IS2:=IS0-IS1
  3002. if (IS1!=0 && IS2!=0)
  3003. Threshold:=Floor((IP1/IS1+IP2/IS2)/2)
  3004. if (Threshold=LastThreshold)
  3005. Break
  3006. }
  3007. _Gui["Threshold"].Value:=Threshold
  3008. }
  3009. Threshold:=Round(Threshold)
  3010. color:="*" Threshold, k:=i:=0
  3011. Loop nW*nH
  3012. ascii[++k]:=v:=(gray[k]<=Threshold
  3013. ? 0x000000:0xFFFFFF), (!cut[k] && i:=(v?i-1:i+1))
  3014. bg:=(i>0 ? "1":"0")
  3015. ;--------------
  3016. Loop 25 + 0*(ty:=dy-1)*(k:=0)
  3017. Loop 71 + 0*(tx:=dx-1)*(ty++)
  3018. if (k++)*0 + (++tx)<nW && ty<nH && !cut[i:=ty*nW+tx+1]
  3019. SendMessage 0x2001,0,ascii[i],C_[k]
  3020. ListLines lls
  3021. return
  3022. Case "GrayDiff2Two":
  3023. _Gui:=FindText_Capture
  3024. GrayDiff:=_Gui["GrayDiff"].Value
  3025. if (GrayDiff="")
  3026. {
  3027. _Gui.Opt "+OwnDialogs"
  3028. MsgBox(Lang["s11"] " !", "Tip", "4096 T1")
  3029. return
  3030. }
  3031. ListLines (lls:=A_ListLines)?0:0
  3032. gray:=Map(), gray.Default:=0, k:=0
  3033. Loop nW*nH
  3034. gray[++k]:=((((c:=cors[k])>>16)&0xFF)*38+((c>>8)&0xFF)*75+(c&0xFF)*15)>>7
  3035. if (CutLeft=0)
  3036. Gui_("CutL")
  3037. if (CutRight=0)
  3038. Gui_("CutR")
  3039. if (CutUp=0)
  3040. Gui_("CutU")
  3041. if (CutDown=0)
  3042. Gui_("CutD")
  3043. GrayDiff:=Round(GrayDiff)
  3044. color:="**" GrayDiff, k:=i:=0
  3045. Loop nW*nH
  3046. j:=gray[++k]+GrayDiff
  3047. , ascii[k]:=v:=(gray[k-1]>j || gray[k+1]>j
  3048. || gray[k-nW]>j || gray[k+nW]>j
  3049. || gray[k-nW-1]>j || gray[k-nW+1]>j
  3050. || gray[k+nW-1]>j || gray[k+nW+1]>j
  3051. ? 0x000000:0xFFFFFF), (!cut[k] && i:=(v?i-1:i+1))
  3052. bg:=(i>0 ? "1":"0")
  3053. ;--------------
  3054. Loop 25 + 0*(ty:=dy-1)*(k:=0)
  3055. Loop 71 + 0*(tx:=dx-1)*(ty++)
  3056. if (k++)*0 + (++tx)<nW && ty<nH && !cut[i:=ty*nW+tx+1]
  3057. SendMessage 0x2001,0,ascii[i],C_[k]
  3058. ListLines lls
  3059. return
  3060. Case "Color2Two", "ColorPos2Two":
  3061. _Gui:=FindText_Capture
  3062. c:=_Gui["SelColor"].Value
  3063. if (c="")
  3064. {
  3065. _Gui.Opt "+OwnDialogs"
  3066. MsgBox(Lang["s12"] " !", "Tip", "4096 T1")
  3067. return
  3068. }
  3069. UsePos:=(cmd="ColorPos2Two")
  3070. n:=this.Floor(_Gui[UsePos?"Similar2":"Similar1"].Value)
  3071. n:=Round(n/100,2), color:=StrReplace(c,"0x") "@" n
  3072. , n:=Floor(4606*255*255*(1-n)*(1-n)), k:=i:=0
  3073. , rr:=(c>>16)&0xFF, gg:=(c>>8)&0xFF, bb:=c&0xFF
  3074. ListLines (lls:=A_ListLines)?0:0
  3075. Loop nW*nH
  3076. c:=cors[++k], r:=((c>>16)&0xFF)-rr
  3077. , g:=((c>>8)&0xFF)-gg, b:=(c&0xFF)-bb, j:=r+rr+rr
  3078. , ascii[k]:=v:=((1024+j)*r*r+2048*g*g+(1534-j)*b*b<=n
  3079. ? 0x000000:0xFFFFFF), (!cut[k] && i:=(v?i-1:i+1))
  3080. bg:=(i>0 ? "1":"0")
  3081. ;--------------
  3082. Loop 25 + 0*(ty:=dy-1)*(k:=0)
  3083. Loop 71 + 0*(tx:=dx-1)*(ty++)
  3084. if (k++)*0 + (++tx)<nW && ty<nH && !cut[i:=ty*nW+tx+1]
  3085. SendMessage 0x2001,0,ascii[i],C_[k]
  3086. ListLines lls
  3087. return
  3088. Case "ColorDiff2Two":
  3089. _Gui:=FindText_Capture
  3090. c:=_Gui["SelColor"].Value
  3091. if (c="")
  3092. {
  3093. _Gui.Opt "+OwnDialogs"
  3094. MsgBox(Lang["s12"] " !", "Tip", "4096 T1")
  3095. return
  3096. }
  3097. dR:=_Gui["dR"].Value
  3098. dG:=_Gui["dG"].Value
  3099. dB:=_Gui["dB"].Value
  3100. rr:=(c>>16)&0xFF, gg:=(c>>8)&0xFF, bb:=c&0xFF
  3101. , n:=Format("{:06X}",(dR<<16)|(dG<<8)|dB)
  3102. , color:=StrReplace(c "-" n,"0x"), k:=i:=0
  3103. ListLines (lls:=A_ListLines)?0:0
  3104. Loop nW*nH
  3105. c:=cors[++k], r:=(c>>16)&0xFF, g:=(c>>8)&0xFF, b:=c&0xFF
  3106. , ascii[k]:=v:=(Abs(r-rr)<=dR && Abs(g-gg)<=dG && Abs(b-bb)<=dB
  3107. ? 0x000000:0xFFFFFF), (!cut[k] && i:=(v?i-1:i+1))
  3108. bg:=(i>0 ? "1":"0")
  3109. ;--------------
  3110. Loop 25 + 0*(ty:=dy-1)*(k:=0)
  3111. Loop 71 + 0*(tx:=dx-1)*(ty++)
  3112. if (k++)*0 + (++tx)<nW && ty<nH && !cut[i:=ty*nW+tx+1]
  3113. SendMessage 0x2001,0,ascii[i],C_[k]
  3114. ListLines lls
  3115. return
  3116. Case "Modify":
  3117. _Gui:=FindText_Capture
  3118. Modify:=_Gui["Modify"].Value
  3119. return
  3120. Case "MultiColor":
  3121. _Gui:=FindText_Capture
  3122. MultiColor:=_Gui["MultiColor"].Value
  3123. Result:=""
  3124. ToolTip
  3125. return
  3126. Case "Undo":
  3127. Result:=RegExReplace(Result, ",[^/]+/[^/]+/[^/]+$")
  3128. ToolTip Trim(Result,"/,")
  3129. return
  3130. Case "Similar1":
  3131. _Gui:=FindText_Capture
  3132. _Gui["Similar2"].Value:=_Gui["Similar1"].Value
  3133. return
  3134. Case "Similar2":
  3135. _Gui:=FindText_Capture
  3136. _Gui["Similar1"].Value:=_Gui["Similar2"].Value
  3137. return
  3138. Case "GetTxt":
  3139. txt:=""
  3140. if (bg="")
  3141. return
  3142. k:=0
  3143. ListLines (lls:=A_ListLines)?0:0
  3144. Loop nH
  3145. {
  3146. v:=""
  3147. Loop nW
  3148. v.=cut[++k] ? "" : ascii[k] ? "0":"1"
  3149. txt.=v="" ? "" : v "`n"
  3150. }
  3151. ListLines lls
  3152. return
  3153. Case "Auto":
  3154. Gui_("GetTxt")
  3155. if (txt="")
  3156. {
  3157. FindText_Capture.Opt "+OwnDialogs"
  3158. MsgBox(Lang["s13"] " !", "Tip", "4096 T1")
  3159. return
  3160. }
  3161. While InStr(txt,bg)
  3162. {
  3163. if (txt~="^" bg "+\n")
  3164. txt:=RegExReplace(txt, "^" bg "+\n"), Gui_("CutU")
  3165. else if !(txt~="m`n)[^\n" bg "]$")
  3166. txt:=RegExReplace(txt, "m`n)" bg "$"), Gui_("CutR")
  3167. else if (txt~="\n" bg "+\n$")
  3168. txt:=RegExReplace(txt, "\n\K" bg "+\n$"), Gui_("CutD")
  3169. else if !(txt~="m`n)^[^\n" bg "]")
  3170. txt:=RegExReplace(txt, "m`n)^" bg), Gui_("CutL")
  3171. else Break
  3172. }
  3173. txt:=""
  3174. return
  3175. Case "OK", "SplitAdd", "AllAdd":
  3176. _Gui:=FindText_Capture
  3177. _Gui.Opt "+OwnDialogs"
  3178. Gui_("GetTxt")
  3179. if (txt="") && (!MultiColor)
  3180. {
  3181. MsgBox(Lang["s13"] " !", "Tip", "4096 T1")
  3182. return
  3183. }
  3184. if InStr(color,"@") && (UsePos) && (!MultiColor)
  3185. {
  3186. r:=StrSplit(color,"@")
  3187. k:=i:=j:=0
  3188. ListLines (lls:=A_ListLines)?0:0
  3189. Loop nW*nH
  3190. {
  3191. if (cut[++k])
  3192. Continue
  3193. i++
  3194. if (k=cors.SelPos)
  3195. {
  3196. j:=i
  3197. Break
  3198. }
  3199. }
  3200. ListLines lls
  3201. if (j=0)
  3202. {
  3203. MsgBox(Lang["s12"] " !", "Tip", "4096 T1")
  3204. return
  3205. }
  3206. color:="#" j "@" r[2]
  3207. }
  3208. Comment:=_Gui["Comment"].Value
  3209. if (cmd="SplitAdd") && (!MultiColor)
  3210. {
  3211. if InStr(color,"#")
  3212. {
  3213. MsgBox(Lang["s14"], "Tip", "4096 T3")
  3214. return
  3215. }
  3216. bg:=StrLen(StrReplace(txt,"0"))
  3217. > StrLen(StrReplace(txt,"1")) ? "1":"0"
  3218. s:="", i:=0, k:=nW*nH+1+CutLeft
  3219. Loop w:=nW-CutLeft-CutRight
  3220. {
  3221. i++
  3222. if (!cut[k++] && A_Index<w)
  3223. Continue
  3224. i:=Format("{:d}",i)
  3225. v:=RegExReplace(txt,"m`n)^(.{" i "}).*","$1")
  3226. txt:=RegExReplace(txt,"m`n)^.{" i "}"), i:=0
  3227. While InStr(v,bg)
  3228. {
  3229. if (v~="^" bg "+\n")
  3230. v:=RegExReplace(v,"^" bg "+\n")
  3231. else if !(v~="m`n)[^\n" bg "]$")
  3232. v:=RegExReplace(v,"m`n)" bg "$")
  3233. else if (v~="\n" bg "+\n$")
  3234. v:=RegExReplace(v,"\n\K" bg "+\n$")
  3235. else if !(v~="m`n)^[^\n" bg "]")
  3236. v:=RegExReplace(v,"m`n)^" bg)
  3237. else Break
  3238. }
  3239. if (v!="")
  3240. {
  3241. v:=Format("{:d}",InStr(v,"`n")-1) "." this.bit2base64(v)
  3242. s.="`nText.=`"|<" SubStr(Comment, 1, 1) ">" color "$" v "`"`n"
  3243. Comment:=SubStr(Comment, 2)
  3244. }
  3245. }
  3246. Event:=cmd, Result:=s
  3247. _Gui.Hide
  3248. return
  3249. }
  3250. if (!MultiColor)
  3251. txt:=Format("{:d}",InStr(txt,"`n")-1) "." this.bit2base64(txt)
  3252. else
  3253. {
  3254. n:=_Gui["dRGB"].Value
  3255. color:=Format("##{:06X}", n<<16|n<<8|n)
  3256. r:=StrSplit(Trim(StrReplace(Result, ",", "/"), "/"), "/")
  3257. , x:=(r.Has(1)?r[1]:0), y:=(r.Has(2)?r[2]:0), s:="", i:=1
  3258. Loop r.Length//3
  3259. s.="," (r[i++]-x) "/" (r[i++]-y) "/" r[i++]
  3260. txt:=SubStr(s,2)
  3261. }
  3262. s:="`nText.=`"|<" Comment ">" color "$" txt "`"`n"
  3263. if (cmd="AllAdd")
  3264. {
  3265. Event:=cmd, Result:=s
  3266. _Gui.Hide
  3267. return
  3268. }
  3269. x:=nX+CutLeft+(nW-CutLeft-CutRight)//2
  3270. y:=nY+CutUp+(nH-CutUp-CutDown)//2
  3271. s:=StrReplace(s, "Text.=", "Text:="), r:=StrSplit(Lang["s8"] "|||||||", "|")
  3272. s:="`; #Include <FindText>`n"
  3273. . "`nt1:=A_TickCount, Text:=X:=Y:=`"`"`n" s
  3274. . "`nif (ok:=FindText(&X, &Y, " x "-150000, "
  3275. . y "-150000, " x "+150000, " y "+150000, 0, 0, Text))"
  3276. . "`n{"
  3277. . "`n `; FindText()." . "Click(" . "X, Y, `"L`")"
  3278. . "`n}`n"
  3279. . "`n`; ok:=FindText(&X:=`"wait`", &Y:=3, 0,0,0,0,0,0,Text) `; " r[7]
  3280. . "`n`; ok:=FindText(&X:=`"wait0`", &Y:=-1, 0,0,0,0,0,0,Text) `; " r[8]
  3281. . "`n`nMsgBox(`"" r[1] ":``t`" (IsObject(ok)?ok.Length:ok)"
  3282. . "`n . `"``n``n" r[2] ":``t`" (A_TickCount-t1) `" " r[3] "`""
  3283. . "`n . `"``n``n" r[4] ":``t`" X `", `" Y"
  3284. . "`n . `"``n``n" r[5] ":``t<`" (IsObject(ok)?ok[1].id:`"`") `">`", `"Tip`", 4096)`n"
  3285. . "`nTry For i,v in ok `; ok " r[6] " ok:=FindText().ok"
  3286. . "`n if (i<=2)"
  3287. . "`n FindText().MouseTip(ok[i].x, ok[i].y)`n"
  3288. Event:=cmd, Result:=s
  3289. _Gui.Hide
  3290. return
  3291. Case "SavePic2":
  3292. x:=nX+CutLeft, w:=nW-CutLeft-CutRight
  3293. y:=nY+CutUp, h:=nH-CutUp-CutDown
  3294. Gui_("ScreenShot", x "|" y "|" (x+w-1) "|" (y+h-1) "|0")
  3295. return
  3296. Case "ShowPic":
  3297. _Gui:=FindText_Main
  3298. i:=EditGetCurrentLine(hscr)
  3299. s:=EditGetLine(i, hscr)
  3300. _Gui["MyPic"].Value:=Trim(this.ASCII(s),"`n")
  3301. return
  3302. Case "KeyDown":
  3303. Critical
  3304. _Gui:=FindText_Main
  3305. if (WinExist()!=_Gui.Hwnd)
  3306. return
  3307. Try ctrl:="", ctrl:=args[3]
  3308. if (ctrl=hscr)
  3309. SetTimer Gui_ShowPic, -150
  3310. else if (ctrl=_Gui["ClipText"].Hwnd)
  3311. {
  3312. s:=_Gui["ClipText"].Value
  3313. _Gui["MyPic"].Value:=Trim(this.ASCII(s),"`n")
  3314. }
  3315. return
  3316. Case "LButtonDown":
  3317. Critical
  3318. Try k1:="", k1:=GuiFromHwnd(args[3],1).Hwnd
  3319. if (k1=FindText_SubPic.Hwnd)
  3320. {
  3321. ; Two windows trigger two messages
  3322. if (A_TickCount-oldt)<100 || !GetKeyState("LButton","P")
  3323. return
  3324. CoordMode "Mouse"
  3325. MouseGetPos &k1, &k2
  3326. ListLines (lls:=A_ListLines)?0:0
  3327. Loop
  3328. {
  3329. Sleep 50
  3330. MouseGetPos &k3, &k4
  3331. this.RangeTip(Min(k1,k3), Min(k2,k4)
  3332. , Abs(k1-k3), Abs(k2-k4), (A_MSec<500 ? "Red":"Blue"))
  3333. }
  3334. Until !GetKeyState("LButton","P")
  3335. ListLines lls
  3336. this.RangeTip()
  3337. this.GetBitsFromScreen(,,,,0,&zx,&zy)
  3338. this.ClientToScreen(&sx, &sy, 0, 0, sub_hpic)
  3339. if Abs(k1-k3)+Abs(k2-k4)>4
  3340. sx:=zx+Min(k1,k3)-sx, sy:=zy+Min(k2,k4)-sy
  3341. , sw:=Abs(k1-k3), sh:=Abs(k2-k4)
  3342. else
  3343. sx:=zx+k1-sx-71//2, sy:=zy+k2-sy-25//2, sw:=71, sh:=25
  3344. Gui_("CaptureUpdate")
  3345. FindText_Capture["MyTab1"].Choose(1)
  3346. oldt:=A_TickCount
  3347. return
  3348. }
  3349. if (k1!=FindText_Capture.Hwnd)
  3350. return Gui_("KeyDown", arg1, args*)
  3351. MouseGetPos(,,, &k2, 2)
  3352. k1:=0
  3353. ListLines (lls:=A_ListLines)?0:0
  3354. For k_,v_ in C_
  3355. if (v_=k2) && (k1:=k_)
  3356. Break
  3357. ListLines lls
  3358. if (k1<1)
  3359. return
  3360. else if (k1>71*25)
  3361. {
  3362. k3:=nW*nH+dx+(k1-71*25)
  3363. SendMessage 0x2001,0,((cut[k3]:=!cut[k3])?0x0000FF:0xAAFFFF),k2
  3364. return
  3365. }
  3366. k2:=Mod(k1-1,71)+dx, k3:=(k1-1)//71+dy
  3367. if (k2<0 || k2>=nW || k3<0 || k3>=nH)
  3368. return
  3369. k1:=k, k4:=c, k:=k3*nW+k2+1
  3370. if (MultiColor && !cut[k])
  3371. {
  3372. c:="," (nX+k2) "/" (nY+k3) "/"
  3373. . Format("{:06X}",cors[k]&0xFFFFFF)
  3374. , Result.=InStr(Result,c) ? "":c
  3375. ToolTip Trim(Result,"/,")
  3376. }
  3377. if (Modify && bg!="" && !cut[k])
  3378. {
  3379. ascii[k]:=c:=(ascii[k] ? 0x000000:0xFFFFFF)
  3380. if (tx:=Mod(k-1,nW)-dx)>=0 && tx<71 && (ty:=(k-1)//nW-dy)>=0 && ty<25
  3381. SendMessage 0x2001,0,c,C_[ty*71+tx+1]
  3382. }
  3383. else
  3384. {
  3385. c:=cors[k], cors.SelPos:=k
  3386. _Gui:=FindText_Capture
  3387. _Gui["SelGray"].Value:=(((c>>16)&0xFF)*38+((c>>8)&0xFF)*75+(c&0xFF)*15)>>7
  3388. _Gui["SelColor"].Value:=Format("0x{:06X}",c&0xFFFFFF)
  3389. _Gui["SelR"].Value:=(c>>16)&0xFF
  3390. _Gui["SelG"].Value:=(c>>8)&0xFF
  3391. _Gui["SelB"].Value:=c&0xFF
  3392. }
  3393. k:=k1, c:=k4
  3394. return
  3395. Case "RButtonDown":
  3396. Critical
  3397. Try k1:="", k1:=GuiFromHwnd(args[3],1).Hwnd
  3398. if (k1!=FindText_SubPic.Hwnd)
  3399. return
  3400. ; Two windows trigger two messages
  3401. if (A_TickCount-oldt)<100 || !GetKeyState("RButton","P")
  3402. return
  3403. r:=[x, y, w, h, pX, pY, pW, pH]
  3404. CoordMode "Mouse"
  3405. MouseGetPos &k1, &k2
  3406. WinGetPos &x, &y, &w, &h, parent_id
  3407. WinGetPos &pX, &pY, &pW, &pH, sub_hpic
  3408. pX-=x, pY-=y, pW-=w, pH-=h
  3409. ListLines (lls:=A_ListLines)?0:0
  3410. Loop
  3411. {
  3412. Sleep 10
  3413. MouseGetPos &k3, &k4
  3414. x:=Min(Max(pX+k3-k1,-pW),0), y:=Min(Max(pY+k4-k2,-pH),0)
  3415. FindText_SubPic.Show "NA x" x " y" y
  3416. FindText_Capture["MySlider3"].Value:=Round(-x/pW*100)
  3417. FindText_Capture["MySlider4"].Value:=Round(-y/pH*100)
  3418. }
  3419. Until !GetKeyState("RButton","P")
  3420. ListLines lls
  3421. x:=r[1], y:=r[2], w:=r[3], h:=r[4], pX:=r[5], pY:=r[6], pW:=r[7], pH:=r[8]
  3422. oldt:=A_TickCount
  3423. return
  3424. Case "MouseMove":
  3425. Try ctrl_name:="", ctrl_name:=GuiCtrlFromHwnd(args[3]).Name
  3426. if (PrevControl != ctrl_name)
  3427. {
  3428. ToolTip
  3429. PrevControl:=ctrl_name
  3430. if IsSet(Gui_ToolTip)
  3431. {
  3432. SetTimer Gui_ToolTip, PrevControl ? -500 : 0
  3433. SetTimer Gui_ToolTipOff, PrevControl ? -5500 : 0
  3434. }
  3435. }
  3436. return
  3437. Case "ToolTip":
  3438. MouseGetPos(,, &_TT)
  3439. if WinExist("ahk_id " _TT " ahk_class AutoHotkeyGUI")
  3440. Try ToolTip Tip_Text[PrevControl]
  3441. return
  3442. Case "ToolTipOff":
  3443. ToolTip
  3444. return
  3445. Case "CutL2", "CutR2", "CutU2", "CutD2":
  3446. _Gui:=FindText_Main
  3447. s:=_Gui["MyPic"].Value
  3448. s:=Trim(s,"`n") . "`n", v:=SubStr(cmd,4,1)
  3449. if (v="U")
  3450. s:=RegExReplace(s,"^[^\n]+\n")
  3451. else if (v="D")
  3452. s:=RegExReplace(s,"[^\n]+\n$")
  3453. else if (v="L")
  3454. s:=RegExReplace(s,"m`n)^[^\n]")
  3455. else if (v="R")
  3456. s:=RegExReplace(s,"m`n)[^\n]$")
  3457. _Gui["MyPic"].Value:=Trim(s,"`n")
  3458. return
  3459. Case "Update":
  3460. _Gui:=FindText_Main
  3461. ControlFocus(hscr)
  3462. i:=EditGetCurrentLine(hscr)
  3463. s:=EditGetLine(i, hscr)
  3464. if !RegExMatch(s, "(<[^>\n]*>[^$\n]+\$)\d+\.[\w+/]+", &r)
  3465. return
  3466. v:=_Gui["MyPic"].Value
  3467. v:=Trim(v,"`n") . "`n", w:=Format("{:d}",InStr(v,"`n")-1)
  3468. v:=StrReplace(StrReplace(v,"0","1"),"_","0")
  3469. s:=StrReplace(s, r[0], r[1] . w "." this.bit2base64(v))
  3470. v:="{End}{Shift Down}{Home}{Shift Up}{Del}"
  3471. ControlSend(v, hscr)
  3472. EditPaste(s, hscr)
  3473. ControlSend("{Home}", hscr)
  3474. return
  3475. }
  3476. }
  3477. Lang(text:="", getLang:=0)
  3478. {
  3479. static Lang1:="", Lang2
  3480. if (!Lang1)
  3481. {
  3482. s:="
  3483. (
  3484. Myww = 宽度 = 调整抓图范围的宽度
  3485. Myhh = 高度 = 调整抓图范围的高度
  3486. AddFunc = 附加 = 复制时带 FindText() 函数
  3487. NowHotkey = 截屏热键 = 当前的截屏热键
  3488. SetHotkey1 = = 第一优先级的截屏热键
  3489. SetHotkey2 = = 第二优先级的截屏热键
  3490. Apply = 应用 = 应用新的截屏热键
  3491. CutU2 = 上删 = 裁剪下面编辑框中文字的上边缘
  3492. CutL2 = 左删 = 裁剪下面编辑框中文字的左边缘
  3493. CutR2 = 右删 = 裁剪下面编辑框中文字的右边缘
  3494. CutD2 = 下删 = 裁剪下面编辑框中文字的下边缘
  3495. Update = 更新 = 更新下面编辑框中文字到代码行中
  3496. GetRange = 获取屏幕范围 = 获取屏幕范围并替换代码中的范围参数
  3497. GetOffset = 获取相对坐标 = 获取相对图像位置的偏移坐标并替换代码中的坐标
  3498. GetClipOffset = 获取相对坐标2 = 获取相对左边编辑框的图像的偏移坐标
  3499. Capture = 抓图 = 开始屏幕抓图
  3500. CaptureS = 截屏抓图 = 先恢复某个截屏到屏幕上再开始抓图
  3501. Test = 测试 = 测试生成的代码是否可以查找成功
  3502. TestClip = 测试2 = 测试左边文本框中的文字,结果复制到剪贴板
  3503. Paste = 粘贴 = 粘贴剪贴板的文字数据
  3504. CopyOffset = 复制2 = 复制左边的偏移坐标到剪贴板
  3505. Copy = 复制 = 复制代码到剪贴板
  3506. Reset = 重读 = 重新读取原来的彩色图像
  3507. SplitAdd = 分割添加 = 使用黄色的标签来分割图像为单个的图像数据,添加到旧代码中
  3508. AllAdd = 整体添加 = 将文字数据整体添加到旧代码中
  3509. Gray2Two = 灰度阈值二值化 = 灰度小于阈值的为黑色其余白色
  3510. GrayDiff2Two = 灰度差值二值化 = 某点与周围灰度之差大于差值的为黑色其余白色
  3511. Color2Two = 颜色相似二值化 = 指定颜色及相似色为黑色其余白色
  3512. ColorPos2Two = 颜色位置二值化 = 指定颜色及相似色为黑色其余白色,但是记录该色的位置
  3513. ColorDiff2Two = 颜色分量二值化 = 指定颜色及颜色分量小于允许值的为黑色其余白色
  3514. SelGray = 灰度 = 选定颜色的灰度值 (0-255)
  3515. SelColor = 颜色 = 选定颜色的RGB颜色值
  3516. SelR = 红 = 选定颜色的红色分量
  3517. SelG = 绿 = 选定颜色的绿色分量
  3518. SelB = 蓝 = 选定颜色的蓝色分量
  3519. RepU = -上 = 撤销裁剪上边缘1个像素
  3520. CutU = 上 = 裁剪上边缘1个像素
  3521. CutU3 = 上3 = 裁剪上边缘3个像素
  3522. RepL = -左 = 撤销裁剪左边缘1个像素
  3523. CutL = 左 = 裁剪左边缘1个像素
  3524. CutL3 = 左3 = 裁剪左边缘3个像素
  3525. Auto = 自动 = 二值化之后自动裁剪空白边缘
  3526. RepR = -右 = 撤销裁剪右边缘1个像素
  3527. CutR = 右 = 裁剪右边缘1个像素
  3528. CutR3 = 右3 = 裁剪右边缘3个像素
  3529. RepD = -下 = 撤销裁剪下边缘1个像素
  3530. CutD = 下 = 裁剪下边缘1个像素
  3531. CutD3 = 下3 = 裁剪下边缘3个像素
  3532. Modify = 修改 = 二值化后可以用鼠标在预览区点击手动修改黑白点
  3533. MultiColor = 多色查找 = 鼠标选择多种颜色,之后点击“确定”按钮
  3534. Undo = 撤销 = 撤销上一次选择的颜色
  3535. Comment = 识别文字 = 识别文本 (包含在<>中),分割添加时也会分解成单个文字
  3536. Threshold = 灰度阈值 = 灰度阈值 (0-255)
  3537. GrayDiff = 灰度差值 = 灰度差值 (0-255)
  3538. Similar1 = 相似度 = 与选定颜色的相似度
  3539. Similar2 = 相似度 = 与选定颜色的相似度
  3540. DiffR = 红 = 红色分量允许的偏差 (0-255)
  3541. DiffG = 绿 = 绿色分量允许的偏差 (0-255)
  3542. DiffB = 蓝 = 蓝色分量允许的偏差 (0-255)
  3543. DiffRGB = 红/绿/蓝 = 多色查找时各分量允许的偏差 (0-255)
  3544. Bind0 = 绑定窗口1 = 绑定窗口使用GetDCEx()获取后台窗口图像
  3545. Bind1 = 绑定窗口1+ = 绑定窗口使用GetDCEx()并修改窗口透明度
  3546. Bind2 = 绑定窗口2 = 绑定窗口使用PrintWindow()获取后台窗口图像
  3547. Bind3 = 绑定窗口2+ = 绑定窗口使用PrintWindow()并修改窗口透明度
  3548. Bind4 = 绑定窗口3 = 绑定窗口使用PrintWindow(,,3)获取后台窗口图像
  3549. OK = 确定 = 生成全新的代码替换旧代码
  3550. OK2 = 确定 = 恢复截屏到屏幕然后再抓图
  3551. Cancel = 取消 = 关闭窗口不做任何事
  3552. Cancel2 = 取消 = 关闭窗口不做任何事
  3553. ClearAll = 清空 = 清空所有保存的截图
  3554. OpenDir = 打开目录 = 打开保存屏幕截图的目录
  3555. SavePic = 保存图片 = 选择一个范围保存为图片
  3556. SavePic2 = 保存图片 = 将修剪后的原始图像保存为图片
  3557. LoadPic = 载入图片 = 载入一张图片作为抓取的图像
  3558. ClipText = = 显示粘贴的文字数据
  3559. Offset = = 显示“获取相对坐标2”或者“获取屏幕范围”的结果
  3560. SelectBox = = 选择截图显示到屏幕左上角
  3561. s1 = FindText
  3562. s2 = 灰度阈值|灰度差值|颜色相似|颜色位置|颜色分量|多色查找
  3563. s3 = 图像二值化及分割
  3564. s4 = 抓图生成字库及找字代码
  3565. s5 = 方向键微调选框\n先点击右键一次\n把鼠标移开\n再点击右键一次
  3566. s6 = 解绑窗口使用
  3567. s7 = 请用左键拖动范围\n坐标复制到剪贴板
  3568. s8 = 找到|时间|毫秒|位置|结果|值可以这样获取|等待3秒等图像出现|无限等待等图像消失
  3569. s9 = 截屏成功
  3570. s10 = 鼠标位置|穿透显示绑定窗口\n点击右键完成抓图
  3571. s11 = 请先设定灰度差值
  3572. s12 = 请先选择核心颜色
  3573. s13 = 请先将图像二值化
  3574. s14 = 不能用于颜色位置二值化模式, 因为分割后会导致位置错误
  3575. s15 = 重选|到文件|仅范围|到剪贴板
  3576. s16 = 左键拖动选择范围,方向键微调\n右键或ESC仅范围,双击到剪贴板
  3577. s17 = 请先保存图片
  3578. s18 = 捕获|截图
  3579. )"
  3580. Lang1:=Map(), Lang1.Default:="", Lang2:=Map(), Lang2.Default:=""
  3581. Loop Parse, s, "`n", "`r"
  3582. if InStr(v:=A_LoopField, "=")
  3583. r:=StrSplit(StrReplace(v "==","\n","`n"), "=", "`t ")
  3584. , Lang1[r[1]]:=r[2], Lang2[r[1]]:=r[3]
  3585. }
  3586. return getLang=1 ? Lang1 : getLang=2 ? Lang2 : Lang1[text]
  3587. }
  3588. } ;// Class End
  3589. Script_End() {
  3590. }
  3591. ;================= The End =================
  3592. ;