FindText-v10.0中文版-V2.ahk 123 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649
  1. ;/*
  2. ;===========================================
  3. ; FindText - 屏幕抓字生成字库工具与找字函数
  4. ; https://www.autohotkey.com/boards/viewtopic.php?f=83&t=116471
  5. ;
  6. ; 脚本作者 : FeiYue
  7. ; 最新版本 : 10.0
  8. ; 更新时间 : 2024-10-06
  9. ;
  10. ; 用法: (需要最新版本 AHK v2.0.2+)
  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. Try DllCall("DeleteObject", "Ptr",this.bits.hBM)
  49. }
  50. New()
  51. {
  52. return FindTextClass()
  53. }
  54. help()
  55. {
  56. return "
  57. (
  58. ;--------------------------------
  59. ; FindText - 屏幕找字函数
  60. ; 版本 : 10.0 (2024-10-06)
  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. ; 设置 err1<0 或 err0<0 可以打开左右膨胀算法
  72. ; 忽略文字线条的轻微错位,此时容错值应该非常小
  73. ; 在找图模式中,err0 可以设置要跳过的行列数,加快速度
  74. ; , Text --> 由工具生成的查找图像的数据,可以一次查找多个,用“|”分隔
  75. ; , ScreenShot --> 是否截屏,为0则使用上一次的截屏数据
  76. ; , FindAll --> 是否搜索所有位置,为0则找到一个位置就返回
  77. ; , JoinText --> 如果想组合查找,可以为1,或者是要查找单词的数组
  78. ; , offsetX --> 组合图像的每个字和前一个字的最大横向间隔
  79. ; , offsetY --> 组合图像的每个字和前一个字的最大高低间隔
  80. ; , dir --> 查找的方向,有上、下、左、右、中心9种
  81. ; 默认 dir=0,这种返回的结果将按最小误差排序,
  82. ; 即使设置了较大的容错,第一个结果也是误差最小的
  83. ; , zoomW --> 图像宽度的缩放百分率(1.0=100%)
  84. ; , zoomH --> 图像高度的缩放百分率(1.0=100%)
  85. ; )
  86. ;
  87. ; 返回变量 --> 如果没找到结果会返回0。否则返回一个二级数组,
  88. ; 第一级是每个结果对象,第二级是结果对象的具体信息对象:
  89. ; { 1:左上角X, 2:左上角Y, 3:图像宽度W, 4:图像高度H
  90. ; , x:中心点X, y:中心点Y, id:图像识别文本 }
  91. ; 所有坐标都是相对于屏幕,颜色使用RGB格式
  92. ; 所有 RRGGBB 可以使用 Black、White、Red、Green、Blue 代替,
  93. ; 所有 DRDGDB 可以使用相似度 1.0(100%) 代替,它是浮点数
  94. ;
  95. ; 如果 OutputX 等于 'wait' 或 'wait1' 意味着等待图像出现,
  96. ; 如果 OutputX 等于 'wait0' 意味着等待图像消失
  97. ; 此时 OutputY 设置等待时间的秒数,如果小于0则无限等待
  98. ; 如果超时则返回0,意味着失败,如果等待图像出现成功,则返回位置数组
  99. ; 如果等待图像消失成功,则返回 1
  100. ; 例1: FindText(&X:='wait', &Y:=3, 0,0,0,0,0,0,Text) ; 等待3秒等图像出现
  101. ; 例2: FindText(&X:='wait0', &Y:=-1, 0,0,0,0,0,0,Text) ; 无限等待等图像消失
  102. ;
  103. ; <FindMultiColor> 或 <FindColor> : 找色 是仅有一个点的 多点找色
  104. ; Text:='|<>##DRDGDB $ 0/0/RRGGBB1-DRDGDB1/RRGGBB2, xn/yn/-RRGGBB3/RRGGBB4, ...'
  105. ; '##'之后的颜色 (0xDRDGDB) 是所有颜色的默认偏色(各个分量允许的变化值)
  106. ; 初始点 (0,0) 匹配 0xRRGGBB1(+/-0xDRDGDB1) 或者 0xRRGGBB2(+/-0xDRDGDB),
  107. ; 点 (xn,yn) 匹配 排除 0xRRGGBB3(+/-0xDRDGDB) 和排除 0xRRGGBB4(+/-0xDRDGDB)
  108. ; 点坐标后面以 '-' 开头表示要排除后面的所有颜色,其他颜色都匹配
  109. ; 每个点最多允许匹配10组颜色 (xn/yn/RRGGBB1/.../RRGGBB10)
  110. ;
  111. ; <FindShape> : 类似于 FindMultiColor,仅是把具体颜色替换为
  112. ; 这一点的颜色是否与第一点的颜色是否相似
  113. ; Text:='|<>##DRDGDB $ 0/0/1, x1/y1/0, x2/y2/1, xn/yn/0, ...'
  114. ;
  115. ; <FindPic> : Text 参数需要手动输入
  116. ; Text:='|<>##DRDGDB/RRGGBB1-DRDGDB1/RRGGBB2... $ d:\a.bmp'
  117. ; '##'之后的颜色 (0xDRDGDB) 是所有颜色的默认偏色(各个分量允许的变化值)
  118. ; 这个 0xRRGGBB1(+/-0xDRDGDB1) 和 0xRRGGBB2(+/-0xDRDGDB)... 都是透明色
  119. ;
  120. ;--------------------------------
  121. )"
  122. }
  123. FindText(&OutputX:="", &OutputY:=""
  124. , x1:=0, y1:=0, x2:=0, y2:=0, err1:=0, err0:=0, text:=""
  125. , ScreenShot:=1, FindAll:=1, JoinText:=0, offsetX:=20, offsetY:=10
  126. , dir:=0, zoomW:=1, zoomH:=1)
  127. {
  128. if IsSet(OutputX) && (OutputX ~= "i)^\s*wait[10]?\s*$")
  129. {
  130. found:=!InStr(OutputX, "0"), time:=this.Floor(OutputY ?? 0)
  131. , timeout:=A_TickCount+Round(time*1000), OutputX:=""
  132. Loop
  133. {
  134. ok:=this.FindText(,, x1, y1, x2, y2, err1, err0, text, ScreenShot
  135. , FindAll, JoinText, offsetX, offsetY, dir, zoomW, zoomH)
  136. if (found && ok)
  137. {
  138. OutputX:=ok[1].x, OutputY:=ok[1].y
  139. return ok
  140. }
  141. if (!found && !ok)
  142. return 1
  143. if (time>=0 && A_TickCount>=timeout)
  144. Break
  145. Sleep 50
  146. }
  147. return 0
  148. }
  149. x1:=this.Floor(x1), y1:=this.Floor(y1), x2:=this.Floor(x2), y2:=this.Floor(y2)
  150. if (x1=0 && y1=0 && x2=0 && y2=0)
  151. n:=150000, x:=y:=-n, w:=h:=2*n
  152. else
  153. x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x2-x1)+1, h:=Abs(y2-y1)+1
  154. bits:=this.GetBitsFromScreen(&x,&y,&w,&h,ScreenShot,&zx,&zy), x-=zx, y-=zy
  155. , this.ok:=0, info:=[]
  156. Loop Parse, text, "|"
  157. if IsObject(j:=this.PicInfo(A_LoopField))
  158. info.Push(j)
  159. if (w<1 || h<1 || !(num:=info.Length) || !bits.Scan0)
  160. {
  161. return 0
  162. }
  163. arr:=[], info2:=Map(), k:=0, s:=""
  164. , mode:=(IsObject(JoinText) ? 2 : JoinText ? 1 : 0)
  165. For i,j in info
  166. {
  167. k:=Max(k, (j[7]=5 && j[8]!=2 ? j[9] : j[2]*j[3]))
  168. if (mode)
  169. v:=(mode=1 ? i : j[10]) . "", s.="|" v
  170. , (v!="") && ((!info2.Has(v) && info2[v]:=[]), info2[v].Push(j))
  171. }
  172. sx:=x, sy:=y, sw:=w, sh:=h, (mode=1 && JoinText:=[s])
  173. , allpos_max:=(FindAll || JoinText ? 10000:1)
  174. , s1:=Buffer(k*4), s0:=Buffer(k*4)
  175. , ss:=Buffer(sw*(sh+3)), allpos:=Buffer(allpos_max*8)
  176. , ini:={ sx:sx, sy:sy, sw:sw, sh:sh, zx:zx, zy:zy
  177. , mode:mode, bits:bits, ss:ss.Ptr, s1:s1.Ptr, s0:s0.Ptr
  178. , allpos:allpos.Ptr, allpos_max:allpos_max
  179. , err1:err1, err0:err0, zoomW:zoomW, zoomH:zoomH }
  180. Loop 2
  181. {
  182. if (err1=0 && err0=0) && (num>1 || A_Index>1)
  183. ini.err1:=err1:=0.05, ini.err0:=err0:=0.05
  184. if (!JoinText)
  185. {
  186. For i,j in info
  187. Loop this.PicFind(ini, j, dir, sx, sy, sw, sh)
  188. {
  189. v:=NumGet(allpos,4*A_Index-4,"uint"), x:=(v&0xFFFF)+zx, y:=(v>>16)+zy
  190. , w:=Floor(j[2]*zoomW), h:=Floor(j[3]*zoomH)
  191. , arr.Push({1:x, 2:y, 3:w, 4:h, x:x+w//2, y:y+h//2, id:j[10]})
  192. if (!FindAll)
  193. Break 3
  194. }
  195. }
  196. else
  197. For k,v in JoinText
  198. {
  199. v:=StrSplit(Trim(RegExReplace(v, "\s*\|[|\s]*", "|"), "|")
  200. , (InStr(v,"|")?"|":""), " `t")
  201. , this.JoinText(arr, ini, info2, v, 1, offsetX, offsetY
  202. , FindAll, dir, 0, 0, 0, sx, sy, sw, sh)
  203. if (!FindAll && arr.Length)
  204. Break 2
  205. }
  206. if (err1!=0 || err0!=0 || arr.Length || info[1][4] || info[1][7]=5)
  207. Break
  208. }
  209. if (arr.Length)
  210. {
  211. OutputX:=arr[1].x, OutputY:=arr[1].y, this.ok:=arr
  212. return arr
  213. }
  214. return 0
  215. }
  216. ; the join text object use [ "abc", "xyz", "a1|a2|a3" ]
  217. JoinText(arr, ini, info2, text, index, offsetX, offsetY
  218. , FindAll, dir, minX, minY, maxY, sx, sy, sw, sh)
  219. {
  220. if !(Len:=text.Length) || !info2.Has(key:=text[index])
  221. return 0
  222. zoomW:=ini.zoomW, zoomH:=ini.zoomH, mode:=ini.mode
  223. For i,j in info2[key]
  224. if (mode!=2 || key==j[10])
  225. Loop ok:=this.PicFind(ini, j, dir, sx, sy, (index=1 ? sw
  226. : Min(sx+offsetX+Floor(j[2]*zoomW),ini.sx+ini.sw)-sx), sh)
  227. {
  228. if (A_Index=1)
  229. {
  230. pos:=[], p:=ini.allpos-4
  231. Loop ok
  232. pos.Push(NumGet(p+=4,"uint"))
  233. }
  234. v:=pos[A_Index], x:=v&0xFFFF, y:=v>>16
  235. , w:=Floor(j[2]*zoomW), h:=Floor(j[3]*zoomH)
  236. , (index=1 && (minX:=x, minY:=y, maxY:=y+h))
  237. , minY1:=Min(y, minY), maxY1:=Max(y+h, maxY), sx1:=x+w
  238. if (index<Len)
  239. {
  240. sy1:=Max(minY1-offsetY, ini.sy)
  241. , sh1:=Min(maxY1+offsetY, ini.sy+ini.sh)-sy1
  242. if this.JoinText(arr, ini, info2, text, index+1, offsetX, offsetY
  243. , FindAll, 5, minX, minY1, maxY1, sx1, sy1, 0, sh1)
  244. && (index>1 || !FindAll)
  245. return 1
  246. }
  247. else
  248. {
  249. comment:=""
  250. For k,v in text
  251. comment.=(mode=2 ? v : info2[v][1][10])
  252. x:=minX+ini.zx, y:=minY1+ini.zy, w:=sx1-minX, h:=maxY1-minY1
  253. , arr.Push({1:x, 2:y, 3:w, 4:h, x:x+w//2, y:y+h//2, id:comment})
  254. if (index>1 || !FindAll)
  255. return 1
  256. }
  257. }
  258. return 0
  259. }
  260. PicFind(ini, j, dir, sx, sy, sw, sh)
  261. {
  262. static MyFunc:=""
  263. if (!MyFunc)
  264. {
  265. x32:="VVdWU4HsmAAAAIuEJNQAAAADhCTMAAAAi5wk@AAAAIO8JKwAAAAFiUQkIIuEJPgA"
  266. . "AACNBJiJRCQ0D4RKBgAAi4Qk6AAAAIXAD45ADwAAiXwkEIu8JOQAAAAx7ccEJAAA"
  267. . "AADHRCQIAAAAAMdEJBQAAAAAx0QkDAAAAACNtgAAAACLhCTgAAAAi0wkDDH2MdsB"
  268. . "yIX@iUQkBH896ZAAAABmkA+vhCTMAAAAicGJ8Jn3@wHBi0QkBIA8GDF0TIuEJNwA"
  269. . "AACDwwEDtCQAAQAAiQyog8UBOd90VIsEJJn3vCToAAAAg7wkrAAAAAR1tQ+vhCTA"
  270. . "AAAAicGJ8Jn3@40MgYtEJASAPBgxdbSLRCQUi5Qk2AAAAIPDAQO0JAABAACJDIKD"
  271. . "wAE534lEJBR1rAF8JAyDRCQIAYu0JAQBAACLRCQIATQkOYQk6AAAAA+FMv@@@4tE"
  272. . "JBSLfCQQD6+EJOwAAACJbCQwwfgKiUQkKIuEJPAAAAAPr8XB+AqJRCRAg7wkrAAA"
  273. . "AAQPhCIGAACLhCTAAAAAi5wkxAAAAA+vhCTIAAAAjSyYi4QkzAAAAIucJMAAAAD3"
  274. . "2IO8JKwAAAABjQSDiUQkLA+ELwYAAIO8JKwAAAACD4Q4CAAAg7wkrAAAAAMPhLkL"
  275. . "AACLjCTQAAAAhckPjicBAACLhCTMAAAAi6wkzAAAAMdEJAwAAAAAx0QkEAAAAACJ"
  276. . "fCQYg+gBiUQkCI22AAAAAIt8JBCLtCTUAAAAMcCLXCQgAfsB94Xtif6J738X6bwA"
  277. . "AADGBAYEg8ABg8MBOccPhKQAAACDvCSsAAAAA3@khcAPtgsPhLoPAAAPtlP@iVQk"
  278. . "BDlEJAgPhMIPAAAPtlMBiRQki5Qk9AAAAIXSD4SfAQAAD7bpugYAAACD7QGD@QF2"
  279. . "G4N8JAQBD5TCgzwkAYnVD5TCCeoPttIB0oPKBIHh@QAAAL0BAAAAdByLTCQEiywk"
  280. . "hckPlEQkBIXtD5TBic0PtkwkBAnNCeqDwwGIFAaDwAE5xw+FXP@@@wF8JBCJ@YNE"
  281. . "JAwBi0QkDDmEJNAAAAAPjwz@@@+LfCQYg7wkrAAAAAN@FouEJPQAAACFwA+VwDwB"
  282. . "g5wkxAAAAP+LXCQUi3QkKDHAOfOLdCRAD07YiVwkFItcJDA58w9Pw4lEJDCLhCTM"
  283. . "AAAAK4QkAAEAAIlEJASLhCTQAAAAK4QkBAEAAIO8JLgAAAAJiUQkCA+ExgAAAIuE"
  284. . "JLgAAACD6AGD+AcPh7wCAACD+AOJRCQkD463AgAAi0QkBMdEJEQAAAAAx0QkDAAA"
  285. . "AACJBCSLRCQIiUQkHItcJEQ5HCTHRCRMAAAAAA+MCwEAAItcJEw5XCQcD4zCDQAA"
  286. . "i3QkRItcJCSLBCQp8PbDAg9Exot0JEyJwotEJBwp8PbDAQ9ExoP7A4nWD0@wD0@C"
  287. . "iXQkGIlEJBDp3gsAAI12AA+20YPqAYP6AhnSg+ICg8IEgeH9AAAAD5TBCcqIFAbp"
  288. . "8v3@@4tcJASLdCQIx0QkZAAAAADHRCRgAQAAAMdEJFQAAAAAx0QkWAAAAACJ2I1W"
  289. . "AYk0JMHoH4lcJBzHRCQMAAAAAAHY0fiJRCQQifDB6B8B8NH4iUQkGInYg8ABicEP"
  290. . "r8o50A9MwoPACIlMJHyJwQ+vyImMJIAAAACLXCR8OVwkZH0Zi5wkgAAAADlcJFjH"
  291. . "RCRcAAAAAA+M9QQAAIuMJLgAAACFyQ+FnQIAAIuUJPgAAACF0g+EjgIAAIuEJAQB"
  292. . "AAAPr4QkAAEAAIP4AQ+EdgIAAIN8JAwBD46lCgAAi0QkNIucJPgAAAAx7cdEJAQA"
  293. . "AAAAiSwkjXgEi0QkDIPoAYlEJBCLRCQEiwwkizeLRAMEhcmJRCQIich4NotP@DnO"
  294. . "D4N1BQAAifqNa@zrDY12AIPqBItK@DnOcxeJCotMhQSJTIMEg+gBg@j@deS4@@@@"
  295. . "@4tMJDSDwAGDBCQBg8cEg0QkBASJNIGLdCQIiTSDiwQkO0QkEHWNi4QkBAEAAIus"
  296. . "JAABAAAPr8APr+2JRCQEi7Qk+AAAAMdEJAgAAAAAMduLRCQIiwSGiUQkEA+3+MHo"
  297. . "EIXbiQQkdC0xyY22AAAAAIsUjg+3win4D6@AOeh9D8HqECsUJA+v0jtUJAR8EYPB"
  298. . "ATnZdduLRCQQiQSeg8MBg0QkCAGLRCQIOUQkDHWiidiBxJgAAABbXl9dwlwAx0Qk"
  299. . "JAAAAACLRCQIx0QkRAAAAADHRCQMAAAAAIkEJItEJASJRCQc6UT9@@8xwIO8JLAA"
  300. . "AAACD5TAiYQkhAAAAA+EUAQAADHAg7wksAAAAAGLrCS0AAAAD5TAhe2JRCR4D4SG"
  301. . "CwAAi7Qk2AAAAIuUJLQAAAAx7YucJOAAAACLjCTcAAAAiXwkCI0ElolEJASNdCYA"
  302. . "izuDxgSDw1iDwQSJ+MHoEA+vhCQEAQAAmfe8JOgAAAAPr4QkwAAAAIkEJA+3xw+v"
  303. . "hCQAAQAAmfe8JOQAAACLFCSNBIKJRvyLQ6yNREUAg8UWiUH8O3QkBHWmi4QktAAA"
  304. . "AIm8JLAAAACLfCQIiUQkFIuEJOwAAAAPr4QktAAAAMH4ColEJCiLhCTgAAAAx0Qk"
  305. . "QAAAAADHRCQwAAAAAIPACIlEJFDpSfr@@4tEJAyBxJgAAABbXl9dwlwAi4QksAAA"
  306. . "AMHoEA+vhCQEAQAAmfe8JOgAAAAPr4QkwAAAAInBD7eEJLAAAAAPr4QkAAEAAJn3"
  307. . "vCTkAAAAjQSBiYQksAAAAOnt+f@@i4Qk6AAAAIu0JNAAAAAPr4Qk5AAAANGkJLQA"
  308. . "AAADhCTgAAAAhfaJRCRQD47z+v@@i4QkzAAAAInqi2wkUMdEJCQAAAAAx0QkOAAA"
  309. . "AADB4AKJRCRIMcCLnCTMAAAAhdsPjisBAACLnCS8AAAAAdMDVCRIiVwkEItcJCAD"
  310. . "XCQ4iVQkPAOUJLwAAACJXCQYiVQkHI12AI28JwAAAACLdCQQMds5nCS0AAAAD7ZO"
  311. . "AolMJAQPtk4BD7Y2iUwkCIl0JAx2W412AI28JwAAAACLRJ0Ag8MCi3yd@InCD7bM"
  312. . "D7bAK0QkDMHqECtMJAgPttIrVCQEgf@@@@8AiQQkdyUPr9IPr8mNFFIPr8CNFIqN"
  313. . "BEI5x3NGMcA5nCS0AAAAd6+JwutBif7B7hCJ8A+28A+v0g+v9jnyd92J+A+21A+v"
  314. . "yQ+v0jnRd86LNCSJ+A+20A+v0onwD6@GOdB3uroBAAAAuAEAAACLXCQYg0QkEASL"
  315. . "TCQQiBODwwE7TCQciVwkGA+FGv@@@4u0JMwAAAABdCQ4i1QkPINEJCQBA1QkLItc"
  316. . "JCQ5nCTQAAAAD4Ws@v@@6U34@@+LRCQQhcB4G4tcJBw52H8Ti0QkGIXAeAuLHCQ5"
  317. . "2A+ONwYAAItsJFSF7Q+F4AUAAINsJBgBg0QkXAGDRCRYAYt0JGA5dCRcfLiLXCRU"
  318. . "idiD4AEBxonYg8ABiXQkYIPgA4lEJFTpvvr@@4uEJLAAAACLjCTQAAAAxwQkAAAA"
  319. . "AMdEJAQAAAAAg8ABweAHiYQksAAAAIuEJMwAAADB4AKFyYlEJAwPjsz4@@+J6Ius"
  320. . "JLAAAACJfCQQi5QkzAAAAIXSfmaLjCS8AAAAi1wkIIu8JLwAAAADXCQEAcEDRCQM"
  321. . "iUQkCAHHjXYAjbwnAAAAAA+2UQIPtkEBD7Yxa8BLa9ImAcKJ8MHgBCnwAdA5xQ+X"
  322. . "A4PBBIPDATn5ddWLnCTMAAAAAVwkBItEJAiDBCQBA0QkLIs8JDm8JNAAAAAPhXf@"
  323. . "@@+LfCQQ6Qb3@@+LBCTprvr@@4uEJOgAAACLvCTgAAAAD6+EJOQAAADRpCS0AAAA"
  324. . "jQSHiUQkUIuEJPAAAADB+AqDwAGJRCQki4Qk6AAAAIXAD45ECgAAi3wkJIuEJAQB"
  325. . "AACLdCRQx0QkMAAAAADHRCQUAAAAAA+vx4lEJECLhCTkAAAAD6@HweACiUQkSIuE"
  326. . "JOAAAACDwAKJRCQ4ifiNPL0AAAAAiXwkLInHD6+EJAABAACJfCQ8iUQkKIuEJOQA"
  327. . "AACFwA+OaQEAAItEJDjHRCQcAAAAAIlEJBCLRCQkiUQkGItEJBC7AgAAAA+2OIk8"
  328. . "JA+2eP8PtkD+iXwkBIlEJAg5nCS0AAAAD4bCAAAAiwSeg8MCi3ye@InCD7bMD7bA"
  329. . "K0QkCMHqECtMJAQPttIrFCSB@@@@@wCJRCQMd0YPr9IPr8mNFFIPr8CNFIqNBEI5"
  330. . "x3Kui3wkGItEJCSLTCQsAUwkEItMJCgBTCQcAfg5vCTkAAAAD465AAAAiUQkGOlf"
  331. . "@@@@if3B7RCJ6A+26A+v0g+v7TnqD4dm@@@@ifgPttQPr8kPr9I50Q+HU@@@@4tM"
  332. . "JAyJ+A+2+A+v@4nID6@BOfh2kDmcJLQAAAAPhz7@@@+LRCQwi3wkFJmNHL0AAAAA"
  333. . "97wk6AAAAA+vhCTAAAAAicGLRCQcmfe8JOQAAACLFCTB4hCNBIGLjCTYAAAAiQS5"
  334. . "i0QkBIPHAYl8JBSLvCTcAAAAweAICdALRCQIiQQf6SD@@@+LfCQ8i0QkJItMJEAB"
  335. . "TCQwi0wkSAFMJDgB+Dm8JOgAAAB+CYlEJDzpXP7@@4tEJBQPr4Qk7AAAAMH4ColE"
  336. . "JCiLRCRQx0QkQAAAAADHRCQwAAAAAIt4BIn4ifvB6BAPtteJ+w+2wA+2y4nDD6@Y"
  337. . "idAPr8KJXCRwiUQkdInID6@BiUQkbOlH9P@@i4Qk0AAAAIXAD45u9f@@i5wkzAAA"
  338. . "AItEJCDHBCQAAAAAx0QkBAAAAACJfCQMjQRYiUQkGInYweACiUQkCIu0JMwAAACF"
  339. . "9n5Xi4wkvAAAAItcJBiLvCS8AAAAA1wkBAHpA2wkCAHvD7ZRAoPBBIPDAWvyJg+2"
  340. . "Uf1rwkuNFAYPtnH8ifDB4AQp8AHQwfgHiEP@Ofl10ou8JMwAAAABfCQEgwQkAQNs"
  341. . "JCyLBCQ5hCTQAAAAdYqLhCTMAAAAi3wkDDHti5QktAAAADH2g+gBiXwkJIlEJAyL"
  342. . "hCTQAAAAg+gBiUQkEIucJMwAAACF2w+O4gAAAIu8JMwAAACLRCQYAfeNDDCJ+4l8"
  343. . "JByJxwHfifMrnCTMAAAAiXwkBIt8JCABwwH3McCJfCQIiRwkhcAPhGQDAAA5RCQM"
  344. . "D4RaAwAAhe0PhFIDAAA5bCQQD4RIAwAAD7YRD7Z5@74BAAAAA5QksAAAADn6ckYP"
  345. . "tnkBOfpyPos8JA+2Pzn6cjSLXCQED7Y7OfpyKYs8JA+2f@85+nIeizwkD7Z@ATn6"
  346. . "chMPtnv@OfpyCw+2cwE58g+Sw4nei3wkCInziBwHg8ABg8EBg0QkBAGDBCQBOYQk"
  347. . "zAAAAA+FWv@@@4t0JByDxQE5rCTQAAAAD4X@@v@@i3wkJImUJLQAAADpY@L@@8dE"
  348. . "JEAAAAAAx0QkKAAAAADHRCQwAAAAAMdEJBQAAAAA6cfx@@+DfCRUAQ+E6gEAAIN8"
  349. . "JFQCD4SVAgAAg2wkEAHpBfr@@4uEJAQBAACLrCQAAQAAD6@AD6@tiUQkBItEJAyF"
  350. . "wA+P6PX@@zHA6VL2@@+DRCRkAcdEJCQJAAAAi0QkGIucJNQAAAAPr4QkzAAAAANE"
  351. . "JBCAPAMDD4ZnAQAAi3QkFItcJDA53g9N3oO8JKwAAAADiVwkIA+OdQEAAItEJBgD"
  352. . "hCTIAAAAD6+EJMAAAACLVCQQA5QkxAAAAIO8JKwAAAAFD4RsAgAAjTSQi4QksAAA"
  353. . "AIucJLwAAAAB8A+2XAMCiVwkOIucJLwAAAAPtlwDAYlcJDyLnCS8AAAAD7YEA4lE"
  354. . "JEiLRCQghcAPhKoBAACLRCRAiXwkLDHbi2wkKIu8JLwAAACJRCRo62KNtCYAAAAA"
  355. . "OVwkMH5Ii4Qk3AAAAIsUmAHyD7ZEFwIPtkwXAStEJDgrTCQ8D7YUFytUJEgPr8AP"
  356. . "r8mNBEAPr9KNBIiNBFA5hCS0AAAAcgeDbCRoAXhhg8MBOVwkIA+EogEAADlcJBR+"
  357. . "n4uEJNgAAACLFJgB8g+2RBcCD7ZMFwErRCQ4K0wkPA+2FBcrVCRID6@AD6@JjQRA"
  358. . "D6@SjQSIjQRQOYQktAAAAA+DWv@@@4PtAQ+JUf@@@4t8JCyDfCQkCQ+EKfj@@4NE"
  359. . "JEwB6Try@@+DRCQQAekm+P@@g0QkRAHpEfL@@410JgCF2w+EoAAAAAOEJNQAAACL"
  360. . "XCRAMdKLbCQoicHrJTlUJDB+Fou0JNwAAACLBJYByPYAAXUFg+sBeJqDwgE5VCQg"
  361. . "dGo5VCQUftWLtCTYAAAAiwSWAcj2AAJ1xIPtAXm@6XD@@@@HRCQEAwAAAOlB8P@@"
  362. . "i3wkCMYEBwLpEf3@@8cEJAMAAADpOfD@@8dEJCgAAAAAx0QkFAAAAADpGPX@@4NE"
  363. . "JBgB6XD3@@+LbCQoi4Qk+AAAAINEJAwBhcAPhMoDAACLVCQYA5QkyAAAAItcJAyL"
  364. . "RCQQA4QkxAAAAIu0JPgAAADB4hCNi@@@@z8J0IkEjou0JLgAAACF9g+F0gIAAItE"
  365. . "JCiLdCQ0Keg5nCT8AAAAiQSOD44z8v@@6bb+@@+LfCQs64mLtCSEAAAAjQSQiUQk"
  366. . "PIX2D4WuAQAAi1wkIItEJFAx9otsJCiF24lEJGgPhFn@@@+LhCTYAAAAi1wkaItU"
  367. . "JDwDFLCJXCRIa8YWgTv@@@8AiUQkOA+XwA+2wIlEJCyLhCTcAAAAiwSwiYQktAAA"
  368. . "AIuEJLwAAAAPtkQQAomEJIwAAADB4BCJwYuEJLwAAAAPtkQQAYmEJJAAAADB4AgJ"
  369. . "yIuMJLwAAAAPtgwRCciJjCSUAAAAiYQkiAAAAOsfD6@SD6@JjRRSD6@AjRSKjQRC"
  370. . "OccPg70AAACDRCRICItEJDg7hCS0AAAAD4PPAAAAi1QkeIt8JEiDRCQ4AoXSiweL"
  371. . "fwR0JoX2i5wkiAAAAA9FnCSwAAAAhcAPlMAPtsCJRCQsiZwksAAAAInYicIPtswP"
  372. . "tsDB6hArjCSQAAAAK4QklAAAAA+20iuUJIwAAACB@@@@@wAPhmX@@@+J+8HrEA+2"
  373. . "2w+v0g+v2znaD4dp@@@@ifsPttcPr8kPr9I50Q+HVv@@@4n7D7bTD6@AD6@SOdAP"
  374. . "h0P@@@+LRCQshcB0CYPtAQ+IDf3@@4PGAYNEJGhYOXQkIA+Fe@7@@+nP@f@@i0Qk"
  375. . "LIXAdeHr1otMJCCLbCQohckPhLX9@@8x9usuOUQkcHwSD6@JOUwkdHwJD6@SOVQk"
  376. . "bH0Jg+0BD4i3@P@@g8YBOXQkIA+Eg@3@@4uEJNgAAACLVCQ8i5wkvAAAAAMUsIuE"
  377. . "JNwAAACLBLCJhCSwAAAAi4QkvAAAAIuMJLAAAAAPtkQQAsHpEA+2ySnID7ZMEwGL"
  378. . "nCSwAAAAD6@AD7bfKdmLnCS8AAAAD7YUEw+2nCSwAAAAKdqB@@@@@wAPh1z@@@8P"
  379. . "r8mNBEAPr9KNBIiNBFA5xw+CXf@@@+lh@@@@x0QkKAAAAADHRCQUAAAAAOnC9@@@"
  380. . "i1wkDDmcJPwAAACJ2A+OrfD@@4tcJBgxyYnOidgrhCQEAQAAg8ABD0jBicKJ2Iuc"
  381. . "JAQBAACNRBj@i1wkCDnDD07Di1wkEInFidgrhCQAAQAAg8ABD0nwidiLnCQAAQAA"
  382. . "jUQY@4tcJAQ5ww9OwznVicMPjIz7@@+LhCTMAAAAg8UBD6@CA4Qk1AAAAInBjUMB"
  383. . "iUQkIDnefw+J8IAkAQODwAE7RCQgdfODwgEDjCTMAAAAOep13+lJ+@@@i6wkuAAA"
  384. . "AIXtD4VK@@@@6TX7@@+QkA=="
  385. x64:="QVdBVkFVQVRVV1ZTSIHsyAAAAEhjhCRQAQAASIu8JKgBAACJjCQQAQAAiVQkMESJ"
  386. . "jCQoAQAAi7QkgAEAAIusJIgBAABJicRIiUQkWEgDhCRgAQAAg@kFSIlEJChIY4Qk"
  387. . "sAEAAEiNBIdIiUQkYA+E3AUAAIXtD44BDAAARTH2iVwkEIu8JLgBAABEiXQkCIuc"
  388. . "JBABAABFMe1Mi7QkcAEAAEUx20Ux@0SJbCQYRImEJCABAABMY1QkCEUxyUUxwEwD"
  389. . "lCR4AQAAhfZ@Mut3Dx9AAEEPr8SJwUSJyJn3@gHBQ4A8AjF0PEmDwAFJY8dBAflB"
  390. . "g8cBRDnGQYkMhn5DRInYmff9g@sEdckPr4QkOAEAAInBRInImff+Q4A8AjGNDIF1"
  391. . "xEiLlCRoAQAASYPAAUljxUEB+UGDxQFEOcaJDIJ@vQF0JAiDRCQYAUQDnCTAAQAA"
  392. . "i0QkGDnFD4VX@@@@RInoi1wkEESLhCQgAQAAD6+EJJABAABEiWwkGMH4ColEJByL"
  393. . "hCSYAQAAQQ+vx8H4ColEJECDvCQQAQAABA+EtwUAAIuEJDgBAACLvCRAAQAAD6+E"
  394. . "JEgBAACNBLiLvCQ4AQAAiUQkCESJ4PfYg7wkEAEAAAGNBIeJRCQgD4SxBQAAg7wk"
  395. . "EAEAAAIPhIQHAACDvCQQAQAAAw+EowoAAIuEJFgBAACFwA+OHwEAAESJfCQQRIuc"
  396. . "JBABAABBjWwk@0yLfCQoi7wkoAEAAEUx9kUx7YlcJAhEiYQkIAEAAA8fhAAAAAAA"
  397. . "RYXkD467AAAASWPFMclJicFNjUQHAUwDjCRgAQAA6xhBxgEEg8EBSYPBAUmDwAFB"
  398. . "OcwPhIkAAABBg@sDf+KFyUEPtlD@D4S1DgAAQQ+2WP45zQ+Euw4AAEUPthCF@w+E"
  399. . "fAEAAA+28rgGAAAAg+4Bg@4BdhiD+wFAD5TGQYP6AQ+UwAnwD7bAAcCDyASB4v0A"
  400. . "AAC+AQAAAHQOhdtAD5TGRYXSD5TCCdYJ8IPBAUmDwQFBiEH@SYPAAUE5zA+Fd@@@"
  401. . "@0UB5UGDxgFEObQkWAEAAA+PKv@@@4tcJAhEi3wkEESLhCQgAQAAg7wkEAEAAAN@"
  402. . "FouEJKABAACFwA+VwDwBg5wkQAEAAP+LfCQYi3QkHDHARInlRIucJFgBAAA59w9O"
  403. . "+EQ7fCRAiXwkGEQPTvgrrCS4AQAARCucJMABAACDvCQoAQAACQ+EuQAAAIuEJCgB"
  404. . "AACD6AGD+AcPh5ACAACD+AOJRCRID46LAgAAiWwkCESJXCQQRTH2x0QkTAAAAACL"
  405. . "fCRMOXwkCMdEJGgAAAAAD4wNAQAAi3wkaDl8JBAPjNIMAACLfCRIi3QkTItEJAgp"
  406. . "8ED2xwIPRMaLdCRoicKLRCQQKfBA9scBD0TGg@8DidcPT@gPT8JBicXptgoAAGaQ"
  407. . "D7bCg+gBg@gCGcCD4AKDwASB4v0AAAAPlMIJ0EGIAekg@v@@iehBjVMBRIlcJAjB"
  408. . "6B+JbCQQx4QkiAAAAAAAAAAB6MeEJIQAAAABAAAAx0QkbAAAAADR+MdEJHwAAAAA"
  409. . "QYnFRInYwegfRAHY0fiJx41FAYnGD6@yOdAPTMJFMfaDwAiJtCSkAAAAicYPr@CJ"
  410. . "tCSoAAAAi7QkpAAAADm0JIgAAAB9HIu0JKgAAAA5dCR8x4QkgAAAAAAAAAAPjEYE"
  411. . "AACLhCQoAQAAhcAPhV0CAABIg7wkqAEAAAAPhE4CAACLhCTAAQAAD6+EJLgBAACD"
  412. . "+AEPhDYCAABBg@4BD45dCQAAQY1G@kyLRCRgTIucJKgBAABFMclFMdJIjRyFBAAA"
  413. . "AEOLdAgEQ4sUCESJ0UOLfAsETInQOdZyE+kJBAAAZpBIg+gBQYsUgDnWcx1BiVSA"
  414. . "BEGLFIOD6QGD+f9BiVSDBHXeSMfA@@@@@0mDwQRIg8ABSYPCAUk52UGJNIBBiTyD"
  415. . "dZ9Ei5QkuAEAAIucJMABAABFD6@SD6@bTIuMJKgBAAAx9jHAQYsssYnvRA+33cHv"
  416. . "EIXAdDJFMcAPH4QAAAAAAEOLDIEPt9FEKdoPr9JEOdJ9DMHpECn5D6@JOdl8E0mD"
  417. . "wAFEOcB@2Uhj0IPAAUGJLJFIg8YBQTn2f6pIgcTIAAAAW15fXUFcQV1BXkFfw8dE"
  418. . "JEgAAAAARIlcJAiJbCQQRTH2x0QkTAAAAADpcP3@@4tEJDAx@4P4AkAPlMeJvCSs"
  419. . "AAAAD4SpAwAAMcCDfCQwAQ+UwEWFwImEJKAAAAAPhNsKAABEiaQkUAEAAEyLlCR4"
  420. . "AQAARTHJi7wkOAEAAEyLpCRoAQAARTHbTIusJHABAABEi7QkuAEAAESLvCTAAQAA"
  421. . "iVwkGEGLGkmDwliJ2MHoEEEPr8eZ9@0Pr8eJwQ+3w0EPr8aZ9@6NBIFDiQSMQYtC"
  422. . "rEGNBENBg8MWQ4lEjQBJg8EBRTnId72LhCSQAQAARIukJFABAACJXCQwi1wkGESJ"
  423. . "RCQYQQ+vwMH4ColEJBxIi4QkeAEAAMdEJEAAAAAARTH@SIPACEiJBCTpq@r@@0SJ"
  424. . "8OnE@v@@i3wkMIn4wegQD6+EJMABAACZ9@0Pr4QkOAEAAInBD7fHD6+EJLgBAACZ"
  425. . "9@6NBIGJRCQw6Wv6@@+J6ESLjCRYAQAARQHAD6@GSJhIA4QkeAEAAEWFyUiJBCQP"
  426. . "jnL7@@9CjTylAAAAAMdEJBAAAAAAMcDHRCRIAAAAAESJfCR4iXwkUEWF5A+O6QAA"
  427. . "AEhjVCQISIu8JDABAABFMe1MY3QkSEwDdCQoSI1sFwJMiwwkRTHSD7Z9AA+2df9E"
  428. . "D7Zd@usmZi4PH4QAAAAAAA+vyQ+v0o0MSQ+vwI0UkY0EQjnDc2hJg8EIMcBFOcIP"
  429. . "gxsBAABBiwFBi1kEQYPCAonBD7bUD7bAwekQKfJEKdgPtskp+YH7@@@@AHazQYnf"
  430. . "QcHvEEUPtv8Pr8lFD6@@RDn5d7IPts8Pr9IPr8k5ynelD7bTD6@AD6@SOdB3mLoB"
  431. . "AAAAuAEAAABDiBQuSYPFAUiDxQRFOewPj0P@@@+LdCRQRAFkJEgBdCQIg0QkEAGL"
  432. . "VCQgi3wkEAFUJAg5vCRYAQAAD4Xw@v@@RIt8JHjpFvn@@0WF7XgVRDtsJBB@DoX@"
  433. . "eAo7fCQID464BQAAi0QkbIXAD4WNBQAAg+8Bg4QkgAAAAAGDRCR8AYuUJIQAAAA5"
  434. . "lCSAAAAAfLqLdCRsifCD4AEBwonwg8ABiZQkhAAAAIPgA4lEJGzpW@v@@w8fRAAA"
  435. . "icLpQf@@@0yJ0Oka@P@@i0QkMIuMJFgBAAAx9jH@Qo0spQAAAACDwAHB4AeFyYlE"
  436. . "JDAPjo@5@@9Ei3QkCESLbCQwRYXkflVIi5QkMAEAAExj30wDXCQoSWPGRTHJSI1M"
  437. . "AgIPthEPtkH@RA+2Uf5rwEtr0iYBwkSJ0MHgBEQp0AHQQTnFQw+XBAtJg8EBSIPB"
  438. . "BEU5zH@MQQHuRAHng8YBRAN0JCA5tCRYAQAAdZXp9vf@@4noRQHAD6@GweACSJhI"
  439. . "A4QkeAEAAEiJBCSLhCSYAQAAwfgKg8ABhe2JRCQID46VCgAAi3wkCIuEJMABAADH"
  440. . "RCRIAAAAAMdEJBgAAAAARImkJFABAACJrCSIAQAAD6@HiXwkUIlEJHiJ+A+vxsHg"
  441. . "AkiYSIlEJHBIi4QkeAEAAEiJRCRAifjB4AJImEiJRCQQi4QkuAEAAA+vx4lEJBxI"
  442. . "iwQkSIPACEiJRCQghfYPjiYBAABIi3wkQESLZCQIMe0Ptl8CTItMJCBBvgIAAABE"
  443. . "D7ZXAUQPth9Bid3rHQ8fAA+v2w+v0o0cWw+vwI0Uk40EQjnBc2pJg8EIRTnwD4Z9"
  444. . "AAAAQYsBQYtJBEGDxgKJww+21A+2wMHrEEQp0kQp2A+220Qp64H5@@@@AHazQYnP"
  445. . "QcHvEEUPtv8Pr9tFD6@@RDn7d7IPtt0Pr9IPr9s52nelD7bJD6@AD6@JOch3mGaQ"
  446. . "i0QkCEgDfCQQA2wkHEQB4EQ55n5lQYnE6UP@@@8PHwCLRCRIRIt0JBhEievB4xBB"
  447. . "weIIQQnamU1jzkUJ2ve8JIgBAAAPr4QkOAEAAInBieiZ9@5Ii5QkaAEAAI0EgUKJ"
  448. . "BIpEifCDwAGJRCQYSIuEJHABAABGiRSI64aLfCRQi0QkCItUJHgBVCRISItUJHBI"
  449. . "AVQkQAH4ObwkiAEAAH4JiUQkUOmk@v@@i0QkGESLpCRQAQAAD6+EJJABAADB+AqJ"
  450. . "RCQcSIsEJMdEJEAAAAAARTH@i1gEidgPts8PttPB6BAPtsCJxw+v+InID6@Bibwk"
  451. . "mAAAAImEJJwAAACJ0A+vwomEJJQAAADpffX@@8dEJEAAAAAAx0QkHAAAAABFMf@H"
  452. . "RCQYAAAAAOn19P@@i5QkWAEAAIXSD4589v@@Q40EZESLdCQIQo0spQAAAAAx9jH@"
  453. . "SJhIA4QkYAEAAEmJxUWF5H5aSIuUJDABAABJY8ZMY99FMclNAetIjUwCAg8fRAAA"
  454. . "D7YRSIPBBERr0iYPtlH7a8JLQY0UAkQPtlH6RInQweAERCnQAdDB+AdDiAQLSYPB"
  455. . "AUU5zH@KQQHuRAHng8YBRAN0JCA5tCRYAQAAdZBIi3wkWDHSQY1sJP9EiXwkSEUx"
  456. . "0olcJCBBiddIifhIg8ABSIlEJAi4AQAAAEiJxouEJFgBAABIKf6LfCQwSIl0JBBE"
  457. . "jXD@RYXkD47TAAAASItEJAhNY99Ii3QkKEuNVB0BTo0MGEiLRCQQTAHeTQHpSo0M"
  458. . "GDHATAHpZi4PH4QAAAAAAEiFwA+EgQMAADnFD4R5AwAARYXSD4RwAwAARTnWD4Rn"
  459. . "AwAARA+2Qv9ED7Za@rsBAAAAQQH4RTnYckZED7YaRTnYcj1ED7ZZ@0U52HIzRQ+2"
  460. . "Wf9FOdhyKUQPtln+RTnYch9ED7YZRTnYchZFD7ZZ@kU52HIMRQ+2GUU52A+Sw2aQ"
  461. . "iBwGSIPAAUiDwgFJg8EBSIPBAUE5xA+PZP@@@0UB50GDwgFEOZQkWAEAAA+FEv@@"
  462. . "@4tcJCBEi3wkSOmJ8@@@RIuUJLgBAACLnCTAAQAAMcBFD6@SD6@bRYX2D4569@@@"
  463. . "6RP3@@+DfCRsAQ+E@AEAAIN8JGwCD4S4AgAAQYPtAelX+v@@g4QkiAAAAAHHRCRI"
  464. . "CQAAAIn4SIu0JGABAABBD6@ERo0MKEljwYA8BgMPhqQBAACLRCQYRDn4QQ9Mx4O8"
  465. . "JBABAAADiUQkIA+OsAEAAIuEJEgBAACLlCRAAQAAAfhEAeoPr4QkOAEAAIO8JBAB"
  466. . "AAAFD4TAAgAARI0MkItEJDBIi7QkMAEAAESLVCQgRAHIjVACRYXSSGPSD7Y0Fo1Q"
  467. . "AUiYSGPSiXQkUEiLtCQwAQAAD7Y0Fol0JHhIi7QkMAEAAA+2BAaJRCRwD4TrAQAA"
  468. . "i0QkQESJXCQoRTHSi3QkHEyLnCQwAQAAiYQkjAAAAOtyRDu8JJAAAAB+WUiLhCRw"
  469. . "AQAAQosUkEQByo1CAo1KAUhj0kEPthQTSJhIY8krVCRwQQ+2BANBD7YMCytEJFAr"
  470. . "TCR4D6@SD6@AD6@JjQRAjQSIjQRQQTnAcgqDrCSMAAAAAXh+SYPCAUQ5VCQgD47P"
  471. . "AQAARDlUJBhEiZQkkAAAAA+Oe@@@@0iLhCRoAQAAQosUkEQByo1CAo1KAUhj0kEP"
  472. . "thQTSJhIY8krVCRwQQ+2BANBD7YMCytEJFArTCR4D6@SD6@AD6@JjQRAjQSIjQRQ"
  473. . "QTnAD4Mo@@@@g+4BD4kf@@@@RItcJCiDfCRICQ+Eavj@@4NEJGgB6Snz@@9Bg8UB"
  474. . "6Wb4@@+DRCRMAekA8@@@kIXAD4SzAAAARItUJECLdCQcMcnrM0Q7fCQofiJIi5Qk"
  475. . "cAEAAESJyAMEikiLlCRgAQAA9gQCAXUGQYPqAXiZSIPBATlMJCB+dzlMJBiJTCQo"
  476. . "fsNIi4QkaAEAAESJygMUiEiLhCRgAQAA9gQQAnWng+4BeaLpX@@@@w8fhAAAAAAA"
  477. . "uwMAAADpRvH@@8YEBgLp8Pz@@0G6AwAAAOk+8f@@x0QkHAAAAADHRCQYAAAAAOm7"
  478. . "9f@@g8cB6aD3@@+LdCQcQYPGAUiDvCSoAQAAAA+EHQQAAEljxouUJEgBAABIjQyF"
  479. . "AAAAAIuEJEABAAAB+sHiEEQB6AnQSIuUJKgBAACJRAr8i5QkKAEAAIXSD4UeAwAA"
  480. . "i0QkHCnwRDm0JLABAABIi3QkYIlEDvwPjhPz@@@ppf7@@0SLXCQo64aNBJCJRCQo"
  481. . "i4QkrAAAAIXAD4XjAQAAi0QkIIXAD4Rg@@@@SIsEJIt0JBxFMcnHRCR4AAAAAESJ"
  482. . "dCRwRIm8JIwAAABEiZwkkAAAAEiJRCRQSIuEJGgBAACLTCQoTIu8JDABAABMi1Qk"
  483. . "UEyLhCRwAQAARItcJHhCAwyIQYE6@@@@AEeLBIiNUQKNQQFIY8lBD5fGSGPSSJhF"
  484. . "D7b2QQ+2FBdBD7YEB4mUJLQAAACJhCS4AAAAweIQweAICdBBD7YUDwnQiZQkvAAA"
  485. . "AImEJLAAAADrHg+v0g+vyY0UUg+vwI0Uio0EQjnDD4OvAAAASYPCCEU5ww+D4AAA"
  486. . "AESLvCSgAAAAQYPDAkGLAkGLWgRFhf90Hk2FyYtUJDAPRJQksAAAAEUx9oXAQQ+U"
  487. . "xolUJDCJ0InCD7bMD7bAweoQK4wkuAAAACuEJLwAAAAPttIrlCS0AAAAgfv@@@8A"
  488. . "D4Z0@@@@QYnfQcHvEEUPtv8Pr9JFD6@@RDn6D4dz@@@@D7bXD6@JD6@SOdEPh2L@"
  489. . "@@8PttMPr8APr9I50A+HUf@@@0WF9nQFg+4BeDtJg8EBSINEJFBYg0QkeBZEOUwk"
  490. . "IA+Pkf7@@0SLdCRwRIu8JIwAAABEi5wkkAAAAOmu@f@@RYX2dcfrwESLdCRwRIu8"
  491. . "JIwAAABEi5wkkAAAAOml@P@@i0QkIIt0JByFwA+Eff3@@0Ux0us5OYQkmAAAAHwY"
  492. . "D6@JOYwknAAAAHwMD6@SOZQklAAAAH0Jg+4BD4hm@P@@SYPCAUQ5VCQgD44@@f@@"
  493. . "SIuEJGgBAACLVCQoTIuMJDABAABCAxSQSIuEJHABAABCiwSQicGNQgKJTCQwwekQ"
  494. . "SJgPtslBD7YEASnIjUoBSGPSD6@ASGPJRQ+2DAlIi0wkMA+2zUEpyUSJyUyLjCQw"
  495. . "AQAAQQ+2FBFED7ZMJDBEKcqB+@@@@wAPh0r@@@8Pr8mNBEAPr9KNBIiNBFA5ww+C"
  496. . "VP@@@+lY@@@@x0QkHAAAAADHRCQYAAAAAOlF9@@@RDm0JLABAABEifAPjhvx@@+J"
  497. . "+CuEJMABAABFMdKDwAFBD0jCicGLhCTAAQAAjUQH@0E5w0EPTsOJxkSJ6CuEJLgB"
  498. . "AACDwAFED0nQi4QkuAEAAEGNRAX@OcUPTsU5zolEJCAPjEH7@@9EieJJY8IPr9FI"
  499. . "Y9JIAdBIA4QkYAEAAEmJwY1GAYlEJCiLRCQgRCnQSI1wAUQ7VCQgfxNKjRQOTInI"
  500. . "gCADSIPAAUg50HX0g8EBTANMJFg7TCQoddjp6Pr@@4uMJCgBAACFyQ+FQf@@@+nU"
  501. . "+v@@kJCQkJCQkJCQkJCQkA=="
  502. MyFunc:=this.MCode(StrReplace((A_PtrSize=8?x64:x32),"@","/"))
  503. }
  504. text:=j[1], w:=j[2], h:=j[3]
  505. , err1:=this.Floor(j[4] ? j[5] : ini.err1)
  506. , err0:=this.Floor(j[4] ? j[6] : ini.err0)
  507. , mode:=j[7], color:=j[8], n:=j[9]
  508. ok:=(!ini.bits.Scan0 || mode<1 || mode>5) ? 0
  509. : DllCall(MyFunc.Ptr, "int",mode, "uint",color, "uint",n, "int",dir
  510. , "Ptr",ini.bits.Scan0, "int",ini.bits.Stride
  511. , "int",sx, "int",sy, "int",sw, "int",sh
  512. , "Ptr",ini.ss, "Ptr",ini.s1, "Ptr",ini.s0
  513. , "Ptr",text, "int",w, "int",h
  514. , "int",Floor(Abs(err1)*1024), "int",Floor(Abs(err0)*1024)
  515. , "int",(err1<0||err0<0), "Ptr",ini.allpos, "int",ini.allpos_max
  516. , "int",Floor(w*ini.zoomW), "int",Floor(h*ini.zoomH))
  517. return ok
  518. }
  519. code()
  520. {
  521. return "
  522. (
  523. //***** C source code of machine code *****
  524. // gcc.exe -m32/-m64 -O2
  525. int __attribute__((__stdcall__)) PicFind(
  526. int mode, unsigned int c, unsigned int n, int dir
  527. , unsigned char * Bmp, int Stride
  528. , int sx, int sy, int sw, int sh
  529. , unsigned char * ss, unsigned int * s1, unsigned int * s0
  530. , unsigned char * text, int w, int h
  531. , int err1, int err0, int more_err
  532. , unsigned int * allpos, int allpos_max
  533. , int new_w, int new_h )
  534. {
  535. int ok, o, i, j, k, v, e1, e0, len1, len0, max, pic, shape, sort;
  536. int x, y, x1, y1, x2, y2, x3, y3, r, g, b, rr, gg, bb, dR, dG, dB;
  537. int ii, jj, RunDir, DirCount, RunCount, AllCount1, AllCount2;
  538. unsigned int c1, c2, *cors, *arr;
  539. unsigned char *ts, *gs;
  540. ok=0; o=0; v=0; len1=0; len0=0; ts=ss+sw; gs=ss+sw*3;
  541. arr=allpos+allpos_max; sort=(dir==0);
  542. //----------------------
  543. if (mode==5)
  544. {
  545. if (pic=(c==2)) // FindPic
  546. {
  547. cors=(unsigned int *)(text+w*h*4); j=(err0>>10)+1; n*=2;
  548. for (y=0; y<h; y+=j)
  549. {
  550. for (x=0; x<w; x+=j)
  551. {
  552. o=(y*w+x)*4; rr=text[2+o]; gg=text[1+o]; bb=text[o];
  553. for (i=2; i<n;)
  554. {
  555. c1=cors[i++]; c2=cors[i++];
  556. r=((c1>>16)&0xFF)-rr; g=((c1>>8)&0xFF)-gg; b=(c1&0xFF)-bb;
  557. v=(c2<0x1000000) ? (3*r*r+4*g*g+2*b*b<=c2)
  558. : (r*r<=((c2>>16)&0xFF)*((c2>>16)&0xFF)
  559. && g*g<=((c2>>8)&0xFF)*((c2>>8)&0xFF) && b*b<=(c2&0xFF)*(c2&0xFF));
  560. if (v) goto NoMatch1;
  561. }
  562. s1[len1]=(y*new_h/h)*Stride+(x*new_w/w)*4;
  563. s0[len1++]=rr<<16|gg<<8|bb;
  564. NoMatch1:;
  565. }
  566. }
  567. c2=cors[1]; r=(c2>>16)&0xFF; g=(c2>>8)&0xFF; b=c2&0xFF; dR=r*r; dG=g*g; dB=b*b;
  568. }
  569. else // FindMultiColor or FindColor
  570. {
  571. shape=(c==1); // FindShape
  572. cors=(unsigned int *)text;
  573. for (i=0; i<n; i++, o+=22)
  574. {
  575. c=cors[o]; y=c>>16; x=c&0xFFFF;
  576. s1[len1]=(y*new_h/h)*Stride+(x*new_w/w)*4;
  577. s0[len1++]=o+cors[o+1]*2;
  578. }
  579. cors+=2;
  580. }
  581. goto StartLookUp;
  582. }
  583. //----------------------
  584. // Generate Lookup Table
  585. for (y=0; y<h; y++)
  586. {
  587. for (x=0; x<w; x++)
  588. {
  589. i=(mode==4) ? (y*new_h/h)*Stride+(x*new_w/w)*4 : (y*new_h/h)*sw+(x*new_w/w);
  590. if (text[o++]=='1')
  591. s1[len1++]=i;
  592. else
  593. s0[len0++]=i;
  594. }
  595. }
  596. //----------------------
  597. // Color Position Mode
  598. // only used to recognize multicolored Verification Code
  599. if (mode==4)
  600. {
  601. y=c>>16; x=c&0xFFFF;
  602. c=(y*new_h/h)*Stride+(x*new_w/w)*4;
  603. goto StartLookUp;
  604. }
  605. //----------------------
  606. // Generate Two Value Image
  607. o=sy*Stride+sx*4; j=Stride-sw*4; i=0;
  608. if (mode==1) // Color Mode
  609. {
  610. cors=(unsigned int *)(text+w*h); n*=2;
  611. for (y=0; y<sh; y++, o+=j)
  612. {
  613. for (x=0; x<sw; x++, o+=4, i++)
  614. {
  615. rr=Bmp[2+o]; gg=Bmp[1+o]; bb=Bmp[o];
  616. for (k=0; k<n;)
  617. {
  618. c1=cors[k++]; c2=cors[k++];
  619. r=((c1>>16)&0xFF)-rr; g=((c1>>8)&0xFF)-gg; b=(c1&0xFF)-bb;
  620. v=(c2<0x1000000) ? (3*r*r+4*g*g+2*b*b<=c2)
  621. : (r*r<=((c2>>16)&0xFF)*((c2>>16)&0xFF)
  622. && g*g<=((c2>>8)&0xFF)*((c2>>8)&0xFF) && b*b<=(c2&0xFF)*(c2&0xFF));
  623. if (v) break;
  624. }
  625. ts[i]=(v) ? 1:0;
  626. }
  627. }
  628. }
  629. else if (mode==2) // Gray Threshold Mode
  630. {
  631. c=(c+1)<<7;
  632. for (y=0; y<sh; y++, o+=j)
  633. for (x=0; x<sw; x++, o+=4, i++)
  634. ts[i]=(Bmp[2+o]*38+Bmp[1+o]*75+Bmp[o]*15<c) ? 1:0;
  635. }
  636. else if (mode==3) // Gray Difference Mode
  637. {
  638. for (y=0; y<sh; y++, o+=j)
  639. {
  640. for (x=0; x<sw; x++, o+=4, i++)
  641. gs[i]=(Bmp[2+o]*38+Bmp[1+o]*75+Bmp[o]*15)>>7;
  642. }
  643. for (i=0, y=0; y<sh; y++)
  644. for (x=0; x<sw; x++, i++)
  645. if (x==0 || x==sw-1 || y==0 || y==sh-1)
  646. ts[i]=2;
  647. else
  648. {
  649. n=gs[i]+c;
  650. ts[i]=(gs[i-1]>n || gs[i+1]>n
  651. || gs[i-sw]>n || gs[i+sw]>n
  652. || gs[i-sw-1]>n || gs[i-sw+1]>n
  653. || gs[i+sw-1]>n || gs[i+sw+1]>n) ? 1:0;
  654. }
  655. }
  656. //----------------------
  657. StartLookUp:
  658. for (i=0, y=0; y<sh; y++)
  659. {
  660. for (x=0; x<sw; x++, i++)
  661. {
  662. if (mode>=4) { ss[i]=4; continue; }
  663. r=ts[i]; g=(x==0 ? 3 : ts[i-1]); b=(x==sw-1 ? 3 : ts[i+1]);
  664. if (more_err)
  665. ss[i]=4|(r==2||r==1||g==1||b==1)<<1|(r==2||r==0||g==0||b==0);
  666. else
  667. ss[i]=4|(r==2||r==1)<<1|(r==2||r==0);
  668. }
  669. }
  670. if (mode<4 && more_err) sx++;
  671. err1=(len1*err1)>>10;
  672. err0=(len0*err0)>>10;
  673. if (err1>=len1) len1=0;
  674. if (err0>=len0) len0=0;
  675. max=(len1>len0) ? len1 : len0;
  676. w=new_w; h=new_h; x1=0; y1=0; x2=sw-w; y2=sh-h;
  677. // 1 ==> ( Left to Right ) Top to Bottom
  678. // 2 ==> ( Right to Left ) Top to Bottom
  679. // 3 ==> ( Left to Right ) Bottom to Top
  680. // 4 ==> ( Right to Left ) Bottom to Top
  681. // 5 ==> ( Top to Bottom ) Left to Right
  682. // 6 ==> ( Bottom to Top ) Left to Right
  683. // 7 ==> ( Top to Bottom ) Right to Left
  684. // 8 ==> ( Bottom to Top ) Right to Left
  685. // 9 ==> Center to Four Sides
  686. if (dir==9)
  687. {
  688. x=(x1+x2)/2; y=(y1+y2)/2; i=x2-x1+1; j=y2-y1+1;
  689. AllCount1=i*j; i=(i>j?i:j)+8;
  690. AllCount2=i*i; RunCount=0; DirCount=1; RunDir=0;
  691. for (ii=0; RunCount<AllCount1 && ii<AllCount2;)
  692. {
  693. for(jj=0; jj<DirCount; jj++, ii++)
  694. {
  695. if(x>=x1 && x<=x2 && y>=y1 && y<=y2)
  696. {
  697. RunCount++;
  698. goto FindPos;
  699. FindPos_GoBak:;
  700. }
  701. if (RunDir==0) y--;
  702. else if (RunDir==1) x++;
  703. else if (RunDir==2) y++;
  704. else x--;
  705. }
  706. if (RunDir & 1) DirCount++;
  707. RunDir = (++RunDir) & 3;
  708. }
  709. goto Return1;
  710. }
  711. if (dir<1 || dir>8) dir=1;
  712. if (--dir>3) { r=y1; y1=x1; x1=r; r=y2; y2=x2; x2=r; }
  713. for (y3=y1; y3<=y2; y3++)
  714. {
  715. for (x3=x1; x3<=x2; x3++)
  716. {
  717. y=(dir & 2) ? y1+y2-y3 : y3;
  718. x=(dir & 1) ? x1+x2-x3 : x3;
  719. if (dir>3) { r=y; y=x; x=r; }
  720. //----------------------
  721. FindPos:
  722. e1=err1; e0=err0; o=y*sw+x;
  723. if (ss[o]<4) goto NoMatch;
  724. if (mode<4)
  725. {
  726. for (i=0; i<max; i++)
  727. {
  728. if (i<len1 && (ss[o+s1[i]]&2)==0 && (--e1)<0) goto NoMatch;
  729. if (i<len0 && (ss[o+s0[i]]&1)==0 && (--e0)<0) goto NoMatch;
  730. }
  731. }
  732. else if (mode==5)
  733. {
  734. o=(sy+y)*Stride+(sx+x)*4;
  735. if (pic)
  736. {
  737. for (i=0; i<max; i++)
  738. {
  739. j=o+s1[i]; c=s0[i]; r=Bmp[2+j]-((c>>16)&0xFF);
  740. g=Bmp[1+j]-((c>>8)&0xFF); b=Bmp[j]-(c&0xFF);
  741. v=(c2<0x1000000)?(3*r*r+4*g*g+2*b*b>c2):(r*r>dR||g*g>dG||b*b>dB);
  742. if (v && (--e1)<0) goto NoMatch;
  743. }
  744. }
  745. else
  746. {
  747. for (i=0; i<max; i++)
  748. {
  749. j=o+s1[i]; rr=Bmp[2+j]; gg=Bmp[1+j]; bb=Bmp[j];
  750. for (j=i*22, k=cors[j]>0xFFFFFF, n=s0[i]; j<n;)
  751. {
  752. c1=cors[j++]; c2=cors[j++];
  753. if (shape) { if (i==0) c=rr<<16|gg<<8|bb; k=!c1; c1=c; }
  754. r=((c1>>16)&0xFF)-rr; g=((c1>>8)&0xFF)-gg; b=(c1&0xFF)-bb;
  755. v=(c2<0x1000000) ? (3*r*r+4*g*g+2*b*b<=c2)
  756. : (r*r<=((c2>>16)&0xFF)*((c2>>16)&0xFF)
  757. && g*g<=((c2>>8)&0xFF)*((c2>>8)&0xFF) && b*b<=(c2&0xFF)*(c2&0xFF));
  758. if (v) { if (k) goto NoMatch2; goto MatchOK; }
  759. }
  760. if (k) goto MatchOK;
  761. NoMatch2:
  762. if ((--e1)<0) goto NoMatch;
  763. MatchOK:;
  764. }
  765. }
  766. }
  767. else // mode==4
  768. {
  769. o=(sy+y)*Stride+(sx+x)*4; j=o+c; rr=Bmp[2+j]; gg=Bmp[1+j]; bb=Bmp[j];
  770. for (i=0; i<max; i++)
  771. {
  772. if (i<len1)
  773. {
  774. j=o+s1[i]; r=Bmp[2+j]-rr; g=Bmp[1+j]-gg; b=Bmp[j]-bb;
  775. if (3*r*r+4*g*g+2*b*b>n && (--e1)<0) goto NoMatch;
  776. }
  777. if (i<len0)
  778. {
  779. j=o+s0[i]; r=Bmp[2+j]-rr; g=Bmp[1+j]-gg; b=Bmp[j]-bb;
  780. if (3*r*r+4*g*g+2*b*b<=n && (--e0)<0) goto NoMatch;
  781. }
  782. }
  783. }
  784. ok++;
  785. if (allpos)
  786. {
  787. allpos[ok-1]=(sy+y)<<16|(sx+x); if (sort) arr[ok-1]=err1-e1;
  788. if (ok>=allpos_max) goto Return1;
  789. }
  790. // Skip areas that may overlap
  791. if (!sort)
  792. {
  793. r=y-h+1; if (r<0) r=0; rr=y+h-1; if (rr>sh-h) rr=sh-h;
  794. g=x-w+1; if (g<0) g=0; gg=x+w-1; if (gg>sw-w) gg=sw-w;
  795. for (i=r; i<=rr; i++)
  796. for (j=g; j<=gg; j++)
  797. ss[i*sw+j] &= 3;
  798. }
  799. NoMatch:
  800. if (dir==9) goto FindPos_GoBak;
  801. }
  802. }
  803. //----------------------
  804. Return1:
  805. if (!sort || !allpos || w*h==1)
  806. return ok;
  807. // Sort by smallest error
  808. for (i=1; i<ok; i++)
  809. {
  810. k=arr[i]; v=allpos[i];
  811. for (j=i-1; j>=0 && arr[j]>k; j--)
  812. {
  813. arr[j+1]=arr[j]; allpos[j+1]=allpos[j];
  814. }
  815. arr[j+1]=k; allpos[j+1]=v;
  816. }
  817. // Clean up overlapping results
  818. w*=w; h*=h; k=ok; ok=0;
  819. for (i=0; i<k; i++)
  820. {
  821. c1=allpos[i]; x1=c1&0xFFFF; y1=c1>>16;
  822. for (j=0; j<ok; j++)
  823. {
  824. c2=allpos[j]; x=(c2&0xFFFF)-x1; y=(c2>>16)-y1;
  825. if (x*x<w && y*y<h) goto NoMatch3;
  826. }
  827. allpos[ok++]=c1;
  828. NoMatch3:;
  829. }
  830. return ok;
  831. }
  832. )"
  833. }
  834. PicInfo(text)
  835. {
  836. if !InStr(text, "$")
  837. return
  838. static info:=Map(), bmp:=[]
  839. key:=(r:=StrLen(v:=Trim(text,"|")))<10000 ? v
  840. : DllCall("ntdll\RtlComputeCrc32", "uint",0
  841. , "Ptr",StrPtr(v), "uint",r*2, "uint")
  842. if info.Has(key)
  843. return info[key]
  844. comment:="", seterr:=err1:=err0:=0
  845. ; You Can Add Comment Text within The <>
  846. if RegExMatch(v, "<([^>\n]*)>", &r)
  847. v:=StrReplace(v,r[0]), comment:=Trim(r[1])
  848. ; You can Add two fault-tolerant in the [], separated by commas
  849. if RegExMatch(v, "\[([^\]\n]*)]", &r)
  850. {
  851. v:=StrReplace(v,r[0]), r:=StrSplit(r[1] ",", ",")
  852. , seterr:=1, err1:=r[1], err0:=r[2]
  853. }
  854. color:=SubStr(v,1,InStr(v,"$")-1), v:=Trim(SubStr(v,InStr(v,"$")+1))
  855. mode:=InStr(color,"##") ? 5 : InStr(color,"#") ? 4
  856. : InStr(color,"**") ? 3 : InStr(color,"*") ? 2 : 1
  857. color:=RegExReplace(StrReplace(color,"@","-"), "[*#\s]")
  858. (mode=1 || mode=5) && color:=StrReplace(color,"0x")
  859. if (mode=5)
  860. {
  861. if !(v~="^[\s\-\w.]+/[\s\-\w.]+/[\s\-\w./,]+$") ; <FindPic>
  862. {
  863. if !(hBM:=LoadPicture(v))
  864. {
  865. MsgBox "Can't Load Picture ! " v, "Tip", 4096
  866. return
  867. }
  868. this.GetBitmapWH(hBM, &w, &h)
  869. if (w<1 || h<1)
  870. return
  871. hBM2:=this.CreateDIBSection(w, h, 32, &Scan0)
  872. this.CopyHBM(hBM2, 0, 0, hBM, 0, 0, w, h)
  873. DllCall("DeleteObject", "Ptr",hBM)
  874. if (!Scan0)
  875. return
  876. arr:=StrSplit(color "/", "/"), arr.Pop(), n:=arr.Length
  877. bmp.Push(buf:=Buffer(w*h*4 + n*2*4)), v:=buf.Ptr, p:=v+w*h*4-4
  878. DllCall("RtlMoveMemory", "Ptr",v, "Ptr",Scan0, "Ptr",w*h*4)
  879. DllCall("DeleteObject", "Ptr",hBM2), color:=Trim(arr[1],"-")
  880. For k1,v1 in arr
  881. c:=StrSplit(Trim(v1,"-") "-" color, "-")
  882. , x:=this.Floor(c[2]), x:=(x<=0||x>1?0:Floor(9*255*255*(1-x)*(1-x)))
  883. , NumPut("uint", this.ToRGB(c[1]), p+=4)
  884. , NumPut("uint", (InStr(c[2],".")?x:this.Floor("0x" c[2])|0x1000000), p+=4)
  885. color:=2
  886. }
  887. else ; <FindMultiColor> or <FindColor> or <FindShape>
  888. {
  889. color:=Trim(StrSplit(color "/", "/")[1], "-")
  890. arr:=StrSplit(Trim(RegExReplace(v, "i)\s|0x"), ","), ",")
  891. if !(n:=arr.Length)
  892. return
  893. bmp.Push(buf:=Buffer(n*22*4)), v:=buf.Ptr
  894. shape:=(n>1 && StrLen(StrSplit(arr[1] "//","/")[3])=1 ? 1:0)
  895. For k1,v1 in arr
  896. {
  897. r:=StrSplit(v1 "/","/"), x:=this.Floor(r[1]), y:=this.Floor(r[2])
  898. , (A_Index=1) ? (x1:=x2:=x, y1:=y2:=y)
  899. : (x1:=Min(x1,x), x2:=Max(x2,x), y1:=Min(y1,y), y2:=Max(y2,y))
  900. }
  901. For k1,v1 in arr
  902. {
  903. r:=StrSplit(v1 "/","/"), x:=this.Floor(r[1])-x1, y:=this.Floor(r[2])-y1
  904. , NumPut("uint", y<<16|x, p:=v+(A_Index-1)*22*4)
  905. , NumPut("uint", n1:=Min(Max(r.Length-3,0),(shape?1:10)), p+=4)
  906. Loop n1
  907. c:=StrSplit(Trim(v1:=r[2+A_Index],"-") "-" color, "-")
  908. , x:=this.Floor(c[2]), x:=(x<=0||x>1?0:Floor(9*255*255*(1-x)*(1-x)))
  909. , NumPut("uint", this.ToRGB(c[1])&0xFFFFFF|(!shape&&InStr(v1,"-")=1?0x1000000:0), p+=4)
  910. , NumPut("uint", (InStr(c[2],".")?x:this.Floor("0x" c[2])|0x1000000), p+=4)
  911. }
  912. color:=shape, w:=x2-x1+1, h:=y2-y1+1
  913. }
  914. }
  915. else
  916. {
  917. r:=StrSplit(v ".", "."), w:=this.Floor(r[1])
  918. , v:=this.base64tobit(r[2]), h:=StrLen(v)//w
  919. if (w<1 || h<1 || StrLen(v)!=w*h)
  920. return
  921. arr:=StrSplit(color "/", "/"), arr.Pop(), n:=arr.Length
  922. , bmp.Push(buf:=Buffer(StrPut(v, "CP0") + n*2*4))
  923. , StrPut(v, buf.Ptr, "CP0"), v:=buf.Ptr, p:=v+w*h-4
  924. , color:=this.Floor(color)
  925. if (mode=1)
  926. {
  927. For k1,v1 in arr
  928. c:=StrSplit(Trim(v1,"-") "-", "-")
  929. , x:=this.Floor(c[2]), x:=(x<=0||x>1?0:Floor(9*255*255*(1-x)*(1-x)))
  930. , NumPut("uint", this.ToRGB(c[1]), p+=4)
  931. , NumPut("uint", (InStr(c[2],".")?x:this.Floor("0x" c[2])|0x1000000), p+=4)
  932. }
  933. else if (mode=4)
  934. {
  935. r:=StrSplit(Trim(arr[1],"-") "-", "-")
  936. , n:=this.Floor(r[2]), n:=(n<=0||n>1?0:Floor(9*255*255*(1-n)*(1-n)))
  937. , c:=this.Floor(r[1]), color:=(c<1||c>w*h?0:((c-1)//w)<<16|Mod(c-1,w))
  938. }
  939. }
  940. return info[key]:=[v, w, h, seterr, err1, err0, mode, color, n, comment]
  941. }
  942. ToRGB(color) ; color can use: RRGGBB, Red, Yellow, Black, White
  943. {
  944. static tab:=""
  945. if (!tab)
  946. tab:=Map(), tab.CaseSense:="Off"
  947. , tab.Set("Black", "000000", "White", "FFFFFF"
  948. , "Red", "FF0000", "Green", "008000", "Blue", "0000FF"
  949. , "Yellow", "FFFF00", "Silver", "C0C0C0", "Gray", "808080"
  950. , "Teal", "008080", "Navy", "000080", "Aqua", "00FFFF"
  951. , "Olive", "808000", "Lime", "00FF00", "Fuchsia", "FF00FF"
  952. , "Purple", "800080", "Maroon", "800000")
  953. return this.Floor("0x" (tab.Has(color)?tab[color]:color))
  954. }
  955. GetBitsFromScreen(&x:=0, &y:=0, &w:=0, &h:=0
  956. , ScreenShot:=1, &zx:=0, &zy:=0, &zw:=0, &zh:=0)
  957. {
  958. static CAPTUREBLT:=""
  959. if (CAPTUREBLT="") ; thanks Descolada
  960. {
  961. DllCall("Dwmapi\DwmIsCompositionEnabled", "Int*", &i:=0)
  962. CAPTUREBLT:=i ? 0 : 0x40000000
  963. }
  964. if InStr(A_OSVersion, ".") ; thanks QQ:349029755
  965. Try DllCall("SetThreadDpiAwarenessContext", "Ptr",-3, "Ptr")
  966. (!IsObject(this.bits) && this.bits:={Scan0:0, hBM:0, oldzw:0, oldzh:0})
  967. , bits:=this.bits
  968. if (!ScreenShot && bits.Scan0)
  969. {
  970. zx:=bits.zx, zy:=bits.zy, zw:=bits.zw, zh:=bits.zh
  971. , w:=Min(x+w,zx+zw), x:=Max(x,zx), w-=x
  972. , h:=Min(y+h,zy+zh), y:=Max(y,zy), h-=y
  973. return bits
  974. }
  975. cri:=A_IsCritical
  976. Critical
  977. bits.BindWindow:=id:=this.BindWindow(0,0,1)
  978. if (id)
  979. {
  980. Try
  981. WinGetPos &zx, &zy, &zw, &zh, id
  982. Catch
  983. id:=0
  984. }
  985. if (!id)
  986. {
  987. zx:=SysGet(76)
  988. , zy:=SysGet(77)
  989. , zw:=SysGet(78)
  990. , zh:=SysGet(79)
  991. }
  992. this.UpdateBits(bits, zx, zy, zw, zh)
  993. , w:=Min(x+w,zx+zw), x:=Max(x,zx), w-=x
  994. , h:=Min(y+h,zy+zh), y:=Max(y,zy), h-=y
  995. if (!ScreenShot || w<1 || h<1 || !bits.hBM)
  996. {
  997. Critical cri
  998. return bits
  999. }
  1000. if IsSet(GetBitsFromScreen2) && (GetBitsFromScreen2 is Func)
  1001. && GetBitsFromScreen2(bits, x-zx, y-zy, w, h)
  1002. {
  1003. ; Get the bind window use bits.BindWindow
  1004. ; Each small range of data obtained from DXGI must be
  1005. ; copied to the screenshot cache using FindText().CopyBits()
  1006. zx:=bits.zx, zy:=bits.zy, zw:=bits.zw, zh:=bits.zh
  1007. Critical cri
  1008. return bits
  1009. }
  1010. mDC:=DllCall("CreateCompatibleDC", "Ptr",0, "Ptr")
  1011. oBM:=DllCall("SelectObject", "Ptr",mDC, "Ptr",bits.hBM, "Ptr")
  1012. if (id)
  1013. {
  1014. if (mode:=this.BindWindow(0,0,0,1))<2
  1015. {
  1016. hDC:=DllCall("GetDCEx", "Ptr",id, "Ptr",0, "int",3, "Ptr")
  1017. DllCall("BitBlt","Ptr",mDC,"int",x-zx,"int",y-zy,"int",w,"int",h
  1018. , "Ptr",hDC, "int",x-zx, "int",y-zy, "uint",0xCC0020|CAPTUREBLT)
  1019. DllCall("ReleaseDC", "Ptr",id, "Ptr",hDC)
  1020. }
  1021. else
  1022. {
  1023. hBM2:=this.CreateDIBSection(zw, zh)
  1024. mDC2:=DllCall("CreateCompatibleDC", "Ptr",0, "Ptr")
  1025. oBM2:=DllCall("SelectObject", "Ptr",mDC2, "Ptr",hBM2, "Ptr")
  1026. DllCall("UpdateWindow", "Ptr",id)
  1027. ; RDW_INVALIDATE=0x1|RDW_ERASE=0x4|RDW_ALLCHILDREN=0x80|RDW_FRAME=0x400
  1028. ; DllCall("RedrawWindow", "Ptr",id, "Ptr",0, "Ptr",0, "uint", 0x485)
  1029. DllCall("PrintWindow", "Ptr",id, "Ptr",mDC2, "uint",(mode>3)*3)
  1030. DllCall("BitBlt","Ptr",mDC,"int",x-zx,"int",y-zy,"int",w,"int",h
  1031. , "Ptr",mDC2, "int",x-zx, "int",y-zy, "uint",0xCC0020)
  1032. DllCall("SelectObject", "Ptr",mDC2, "Ptr",oBM2)
  1033. DllCall("DeleteDC", "Ptr",mDC2)
  1034. DllCall("DeleteObject", "Ptr",hBM2)
  1035. }
  1036. }
  1037. else
  1038. {
  1039. hDC:=DllCall("GetWindowDC","Ptr",id:=DllCall("GetDesktopWindow","Ptr"),"Ptr")
  1040. DllCall("BitBlt","Ptr",mDC,"int",x-zx,"int",y-zy,"int",w,"int",h
  1041. , "Ptr",hDC, "int",x, "int",y, "uint",0xCC0020|CAPTUREBLT)
  1042. DllCall("ReleaseDC", "Ptr",id, "Ptr",hDC)
  1043. }
  1044. if this.CaptureCursor(0,0,0,0,0,1)
  1045. this.CaptureCursor(mDC, zx, zy, zw, zh)
  1046. DllCall("SelectObject", "Ptr",mDC, "Ptr",oBM)
  1047. DllCall("DeleteDC", "Ptr",mDC)
  1048. Critical cri
  1049. return bits
  1050. }
  1051. UpdateBits(bits, zx, zy, zw, zh)
  1052. {
  1053. if (zw>bits.oldzw || zh>bits.oldzh || !bits.hBM)
  1054. {
  1055. Try DllCall("DeleteObject", "Ptr",bits.hBM)
  1056. bits.hBM:=this.CreateDIBSection(zw, zh, bpp:=32, &ppvBits)
  1057. , bits.Scan0:=(!bits.hBM ? 0:ppvBits)
  1058. , bits.Stride:=((zw*bpp+31)//32)*4
  1059. , bits.oldzw:=zw, bits.oldzh:=zh
  1060. }
  1061. bits.zx:=zx, bits.zy:=zy, bits.zw:=zw, bits.zh:=zh
  1062. }
  1063. CreateDIBSection(w, h, bpp:=32, &ppvBits:=0)
  1064. {
  1065. NumPut("int",40, "int",w, "int",-h, "short",1, "short",bpp, bi:=Buffer(40,0))
  1066. return DllCall("CreateDIBSection", "Ptr",0, "Ptr",bi
  1067. , "int",0, "Ptr*",&ppvBits:=0, "Ptr",0, "int",0, "Ptr")
  1068. }
  1069. GetBitmapWH(hBM, &w, &h)
  1070. {
  1071. bm:=Buffer(size:=(A_PtrSize=8 ? 32:24), 0)
  1072. , DllCall("GetObject", "Ptr",hBM, "int",size, "Ptr",bm)
  1073. , w:=NumGet(bm,4,"int"), h:=Abs(NumGet(bm,8,"int"))
  1074. }
  1075. CopyHBM(hBM1, x1, y1, hBM2, x2, y2, w, h, Clear:=0)
  1076. {
  1077. if (w<1 || h<1 || !hBM1 || !hBM2)
  1078. return
  1079. mDC1:=DllCall("CreateCompatibleDC", "Ptr",0, "Ptr")
  1080. oBM1:=DllCall("SelectObject", "Ptr",mDC1, "Ptr",hBM1, "Ptr")
  1081. mDC2:=DllCall("CreateCompatibleDC", "Ptr",0, "Ptr")
  1082. oBM2:=DllCall("SelectObject", "Ptr",mDC2, "Ptr",hBM2, "Ptr")
  1083. DllCall("BitBlt", "Ptr",mDC1, "int",x1, "int",y1, "int",w, "int",h
  1084. , "Ptr",mDC2, "int",x2, "int",y2, "uint",0xCC0020)
  1085. if (Clear)
  1086. DllCall("BitBlt", "Ptr",mDC1, "int",x1, "int",y1, "int",w, "int",h
  1087. , "Ptr",mDC1, "int",x1, "int",y1, "uint",MERGECOPY:=0xC000CA)
  1088. DllCall("SelectObject", "Ptr",mDC1, "Ptr",oBM1)
  1089. DllCall("DeleteDC", "Ptr",mDC1)
  1090. DllCall("SelectObject", "Ptr",mDC2, "Ptr",oBM2)
  1091. DllCall("DeleteDC", "Ptr",mDC2)
  1092. }
  1093. CopyBits(Scan01,Stride1,x1,y1,Scan02,Stride2,x2,y2,w,h,Reverse:=0)
  1094. {
  1095. if (w<1 || h<1 || !Scan01 || !Scan02)
  1096. return
  1097. static init:=0, MFCopyImage
  1098. if (!init && init:=1)
  1099. {
  1100. MFCopyImage:=DllCall("GetProcAddress", "Ptr"
  1101. , DllCall("LoadLibrary", "Str","Mfplat.dll", "Ptr")
  1102. , "AStr","MFCopyImage", "Ptr")
  1103. }
  1104. if (MFCopyImage && !Reverse) ; thanks QQ:121507989
  1105. {
  1106. return DllCall(MFCopyImage
  1107. , "Ptr",Scan01+y1*Stride1+x1*4, "int",Stride1
  1108. , "Ptr",Scan02+y2*Stride2+x2*4, "int",Stride2
  1109. , "uint",w*4, "uint",h)
  1110. }
  1111. ListLines (lls:=A_ListLines)?0:0
  1112. p1:=Scan01+(y1-1)*Stride1+x1*4
  1113. , p2:=Scan02+(y2-1)*Stride2+x2*4, w*=4
  1114. , (Reverse) && (p2+=(h+1)*Stride2, Stride2:=-Stride2)
  1115. Loop h
  1116. DllCall("RtlMoveMemory","Ptr",p1+=Stride1,"Ptr",p2+=Stride2,"Ptr",w)
  1117. ListLines lls
  1118. }
  1119. DrawHBM(hBM, lines)
  1120. {
  1121. mDC:=DllCall("CreateCompatibleDC", "Ptr",0, "Ptr")
  1122. oBM:=DllCall("SelectObject", "Ptr",mDC, "Ptr",hBM, "Ptr")
  1123. oldc:="", brush:=0, rect:=Buffer(16)
  1124. For k,v in lines ; [ [x, y, w, h, color] ]
  1125. if IsObject(v)
  1126. {
  1127. if (oldc!=v[5])
  1128. {
  1129. oldc:=v[5], BGR:=(oldc&0xFF)<<16|oldc&0xFF00|(oldc>>16)&0xFF
  1130. DllCall("DeleteObject", "Ptr",brush)
  1131. brush:=DllCall("CreateSolidBrush", "uint",BGR, "Ptr")
  1132. }
  1133. DllCall("SetRect", "Ptr",rect, "int",v[1], "int",v[2]
  1134. , "int",v[1]+v[3], "int",v[2]+v[4])
  1135. DllCall("FillRect", "Ptr",mDC, "Ptr",rect, "Ptr",brush)
  1136. }
  1137. DllCall("DeleteObject", "Ptr",brush)
  1138. DllCall("SelectObject", "Ptr",mDC, "Ptr",oBM)
  1139. DllCall("DeleteObject", "Ptr",mDC)
  1140. }
  1141. ; 绑定窗口从而可以后台查找这个窗口的图像
  1142. ; 相当于始终在前台。解绑窗口使用 FindText().BindWindow(0)
  1143. BindWindow(bind_id:=0, bind_mode:=0, get_id:=0, get_mode:=0)
  1144. {
  1145. (!IsObject(this.bind) && this.bind:={id:0, mode:0, oldStyle:0})
  1146. , bind:=this.bind
  1147. if (get_id)
  1148. return bind.id
  1149. if (get_mode)
  1150. return bind.mode
  1151. if (bind_id)
  1152. {
  1153. bind.id:=bind_id:=this.Floor(bind_id)
  1154. , bind.mode:=bind_mode, bind.oldStyle:=0
  1155. if (bind_mode & 1)
  1156. {
  1157. i:=WinGetExStyle(bind_id)
  1158. bind.oldStyle:=i
  1159. WinSetTransparent(255, bind_id)
  1160. Loop 30
  1161. {
  1162. Sleep 100
  1163. i:=WinGetTransparent(bind_id)
  1164. }
  1165. Until (i=255)
  1166. }
  1167. }
  1168. else
  1169. {
  1170. bind_id:=bind.id
  1171. if (bind.mode & 1)
  1172. WinSetExStyle(bind.oldStyle, bind_id)
  1173. bind.id:=0, bind.mode:=0, bind.oldStyle:=0
  1174. }
  1175. }
  1176. ; 使用 FindText().CaptureCursor(1) 设置抓图时捕获鼠标
  1177. ; 使用 FindText().CaptureCursor(0) 取消抓图时捕获鼠标
  1178. CaptureCursor(hDC:=0, zx:=0, zy:=0, zw:=0, zh:=0, get_cursor:=0)
  1179. {
  1180. if (get_cursor)
  1181. return this.Cursor
  1182. if (hDC=1 || hDC=0) && (zw=0)
  1183. {
  1184. this.Cursor:=hDC
  1185. return
  1186. }
  1187. mi:=Buffer(40, 0), NumPut("int", 16+A_PtrSize, mi)
  1188. DllCall("GetCursorInfo", "Ptr",mi)
  1189. bShow:=NumGet(mi, 4, "int")
  1190. hCursor:=NumGet(mi, 8, "Ptr")
  1191. x:=NumGet(mi, 8+A_PtrSize, "int")
  1192. y:=NumGet(mi, 12+A_PtrSize, "int")
  1193. if (!bShow) || (x<zx || y<zy || x>=zx+zw || y>=zy+zh)
  1194. return
  1195. ni:=Buffer(40, 0)
  1196. DllCall("GetIconInfo", "Ptr",hCursor, "Ptr",ni)
  1197. xCenter:=NumGet(ni, 4, "int")
  1198. yCenter:=NumGet(ni, 8, "int")
  1199. hBMMask:=NumGet(ni, (A_PtrSize=8?16:12), "Ptr")
  1200. hBMColor:=NumGet(ni, (A_PtrSize=8?24:16), "Ptr")
  1201. DllCall("DrawIconEx", "Ptr",hDC
  1202. , "int",x-xCenter-zx, "int",y-yCenter-zy, "Ptr",hCursor
  1203. , "int",0, "int",0, "int",0, "int",0, "int",3)
  1204. DllCall("DeleteObject", "Ptr",hBMMask)
  1205. DllCall("DeleteObject", "Ptr",hBMColor)
  1206. }
  1207. MCode(hex)
  1208. {
  1209. flag:=((hex~="[^A-Fa-f\d\s]") ? 1:4), len:=0
  1210. Loop 2
  1211. if !DllCall("crypt32\CryptStringToBinary", "Str",hex, "uint",0, "uint",flag
  1212. , "Ptr",(A_Index=1?0:(p:=Buffer(len)).Ptr), "uint*",&len, "Ptr",0, "Ptr",0)
  1213. return
  1214. if DllCall("VirtualProtect", "Ptr",p.Ptr, "Ptr",len, "uint",0x40, "uint*",0)
  1215. return p
  1216. }
  1217. bin2hex(addr, size, base64:=0)
  1218. {
  1219. flag:=(base64 ? 1:4)|0x40000000, len:=0
  1220. Loop 2
  1221. DllCall("crypt32\CryptBinaryToString", "Ptr",addr, "uint",size, "uint",flag
  1222. , "Ptr",(A_Index=1?0:(p:=Buffer(len*2)).Ptr), "uint*",&len)
  1223. return RegExReplace(StrGet(p.Ptr, len), "\s+")
  1224. }
  1225. base64tobit(s)
  1226. {
  1227. ListLines (lls:=A_ListLines)?0:0
  1228. Chars:="0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
  1229. Loop Parse, Chars
  1230. if InStr(s, A_LoopField, 1)
  1231. s:=RegExReplace(s, "[" A_LoopField "]", ((i:=A_Index-1)>>5&1)
  1232. . (i>>4&1) . (i>>3&1) . (i>>2&1) . (i>>1&1) . (i&1))
  1233. s:=RegExReplace(RegExReplace(s,"[^01]+"),"10*$")
  1234. ListLines lls
  1235. return s
  1236. }
  1237. bit2base64(s)
  1238. {
  1239. ListLines (lls:=A_ListLines)?0:0
  1240. s:=RegExReplace(s,"[^01]+")
  1241. s.=SubStr("100000",1,6-Mod(StrLen(s),6))
  1242. s:=RegExReplace(s,".{6}","|$0")
  1243. Chars:="0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
  1244. Loop Parse, Chars
  1245. s:=StrReplace(s, "|" . ((i:=A_Index-1)>>5&1)
  1246. . (i>>4&1) . (i>>3&1) . (i>>2&1) . (i>>1&1) . (i&1), A_LoopField)
  1247. ListLines lls
  1248. return s
  1249. }
  1250. ASCII(s)
  1251. {
  1252. if RegExMatch(s, "\$(\d+)\.([\w+/]+)", &r)
  1253. {
  1254. s:=RegExReplace(this.base64tobit(r[2]),".{" r[1] "}","$0`n")
  1255. s:=StrReplace(StrReplace(s,"0","_"),"1","0")
  1256. }
  1257. else s:=""
  1258. return s
  1259. }
  1260. ; 可以在脚本的开头用 FindText().PicLib(Text,1) 导入字库,
  1261. ; 然后使用 FindText().PicLib("说明文字1|说明文字2|...") 获取字库中的数据
  1262. PicLib(comments, add_to_Lib:=0, index:=1)
  1263. {
  1264. (!IsObject(this.Lib) && this.Lib:=Map()), Lib:=this.Lib
  1265. , (!Lib.Has(index) && Lib[index]:=Map()), Lib:=Lib[index]
  1266. if (add_to_Lib)
  1267. {
  1268. re:="<([^>\n]*)>[^$\n]+\$[^`"'\r\n]+"
  1269. Loop Parse, comments, "|"
  1270. if RegExMatch(A_LoopField, re, &r)
  1271. {
  1272. s1:=Trim(r[1]), s2:=""
  1273. Loop Parse, s1
  1274. s2.=Format("_{:d}", Ord(A_LoopField))
  1275. (s2!="") && Lib[s2]:=r[0]
  1276. }
  1277. }
  1278. else
  1279. {
  1280. Text:=""
  1281. Loop Parse, comments, "|"
  1282. {
  1283. s1:=Trim(A_LoopField), s2:=""
  1284. Loop Parse, s1
  1285. s2.=Format("_{:d}", Ord(A_LoopField))
  1286. (Lib.Has(s2)) && Text.="|" Lib[s2]
  1287. }
  1288. return Text
  1289. }
  1290. }
  1291. ; 分割字符串为单个文字并获取数据
  1292. PicN(Number, index:=1)
  1293. {
  1294. return this.PicLib(RegExReplace(Number,".","|$0"), 0, index)
  1295. }
  1296. ; 使用 FindText().PicX(Text) 可以将文字分割成多个单字的组合,从而适应间隔变化
  1297. ; 但是不能用于“颜色位置二值化”模式, 因为位置是与整体图像相关的
  1298. PicX(Text)
  1299. {
  1300. if !RegExMatch(Text, "(<[^$\n]+)\$(\d+)\.([\w+/]+)", &r)
  1301. return Text
  1302. v:=this.base64tobit(r[3]), Text:=""
  1303. c:=StrLen(StrReplace(v,"0"))<=StrLen(v)//2 ? "1":"0"
  1304. txt:=RegExReplace(v,".{" r[2] "}","$0`n")
  1305. While InStr(txt,c)
  1306. {
  1307. While !(txt~="m`n)^" c)
  1308. txt:=RegExReplace(txt,"m`n)^.")
  1309. i:=0
  1310. While (txt~="m`n)^.{" i "}" c)
  1311. i:=Format("{:d}",i+1)
  1312. v:=RegExReplace(txt,"m`n)^(.{" i "}).*","$1")
  1313. txt:=RegExReplace(txt,"m`n)^.{" i "}")
  1314. if (v!="")
  1315. Text.="|" r[1] "$" i "." this.bit2base64(v)
  1316. }
  1317. return Text
  1318. }
  1319. ; 截屏,作为后续操作要用的“上一次的截屏”
  1320. ScreenShot(x1:=0, y1:=0, x2:=0, y2:=0)
  1321. {
  1322. this.FindText(,, x1, y1, x2, y2)
  1323. }
  1324. ; 从“上一次的截屏”中快速获取指定坐标的RGB颜色
  1325. ; 如果坐标超出了屏幕范围,将返回白色
  1326. GetColor(x, y, fmt:=1)
  1327. {
  1328. bits:=this.GetBitsFromScreen(,,,,0,&zx,&zy,&zw,&zh), x-=zx, y-=zy
  1329. , c:=(x>=0 && x<zw && y>=0 && y<zh && bits.Scan0)
  1330. ? NumGet(bits.Scan0+y*bits.Stride+x*4,"uint") : 0xFFFFFF
  1331. return (fmt ? Format("0x{:06X}",c&0xFFFFFF) : c)
  1332. }
  1333. ; 在“上一次的截屏”中设置点的RGB颜色
  1334. SetColor(x, y, color:=0x000000)
  1335. {
  1336. bits:=this.GetBitsFromScreen(,,,,0,&zx,&zy,&zw,&zh), x-=zx, y-=zy
  1337. if (x>=0 && x<zw && y>=0 && y<zh && bits.Scan0)
  1338. NumPut("uint", color, bits.Scan0+y*bits.Stride+x*4)
  1339. }
  1340. ; 根据 FindText() 的结果识别一行文字或验证码
  1341. ; offsetX 为两个文字的最大间隔,超过会插入*号
  1342. ; offsetY 为两个文字的最大高度差
  1343. ; overlapW 用于设置覆盖的宽度
  1344. ; 最后返回数组:{text:识别结果, x:结果左上角X, y:结果左上角Y, w:宽, h:高}
  1345. Ocr(ok, offsetX:=20, offsetY:=20, overlapW:=0)
  1346. {
  1347. ocr_Text:=ocr_X:=ocr_Y:=min_X:=dx:=""
  1348. For k,v in ok
  1349. x:=v.1
  1350. , min_X:=(A_Index=1 || x<min_X ? x : min_X)
  1351. , max_X:=(A_Index=1 || x>max_X ? x : max_X)
  1352. While (min_X!="" && min_X<=max_X)
  1353. {
  1354. LeftX:=""
  1355. For k,v in ok
  1356. {
  1357. x:=v.1, y:=v.2
  1358. if (x<min_X) || (ocr_Y!="" && Abs(y-ocr_Y)>offsetY)
  1359. Continue
  1360. ; Get the leftmost X coordinates
  1361. if (LeftX="" || x<LeftX)
  1362. LeftX:=x, LeftY:=y, LeftW:=v.3, LeftH:=v.4, LeftOCR:=v.id
  1363. }
  1364. if (LeftX="")
  1365. Break
  1366. if (ocr_X="")
  1367. ocr_X:=LeftX, min_Y:=LeftY, max_Y:=LeftY+LeftH
  1368. ; If the interval exceeds the set value, add "*" to the result
  1369. ocr_Text.=(ocr_Text!="" && LeftX>dx ? "*":"") . LeftOCR
  1370. ; Update for next search
  1371. min_X:=LeftX+LeftW-(overlapW>LeftW//2 ? LeftW//2:overlapW)
  1372. , dx:=LeftX+LeftW+offsetX, ocr_Y:=LeftY
  1373. , (LeftY<min_Y && min_Y:=LeftY)
  1374. , (LeftY+LeftH>max_Y && max_Y:=LeftY+LeftH)
  1375. }
  1376. (ocr_X="") && ocr_X:=min_Y:=min_X:=max_Y:=0
  1377. return {text:ocr_Text, x:ocr_X, y:min_Y, w:min_X-ocr_X, h:max_Y-min_Y}
  1378. }
  1379. ; 按照从左到右、从上到下的顺序排序FindText()的结果
  1380. ; 忽略轻微的Y坐标差距,返回排序后的数组对象
  1381. Sort(ok, dy:=10)
  1382. {
  1383. if !IsObject(ok)
  1384. return ok
  1385. s:="", n:=150000, ypos:=[]
  1386. For k,v in ok
  1387. {
  1388. x:=v.x, y:=v.y, add:=1
  1389. For k1,v1 in ypos
  1390. if Abs(y-v1)<=dy
  1391. {
  1392. y:=v1, add:=0
  1393. Break
  1394. }
  1395. if (add)
  1396. ypos.Push(y)
  1397. s.=(y*n+x) "." k "|"
  1398. }
  1399. s:=Trim(s,"|")
  1400. s:=Sort(s, "N D|")
  1401. ok2:=[]
  1402. For k,v in StrSplit(s,"|")
  1403. ok2.Push(ok[SubStr(v,InStr(v,".")+1)])
  1404. return ok2
  1405. }
  1406. ; 以指定点为中心,按从近到远排序FindText()的结果,返回排序后的数组
  1407. Sort2(ok, px, py)
  1408. {
  1409. if !IsObject(ok)
  1410. return ok
  1411. s:=""
  1412. For k,v in ok
  1413. s.=((v.x-px)**2+(v.y-py)**2) "." k "|"
  1414. s:=Trim(s,"|")
  1415. s:=Sort(s, "N D|")
  1416. ok2:=[]
  1417. For k,v in StrSplit(s,"|")
  1418. ok2.Push(ok[SubStr(v,InStr(v,".")+1)])
  1419. return ok2
  1420. }
  1421. ; 按指定的查找方向,排序FindText()的结果,返回排序后的数组
  1422. Sort3(ok, dir:=1)
  1423. {
  1424. if !IsObject(ok)
  1425. return ok
  1426. s:="", n:=150000
  1427. For k,v in ok
  1428. x:=v.1, y:=v.2
  1429. , s.=(dir=1 ? y*n+x
  1430. : dir=2 ? y*n-x
  1431. : dir=3 ? -y*n+x
  1432. : dir=4 ? -y*n-x
  1433. : dir=5 ? x*n+y
  1434. : dir=6 ? x*n-y
  1435. : dir=7 ? -x*n+y
  1436. : dir=8 ? -x*n-y : y*n+x) "." k "|"
  1437. s:=Trim(s,"|")
  1438. s:=Sort(s, "N D|")
  1439. ok2:=[]
  1440. For k,v in StrSplit(s,"|")
  1441. ok2.Push(ok[SubStr(v,InStr(v,".")+1)])
  1442. return ok2
  1443. }
  1444. ; 提示某个坐标的位置,或远程控制中当前鼠标的位置
  1445. MouseTip(x:="", y:="", w:=10, h:=10, d:=3)
  1446. {
  1447. if (x="")
  1448. {
  1449. pt:=Buffer(16,0), DllCall("GetCursorPos", "Ptr",pt)
  1450. x:=NumGet(pt,0,"uint"), y:=NumGet(pt,4,"uint")
  1451. }
  1452. Loop 4
  1453. {
  1454. this.RangeTip(x-w, y-h, 2*w+1, 2*h+1, (A_Index & 1 ? "Red":"Blue"), d)
  1455. Sleep 500
  1456. }
  1457. this.RangeTip()
  1458. }
  1459. ; 显示范围的边框,类似于 ToolTip
  1460. RangeTip(x:="", y:="", w:="", h:="", color:="Red", d:=3, num:=1)
  1461. {
  1462. ListLines (lls:=A_ListLines)?0:0
  1463. static tab:=Map()
  1464. (!tab.Has(num) && tab[num]:=[0,0,0,0]), Range:=tab[num]
  1465. if (x="")
  1466. {
  1467. if (Range[1])
  1468. Loop 4
  1469. Range[A_Index].Destroy(), Range[A_Index]:=""
  1470. ListLines lls
  1471. return
  1472. }
  1473. if !(Range[1])
  1474. {
  1475. Loop 4
  1476. Range[A_Index]:=Gui("+AlwaysOnTop -Caption +ToolWindow -DPIScale +E0x08000000")
  1477. }
  1478. x:=this.Floor(x), y:=this.Floor(y), w:=this.Floor(w), h:=this.Floor(h), d:=this.Floor(d)
  1479. Loop 4
  1480. {
  1481. i:=A_Index
  1482. , x1:=(i=2 ? x+w : x-d)
  1483. , y1:=(i=3 ? y+h : y-d)
  1484. , w1:=(i=1 || i=3 ? w+2*d : d)
  1485. , h1:=(i=2 || i=4 ? h+2*d : d)
  1486. Range[i].BackColor:=color
  1487. Range[i].Show("NA x" x1 " y" y1 " w" w1 " h" h1)
  1488. }
  1489. ListLines lls
  1490. }
  1491. State(key)
  1492. {
  1493. return GetKeyState(key,"P") || GetKeyState(key)
  1494. }
  1495. ; 用鼠标左右键选取屏幕范围
  1496. GetRange(ww:=25, hh:=8, key:="RButton")
  1497. {
  1498. static KeyOff:="", hk
  1499. if (!KeyOff)
  1500. KeyOff:=this.GetRange.Bind(this, "Off")
  1501. if (ww=="Off")
  1502. return hk:=Trim(A_ThisHotkey, "*")
  1503. ;---------------------
  1504. GetRange_HotkeyIf:=_Gui:=Gui()
  1505. _Gui.Opt("-Caption +ToolWindow +E0x80000")
  1506. _Gui.Title:="GetRange_HotkeyIf"
  1507. _Gui.Show("NA x0 y0 w0 h0")
  1508. ;---------------------
  1509. if GetKeyState("Ctrl")
  1510. Send "{Ctrl Up}"
  1511. HotIfWinExist "GetRange_HotkeyIf"
  1512. keys:=key "|Up|Down|Left|Right"
  1513. For k,v in StrSplit(keys, "|")
  1514. {
  1515. if GetKeyState(v)
  1516. Send "{" v " Up}"
  1517. Try Hotkey "*" v, KeyOff, "On"
  1518. }
  1519. HotIfWinExist
  1520. ;---------------------
  1521. Critical (cri:=A_IsCritical)?"Off":"Off"
  1522. CoordMode "Mouse"
  1523. tip:=this.Lang("s5")
  1524. hk:="", oldx:=oldy:="", keydown:=0
  1525. Loop
  1526. {
  1527. Sleep 50
  1528. MouseGetPos &x2, &y2
  1529. if (hk=key) || this.State(key) || this.State("Ctrl")
  1530. {
  1531. keydown++
  1532. if (keydown=1)
  1533. MouseGetPos &x1, &y1, &Bind_ID
  1534. timeout:=A_TickCount+3000
  1535. While (A_TickCount<timeout) && (this.State(key) || this.State("Ctrl"))
  1536. Sleep 50
  1537. hk:=""
  1538. if (keydown>=2)
  1539. Break
  1540. }
  1541. else if (hk="Up") || this.State("Up")
  1542. (hh>1 && hh--), hk:=""
  1543. else if (hk="Down") || this.State("Down")
  1544. hh++, hk:=""
  1545. else if (hk="Left") || this.State("Left")
  1546. (ww>1 && ww--), hk:=""
  1547. else if (hk="Right") || this.State("Right")
  1548. ww++, hk:=""
  1549. x:=(keydown?x1:x2), y:=(keydown?y1:y2)
  1550. this.RangeTip(x-ww, y-hh, 2*ww+1, 2*hh+1, (A_MSec<500?"Red":"Blue"))
  1551. if (oldx=x2 && oldy=y2)
  1552. Continue
  1553. oldx:=x2, oldy:=y2
  1554. ToolTip "x: " x " y: " y "`n" tip
  1555. }
  1556. ToolTip
  1557. this.RangeTip()
  1558. HotIfWinExist "GetRange_HotkeyIf"
  1559. For k,v in StrSplit(keys, "|")
  1560. Try Hotkey "*" v, KeyOff, "Off"
  1561. HotIfWinExist
  1562. GetRange_HotkeyIf.Destroy()
  1563. Critical cri
  1564. return [x-ww, y-hh, x+ww, y+hh, Bind_ID]
  1565. }
  1566. GetRange2(key:="LButton")
  1567. {
  1568. FindText_GetRange:=_Gui:=Gui()
  1569. _Gui.Opt("+LastFound +AlwaysOnTop -Caption +ToolWindow -DPIScale +E0x08000000")
  1570. _Gui.BackColor:="White"
  1571. WinSetTransparent(10)
  1572. this.GetBitsFromScreen(,,,,0,&x,&y,&w,&h)
  1573. _Gui.Title:="FindText_GetRange"
  1574. _Gui.Show("NA x" x " y" y " w" w " h" h)
  1575. CoordMode "Mouse"
  1576. tip:=this.Lang("s7"), oldx:=oldy:=""
  1577. Loop
  1578. {
  1579. Sleep 50
  1580. MouseGetPos &x1, &y1
  1581. if (oldx=x1 && oldy=y1)
  1582. Continue
  1583. oldx:=x1, oldy:=y1
  1584. ToolTip "x: " x1 " y: " y1 " w: 0 h: 0`n" tip
  1585. }
  1586. Until this.State(key) || this.State("Ctrl")
  1587. Loop
  1588. {
  1589. Sleep 50
  1590. MouseGetPos &x2, &y2
  1591. x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x2-x1)+1, h:=Abs(y2-y1)+1
  1592. this.RangeTip(x, y, w, h, (A_MSec<500 ? "Red":"Blue"))
  1593. if (oldx=x2 && oldy=y2)
  1594. Continue
  1595. oldx:=x2, oldy:=y2
  1596. ToolTip "x: " x " y: " y " w: " w " h: " h "`n" tip
  1597. }
  1598. Until !(this.State(key) || this.State("Ctrl"))
  1599. ToolTip
  1600. this.RangeTip()
  1601. FindText_GetRange.Destroy()
  1602. A_Clipboard:=x "," y "," (x+w-1) "," (y+h-1)
  1603. return [x, y, x+w-1, y+h-1]
  1604. }
  1605. BitmapFromScreen(&x:=0, &y:=0, &w:=0, &h:=0
  1606. , ScreenShot:=1, &zx:=0, &zy:=0, &zw:=0, &zh:=0)
  1607. {
  1608. bits:=this.GetBitsFromScreen(&x,&y,&w,&h,ScreenShot,&zx,&zy,&zw,&zh)
  1609. if (w<1 || h<1 || !bits.hBM)
  1610. return
  1611. hBM:=this.CreateDIBSection(w, h)
  1612. this.CopyHBM(hBM, 0, 0, bits.hBM, x-zx, y-zy, w, h, 1)
  1613. return hBM
  1614. }
  1615. ; 快速保存截图为BMP文件,可用于调试
  1616. ; 如果 file=0 或 "" ,会保存到剪贴板
  1617. SavePic(file:=0, x1:=0, y1:=0, x2:=0, y2:=0, ScreenShot:=1)
  1618. {
  1619. x1:=this.Floor(x1), y1:=this.Floor(y1), x2:=this.Floor(x2), y2:=this.Floor(y2)
  1620. if (x1=0 && y1=0 && x2=0 && y2=0)
  1621. n:=150000, x:=y:=-n, w:=h:=2*n
  1622. else
  1623. x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x2-x1)+1, h:=Abs(y2-y1)+1
  1624. hBM:=this.BitmapFromScreen(&x, &y, &w, &h, ScreenShot)
  1625. this.SaveBitmapToFile(file, hBM)
  1626. DllCall("DeleteObject", "Ptr",hBM)
  1627. }
  1628. ; 保存图像到文件,如果 file=0 或者 "",保存到剪贴板
  1629. ; 参数可以是位图句柄或者文件路径,例如: "c:\a.bmp"
  1630. SaveBitmapToFile(file, hBM_or_file, x:=0, y:=0, w:=0, h:=0)
  1631. {
  1632. if IsNumber(hBM_or_file)
  1633. hBM_or_file:="HBITMAP:*" hBM_or_file
  1634. if !hBM:=DllCall("CopyImage", "Ptr",LoadPicture(hBM_or_file)
  1635. , "int",0, "int",0, "int",0, "uint",0x2008)
  1636. return
  1637. if (file) || (w!=0 && h!=0)
  1638. {
  1639. (w=0 || h=0) && this.GetBitmapWH(hBM, &w, &h)
  1640. hBM2:=this.CreateDIBSection(w, -h, bpp:=(file ? 24 : 32))
  1641. this.CopyHBM(hBM2, 0, 0, hBM, x, y, w, h)
  1642. DllCall("DeleteObject", "Ptr",hBM), hBM:=hBM2
  1643. }
  1644. dib:=Buffer(dib_size:=(A_PtrSize=8 ? 104:84), 0)
  1645. , DllCall("GetObject", "Ptr",hBM, "int",dib_size, "Ptr",dib)
  1646. , pbi:=dib.Ptr+(bitmap_size:=A_PtrSize=8 ? 32:24)
  1647. , size:=NumGet(pbi+20, "uint"), pBits:=NumGet(pbi-A_PtrSize, "Ptr")
  1648. if (!file)
  1649. {
  1650. hdib:=DllCall("GlobalAlloc", "uint",2, "Ptr",40+size, "Ptr")
  1651. pdib:=DllCall("GlobalLock", "Ptr",hdib, "Ptr")
  1652. DllCall("RtlMoveMemory", "Ptr",pdib, "Ptr",pbi, "Ptr",40)
  1653. DllCall("RtlMoveMemory", "Ptr",pdib+40, "Ptr",pBits, "Ptr",size)
  1654. DllCall("GlobalUnlock", "Ptr",hdib)
  1655. DllCall("OpenClipboard", "Ptr",0)
  1656. DllCall("EmptyClipboard")
  1657. DllCall("SetClipboardData", "uint",8, "Ptr",hdib)
  1658. DllCall("CloseClipboard")
  1659. }
  1660. else
  1661. {
  1662. if InStr(file,"\") && !FileExist(dir:=RegExReplace(file,"[^\\]*$"))
  1663. Try DirCreate(dir)
  1664. bf:=Buffer(14, 0), NumPut("short", 0x4D42, bf)
  1665. NumPut("uint", 54+size, bf, 2), NumPut("uint", 54, bf, 10)
  1666. f:=FileOpen(file, "w"), f.RawWrite(bf, 14)
  1667. , f.RawWrite(pbi+0, 40), f.RawWrite(pBits+0, size), f.Close()
  1668. }
  1669. DllCall("DeleteObject", "Ptr",hBM)
  1670. }
  1671. ; 显示保存的图像
  1672. ShowPic(file:="", show:=1, &x:="", &y:="", &w:="", &h:="")
  1673. {
  1674. if (file="")
  1675. {
  1676. this.ShowScreenShot()
  1677. return
  1678. }
  1679. if !(hBM:=LoadPicture(file))
  1680. return
  1681. this.GetBitmapWH(hBM, &w, &h)
  1682. bits:=this.GetBitsFromScreen(,,,,0,&x,&y,&zw,&zh)
  1683. this.UpdateBits(bits, x, y, Max(w,zw), Max(h,zh))
  1684. this.CopyHBM(bits.hBM, 0, 0, hBM, 0, 0, w, h)
  1685. DllCall("DeleteObject", "Ptr",hBM)
  1686. if (show)
  1687. this.ShowScreenShot(x, y, x+w-1, y+h-1, 0)
  1688. return 1
  1689. }
  1690. ; 显示内存中的屏幕截图用于调试
  1691. ShowScreenShot(x1:=0, y1:=0, x2:=0, y2:=0, ScreenShot:=1)
  1692. {
  1693. static hPic, oldx, oldy, oldw, oldh, FindText_Screen:=""
  1694. x1:=this.Floor(x1), y1:=this.Floor(y1), x2:=this.Floor(x2), y2:=this.Floor(y2)
  1695. if (x1=0 && y1=0 && x2=0 && y2=0)
  1696. {
  1697. if (FindText_Screen)
  1698. FindText_Screen.Destroy(), FindText_Screen:=""
  1699. return
  1700. }
  1701. x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x2-x1)+1, h:=Abs(y2-y1)+1
  1702. if !hBM:=this.BitmapFromScreen(&x,&y,&w,&h,ScreenShot)
  1703. return
  1704. ;---------------
  1705. if (!FindText_Screen)
  1706. {
  1707. FindText_Screen:=_Gui:=Gui() ; WS_EX_NOACTIVATE:=0x08000000
  1708. _Gui.Opt("+AlwaysOnTop -Caption +ToolWindow -DPIScale +E0x08000000")
  1709. _Gui.MarginX:=0, _Gui.MarginY:=0
  1710. id:=_Gui.Add("Pic", "w" w " h" h), hPic:=id.Hwnd
  1711. _Gui.Title:="Show Pic"
  1712. _Gui.Show("NA x" x " y" y " w" w " h" h)
  1713. oldx:=x, oldy:=y, oldw:=w, oldh:=h
  1714. }
  1715. else if (oldx!=x || oldy!=y || oldw!=w || oldh!=h)
  1716. {
  1717. if (oldw!=w || oldh!=h)
  1718. FindText_Screen[hPic].Move(,, w, h)
  1719. FindText_Screen.Show("NA x" x " y" y " w" w " h" h)
  1720. oldx:=x, oldy:=y, oldw:=w, oldh:=h
  1721. }
  1722. this.BitmapToWindow(hPic, 0, 0, hBM, 0, 0, w, h)
  1723. DllCall("DeleteObject", "Ptr",hBM)
  1724. }
  1725. BitmapToWindow(hwnd, x1, y1, hBM, x2, y2, w, h)
  1726. {
  1727. mDC:=DllCall("CreateCompatibleDC", "Ptr",0, "Ptr")
  1728. oBM:=DllCall("SelectObject", "Ptr",mDC, "Ptr",hBM, "Ptr")
  1729. hDC:=DllCall("GetDC", "Ptr",hwnd, "Ptr")
  1730. DllCall("BitBlt", "Ptr",hDC, "int",x1, "int",y1, "int",w, "int",h
  1731. , "Ptr",mDC, "int",x2, "int",y2, "uint",0xCC0020)
  1732. DllCall("ReleaseDC", "Ptr",hwnd, "Ptr",hDC)
  1733. DllCall("SelectObject", "Ptr",mDC, "Ptr",oBM)
  1734. DllCall("DeleteDC", "Ptr",mDC)
  1735. }
  1736. ; 快速获取屏幕图像的搜索文本数据
  1737. GetTextFromScreen(x1:=0, y1:=0, x2:=0, y2:=0, Threshold:=""
  1738. , ScreenShot:=1, &rx:="", &ry:="", cut:=1)
  1739. {
  1740. if (x1=0 && y1=0 && x2=0 && y2=0)
  1741. return this.Gui("CaptureS", ScreenShot)
  1742. x1:=this.Floor(x1), y1:=this.Floor(y1), x2:=this.Floor(x2), y2:=this.Floor(y2)
  1743. x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x2-x1)+1, h:=Abs(y2-y1)+1
  1744. bits:=this.GetBitsFromScreen(&x,&y,&w,&h,ScreenShot,&zx,&zy)
  1745. if (w<1 || h<1 || !bits.Scan0)
  1746. {
  1747. return
  1748. }
  1749. ListLines (lls:=A_ListLines)?0:0
  1750. gs:=Map(), gs.Default:=0
  1751. j:=bits.Stride-w*4, p:=bits.Scan0+(y-zy)*bits.Stride+(x-zx)*4-j-4
  1752. Loop h + 0*(k:=0)
  1753. Loop w + 0*(p+=j)
  1754. c:=NumGet(p+=4,"uint")
  1755. , gs[++k]:=(((c>>16)&0xFF)*38+((c>>8)&0xFF)*75+(c&0xFF)*15)>>7
  1756. if InStr(Threshold,"**")
  1757. {
  1758. Threshold:=Trim(Threshold,"* "), (Threshold="" && Threshold:=50)
  1759. s:="", sw:=w, w-=2, h-=2, x++, y++
  1760. Loop h + 0*(y1:=0)
  1761. Loop w + 0*(y1++)
  1762. i:=y1*sw+A_Index+1, j:=gs[i]+Threshold
  1763. , s.=( gs[i-1]>j || gs[i+1]>j
  1764. || gs[i-sw]>j || gs[i+sw]>j
  1765. || gs[i-sw-1]>j || gs[i-sw+1]>j
  1766. || gs[i+sw-1]>j || gs[i+sw+1]>j ) ? "1":"0"
  1767. Threshold:="**" Threshold
  1768. }
  1769. else
  1770. {
  1771. Threshold:=Trim(Threshold,"* ")
  1772. if (Threshold="")
  1773. {
  1774. pp:=Map(), pp.Default:=0
  1775. Loop 256
  1776. pp[A_Index-1]:=0
  1777. Loop w*h
  1778. pp[gs[A_Index]]++
  1779. IP0:=IS0:=0
  1780. Loop 256
  1781. k:=A_Index-1, IP0+=k*pp[k], IS0+=pp[k]
  1782. Threshold:=Floor(IP0/IS0)
  1783. Loop 20
  1784. {
  1785. LastThreshold:=Threshold
  1786. IP1:=IS1:=0
  1787. Loop LastThreshold+1
  1788. k:=A_Index-1, IP1+=k*pp[k], IS1+=pp[k]
  1789. IP2:=IP0-IP1, IS2:=IS0-IS1
  1790. if (IS1!=0 && IS2!=0)
  1791. Threshold:=Floor((IP1/IS1+IP2/IS2)/2)
  1792. if (Threshold=LastThreshold)
  1793. Break
  1794. }
  1795. }
  1796. s:=""
  1797. Loop w*h
  1798. s.=gs[A_Index]<=Threshold ? "1":"0"
  1799. Threshold:="*" Threshold
  1800. }
  1801. ListLines lls
  1802. ;--------------------
  1803. w:=Format("{:d}",w), CutUp:=CutDown:=0
  1804. if (cut=1)
  1805. {
  1806. re1:="(^0{" w "}|^1{" w "})"
  1807. re2:="(0{" w "}$|1{" w "}$)"
  1808. While (s~=re1)
  1809. s:=RegExReplace(s,re1), CutUp++
  1810. While (s~=re2)
  1811. s:=RegExReplace(s,re2), CutDown++
  1812. }
  1813. rx:=x+w//2, ry:=y+CutUp+(h-CutUp-CutDown)//2
  1814. s:="|<>" Threshold "$" w "." this.bit2base64(s)
  1815. ;--------------------
  1816. return s
  1817. }
  1818. ; 等待几秒钟直到屏幕图像改变,需要先调用FindText().ScreenShot()
  1819. WaitChange(time:=-1, x1:=0, y1:=0, x2:=0, y2:=0)
  1820. {
  1821. hash:=this.GetPicHash(x1, y1, x2, y2, 0)
  1822. time:=this.Floor(time), timeout:=A_TickCount+Round(time*1000)
  1823. Loop
  1824. {
  1825. if (hash!=this.GetPicHash(x1, y1, x2, y2, 1))
  1826. return 1
  1827. if (time>=0 && A_TickCount>=timeout)
  1828. Break
  1829. Sleep 10
  1830. }
  1831. return 0
  1832. }
  1833. ; 等待屏幕图像稳定下来
  1834. WaitNotChange(time:=1, timeout:=30, x1:=0, y1:=0, x2:=0, y2:=0)
  1835. {
  1836. oldhash:="", time:=this.Floor(time)
  1837. , timeout:=A_TickCount+Round(this.Floor(timeout)*1000)
  1838. Loop
  1839. {
  1840. hash:=this.GetPicHash(x1, y1, x2, y2, 1), t:=A_TickCount
  1841. if (hash!=oldhash)
  1842. oldhash:=hash, timeout2:=t+Round(time*1000)
  1843. if (t>=timeout2)
  1844. return 1
  1845. if (t>=timeout)
  1846. return 0
  1847. Sleep 100
  1848. }
  1849. }
  1850. GetPicHash(x1:=0, y1:=0, x2:=0, y2:=0, ScreenShot:=1)
  1851. {
  1852. static init:=DllCall("LoadLibrary", "Str","ntdll", "Ptr")
  1853. x1:=this.Floor(x1), y1:=this.Floor(y1), x2:=this.Floor(x2), y2:=this.Floor(y2)
  1854. if (x1=0 && y1=0 && x2=0 && y2=0)
  1855. n:=150000, x:=y:=-n, w:=h:=2*n
  1856. else
  1857. x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x2-x1)+1, h:=Abs(y2-y1)+1
  1858. bits:=this.GetBitsFromScreen(&x,&y,&w,&h,ScreenShot,&zx,&zy), x-=zx, y-=zy
  1859. if (w<1 || h<1 || !bits.Scan0)
  1860. return 0
  1861. hash:=0, Stride:=bits.Stride, p:=bits.Scan0+(y-1)*Stride+x*4, w*=4
  1862. ListLines (lls:=A_ListLines)?0:0
  1863. Loop h
  1864. hash:=(hash*31+DllCall("ntdll\RtlComputeCrc32", "uint",0
  1865. , "Ptr",p+=Stride, "uint",w, "uint"))&0xFFFFFFFF
  1866. ListLines lls
  1867. return hash
  1868. }
  1869. WindowToScreen(&x, &y, x1, y1, id:="")
  1870. {
  1871. if (!id)
  1872. id:=WinGetID("A")
  1873. rect:=Buffer(16, 0)
  1874. , DllCall("GetWindowRect", "Ptr",id, "Ptr",rect)
  1875. , x:=x1+NumGet(rect,"int"), y:=y1+NumGet(rect,4,"int")
  1876. }
  1877. ScreenToWindow(&x, &y, x1, y1, id:="")
  1878. {
  1879. this.WindowToScreen(&dx, &dy, 0, 0, id), x:=x1-dx, y:=y1-dy
  1880. }
  1881. ClientToScreen(&x, &y, x1, y1, id:="")
  1882. {
  1883. if (!id)
  1884. id:=WinGetID("A")
  1885. pt:=Buffer(8, 0), NumPut("int64", 0, pt)
  1886. , DllCall("ClientToScreen", "Ptr",id, "Ptr",pt)
  1887. , x:=x1+NumGet(pt,"int"), y:=y1+NumGet(pt,4,"int")
  1888. }
  1889. ScreenToClient(&x, &y, x1, y1, id:="")
  1890. {
  1891. this.ClientToScreen(&dx, &dy, 0, 0, id), x:=x1-dx, y:=y1-dy
  1892. }
  1893. ; 不像 FindText 总是使用屏幕坐标,它使用与内置命令
  1894. ; PixelGetColor 一样的 CoordMode 设置的坐标模式
  1895. PixelGetColor(x, y, ScreenShot:=1, id:="")
  1896. {
  1897. if (A_CoordModePixel="Window")
  1898. this.WindowToScreen(&x, &y, x, y, id)
  1899. else if (A_CoordModePixel="Client")
  1900. this.ClientToScreen(&x, &y, x, y, id)
  1901. if (ScreenShot)
  1902. this.ScreenShot(x, y, x, y)
  1903. return this.GetColor(x, y)
  1904. }
  1905. ; 不像 FindText 总是使用屏幕坐标,它使用与内置命令
  1906. ; ImageSearch 一样的 CoordMode 设置的坐标模式
  1907. ; 图片文件参数可以使用 "*n *TransBlack/White/RRGGBB-DRDGDB... d:\a.bmp"
  1908. ImageSearch(&rx:="", &ry:="", x1:=0, y1:=0, x2:=0, y2:=0
  1909. , ImageFile:="", ScreenShot:=1, FindAll:=0, dir:=1)
  1910. {
  1911. dx:=dy:=0
  1912. if (A_CoordModePixel="Window")
  1913. this.WindowToScreen(&dx, &dy, 0, 0)
  1914. else if (A_CoordModePixel="Client")
  1915. this.ClientToScreen(&dx, &dy, 0, 0)
  1916. text:=""
  1917. Loop Parse, ImageFile, "|"
  1918. if (v:=Trim(A_LoopField))!=""
  1919. {
  1920. text.=InStr(v,"$") ? "|" v : "|##"
  1921. . (RegExMatch(v, "(^|\s)\*(\d+)\s", &r)
  1922. ? Format("{:06X}", r[2]<<16|r[2]<<8|r[2]) : "000000")
  1923. . (RegExMatch(v, "i)(^|\s)\*Trans(\S+)\s", &r) ? "/" Trim(r[2],"/"):"")
  1924. . "$" Trim(RegExReplace(v,"(^|\s)\*\S+"))
  1925. }
  1926. x1:=this.Floor(x1), y1:=this.Floor(y1), x2:=this.Floor(x2), y2:=this.Floor(y2)
  1927. if (x1=0 && y1=0 && x2=0 && y2=0)
  1928. n:=150000, x1:=y1:=-n, x2:=y2:=n
  1929. if (ok:=this.FindText(,, x1+dx, y1+dy, x2+dx, y2+dy
  1930. , 0, 0, text, ScreenShot, FindAll,,,, dir))
  1931. {
  1932. For k,v in ok ; you can use ok:=FindText().ok
  1933. v.1-=dx, v.2-=dy, v.x-=dx, v.y-=dy
  1934. rx:=ok[1].1, ry:=ok[1].2
  1935. return ok
  1936. }
  1937. else
  1938. {
  1939. rx:=ry:=""
  1940. return 0
  1941. }
  1942. }
  1943. ; 不像 FindText 总是使用屏幕坐标,它使用与内置命令
  1944. ; PixelSearch 一样的 CoordMode 设置的坐标模式
  1945. ; 颜色参数可以是 "RRGGBB-DRDGDB|RRGGBB-DRDGDB", Variation 取值 0-255
  1946. PixelSearch(&rx:="", &ry:="", x1:=0, y1:=0, x2:=0, y2:=0
  1947. , ColorID:="", Variation:=0, ScreenShot:=1, FindAll:=0, dir:=1)
  1948. {
  1949. n:=this.Floor(Variation), text:=Format("##{:06X}$0/0/", n<<16|n<<8|n)
  1950. . Trim(StrReplace(ColorID, "|", "/"), "- /")
  1951. return this.ImageSearch(&rx, &ry, x1, y1, x2, y2, text, ScreenShot, FindAll, dir)
  1952. }
  1953. ; 屏幕坐标指示的范围内的某些颜色的像素计数
  1954. ; 颜色参数可以是 "RRGGBB-DRDGDB|RRGGBB-DRDGDB", Variation 取值 0-255
  1955. PixelCount(x1:=0, y1:=0, x2:=0, y2:=0, ColorID:="", Variation:=0, ScreenShot:=1)
  1956. {
  1957. x1:=this.Floor(x1), y1:=this.Floor(y1), x2:=this.Floor(x2), y2:=this.Floor(y2)
  1958. if (x1=0 && y1=0 && x2=0 && y2=0)
  1959. n:=150000, x:=y:=-n, w:=h:=2*n
  1960. else
  1961. x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x2-x1)+1, h:=Abs(y2-y1)+1
  1962. bits:=this.GetBitsFromScreen(&x,&y,&w,&h,ScreenShot,&zx,&zy), x-=zx, y-=zy
  1963. sum:=0, s1:=Buffer(4), s0:=Buffer(4), ss:=Buffer(w*(h+3))
  1964. ini:={ bits:bits, ss:ss.Ptr, s1:s1.Ptr, s0:s0.Ptr, allpos:0, allpos_max:0
  1965. , err1:0, err0:0, zoomW:1, zoomH:1 }
  1966. n:=this.Floor(Variation), text:=Format("##{:06X}$0/0/", n<<16|n<<8|n)
  1967. . Trim(StrReplace(ColorID, "|", "/"), "- /")
  1968. if IsObject(j:=this.PicInfo(text))
  1969. sum:=this.PicFind(ini, j, 1, x, y, w, h)
  1970. return sum
  1971. }
  1972. ; 创建包含特定颜色的色块,可以限定这个色块中符合颜色的数量
  1973. ; ColorID 可以使用 "RRGGBB-DRDGDB|RRGGBB-DRDGDB", "*128", "**50"
  1974. ; Count1, Count0 是这个色块二值化后黑点和白点的数量最小值
  1975. ColorBlock(ColorID, w, h, Count1:=0, Count0:=0)
  1976. {
  1977. (Count0>0 && Count1:=0)
  1978. Text:="|<>[" (1-Count1/(w*h)) "," (1-Count0/(w*h)) "]"
  1979. . Trim(StrReplace(ColorID,"|","/"),"- /") . Format("${:d}.",w)
  1980. . this.bit2base64(StrReplace(Format(Format("{{}:0{:d}d{}}",w*h),0),"0"
  1981. , (Count0>0 ? "0":"1")))
  1982. return Text
  1983. }
  1984. Click(x:="", y:="", other1:="", other2:="", GoBack:=0)
  1985. {
  1986. CoordMode "Mouse", (bak:=A_CoordModeMouse)?"Screen":"Screen"
  1987. if GoBack
  1988. MouseGetPos &oldx, &oldy
  1989. MouseMove x, y, 0
  1990. Sleep 30
  1991. Click x "," y "," other1 "," other2
  1992. if GoBack
  1993. MouseMove oldx, oldy, 0
  1994. CoordMode "Mouse", bak
  1995. return 1
  1996. }
  1997. ; 动态运行AHK代码作为新线程
  1998. Class Thread
  1999. {
  2000. __New(args*)
  2001. {
  2002. this.pid:=this.Exec(args*)
  2003. }
  2004. __Delete()
  2005. {
  2006. ProcessClose this.pid
  2007. }
  2008. Exec(s, Ahk:="", args:="") ; required AHK v1.1.34+ and Ahk2Exe Use .exe
  2009. {
  2010. Ahk:=Ahk ? Ahk : A_IsCompiled ? A_ScriptFullPath : A_AhkPath
  2011. s:="`nDllCall(`"SetWindowText`",`"Ptr`",A_ScriptHwnd,`"Str`",`"<AHK>`")`n"
  2012. . "`n`n" . s, s:=RegExReplace(s, "\R", "`r`n")
  2013. Try
  2014. {
  2015. shell:=ComObject("WScript.Shell")
  2016. oExec:=shell.Exec("`"" Ahk "`" /script /force /CP0 * " args)
  2017. oExec.StdIn.Write(s)
  2018. oExec.StdIn.Close(), pid:=oExec.ProcessID
  2019. }
  2020. Catch
  2021. {
  2022. f:=A_Temp "\~ahk.tmp"
  2023. s:="`r`nTry FileDelete `"" f "`"`r`n" s
  2024. Try FileDelete f
  2025. FileAppend s, f
  2026. r:=this.Clear.Bind(this)
  2027. SetTimer r, -3000
  2028. Run "`"" Ahk "`" /script /force /CP0 `"" f "`" " args,,, &pid
  2029. }
  2030. return pid
  2031. }
  2032. Clear()
  2033. {
  2034. Try FileDelete A_Temp "\~ahk.tmp"
  2035. SetTimer(,0)
  2036. }
  2037. }
  2038. ; FindText().QPC() 用法类似于 A_TickCount
  2039. QPC()
  2040. {
  2041. static f:=0, c:=DllCall("QueryPerformanceFrequency", "Int64*",&f)+(f/=1000)
  2042. return (!DllCall("QueryPerformanceCounter", "Int64*",&c))*0+(c/f)
  2043. }
  2044. ; FindText().ToolTip() 用法类似于 ToolTip
  2045. ToolTip(s:="", x:="", y:="", num:=1, arg:="")
  2046. {
  2047. static ini:=Map(), tip:=Map(), timer:=Map()
  2048. f:="ToolTip_" . this.Floor(num)
  2049. if (s="")
  2050. {
  2051. Try tip[f].Destroy()
  2052. ini[f]:="", tip[f]:=""
  2053. return
  2054. }
  2055. ;-----------------
  2056. r1:=A_CoordModeToolTip
  2057. r2:=A_CoordModeMouse
  2058. CoordMode "Mouse", "Screen"
  2059. MouseGetPos &x1, &y1
  2060. CoordMode "Mouse", r1
  2061. MouseGetPos &x2, &y2
  2062. CoordMode "Mouse", r2
  2063. (x!="" && x:="x" (this.Floor(x)+x1-x2))
  2064. , (y!="" && y:="y" (this.Floor(y)+y1-y2))
  2065. , (x="" && y="" && x:="x" (x1+16) " y" (y1+16))
  2066. ;-----------------
  2067. (!IsObject(arg) && arg:={})
  2068. bgcolor:=arg.HasOwnProp("bgcolor") ? arg.bgcolor : "FAFBFC"
  2069. color:=arg.HasOwnProp("color") ? arg.color : "Black"
  2070. font:=arg.HasOwnProp("font") ? arg.font : "Consolas"
  2071. size:=arg.HasOwnProp("size") ? arg.size : "10"
  2072. bold:=arg.HasOwnProp("bold") ? arg.bold : ""
  2073. trans:=arg.HasOwnProp("trans") ? arg.trans & 255 : 255
  2074. timeout:=arg.HasOwnProp("timeout") ? arg.timeout : ""
  2075. ;-----------------
  2076. r:=bgcolor "|" color "|" font "|" size "|" bold "|" trans "|" s
  2077. if (!ini.Has(f) || ini[f]!=r)
  2078. {
  2079. ini[f]:=r
  2080. Try tip[f].Destroy()
  2081. tip[f]:=_Gui:=Gui() ; WS_EX_LAYERED:=0x80000, WS_EX_TRANSPARENT:=0x20
  2082. _Gui.Opt("+LastFound +AlwaysOnTop -Caption +ToolWindow -DPIScale +E0x80020")
  2083. _Gui.MarginX:=2, _Gui.MarginY:=2
  2084. _Gui.BackColor:=bgcolor
  2085. _Gui.SetFont("c" color " s" size " " bold, font)
  2086. _Gui.Add("Text",, s)
  2087. _Gui.Title:=f
  2088. _Gui.Show("Hide")
  2089. WinSetTransparent(trans)
  2090. }
  2091. tip[f].Opt("+AlwaysOnTop")
  2092. tip[f].Show("NA " x " " y)
  2093. if (timeout)
  2094. {
  2095. (!timer.Has(f) && timer[f]:=this.ToolTip.Bind(this,"","","",num))
  2096. SetTimer timer[f], -Round(Abs(this.Floor(timeout)*1000))-1
  2097. }
  2098. }
  2099. ; FindText().ObjView() 查看对象的值用于调试
  2100. ObjView(obj, keyname:="")
  2101. {
  2102. if IsObject(obj)
  2103. {
  2104. s:=""
  2105. For k,v in (HasMethod(obj,"__Enum") ? obj : obj.OwnProps())
  2106. s.=this.ObjView(v, keyname "[" ((k is Integer) ? k : "`"" k "`"") "]")
  2107. }
  2108. else
  2109. s:=keyname ": " ((obj is Number) ? obj : "`"" obj "`"") "`n"
  2110. if (keyname!="")
  2111. return s
  2112. ;------------------
  2113. _Gui:=Gui("+AlwaysOnTop")
  2114. _Gui.Add("Button", "y270 w350 Default", "OK").OnEvent("Click",(*)=>WinHide())
  2115. _Gui.Add("Edit", "xp y10 w350 h250 -Wrap -WantReturn")
  2116. _Gui["Edit1"].Value:=s
  2117. _Gui.Title:="Debug view object values"
  2118. _Gui.Show()
  2119. DetectHiddenWindows 0
  2120. WinWaitClose "ahk_id " _Gui.Hwnd
  2121. _Gui.Destroy()
  2122. }
  2123. EditScroll(hEdit, regex:="", line:=0, pos:=0)
  2124. {
  2125. s:=ControlGetText(hEdit)
  2126. pos:=(regex!="") ? InStr(SubStr(s,1,s~=regex) " ","`n",0,-1)
  2127. : (line>1) ? InStr(s,"`n",0,1,line-1) : pos
  2128. SendMessage 0xB1, pos, pos, hEdit
  2129. SendMessage 0xB7,,, hEdit
  2130. }
  2131. LastCtrl()
  2132. {
  2133. For Ctrl in GuiFromHwnd(WinExist())
  2134. last:=Ctrl
  2135. return last
  2136. }
  2137. Hide(args*)
  2138. {
  2139. WinMinimize
  2140. WinHide
  2141. ToolTip
  2142. DetectHiddenWindows 0
  2143. WinWaitClose "ahk_id " WinExist()
  2144. }
  2145. SC(RGB, hwnd)
  2146. {
  2147. SendMessage 0x2001,0,(RGB&0xFF)<<16|RGB&0xFF00|(RGB>>16)&0xFF,hwnd
  2148. }
  2149. ;==== Optional GUI interface ====
  2150. Gui(cmd, arg1:="", args*)
  2151. {
  2152. static
  2153. local cri, lls, _Gui
  2154. ListLines InStr("MouseMove|ToolTipOff",cmd)?0:A_ListLines
  2155. static init:=0
  2156. if (!init && init:=1)
  2157. {
  2158. SavePicDir:=A_Temp "\Ahk_ScreenShot\"
  2159. G_ := this.Gui.Bind(this)
  2160. G_G := this.Gui.Bind(this, "G")
  2161. G_Run := this.Gui.Bind(this, "Run")
  2162. G_Show := this.Gui.Bind(this, "Show")
  2163. G_KeyDown := this.Gui.Bind(this, "KeyDown")
  2164. G_LButtonDown := this.Gui.Bind(this, "LButtonDown")
  2165. G_RButtonDown := this.Gui.Bind(this, "RButtonDown")
  2166. G_MouseMove := this.Gui.Bind(this, "MouseMove")
  2167. G_ScreenShot := this.Gui.Bind(this, "ScreenShot")
  2168. G_ShowPic := this.Gui.Bind(this, "ShowPic")
  2169. G_Slider := this.Gui.Bind(this, "Slider")
  2170. G_ToolTip := this.Gui.Bind(this, "ToolTip")
  2171. G_ToolTipOff := this.Gui.Bind(this, "ToolTipOff")
  2172. G_SaveScr := this.Gui.Bind(this, "SaveScr")
  2173. G_PicShowOK := this.Gui.Bind(this, "PicShowOK")
  2174. G_Drag := this.Gui.Bind(this, "Drag")
  2175. FindText_Capture:=FindText_Main:=""
  2176. PrevControl:=x:=y:=oldx:=oldy:=""
  2177. Pics:=Map(), hBM_old:=dx:=dy:=0
  2178. cri:=A_IsCritical
  2179. Critical
  2180. Lang:=this.Lang(,1), Tip_Text:=this.Lang(,2)
  2181. G_.Call("MakeCaptureWindow")
  2182. G_.Call("MakeMainWindow")
  2183. OnMessage(0x100, G_KeyDown)
  2184. OnMessage(0x201, G_LButtonDown)
  2185. OnMessage(0x204, G_RButtonDown)
  2186. OnMessage(0x200, G_MouseMove)
  2187. MenuTray:=A_TrayMenu
  2188. MenuTray.Add
  2189. MenuTray.Add Lang["s1"], G_Show
  2190. if (!A_IsCompiled && A_LineFile=A_ScriptFullPath)
  2191. {
  2192. MenuTray.Default:=Lang["s1"]
  2193. MenuTray.ClickCount:=1
  2194. TraySetIcon "Shell32.dll", 23
  2195. }
  2196. Critical cri
  2197. Gui("+LastFound").Destroy()
  2198. }
  2199. Switch cmd, 1
  2200. {
  2201. Case "G":
  2202. id:=this.LastCtrl()
  2203. Try id.OnEvent("Click", G_Run)
  2204. Catch
  2205. Try id.OnEvent("Change", G_Run)
  2206. return
  2207. Case "Run":
  2208. Critical
  2209. G_.Call(arg1.Name)
  2210. return
  2211. Case "Show":
  2212. FindText_Main.Show(arg1 ? "Center" : "")
  2213. ControlFocus hscr
  2214. return
  2215. Case "Cancel", "Cancel2":
  2216. WinHide
  2217. return
  2218. Case "MakeCaptureWindow":
  2219. WindowColor:="0xDDEEFF"
  2220. Try FindText_Capture.Destroy()
  2221. FindText_Capture:=_Gui:=Gui()
  2222. _Gui.Opt("+LastFound +AlwaysOnTop -DPIScale")
  2223. _Gui.MarginX:=15, _Gui.MarginY:=10
  2224. _Gui.BackColor:=WindowColor
  2225. _Gui.SetFont("s12", "Verdana")
  2226. Tab:=_Gui.Add("Tab3", "vMyTab1 -Wrap", StrSplit(Lang["s18"],"|"))
  2227. Tab.UseTab(1)
  2228. C_:=Map(), Cid_:=Map()
  2229. , nW:=71, nH:=25, w:=h:=12, pW:=nW*(w+1)-1, pH:=(nH+1)*(h+1)-1
  2230. id:=_Gui.Add("Text", "w" pW " h" pH), Cid_[id.Hwnd]:=-1
  2231. _Gui.Opt("-Theme")
  2232. ListLines (lls:=A_ListLines)?0:0
  2233. Loop nW*(nH+1)
  2234. {
  2235. i:=A_Index, j:=i=1 ? "xp yp Section" : Mod(i,nW)=1 ? "xs y+1":"x+1"
  2236. id:=_Gui.Add("Progress", j " w" w " h" h " -E0x20000 Smooth")
  2237. C_[i]:=id.Hwnd, Cid_[id.Hwnd]:=i
  2238. }
  2239. ListLines lls
  2240. _Gui.Opt("+Theme")
  2241. _Gui.Add("Slider", "xs w" pW " vMySlider1 +Center Page20 Line10 NoTicks AltSubmit")
  2242. G_G.Call()
  2243. _Gui.Add("Slider", "ys h" pH " vMySlider2 +Center Page20 Line10 NoTicks AltSubmit +Vertical")
  2244. G_G.Call()
  2245. Tab.UseTab(2)
  2246. id:=_Gui.Add("Pic", "w" (pW-135) " h" pH " +Border -Background Section"), hPic:=id.Hwnd
  2247. Pic_hBM:=this.CreateDIBSection(Pic_w:=(pW-135), Pic_h:=pH)
  2248. _Gui.Add("Slider", "xs wp vMySlider3 +Center Page20 Line10 NoTicks AltSubmit")
  2249. G_G.Call()
  2250. _Gui.Add("Slider", "ys h" pH " vMySlider4 +Center Page20 Line10 NoTicks AltSubmit +Vertical")
  2251. G_G.Call()
  2252. _Gui.Add("ListBox", "ys w120 h200 vSelectBox AltSubmit 0x100")
  2253. G_G.Call()
  2254. _Gui.Add("Button", "y+0 wp vClearAll", Lang["ClearAll"])
  2255. G_G.Call()
  2256. _Gui.Add("Button", "y+0 wp vOpenDir", Lang["OpenDir"])
  2257. G_G.Call()
  2258. _Gui.Add("Button", "y+0 wp vLoadPic", Lang["LoadPic"])
  2259. G_G.Call()
  2260. _Gui.Add("Button", "y+0 wp vSavePic", Lang["SavePic"])
  2261. G_G.Call()
  2262. Tab.UseTab()
  2263. ;--------------
  2264. _Gui.Add("Text", "xm Section", Lang["SelGray"])
  2265. _Gui.Add("Edit", "x+5 yp-3 w80 vSelGray ReadOnly")
  2266. _Gui.Add("Text", "x+15 ys", Lang["SelColor"])
  2267. _Gui.Add("Edit", "x+5 yp-3 w150 vSelColor ReadOnly")
  2268. _Gui.Add("Text", "x+15 ys", Lang["SelR"])
  2269. _Gui.Add("Edit", "x+5 yp-3 w80 vSelR ReadOnly")
  2270. _Gui.Add("Text", "x+5 ys", Lang["SelG"])
  2271. _Gui.Add("Edit", "x+5 yp-3 w80 vSelG ReadOnly")
  2272. _Gui.Add("Text", "x+5 ys", Lang["SelB"])
  2273. _Gui.Add("Edit", "x+5 yp-3 w80 vSelB ReadOnly")
  2274. ;--------------
  2275. id:=_Gui.Add("Button", "xm Hidden Section", Lang["Auto"])
  2276. id.GetPos(&pX, &pY, &pW, &pH)
  2277. w:=Round(pW*0.75), i:=Round(w*3+15+pW*0.5-w*1.5)
  2278. _Gui.Add("Button", "xm+" i " yp w" w " hp -Wrap vRepU", Lang["RepU"])
  2279. G_G.Call()
  2280. _Gui.Add("Button", "x+0 wp hp -Wrap vCutU", Lang["CutU"])
  2281. G_G.Call()
  2282. _Gui.Add("Button", "x+0 wp hp -Wrap vCutU3", Lang["CutU3"])
  2283. G_G.Call()
  2284. _Gui.Add("Button", "xm wp hp -Wrap vRepL", Lang["RepL"])
  2285. G_G.Call()
  2286. _Gui.Add("Button", "x+0 wp hp -Wrap vCutL", Lang["CutL"])
  2287. G_G.Call()
  2288. _Gui.Add("Button", "x+0 wp hp -Wrap vCutL3", Lang["CutL3"])
  2289. G_G.Call()
  2290. _Gui.Add("Button", "x+15 w" pW " hp -Wrap vAuto", Lang["Auto"])
  2291. G_G.Call()
  2292. _Gui.Add("Button", "x+15 w" w " hp -Wrap vRepR", Lang["RepR"])
  2293. G_G.Call()
  2294. _Gui.Add("Button", "x+0 wp hp -Wrap vCutR", Lang["CutR"])
  2295. G_G.Call()
  2296. _Gui.Add("Button", "x+0 wp hp -Wrap vCutR3", Lang["CutR3"])
  2297. G_G.Call()
  2298. _Gui.Add("Button", "xm+" i " wp hp -Wrap vRepD", Lang["RepD"])
  2299. G_G.Call()
  2300. _Gui.Add("Button", "x+0 wp hp -Wrap vCutD", Lang["CutD"])
  2301. G_G.Call()
  2302. _Gui.Add("Button", "x+0 wp hp -Wrap vCutD3", Lang["CutD3"])
  2303. G_G.Call()
  2304. ;--------------
  2305. Tab:=_Gui.Add("Tab3", "ys -Wrap", StrSplit(Lang["s2"],"|"))
  2306. Tab.UseTab(1)
  2307. _Gui.Add("Text", "x+30 y+35", Lang["Threshold"])
  2308. _Gui.Add("Edit", "x+15 w100 vThreshold")
  2309. _Gui.Add("Button", "x+15 yp-3 vGray2Two", Lang["Gray2Two"])
  2310. G_G.Call()
  2311. Tab.UseTab(2)
  2312. _Gui.Add("Text", "x+30 y+35", Lang["GrayDiff"])
  2313. _Gui.Add("Edit", "x+15 w100 vGrayDiff", "50")
  2314. _Gui.Add("Button", "x+15 yp-3 vGrayDiff2Two", Lang["GrayDiff2Two"])
  2315. G_G.Call()
  2316. Tab.UseTab(3)
  2317. _Gui.Add("Text", "x+10 y+15 Section", Lang["Similar1"] " 0")
  2318. _Gui.Add("Slider", "x+0 w100 vSimilar1 +Center Page1 NoTicks ToolTip")
  2319. G_G.Call()
  2320. _Gui.Add("Text", "x+0", "100")
  2321. _Gui.Add("Button", "x+10 ys-2 vAddColorSim", Lang["AddColorSim"])
  2322. G_G.Call()
  2323. _Gui.Add("Text", "x+25 ys+4", Lang["DiffRGB2"])
  2324. _Gui.Add("Edit", "x+5 ys w80 vDiffRGB2 Limit3")
  2325. _Gui.Add("UpDown", "vdRGB2 Range0-255 Wrap", 50)
  2326. _Gui.Add("Button", "x+10 ys-2 vAddColorDiff", Lang["AddColorDiff"])
  2327. G_G.Call()
  2328. _Gui.Add("Button", "xs vUndo2", Lang["Undo2"])
  2329. G_G.Call()
  2330. _Gui.Add("Edit", "x+10 yp+2 w340 vColorList")
  2331. _Gui.Add("Button", "x+10 yp-2 vColor2Two", Lang["Color2Two"])
  2332. G_G.Call()
  2333. Tab.UseTab(4)
  2334. _Gui.Add("Text", "x+30 y+35", Lang["Similar2"] " 0")
  2335. _Gui.Add("Slider", "x+0 w120 vSimilar2 +Center Page1 NoTicks ToolTip")
  2336. G_G.Call()
  2337. _Gui.Add("Text", "x+0", "100")
  2338. _Gui.Add("Button", "x+15 yp-3 vColorPos2Two", Lang["ColorPos2Two"])
  2339. G_G.Call()
  2340. Tab.UseTab(5)
  2341. _Gui.Add("Text", "x+30 y+15 Section", Lang["Similar3"] " 0")
  2342. _Gui.Add("Slider", "x+0 w120 vSimilar3 +Center Page1 NoTicks ToolTip")
  2343. G_G.Call()
  2344. _Gui.Add("Text", "x+0", "100")
  2345. _Gui.Add("Button", "x+15 ys-2 vUndo", Lang["Undo"])
  2346. G_G.Call()
  2347. _Gui.Add("Checkbox", "xs vMultiColor", Lang["MultiColor"])
  2348. G_G.Call()
  2349. _Gui.Add("Checkbox", "x+50 vFindShape", Lang["FindShape"])
  2350. G_G.Call()
  2351. Tab.UseTab()
  2352. ;--------------
  2353. _Gui.Add("Button", "xm vReset", Lang["Reset"])
  2354. G_G.Call()
  2355. _Gui.Add("Checkbox", "x+15 yp+5 vModify", Lang["Modify"])
  2356. G_G.Call()
  2357. _Gui.Add("Text", "x+30", Lang["Comment"])
  2358. _Gui.Add("Edit", "x+5 yp-2 w250 vComment")
  2359. _Gui.Add("Button", "x+10 yp-3 vSplitAdd", Lang["SplitAdd"])
  2360. G_G.Call()
  2361. _Gui.Add("Button", "x+10 vAllAdd", Lang["AllAdd"])
  2362. G_G.Call()
  2363. _Gui.Add("Button", "x+30 wp vOK", Lang["OK"])
  2364. G_G.Call()
  2365. _Gui.Add("Button", "x+15 wp vCancel", Lang["Cancel"])
  2366. G_G.Call()
  2367. _Gui.Add("Button", "xm vBind0", Lang["Bind0"])
  2368. G_G.Call()
  2369. _Gui.Add("Button", "x+10 vBind1", Lang["Bind1"])
  2370. G_G.Call()
  2371. _Gui.Add("Button", "x+10 vBind2", Lang["Bind2"])
  2372. G_G.Call()
  2373. _Gui.Add("Button", "x+10 vBind3", Lang["Bind3"])
  2374. G_G.Call()
  2375. _Gui.Add("Button", "x+10 vBind4", Lang["Bind4"])
  2376. G_G.Call()
  2377. _Gui.Add("Button", "x+30 vSavePic2", Lang["SavePic2"])
  2378. G_G.Call()
  2379. _Gui.Title:=Lang["s3"]
  2380. _Gui.Show("Hide")
  2381. _Gui.OnEvent("DropFiles", G_Drag)
  2382. return
  2383. Case "Drag":
  2384. Try G_.Call("LoadPic", args[2][1])
  2385. return
  2386. Case "MakeMainWindow":
  2387. Try FindText_Main.Destroy()
  2388. FindText_Main:=_Gui:=Gui()
  2389. _Gui.Opt("+LastFound +AlwaysOnTop -DPIScale")
  2390. _Gui.MarginX:=15, _Gui.MarginY:=10
  2391. _Gui.BackColor:=WindowColor
  2392. _Gui.SetFont("s12", "Verdana")
  2393. _Gui.Add("Text", "xm", Lang["NowHotkey"])
  2394. _Gui.Add("Edit", "x+5 w160 vNowHotkey ReadOnly")
  2395. _Gui.Add("Hotkey", "x+5 w160 vSetHotkey1")
  2396. s:="F1|F2|F3|F4|F5|F6|F7|F8|F9|F10|F11|F12|LWin|Ctrl|Shift|Space|MButton"
  2397. . "|ScrollLock|CapsLock|Ins|Esc|BS|Del|Tab|Home|End|PgUp|PgDn"
  2398. . "|NumpadDot|NumpadSub|NumpadAdd|NumpadDiv|NumpadMult"
  2399. _Gui.Add("DDL", "x+5 w160 vSetHotkey2", StrSplit(s,"|"))
  2400. _Gui.Add("Button", "x+15 vApply", Lang["Apply"])
  2401. G_G.Call()
  2402. _Gui.Add("GroupBox", "xm y+0 w280 h55 vMyGroup cBlack")
  2403. _Gui.Add("Text", "xp+15 yp+20 Section", Lang["Myww"] ": ")
  2404. _Gui.Add("Text", "x+0 w80", nW//2)
  2405. _Gui.Add("UpDown", "vMyww Range1-100", nW//2)
  2406. _Gui.Add("Text", "x+15 ys", Lang["Myhh"] ": ")
  2407. _Gui.Add("Text", "x+0 w80", nH//2)
  2408. id:=_Gui.Add("UpDown", "vMyhh Range1-100", nH//2)
  2409. id.GetPos(&pX, &pY, &pW, &pH)
  2410. _Gui["MyGroup"].Move(,, pX+pW, pH+30)
  2411. id:=_Gui.Add("Checkbox", "x+100 ys vAddFunc", Lang["AddFunc"] " FindText()")
  2412. id.GetPos(&pX, &pY, &pW, &pH)
  2413. pW:=pX+pW-15, pW:=(pW<720?720:pW), w:=pW//5
  2414. _Gui.Add("Button", "xm y+18 w" w " vCutL2", Lang["CutL2"])
  2415. G_G.Call()
  2416. _Gui.Add("Button", "x+0 wp vCutR2", Lang["CutR2"])
  2417. G_G.Call()
  2418. _Gui.Add("Button", "x+0 wp vCutU2", Lang["CutU2"])
  2419. G_G.Call()
  2420. _Gui.Add("Button", "x+0 wp vCutD2", Lang["CutD2"])
  2421. G_G.Call()
  2422. _Gui.Add("Button", "x+0 wp vUpdate", Lang["Update"])
  2423. G_G.Call()
  2424. _Gui.SetFont("s6 bold", "Verdana")
  2425. _Gui.Add("Edit", "xm y+10 w" pW " h260 vMyPic -Wrap HScroll")
  2426. _Gui.SetFont("s12 norm", "Verdana")
  2427. w:=pW//3
  2428. _Gui.Add("Button", "xm w" w " vCapture", Lang["Capture"])
  2429. G_G.Call()
  2430. _Gui.Add("Button", "x+0 wp vTest", Lang["Test"])
  2431. G_G.Call()
  2432. _Gui.Add("Button", "x+0 wp vCopy", Lang["Copy"])
  2433. G_G.Call()
  2434. _Gui.Add("Button", "xm y+0 wp vCaptureS", Lang["CaptureS"])
  2435. G_G.Call()
  2436. _Gui.Add("Button", "x+0 wp vGetRange", Lang["GetRange"])
  2437. G_G.Call()
  2438. _Gui.Add("Button", "x+0 wp vGetOffset", Lang["GetOffset"])
  2439. G_G.Call()
  2440. _Gui.Add("Edit", "xm y+10 w130 hp vClipText")
  2441. _Gui.Add("Button", "x+0 vPaste", Lang["Paste"])
  2442. G_G.Call()
  2443. _Gui.Add("Button", "x+0 vTestClip", Lang["TestClip"])
  2444. G_G.Call()
  2445. id:=_Gui.Add("Button", "x+0 vGetClipOffset", Lang["GetClipOffset"])
  2446. G_G.Call()
  2447. id.GetPos(&x,, &w)
  2448. w:=((pW+15)-(x+w))//2
  2449. _Gui.Add("Edit", "x+0 w" w " hp vOffset")
  2450. _Gui.Add("Button", "x+0 wp vCopyOffset", Lang["CopyOffset"])
  2451. G_G.Call()
  2452. _Gui.SetFont("cBlue")
  2453. id:=_Gui.Add("Edit", "xm w" pW " h250 vscr -Wrap HScroll"), hscr:=id.Hwnd
  2454. _Gui.Title:=Lang["s4"]
  2455. _Gui.Show("Hide")
  2456. G_.Call("LoadScr")
  2457. OnExit(G_SaveScr)
  2458. return
  2459. Case "LoadScr":
  2460. f:=A_Temp "\~scr2.tmp"
  2461. Try s:="", s:=FileRead(f)
  2462. FindText_Main["scr"].Value:=s
  2463. return
  2464. Case "SaveScr":
  2465. f:=A_Temp "\~scr2.tmp"
  2466. s:=FindText_Main["scr"].Value
  2467. Try FileDelete f
  2468. FileAppend s, f
  2469. return
  2470. Case "Capture", "CaptureS":
  2471. _Gui:=FindText_Main
  2472. if show_gui:=WinExist("ahk_id " _Gui.Hwnd)
  2473. this.Hide()
  2474. if (cmd="Capture")
  2475. {
  2476. w:=_Gui["Myww"].Value
  2477. h:=_Gui["Myhh"].Value
  2478. p:=this.GetRange(w, h)
  2479. sx:=p[1], sy:=p[2], sw:=p[3]-p[1]+1, sh:=p[4]-p[2]+1
  2480. , Bind_ID:=p[5], bind_mode:=""
  2481. _Gui:=FindText_Capture
  2482. _Gui["MyTab1"].Choose(1)
  2483. }
  2484. else
  2485. {
  2486. sx:=0, sy:=0, sw:=1, sh:=1, Bind_ID:=WinExist("A"), bind_mode:=""
  2487. _Gui:=FindText_Capture
  2488. _Gui["MyTab1"].Choose(2)
  2489. }
  2490. n:=150000, x:=y:=-n, w:=h:=2*n
  2491. hBM:=this.BitmapFromScreen(&x,&y,&w,&h,(arg1=0?0:1))
  2492. Pics:=Map(), Pics[hBM]:=1, hBM_x:=hBM_y:=0
  2493. G_.Call("CaptureUpdate")
  2494. G_.Call("PicUpdate")
  2495. Names:=["HBITMAP:*" hBM], s:="<New>"
  2496. Loop Files, SavePicDir "*.bmp"
  2497. Names.Push(v:=A_LoopFileFullPath), s.="|" RegExReplace(v,"i)^.*\\|\.bmp$")
  2498. _Gui["SelectBox"].Delete()
  2499. _Gui["SelectBox"].Add(StrSplit(Trim(s,"|"),"|"))
  2500. ;------------------------
  2501. s:="SelGray|SelColor|SelR|SelG|SelB|Threshold|Comment|ColorList"
  2502. Loop Parse, s, "|"
  2503. _Gui[A_LoopField].Value:=""
  2504. For k,v in ["Similar1","Similar2","Similar3"]
  2505. _Gui[v].Value:=90
  2506. _Gui["Modify"].Value:=Modify:=0
  2507. _Gui["MultiColor"].Value:=MultiColor:=0
  2508. _Gui["FindShape"].Value:=FindShape:=0
  2509. _Gui["GrayDiff"].Value:=50
  2510. _Gui["Gray2Two"].Focus()
  2511. _Gui["Gray2Two"].Opt("+Default")
  2512. _Gui.Show("Center")
  2513. Event:=Result:=""
  2514. DetectHiddenWindows 0
  2515. Critical "Off"
  2516. WinWaitClose "ahk_id " _Gui.Hwnd
  2517. Critical
  2518. ToolTip
  2519. Pics[hBM]:=1, hBM_old:=0
  2520. For k,v in Pics
  2521. Try DllCall("DeleteObject", "Ptr",k)
  2522. Text:=RegExMatch(Result,"\|<[^>\n]*>[^$\n]+\$[^`"'\r\n]+",&r)?r[0]:""
  2523. ;------------------------
  2524. _Gui:=FindText_Main
  2525. if (bind_mode!="")
  2526. {
  2527. tt:=WinGetTitle(Bind_ID)
  2528. tc:=WinGetClass(Bind_ID)
  2529. tt:=Trim(SubStr(tt,1,30) (tc ? " ahk_class " tc:""))
  2530. tt:=StrReplace(RegExReplace(tt, "[;``]", "``$0"), "`"","```"")
  2531. Result:="`nSetTitleMatchMode 2`nid:=WinExist(`"" tt "`")"
  2532. . "`nFindText().BindWindow(id" (bind_mode=0 ? "":"," bind_mode)
  2533. . ") `; " Lang["s6"] " FindText().BindWindow(0)`n`n" Result
  2534. }
  2535. if (Event="OK")
  2536. {
  2537. s:=""
  2538. if (!A_IsCompiled)
  2539. Try s:=FileRead(A_LineFile)
  2540. re:="i)\n\s*FindText[^\n]+args\*[\s\S]*?Script_End[(){}\s]+}"
  2541. s:=RegExMatch(s, re, &r) ? "`n;==========`n" r[0] "`n" : ""
  2542. _Gui["scr"].Value:=Result "`n" s
  2543. _Gui["MyPic"].Value:=Trim(this.ASCII(Result),"`n")
  2544. }
  2545. else if (Event="SplitAdd" || Event="AllAdd")
  2546. {
  2547. s:=_Gui["scr"].Value
  2548. r:=SubStr(s, 1, InStr(s,"=FindText("))
  2549. i:=j:=0, re:="<[^>\n]*>[^$\n]+\$[^`"'\r\n]+"
  2550. While j:=RegExMatch(r, re,, j+1)
  2551. i:=InStr(r, "`n", 0, j)
  2552. _Gui["scr"].Value:=SubStr(s,1,i) . Result . SubStr(s,i+1)
  2553. _Gui["MyPic"].Value:=Trim(this.ASCII(Result),"`n")
  2554. }
  2555. if (Event) && RegExMatch(Result, "\$\d+\.[\w+/]{1,100}", &r)
  2556. this.EditScroll(hscr, "\Q" r[0] "\E")
  2557. Event:=Result:=s:=""
  2558. ;----------------------
  2559. if (show_gui && arg1="")
  2560. G_Show.Call()
  2561. else A_Clipboard:=Text
  2562. return Text
  2563. Case "CaptureUpdate":
  2564. nX:=sx, nY:=sy, nW:=sw, nH:=sh
  2565. bits:=this.GetBitsFromScreen(&nX,&nY,&nW,&nH,0,&zx,&zy)
  2566. cors:=Map(), cors.Default:=0
  2567. , show:=Map(), show.Default:=0
  2568. , ascii:=Map(), ascii.Default:=0
  2569. , SelPos:=bg:=color:=Result:=""
  2570. , dx:=dy:=CutLeft:=CutRight:=CutUp:=CutDown:=0
  2571. ListLines (lls:=A_ListLines)?0:0
  2572. if (nW>0 && nH>0 && bits.Scan0)
  2573. {
  2574. j:=bits.Stride-nW*4, p:=bits.Scan0+(nY-zy)*bits.Stride+(nX-zx)*4-j-4
  2575. Loop nH + 0*(k:=0)
  2576. Loop nW + 0*(p+=j)
  2577. show[++k]:=1, cors[k]:=NumGet(p+=4,"uint")
  2578. }
  2579. Loop 25 + 0*(ty:=dy-1)*(k:=0)
  2580. Loop 71 + 0*(tx:=dx-1)*(ty++)
  2581. this.SC(((++tx)<nW && ty<nH ? cors[ty*nW+tx+1]:WindowColor), C_[++k])
  2582. Loop 71 + 0*(k:=71*25)
  2583. this.SC(0xFFFFAA, C_[++k])
  2584. ListLines lls
  2585. _Gui:=FindText_Capture
  2586. _Gui["MySlider1"].Enabled:=nW>71
  2587. _Gui["MySlider2"].Enabled:=nH>25
  2588. _Gui["MySlider1"].Value:=0
  2589. _Gui["MySlider2"].Value:=0
  2590. return
  2591. Case "PicUpdate":
  2592. Try i:=0, i:=Pics.Has(hBM_old)
  2593. Try (!i) && DllCall("DeleteObject", "Ptr",hBM_old)
  2594. this.GetBitmapWH(hBM, &hBM_w, &hBM_h), hBM_old:=hBM
  2595. G_.Call("PicShow", 1)
  2596. return
  2597. Case "MySlider3", "MySlider4":
  2598. hBM_x:=Round(FindText_Capture["MySlider3"].Value*(hBM_w-Pic_w)/100)
  2599. hBM_y:=Round(FindText_Capture["MySlider4"].Value*(hBM_h-Pic_h)/100)
  2600. G_.Call("PicShow")
  2601. return
  2602. Case "PicShow":
  2603. w:=hBM_w-Pic_w, h:=hBM_h-Pic_h
  2604. , hBM_x:=Max(Min(hBM_x,w),0), hBM_y:=Max(Min(hBM_y,h),0)
  2605. if (w<0 || h<0)
  2606. this.DrawHBM(Pic_hBM, [[0, 0, Pic_w, Pic_h, WindowColor]])
  2607. this.CopyHBM(Pic_hBM,0,0,hBM,hBM_x,hBM_y,Min(Pic_w,hBM_w),Min(Pic_h,hBM_h))
  2608. if (arg1)
  2609. G_PicShowOK.Call()
  2610. else
  2611. {
  2612. this.BitmapToWindow(hPic,0,0,Pic_hBM,0,0,Pic_w,Pic_h)
  2613. SetTimer G_PicShowOK, -1000
  2614. }
  2615. FindText_Capture["MySlider3"].Value:=w>0?Round(hBM_x/w*100):0
  2616. FindText_Capture["MySlider4"].Value:=h>0?Round(hBM_y/h*100):0
  2617. return
  2618. Case "PicShowOK":
  2619. FindText_Capture[hPic].Value:="*w0 *h0 HBITMAP:*" Pic_hBM
  2620. return
  2621. Case "Reset":
  2622. G_.Call("CaptureUpdate")
  2623. return
  2624. Case "LoadPic":
  2625. FindText_Capture.Opt("+OwnDialogs")
  2626. f:=arg1
  2627. if (f="")
  2628. {
  2629. if !FileExist(SavePicDir)
  2630. DirCreate SavePicDir
  2631. f:=SavePicDir "*.bmp"
  2632. Loop Files, f
  2633. f:=A_LoopFileFullPath
  2634. f:=FileSelect(, f, "Select Picture")
  2635. }
  2636. if !InStr(f,"HBITMAP:") && !FileExist(f)
  2637. {
  2638. MsgBox Lang["s17"], "Tip", "4096 T1"
  2639. return
  2640. }
  2641. if !this.ShowPic(f, 0, &sx, &sy, &sw, &sh)
  2642. return
  2643. hBM:=this.BitmapFromScreen(&sx, &sy, &sw, &sh, 0)
  2644. sw:=Min(sw,71), sh:=Min(sh,25)
  2645. G_.Call("CaptureUpdate")
  2646. G_.Call("PicUpdate")
  2647. return
  2648. Case "SavePic":
  2649. FindText_Capture.Hide()
  2650. this.ScreenShot(), this.ShowPic("HBITMAP:*" hBM)
  2651. Try GuiFromHwnd(WinExist("Show Pic")).Opt("+OwnDialogs")
  2652. Loop
  2653. {
  2654. p:=this.GetRange2()
  2655. r:=MsgBox(Lang["s15"], "Tip", "4099")
  2656. if (r!="No")
  2657. Break
  2658. }
  2659. if (r="Yes")
  2660. G_.Call("ScreenShot", p[1] "|" p[2] "|" p[3] "|" p[4] "|0")
  2661. this.ShowPic()
  2662. return
  2663. Case "SelectBox":
  2664. SelectBox:=FindText_Capture["SelectBox"].Value
  2665. Try f:="", f:=Names[SelectBox]
  2666. if (f!="")
  2667. G_.Call("LoadPic", f)
  2668. return
  2669. Case "ClearAll":
  2670. FindText_Capture.Opt("+OwnDialogs")
  2671. if MsgBox(Lang["s19"], "Tip", "4100")="Yes"
  2672. {
  2673. FindText_Capture.Hide()
  2674. Try FileDelete SavePicDir "*.bmp"
  2675. }
  2676. return
  2677. Case "OpenDir":
  2678. if !FileExist(SavePicDir)
  2679. DirCreate SavePicDir
  2680. Run SavePicDir
  2681. return
  2682. Case "GetRange":
  2683. _Gui:=FindText_Main
  2684. _Gui.Opt("+LastFound")
  2685. this.Hide()
  2686. p:=this.GetRange2(), v:=p[1] ", " p[2] ", " p[3] ", " p[4]
  2687. s:=_Gui["scr"].Value
  2688. re:="i)(=FindText\([^\n]*?)([^(,\n]*,){4}([^,\n]*,[^,\n]*,[^,\n]*Text)"
  2689. if SubStr(s,1,s~="i)\n\s*FindText[^\n]+args\*")~=re
  2690. {
  2691. s:=RegExReplace(s, re, "$1 " v ",$3",, 1)
  2692. _Gui["scr"].Value:=s
  2693. }
  2694. _Gui["Offset"].Value:=v
  2695. G_Show.Call()
  2696. return
  2697. Case "Test", "TestClip":
  2698. _Gui:=FindText_Main
  2699. _Gui.Opt("+LastFound")
  2700. this.Hide()
  2701. ;----------------------
  2702. if (cmd="Test")
  2703. s:=_Gui["scr"].Value
  2704. else
  2705. s:=_Gui["ClipText"].Value
  2706. if (cmd="Test") && InStr(s, "MCode(")
  2707. {
  2708. s:="`nA_TrayMenu.ClickCount:=1`n" s "`nExitApp`n"
  2709. Thread1:=FindTextClass.Thread(s)
  2710. DetectHiddenWindows 1
  2711. if WinWait("ahk_class AutoHotkey ahk_pid " Thread1.pid,, 3)
  2712. WinWaitClose(,, 30)
  2713. ; Thread1:="" ; kill the Thread
  2714. }
  2715. else
  2716. {
  2717. t:=A_TickCount, v:=X:=Y:=""
  2718. if RegExMatch(s, "<[^>\n]*>[^$\n]+\$[^`"'\r\n]+", &r)
  2719. v:=this.FindText(&X, &Y, 0,0,0,0, 0,0, r[0])
  2720. r:=StrSplit(Lang["s8"] "||||", "|")
  2721. MsgBox r[1] ":`t" (IsObject(v)?v.Length:v) "`n`n"
  2722. . r[2] ":`t" (A_TickCount-t) " " r[3] "`n`n"
  2723. . r[4] ":`t" X ", " Y "`n`n"
  2724. . r[5] ":`t<" (IsObject(v)?v[1].id:"") ">", "Tip", "4096 T3"
  2725. Try For i,j in v
  2726. if (i<=2)
  2727. this.MouseTip(j.x, j.y)
  2728. v:="", A_Clipboard:=X "," Y
  2729. }
  2730. ;----------------------
  2731. G_Show.Call()
  2732. return
  2733. Case "GetOffset", "GetClipOffset":
  2734. FindText_Main.Hide()
  2735. p:=this.GetRange()
  2736. _Gui:=FindText_Main
  2737. if (cmd="GetOffset")
  2738. s:=_Gui["scr"].Value
  2739. else
  2740. s:=_Gui["ClipText"].Value
  2741. if RegExMatch(s, "<[^>\n]*>[^$\n]+\$[^`"'\r\n]+", &r)
  2742. && this.FindText(&X, &Y, 0,0,0,0, 0,0, r[0])
  2743. {
  2744. r:=StrReplace("X+" ((p[1]+p[3])//2-X)
  2745. . ", Y+" ((p[2]+p[4])//2-Y), "+-", "-")
  2746. if (cmd="GetOffset")
  2747. {
  2748. re:="i)(\(\)\.\w*Click\w*\()[^,\n]*,[^,)\n]*"
  2749. if SubStr(s,1,s~="i)\n\s*FindText[^\n]+args\*")~=re
  2750. s:=RegExReplace(s, re, "$1" r,, 1)
  2751. _Gui["scr"].Value:=s
  2752. }
  2753. _Gui["Offset"].Value:=r
  2754. }
  2755. s:="", G_Show.Call()
  2756. return
  2757. Case "Paste":
  2758. if RegExMatch(A_Clipboard, "\|?<[^>\n]*>[^$\n]+\$[^`"'\r\n]+", &r)
  2759. {
  2760. FindText_Main["ClipText"].Value:=r[0]
  2761. FindText_Main["MyPic"].Value:=Trim(this.ASCII(r[0]),"`n")
  2762. }
  2763. return
  2764. Case "CopyOffset":
  2765. A_Clipboard:=FindText_Main["Offset"].Value
  2766. return
  2767. Case "Copy":
  2768. s:=EditGetSelectedText(hscr)
  2769. if (s="")
  2770. {
  2771. s:=FindText_Main["scr"].Value
  2772. r:=FindText_Main["AddFunc"].Value
  2773. if (r != 1)
  2774. s:=RegExReplace(s, "i)\n\s*FindText[^\n]+args\*[\s\S]*")
  2775. , s:=RegExReplace(s, "i)\n; ok:=FindText[\s\S]*")
  2776. , s:=SubStr(s, (s~="i)\n[ \t]*Text"))
  2777. }
  2778. A_Clipboard:=RegExReplace(s, "\R", "`r`n")
  2779. ControlFocus hscr
  2780. return
  2781. Case "Apply":
  2782. _Gui:=FindText_Main
  2783. NowHotkey:=_Gui["NowHotkey"].Value
  2784. SetHotkey1:=_Gui["SetHotkey1"].Value
  2785. SetHotkey2:=_Gui["SetHotkey2"].Text
  2786. if (NowHotkey!="")
  2787. Try Hotkey "*" NowHotkey,, "Off"
  2788. k:=SetHotkey1!="" ? SetHotkey1 : SetHotkey2
  2789. if (k!="")
  2790. Try Hotkey "*" k, G_ScreenShot, "On"
  2791. _Gui["NowHotkey"].Value:=k
  2792. _Gui["SetHotkey1"].Value:=""
  2793. _Gui["SetHotkey2"].Choose(0)
  2794. return
  2795. Case "ScreenShot":
  2796. Critical
  2797. if !FileExist(SavePicDir)
  2798. DirCreate SavePicDir
  2799. Loop
  2800. f:=SavePicDir . Format("{:03d}.bmp",A_Index)
  2801. Until !FileExist(f)
  2802. this.SavePic(f, StrSplit(arg1,"|")*)
  2803. CoordMode "ToolTip"
  2804. this.ToolTip(Lang["s9"],, 0,, { bgcolor:"Yellow", color:"Red"
  2805. , size:48, bold:"bold", trans:200, timeout:0.2 })
  2806. return
  2807. Case "Bind0", "Bind1", "Bind2", "Bind3", "Bind4":
  2808. this.BindWindow(Bind_ID, bind_mode:=SubStr(cmd,5))
  2809. n:=150000, x:=y:=-n, w:=h:=2*n
  2810. hBM:=this.BitmapFromScreen(&x,&y,&w,&h,1)
  2811. G_.Call("PicUpdate")
  2812. FindText_Capture["MyTab1"].Choose(2)
  2813. this.BindWindow(0)
  2814. return
  2815. Case "MySlider1", "MySlider2":
  2816. SetTimer G_Slider, -10
  2817. return
  2818. Case "Slider":
  2819. Critical
  2820. dx:=nW>71 ? Round(FindText_Capture["MySlider1"].Value*(nW-71)/100):0
  2821. dy:=nH>25 ? Round(FindText_Capture["MySlider2"].Value*(nH-25)/100):0
  2822. if (oldx=dx && oldy=dy)
  2823. return
  2824. ListLines (lls:=A_ListLines)?0:0
  2825. Loop 25 + 0*(ty:=dy-1)*(k:=0)
  2826. Loop 71 + 0*(tx:=dx-1)*(ty++)
  2827. this.SC(((++tx)>=nW || ty>=nH || !show[i:=ty*nW+tx+1]
  2828. ? WindowColor : bg="" ? cors[i] : ascii[i] ? 0:0xFFFFFF), C_[++k])
  2829. Loop 71*(oldx!=dx) + 0*(i:=nW*nH+dx)*(k:=71*25)
  2830. this.SC((show[++i]?0xFF0000:0xFFFFAA), C_[++k])
  2831. ListLines lls
  2832. oldx:=dx, oldy:=dy
  2833. return
  2834. Case "RepColor", "CutColor":
  2835. if (cmd="RepColor")
  2836. show[k]:=1, c:=(bg="" ? cors[k] : ascii[k] ? 0:0xFFFFFF)
  2837. else
  2838. show[k]:=0, c:=WindowColor
  2839. if (tx:=Mod(k-1,nW)-dx)>=0 && tx<71 && (ty:=(k-1)//nW-dy)>=0 && ty<25
  2840. this.SC(c, C_[ty*71+tx+1])
  2841. return
  2842. Case "RepL":
  2843. if (CutLeft<=0) || (bg!="" && InStr(color,"**") && CutLeft=1)
  2844. return
  2845. k:=CutLeft-nW, CutLeft--
  2846. Loop nH
  2847. k+=nW, (A_Index>CutUp && A_Index<nH+1-CutDown && G_.Call("RepColor"))
  2848. return
  2849. Case "CutL":
  2850. if (CutLeft+CutRight>=nW)
  2851. return
  2852. CutLeft++, k:=CutLeft-nW
  2853. Loop nH
  2854. k+=nW, (A_Index>CutUp && A_Index<nH+1-CutDown && G_.Call("CutColor"))
  2855. return
  2856. Case "CutL3":
  2857. Loop 3
  2858. G_.Call("CutL")
  2859. return
  2860. Case "RepR":
  2861. if (CutRight<=0) || (bg!="" && InStr(color,"**") && CutRight=1)
  2862. return
  2863. k:=1-CutRight, CutRight--
  2864. Loop nH
  2865. k+=nW, (A_Index>CutUp && A_Index<nH+1-CutDown && G_.Call("RepColor"))
  2866. return
  2867. Case "CutR":
  2868. if (CutLeft+CutRight>=nW)
  2869. return
  2870. CutRight++, k:=1-CutRight
  2871. Loop nH
  2872. k+=nW, (A_Index>CutUp && A_Index<nH+1-CutDown && G_.Call("CutColor"))
  2873. return
  2874. Case "CutR3":
  2875. Loop 3
  2876. G_.Call("CutR")
  2877. return
  2878. Case "RepU":
  2879. if (CutUp<=0) || (bg!="" && InStr(color,"**") && CutUp=1)
  2880. return
  2881. k:=(CutUp-1)*nW, CutUp--
  2882. Loop nW
  2883. k++, (A_Index>CutLeft && A_Index<nW+1-CutRight && G_.Call("RepColor"))
  2884. return
  2885. Case "CutU":
  2886. if (CutUp+CutDown>=nH)
  2887. return
  2888. CutUp++, k:=(CutUp-1)*nW
  2889. Loop nW
  2890. k++, (A_Index>CutLeft && A_Index<nW+1-CutRight && G_.Call("CutColor"))
  2891. return
  2892. Case "CutU3":
  2893. Loop 3
  2894. G_.Call("CutU")
  2895. return
  2896. Case "RepD":
  2897. if (CutDown<=0) || (bg!="" && InStr(color,"**") && CutDown=1)
  2898. return
  2899. k:=(nH-CutDown)*nW, CutDown--
  2900. Loop nW
  2901. k++, (A_Index>CutLeft && A_Index<nW+1-CutRight && G_.Call("RepColor"))
  2902. return
  2903. Case "CutD":
  2904. if (CutUp+CutDown>=nH)
  2905. return
  2906. CutDown++, k:=(nH-CutDown)*nW
  2907. Loop nW
  2908. k++, (A_Index>CutLeft && A_Index<nW+1-CutRight && G_.Call("CutColor"))
  2909. return
  2910. Case "CutD3":
  2911. Loop 3
  2912. G_.Call("CutD")
  2913. return
  2914. Case "Gray2Two":
  2915. ListLines (lls:=A_ListLines)?0:0
  2916. gs:=Map(), gs.Default:=0, k:=0
  2917. Loop nW*nH
  2918. gs[++k]:=((((c:=cors[k])>>16)&0xFF)*38+((c>>8)&0xFF)*75+(c&0xFF)*15)>>7
  2919. _Gui:=FindText_Capture
  2920. _Gui["Threshold"].Focus()
  2921. Threshold:=_Gui["Threshold"].Value
  2922. if (Threshold="")
  2923. {
  2924. pp:=Map(), pp.Default:=0
  2925. Loop 256
  2926. pp[A_Index-1]:=0
  2927. Loop nW*nH
  2928. if (show[A_Index])
  2929. pp[gs[A_Index]]++
  2930. IP0:=IS0:=0
  2931. Loop 256
  2932. k:=A_Index-1, IP0+=k*pp[k], IS0+=pp[k]
  2933. Threshold:=Floor(IP0/IS0)
  2934. Loop 20
  2935. {
  2936. LastThreshold:=Threshold
  2937. IP1:=IS1:=0
  2938. Loop LastThreshold+1
  2939. k:=A_Index-1, IP1+=k*pp[k], IS1+=pp[k]
  2940. IP2:=IP0-IP1, IS2:=IS0-IS1
  2941. if (IS1!=0 && IS2!=0)
  2942. Threshold:=Floor((IP1/IS1+IP2/IS2)/2)
  2943. if (Threshold=LastThreshold)
  2944. Break
  2945. }
  2946. _Gui["Threshold"].Value:=Threshold
  2947. }
  2948. Threshold:=Round(Threshold)
  2949. color:="*" Threshold, k:=i:=0
  2950. Loop nW*nH
  2951. ascii[++k]:=v:=(gs[k]<=Threshold)
  2952. , (show[k] && i:=(v?i+1:i-1))
  2953. bg:=(i>0 ? "1":"0"), G_.Call("BlackWhite")
  2954. ListLines lls
  2955. return
  2956. Case "GrayDiff2Two":
  2957. _Gui:=FindText_Capture
  2958. GrayDiff:=_Gui["GrayDiff"].Value
  2959. if (GrayDiff="")
  2960. {
  2961. _Gui.Opt("+OwnDialogs")
  2962. MsgBox Lang["s11"], "Tip", "4096 T1"
  2963. return
  2964. }
  2965. ListLines (lls:=A_ListLines)?0:0
  2966. gs:=Map(), gs.Default:=0, k:=0
  2967. Loop nW*nH
  2968. gs[++k]:=((((c:=cors[k])>>16)&0xFF)*38+((c>>8)&0xFF)*75+(c&0xFF)*15)>>7
  2969. if (CutLeft=0)
  2970. G_.Call("CutL")
  2971. if (CutRight=0)
  2972. G_.Call("CutR")
  2973. if (CutUp=0)
  2974. G_.Call("CutU")
  2975. if (CutDown=0)
  2976. G_.Call("CutD")
  2977. GrayDiff:=Round(GrayDiff)
  2978. color:="**" GrayDiff, k:=i:=0
  2979. Loop nW*nH
  2980. j:=gs[++k]+GrayDiff
  2981. , ascii[k]:=v:=( gs[k-1]>j || gs[k+1]>j
  2982. || gs[k-nW]>j || gs[k+nW]>j
  2983. || gs[k-nW-1]>j || gs[k-nW+1]>j
  2984. || gs[k+nW-1]>j || gs[k+nW+1]>j )
  2985. , (show[k] && i:=(v?i+1:i-1))
  2986. bg:=(i>0 ? "1":"0"), G_.Call("BlackWhite")
  2987. ListLines lls
  2988. return
  2989. Case "AddColorSim", "AddColorDiff":
  2990. _Gui:=FindText_Capture
  2991. c:=StrReplace(_Gui["SelColor"].Value, "0x")
  2992. if (c="")
  2993. {
  2994. _Gui.Opt("+OwnDialogs")
  2995. MsgBox Lang["s12"], "Tip", "4096 T1"
  2996. return
  2997. }
  2998. s:=_Gui["ColorList"].Value
  2999. if InStr(cmd, "Sim")
  3000. v:=_Gui["Similar1"].Value, v:=c "-" Round(v/100,2)
  3001. else
  3002. v:=_Gui["dRGB2"].Value, v:=c "-" Format("{:06X}",v<<16|v<<8|v)
  3003. s:=RegExReplace("/" s, "/" c "-[^/]*") . "/" v
  3004. _Gui["ColorList"].Value:=Trim(s,"/")
  3005. ControlSend "{End}", _Gui["ColorList"].Hwnd
  3006. G_.Call("Color2Two")
  3007. return
  3008. Case "Undo2":
  3009. _Gui:=FindText_Capture
  3010. s:=_Gui["ColorList"].Value
  3011. s:=RegExReplace("/" s, "/[^/]+$")
  3012. _Gui["ColorList"].Value:=Trim(s,"/")
  3013. ControlSend "{End}", _Gui["ColorList"].Hwnd
  3014. return
  3015. Case "Color2Two":
  3016. _Gui:=FindText_Capture
  3017. color:=RegExReplace(_Gui["ColorList"].Value, "i)\s|0x")
  3018. if (color="")
  3019. {
  3020. _Gui.Opt("+OwnDialogs")
  3021. MsgBox Lang["s16"], "Tip", "4096 T1"
  3022. return
  3023. }
  3024. ListLines (lls:=A_ListLines)?0:0
  3025. k:=i:=v:=0, arr:=StrSplit(Trim(StrReplace(color,"@","-"), "/"), "/")
  3026. Loop nW*nH
  3027. {
  3028. c:=cors[++k], rr:=(c>>16)&0xFF, gg:=(c>>8)&0xFF, bb:=c&0xFF
  3029. For k1,v1 in arr
  3030. {
  3031. r:=StrSplit(Trim(v1,"-") "-", "-"), c:=this.ToRGB(r[1]), n:=r[2]
  3032. , r:=((c>>16)&0xFF)-rr, g:=((c>>8)&0xFF)-gg, b:=(c&0xFF)-bb
  3033. if InStr(n, ".")
  3034. {
  3035. n:=this.Floor(n), n:=(n<=0||n>1?0:Floor(9*255*255*(1-n)*(1-n)))
  3036. if v:=(3*r*r+4*g*g+2*b*b<=n)
  3037. Break
  3038. }
  3039. else
  3040. {
  3041. c:=this.Floor("0x" n), dR:=(c>>16)&0xFF, dG:=(c>>8)&0xFF, dB:=c&0xFF
  3042. if v:=(Abs(r)<=dR && Abs(g)<=dG && Abs(b)<=dB)
  3043. Break
  3044. }
  3045. }
  3046. ascii[k]:=v, (show[k] && i:=(v?i+1:i-1))
  3047. }
  3048. bg:=(i>0 ? "1":"0"), G_.Call("BlackWhite")
  3049. ListLines lls
  3050. return
  3051. Case "ColorPos2Two":
  3052. _Gui:=FindText_Capture
  3053. c:=_Gui["SelColor"].Value
  3054. if (c="")
  3055. {
  3056. _Gui.Opt("+OwnDialogs")
  3057. MsgBox Lang["s12"], "Tip", "4096 T1"
  3058. return
  3059. }
  3060. n:=_Gui["Similar2"].Value, n:=Round(n/100,2), color:="#" c "-" n
  3061. , n:=(n<=0||n>1?0:Floor(9*255*255*(1-n)*(1-n)))
  3062. , rr:=(c>>16)&0xFF, gg:=(c>>8)&0xFF, bb:=c&0xFF, k:=i:=0
  3063. ListLines (lls:=A_ListLines)?0:0
  3064. Loop nW*nH
  3065. c:=cors[++k], r:=((c>>16)&0xFF)-rr, g:=((c>>8)&0xFF)-gg, b:=(c&0xFF)-bb
  3066. , ascii[k]:=v:=3*r*r+4*g*g+2*b*b<=n, (show[k] && i:=(v?i+1:i-1))
  3067. bg:=(i>0 ? "1":"0"), G_.Call("BlackWhite")
  3068. ListLines lls
  3069. return
  3070. Case "BlackWhite":
  3071. Loop 25 + 0*(ty:=dy-1)*(k:=0)
  3072. Loop 71 + 0*(tx:=dx-1)*(ty++)
  3073. if (k++)*0 + (++tx)<nW && ty<nH && show[i:=ty*nW+tx+1]
  3074. this.SC((ascii[i]?0:0xFFFFFF), C_[k])
  3075. return
  3076. Case "Modify":
  3077. Modify:=FindText_Capture["Modify"].Value
  3078. return
  3079. Case "MultiColor":
  3080. MultiColor:=FindText_Capture["MultiColor"].Value
  3081. Result:=""
  3082. ToolTip
  3083. return
  3084. Case "FindShape":
  3085. FindShape:=FindText_Capture["FindShape"].Value
  3086. (FindShape && !MultiColor) && FindText_Capture["MultiColor"].Value:=MultiColor:=1
  3087. return
  3088. Case "Undo":
  3089. Result:=RegExReplace(Result, ",[^/]+/[^/]+/[^/]+$")
  3090. ToolTip Trim(Result, ",")
  3091. return
  3092. Case "Similar1", "Similar2", "Similar3":
  3093. i:=FindText_Capture[cmd].Value
  3094. For k,v in ["Similar1","Similar2","Similar3"]
  3095. (v!=cmd) && FindText_Capture[v].Value:=i
  3096. return
  3097. Case "GetTxt":
  3098. txt:=""
  3099. if (bg="")
  3100. return
  3101. k:=0
  3102. ListLines (lls:=A_ListLines)?0:0
  3103. Loop nH
  3104. {
  3105. v:=""
  3106. Loop nW
  3107. v.=!show[++k] ? "" : ascii[k] ? "1":"0"
  3108. txt.=v="" ? "" : v "`n"
  3109. }
  3110. ListLines lls
  3111. return
  3112. Case "Auto":
  3113. G_.Call("GetTxt")
  3114. if (txt="")
  3115. {
  3116. FindText_Capture.Opt("+OwnDialogs")
  3117. MsgBox Lang["s13"], "Tip", "4096 T1"
  3118. return
  3119. }
  3120. While InStr(txt,bg)
  3121. {
  3122. if (txt~="^" bg "+\n")
  3123. txt:=RegExReplace(txt, "^" bg "+\n"), G_.Call("CutU")
  3124. else if !(txt~="m`n)[^\n" bg "]$")
  3125. txt:=RegExReplace(txt, "m`n)" bg "$"), G_.Call("CutR")
  3126. else if (txt~="\n" bg "+\n$")
  3127. txt:=RegExReplace(txt, "\n\K" bg "+\n$"), G_.Call("CutD")
  3128. else if !(txt~="m`n)^[^\n" bg "]")
  3129. txt:=RegExReplace(txt, "m`n)^" bg), G_.Call("CutL")
  3130. else Break
  3131. }
  3132. txt:=""
  3133. return
  3134. Case "OK", "SplitAdd", "AllAdd":
  3135. _Gui:=FindText_Capture
  3136. _Gui.Opt("+OwnDialogs")
  3137. G_.Call("GetTxt")
  3138. if (txt="") && (!MultiColor)
  3139. {
  3140. MsgBox Lang["s13"], "Tip", "4096 T1"
  3141. return
  3142. }
  3143. if InStr(color,"#") && (!MultiColor)
  3144. {
  3145. k:=i:=j:=0
  3146. ListLines (lls:=A_ListLines)?0:0
  3147. Loop nW*nH
  3148. {
  3149. if (!show[++k])
  3150. Continue
  3151. i++
  3152. if (k=SelPos)
  3153. {
  3154. j:=i
  3155. Break
  3156. }
  3157. }
  3158. ListLines lls
  3159. if (j=0)
  3160. {
  3161. MsgBox Lang["s12"], "Tip", "4096 T1"
  3162. return
  3163. }
  3164. color:="#" j "-" StrSplit(color "-","-")[2]
  3165. }
  3166. Comment:=_Gui["Comment"].Value
  3167. if (cmd="SplitAdd") && (!MultiColor)
  3168. {
  3169. if InStr(color,"#")
  3170. {
  3171. MsgBox Lang["s14"], "Tip", "4096 T3"
  3172. return
  3173. }
  3174. bg:=StrLen(StrReplace(txt,"0"))
  3175. > StrLen(StrReplace(txt,"1")) ? "1":"0"
  3176. s:="", i:=0, k:=nW*nH+1+CutLeft
  3177. Loop w:=nW-CutLeft-CutRight
  3178. {
  3179. i++
  3180. if (!show[k++] && A_Index<w)
  3181. Continue
  3182. i:=Format("{:d}",i)
  3183. v:=RegExReplace(txt,"m`n)^(.{" i "}).*","$1")
  3184. txt:=RegExReplace(txt,"m`n)^.{" i "}"), i:=0
  3185. While InStr(v,bg)
  3186. {
  3187. if (v~="^" bg "+\n")
  3188. v:=RegExReplace(v,"^" bg "+\n")
  3189. else if !(v~="m`n)[^\n" bg "]$")
  3190. v:=RegExReplace(v,"m`n)" bg "$")
  3191. else if (v~="\n" bg "+\n$")
  3192. v:=RegExReplace(v,"\n\K" bg "+\n$")
  3193. else if !(v~="m`n)^[^\n" bg "]")
  3194. v:=RegExReplace(v,"m`n)^" bg)
  3195. else Break
  3196. }
  3197. if (v!="")
  3198. {
  3199. v:=Format("{:d}.",InStr(v,"`n")-1) . this.bit2base64(v)
  3200. s.="`nText.=`"|<" SubStr(Comment, 1, 1) ">" color "$" v "`"`n"
  3201. Comment:=SubStr(Comment, 2)
  3202. }
  3203. }
  3204. Event:=cmd, Result:=s
  3205. _Gui.Hide()
  3206. return
  3207. }
  3208. if (!MultiColor)
  3209. txt:=Format("{:d}.",InStr(txt,"`n")-1) . this.bit2base64(txt)
  3210. else
  3211. {
  3212. n:=_Gui["Similar3"].Value, n:=Round(n/100,2), color:="##" n
  3213. , n:=(n<=0||n>1?0:Floor(9*255*255*(1-n)*(1-n)))
  3214. , arr:=StrSplit(Trim(StrReplace(Result,",","/"),"/"),"/"), s:="", i:=1
  3215. Loop arr.Length//3
  3216. x1:=arr[i++], y1:=arr[i++], c1:=arr[i++], c:="0x" c1
  3217. , (A_Index=1 && (x:=x1, y:=y1, rr:=(c>>16)&0xFF, gg:=(c>>8)&0xFF, bb:=c&0xFF))
  3218. , r:=((c>>16)&0xFF)-rr, g:=((c>>8)&0xFF)-gg, b:=(c&0xFF)-bb
  3219. , s.="," (x1-x) "/" (y1-y) "/" (FindShape?3*r*r+4*g*g+2*b*b<=n:c1)
  3220. txt:=SubStr(s,2)
  3221. }
  3222. s:="`nText.=`"|<" Comment ">" color "$" txt "`"`n"
  3223. if (cmd="SplitAdd" || cmd="AllAdd")
  3224. {
  3225. Event:=cmd, Result:=s
  3226. _Gui.Hide()
  3227. return
  3228. }
  3229. x:=nX+CutLeft+(nW-CutLeft-CutRight)//2
  3230. y:=nY+CutUp+(nH-CutUp-CutDown)//2
  3231. s:=StrReplace(s, "Text.=", "Text:="), r:=StrSplit(Lang["s8"] "|||||||", "|")
  3232. s:="`; #Include <FindText>`n"
  3233. . "`nt1:=A_TickCount, Text:=X:=Y:=`"`"`n" s
  3234. . "`nif (ok:=FindText(&X, &Y, " x "-150000, "
  3235. . y "-150000, " x "+150000, " y "+150000, 0, 0, Text))"
  3236. . "`n{"
  3237. . "`n `; FindText()." . "Click(" . "X, Y, `"L`")"
  3238. . "`n}`n"
  3239. . "`n`; ok:=FindText(&X:=`"wait`", &Y:=3, 0,0,0,0,0,0,Text) `; " r[7]
  3240. . "`n`; ok:=FindText(&X:=`"wait0`", &Y:=-1, 0,0,0,0,0,0,Text) `; " r[8]
  3241. . "`n`nMsgBox `"" r[1] ":``t`" (IsObject(ok)?ok.Length:ok)"
  3242. . "`n . `"``n``n" r[2] ":``t`" (A_TickCount-t1) `" " r[3] "`""
  3243. . "`n . `"``n``n" r[4] ":``t`" X `", `" Y"
  3244. . "`n . `"``n``n" r[5] ":``t<`" (IsObject(ok)?ok[1].id:`"`") `">`", `"Tip`", 4096`n"
  3245. . "`nTry For i,v in ok `; ok " r[6] " ok:=FindText().ok"
  3246. . "`n if (i<=2)"
  3247. . "`n FindText().MouseTip(ok[i].x, ok[i].y)`n"
  3248. Event:=cmd, Result:=s
  3249. _Gui.Hide()
  3250. return
  3251. Case "SavePic2":
  3252. x:=nX+CutLeft, w:=nW-CutLeft-CutRight
  3253. y:=nY+CutUp, h:=nH-CutUp-CutDown
  3254. G_.Call("ScreenShot", x "|" y "|" (x+w-1) "|" (y+h-1) "|0")
  3255. return
  3256. Case "ShowPic":
  3257. i:=EditGetCurrentLine(hscr)
  3258. s:=EditGetLine(i, hscr)
  3259. FindText_Main["MyPic"].Value:=Trim(this.ASCII(s),"`n")
  3260. return
  3261. Case "KeyDown":
  3262. Critical
  3263. _Gui:=FindText_Main
  3264. if (WinExist()!=_Gui.Hwnd)
  3265. return
  3266. Try ctrl:="", ctrl:=args[3]
  3267. if (ctrl=hscr)
  3268. SetTimer G_ShowPic, -150
  3269. else if (ctrl=_Gui["ClipText"].Hwnd)
  3270. {
  3271. s:=_Gui["ClipText"].Value
  3272. _Gui["MyPic"].Value:=Trim(this.ASCII(s),"`n")
  3273. }
  3274. return
  3275. Case "LButtonDown":
  3276. Critical
  3277. if (WinExist()!=FindText_Capture.Hwnd)
  3278. return G_.Call("KeyDown", arg1, args*)
  3279. CoordMode "Mouse"
  3280. MouseGetPos &k1, &k2,, &k6, 2
  3281. if (k6=hPic)
  3282. {
  3283. ListLines (lls:=A_ListLines)?0:0
  3284. Loop
  3285. {
  3286. Sleep 50
  3287. MouseGetPos &k3, &k4
  3288. this.RangeTip(Min(k1,k3), Min(k2,k4)
  3289. , Abs(k1-k3)+1, Abs(k2-k4)+1, (A_MSec<500 ? "Red":"Blue"))
  3290. }
  3291. Until !this.State("LButton")
  3292. ListLines lls
  3293. this.RangeTip()
  3294. this.GetBitsFromScreen(,,,,0,&zx,&zy)
  3295. this.ClientToScreen(&sx, &sy, 0, 0, hPic)
  3296. sx:=Min(k1,k3)-sx+hBM_x+zx, sy:=Min(k2,k4)-sy+hBM_y+zy
  3297. , sw:=Abs(k1-k3)+1, sh:=Abs(k2-k4)+1
  3298. if (sw+sh)<5
  3299. sx-=71//2, sy-=25//2, sw:=71, sh:=25
  3300. G_.Call("CaptureUpdate")
  3301. FindText_Capture["MyTab1"].Choose(1)
  3302. return
  3303. }
  3304. if !(Cid_.Has(k6) && k5:=Cid_[k6])
  3305. return
  3306. if (k5=-1)
  3307. {
  3308. MouseMove k1+2, k2+2, 0
  3309. MouseGetPos(,,, &k6, 2)
  3310. MouseMove k1, k2, 0
  3311. if !(Cid_.Has(k6) && k5:=Cid_[k6]) || (k5=-1)
  3312. return
  3313. }
  3314. if (k5>71*25)
  3315. {
  3316. k1:=nW*nH+dx+(k5-71*25)
  3317. this.SC(((show[k1]:=!show[k1])?0xFF0000:0xFFFFAA), k6)
  3318. return
  3319. }
  3320. k3:=Mod(k5-1,71)+dx, k4:=(k5-1)//71+dy
  3321. if (k3>=nW || k4>=nH)
  3322. return
  3323. k1:=k4*nW+k3+1
  3324. if (Modify && bg!="" && show[k1])
  3325. this.SC(((ascii[k1]:=!ascii[k1])?0:0xFFFFFF), k6)
  3326. else
  3327. {
  3328. k2:=cors[k1], SelPos:=k1
  3329. _Gui:=FindText_Capture
  3330. _Gui["SelGray"].Value:=(((k2>>16)&0xFF)*38+((k2>>8)&0xFF)*75+(k2&0xFF)*15)>>7
  3331. _Gui["SelColor"].Value:=Format("0x{:06X}",k2&0xFFFFFF)
  3332. _Gui["SelR"].Value:=(k2>>16)&0xFF
  3333. _Gui["SelG"].Value:=(k2>>8)&0xFF
  3334. _Gui["SelB"].Value:=k2&0xFF
  3335. }
  3336. if (MultiColor && show[k1])
  3337. {
  3338. (FindShape && Result="") && G_.Call("ColorPos2Two")
  3339. k2:=Format(",{:d}/{:d}/{:06X}", nX+k3, nY+k4, cors[k1]&0xFFFFFF)
  3340. , Result.=InStr(Result,k2) ? "":k2
  3341. ToolTip Trim(Result, ",")
  3342. }
  3343. return
  3344. Case "RButtonDown":
  3345. Critical
  3346. MouseGetPos(,,, &k2, 2)
  3347. if (k2!=hPic)
  3348. return
  3349. CoordMode "Mouse"
  3350. MouseGetPos &k1, &k2
  3351. k5:=hBM_x, k6:=hBM_y
  3352. ListLines (lls:=A_ListLines)?0:0
  3353. Loop
  3354. {
  3355. Sleep 10
  3356. MouseGetPos &k3, &k4
  3357. hBM_x:=k5+k1-k3, hBM_y:=k6+k2-k4
  3358. G_.Call("PicShow")
  3359. }
  3360. Until !this.State("RButton")
  3361. ListLines lls
  3362. return
  3363. Case "MouseMove":
  3364. Try ctrl_name:="", ctrl_name:=GuiCtrlFromHwnd(args[3]).Name
  3365. if (PrevControl != ctrl_name)
  3366. {
  3367. ToolTip
  3368. PrevControl:=ctrl_name
  3369. Try SetTimer G_ToolTip, (PrevControl ? -500:0)
  3370. Try SetTimer G_ToolTipOff, (PrevControl ? -5500:0)
  3371. }
  3372. return
  3373. Case "ToolTip":
  3374. MouseGetPos(,, &_TT)
  3375. if WinExist("ahk_id " _TT " ahk_class AutoHotkeyGUI")
  3376. Try ToolTip Tip_Text[PrevControl]
  3377. return
  3378. Case "ToolTipOff":
  3379. ToolTip
  3380. return
  3381. Case "CutL2", "CutR2", "CutU2", "CutD2":
  3382. s:=FindText_Main["MyPic"].Value
  3383. s:=Trim(s,"`n") . "`n", v:=SubStr(cmd,4,1)
  3384. if (v="U")
  3385. s:=RegExReplace(s,"^[^\n]+\n")
  3386. else if (v="D")
  3387. s:=RegExReplace(s,"[^\n]+\n$")
  3388. else if (v="L")
  3389. s:=RegExReplace(s,"m`n)^[^\n]")
  3390. else if (v="R")
  3391. s:=RegExReplace(s,"m`n)[^\n]$")
  3392. FindText_Main["MyPic"].Value:=Trim(s,"`n")
  3393. return
  3394. Case "Update":
  3395. ControlFocus hscr
  3396. i:=EditGetCurrentLine(hscr)
  3397. s:=EditGetLine(i, hscr)
  3398. if !RegExMatch(s, "(<[^>\n]*>[^$\n]+\$)\d+\.[\w+/]+", &r)
  3399. return
  3400. v:=FindText_Main["MyPic"].Value
  3401. v:=Trim(v,"`n") . "`n", w:=Format("{:d}",InStr(v,"`n")-1)
  3402. v:=StrReplace(StrReplace(v,"0","1"),"_","0")
  3403. s:=StrReplace(s, r[0], r[1] . w "." this.bit2base64(v))
  3404. v:="{End}{Shift Down}{Home}{Shift Up}{Del}"
  3405. ControlSend v, hscr
  3406. EditPaste s, hscr
  3407. ControlSend "{Home}", hscr
  3408. return
  3409. }
  3410. }
  3411. Lang(text:="", getLang:=0)
  3412. {
  3413. static Lang1:="", Lang2
  3414. if (!Lang1)
  3415. {
  3416. s:="
  3417. (
  3418. Myww = 宽度 = 调整抓图范围的宽度
  3419. Myhh = 高度 = 调整抓图范围的高度
  3420. AddFunc = 附加 = 复制时带 FindText() 函数
  3421. NowHotkey = 截屏热键 = 当前的截屏热键
  3422. SetHotkey1 = = 第一优先级的截屏热键
  3423. SetHotkey2 = = 第二优先级的截屏热键
  3424. Apply = 应用 = 应用新的截屏热键
  3425. CutU2 = 上删 = 裁剪下面编辑框中文字的上边缘
  3426. CutL2 = 左删 = 裁剪下面编辑框中文字的左边缘
  3427. CutR2 = 右删 = 裁剪下面编辑框中文字的右边缘
  3428. CutD2 = 下删 = 裁剪下面编辑框中文字的下边缘
  3429. Update = 更新 = 更新下面编辑框中文字到代码行中
  3430. GetRange = 获取屏幕范围 = 获取屏幕范围到剪贴板并替换代码中的范围参数
  3431. GetOffset = 获取相对坐标 = 获取相对图像位置的偏移坐标并替换代码中的点击坐标
  3432. GetClipOffset = 获取相对坐标2 = 获取相对左边编辑框的图像的偏移坐标
  3433. Capture = 抓图 = 开始屏幕抓图
  3434. CaptureS = 截屏抓图 = 先截屏,然后显示截屏图像,再手动选择图像内的范围抓图
  3435. Test = 测试 = 测试生成的代码是否可以查找成功
  3436. TestClip = 测试2 = 测试左边文本框中的文字是否可以查找成功,结果复制到剪贴板
  3437. Paste = 粘贴 = 粘贴剪贴板的文字数据
  3438. CopyOffset = 复制2 = 复制左边的偏移坐标到剪贴板
  3439. Copy = 复制 = 复制代码到剪贴板
  3440. Reset = 重读 = 重新读取原来的彩色图像
  3441. SplitAdd = 分割添加 = 点击黄色的标签来分割图像为多个图像数据,添加到旧代码中
  3442. AllAdd = 整体添加 = 将文字数据整体添加到旧代码中
  3443. Gray2Two = 灰度阈值二值化 = 灰度小于阈值的为黑色其余白色
  3444. GrayDiff2Two = 灰度差值二值化 = 某点与周围灰度之差大于差值的为黑色其余白色
  3445. Color2Two = 颜色二值化 = 通过颜色列表来转换图像为黑白图
  3446. ColorPos2Two = 颜色位置二值化 = 指定颜色及相似色为黑色其余白色,但是记录该色的位置
  3447. SelGray = 灰度 = 选定颜色的灰度值 (0-255)
  3448. SelColor = 颜色 = 选定颜色的RGB颜色值
  3449. SelR = 红 = 选定颜色的红色分量
  3450. SelG = 绿 = 选定颜色的绿色分量
  3451. SelB = 蓝 = 选定颜色的蓝色分量
  3452. RepU = -上 = 撤销裁剪上边缘1个像素
  3453. CutU = 上 = 裁剪上边缘1个像素
  3454. CutU3 = 上3 = 裁剪上边缘3个像素
  3455. RepL = -左 = 撤销裁剪左边缘1个像素
  3456. CutL = 左 = 裁剪左边缘1个像素
  3457. CutL3 = 左3 = 裁剪左边缘3个像素
  3458. Auto = 自动 = 二值化之后自动裁剪空白边缘
  3459. RepR = -右 = 撤销裁剪右边缘1个像素
  3460. CutR = 右 = 裁剪右边缘1个像素
  3461. CutR3 = 右3 = 裁剪右边缘3个像素
  3462. RepD = -下 = 撤销裁剪下边缘1个像素
  3463. CutD = 下 = 裁剪下边缘1个像素
  3464. CutD3 = 下3 = 裁剪下边缘3个像素
  3465. Modify = 修改 = 二值化后可以用鼠标在预览区点击手动修改黑白点
  3466. MultiColor = 多点找色 = 鼠标选择多种颜色,之后点击“确定”按钮
  3467. FindShape = 找形状 = 鼠标选择多种颜色,会基于第一点的颜色二值化
  3468. Undo = 撤销 = 撤销上一次选择的颜色
  3469. Undo2 = 撤销 = 撤销上一次添加到颜色列表的颜色
  3470. Comment = 识别文字 = 识别文本 (包含在<>中),分割添加时也会分解成单个文字
  3471. Threshold = 灰度阈值 = 灰度阈值 (0-255)
  3472. GrayDiff = 灰度差值 = 灰度差值 (0-255)
  3473. Similar1 = 相似度 = 与选定颜色的相似度
  3474. Similar2 = 相似度 = 与选定颜色的相似度
  3475. Similar3 = 相似度 = 与选定颜色的相似度
  3476. AddColorSim = 添加 = 颜色相似模式添加到颜色列表中再运行颜色二值化
  3477. AddColorDiff = 添加 = 颜色偏色模式添加到颜色列表中再运行颜色二值化
  3478. ColorList = = 颜色列表用于转换图像为二值图
  3479. DiffRGB = 红/绿/蓝 = 多色查找时各分量允许的偏差 (0-255)
  3480. DiffRGB2 = 红/绿/蓝 = 多色查找时各分量允许的偏差 (0-255)
  3481. Bind0 = 绑定窗口1 = 绑定窗口使用GetDCEx()获取后台窗口图像
  3482. Bind1 = 绑定窗口1+ = 绑定窗口使用GetDCEx()并修改窗口透明度
  3483. Bind2 = 绑定窗口2 = 绑定窗口使用PrintWindow()获取后台窗口图像
  3484. Bind3 = 绑定窗口2+ = 绑定窗口使用PrintWindow()并修改窗口透明度
  3485. Bind4 = 绑定窗口3 = 绑定窗口使用PrintWindow(,,3)获取后台窗口图像
  3486. OK = 确定 = 生成全新的代码替换旧代码
  3487. OK2 = 确定 = 恢复截屏到屏幕然后再抓图
  3488. Cancel = 取消 = 关闭窗口不做任何事
  3489. Cancel2 = 取消 = 关闭窗口不做任何事
  3490. ClearAll = 清空 = 清空所有保存的截图
  3491. OpenDir = 打开目录 = 打开保存屏幕截图的目录
  3492. SavePic = 保存图片 = 选择一个范围保存为图片
  3493. SavePic2 = 保存图片 = 将修剪后的原始图像保存为图片
  3494. LoadPic = 载入图片 = 载入一张图片作为抓取的图像
  3495. ClipText = = 显示粘贴的文字数据
  3496. Offset = = 显示“获取相对坐标2”或者“获取屏幕范围”的结果
  3497. SelectBox = = 选择截图显示到屏幕左上角
  3498. s1 = FindText找字工具
  3499. s2 = 灰度阈值|灰度差值|颜色|颜色位置|多色查找
  3500. s3 = 图像二值化及分割
  3501. s4 = 抓图生成字库及找字代码
  3502. s5 = 方向键微调选框\n先点击右键(Ctrl)一次\n把鼠标移开\n再点击右键(Ctrl)一次
  3503. s6 = 解绑窗口使用
  3504. s7 = 左键(Ctrl)拖动选择范围\n坐标复制到剪贴板
  3505. s8 = 找到|时间|毫秒|位置|结果|值可以这样获取|等待3秒等图像出现|无限等待等图像消失
  3506. s9 = 截屏成功
  3507. s10 = 鼠标位置|穿透显示绑定窗口\n点击右键完成抓图
  3508. s11 = 请先设定灰度差值!
  3509. s12 = 请先选择核心颜色!
  3510. s13 = 请先将图像二值化!
  3511. s14 = 不能用于颜色位置二值化模式, 因为分割后会导致位置错误
  3512. s15 = 你确定选择的范围吗?\n\n如果不确定,可以重新选择
  3513. s16 = 请先添加颜色到颜色列表!
  3514. s17 = 你想打开的图片没有找到!
  3515. s18 = 捕获|截图
  3516. s19 = 你确定要删除所有的截图吗?
  3517. )"
  3518. Lang1:=Map(), Lang1.Default:="", Lang2:=Map(), Lang2.Default:=""
  3519. Loop Parse, s, "`n", "`r"
  3520. if InStr(v:=A_LoopField, "=")
  3521. r:=StrSplit(StrReplace(v "==","\n","`n"), "=", "`t ")
  3522. , Lang1[r[1]]:=r[2], Lang2[r[1]]:=r[3]
  3523. }
  3524. return getLang=1 ? Lang1 : getLang=2 ? Lang2 : Lang1[text]
  3525. }
  3526. Script_End() {
  3527. }
  3528. } ;// Class End
  3529. ;================= The End =================
  3530. ;