From 993449614aa7eeebbc8ecc4553fd3bf9b53e5e77 Mon Sep 17 00:00:00 2001 From: Thierry Dalon Date: Wed, 28 Feb 2024 19:25:10 +0100 Subject: [PATCH] update --- Lib/Clip.ahk | 28 +- Lib/Confluence.ahk | 6 +- Lib/Connections.ahk | 2 - Lib/DateConv.ahk | 2 +- Lib/FindText.ahk | 3518 +++++++++++++++++++++++------------------- Lib/Group.ahk | 85 + Lib/IntelliPaste.ahk | 44 +- Lib/OSDTIP.ahk | 366 +++++ Lib/PowerTools.ahk | 644 ++++---- Lib/Teams.ahk | 5 +- Lib/Xray.ahk | 363 +++++ 11 files changed, 3172 insertions(+), 1891 deletions(-) create mode 100644 Lib/Group.ahk create mode 100644 Lib/OSDTIP.ahk create mode 100644 Lib/Xray.ahk diff --git a/Lib/Clip.ahk b/Lib/Clip.ahk index a7fdb58..3eb6639 100644 --- a/Lib/Clip.ahk +++ b/Lib/Clip.ahk @@ -6,14 +6,26 @@ GroupAdd, PlainEditor, ahk_exe Notepad.exe GroupAdd, PlainEditor, ahk_exe notepad++.exe GroupAdd, PlainEditor, ahk_exe atom.exe ; ------------------------------------------------------------------------------------------------------------------- -Clip_Paste(sText,restore := True) { +Clip_Paste(sText) { ; Syntax: Clip_Paste(sText) WinClip.Paste(sText) } ; eofun + +Clip_Paste2(sText,restore:=true) { + If restore + ClipBackup:= ClipboardAll + Clipboard := sText + clipwait 0 + SendInput ^v + If restore { + Clip_Wait() + Clipboard := ClipBackup + } + +} ; eofun ; ------------------------------------------------------------------------------------------------------------------- Clip_Set(sText){ ; Syntax: Clip_Set(sText) -; Clipboard := sText Clip_Wait() } ; eofun @@ -224,6 +236,18 @@ If (restore) Clipboard := ClipBackup return sSelection } + +/* +Clip_GetSelection1() { +;#Include UIA.ahk +el := UIA.GetFocusedElement() +if el.IsTextPatternAvailable { + selectionRange := el.GetSelection()[2] + If txt:= selectionRange.GetText() + return txt +} +} ; eofun +*/ ; ------------------------------------------------------------------------------------------------------------------- Clip_ReplaceSelection(sNeedle, sReplace:=""){ diff --git a/Lib/Confluence.ahk b/Lib/Confluence.ahk index 949e782..471ecb7 100644 --- a/Lib/Confluence.ahk +++ b/Lib/Confluence.ahk @@ -270,10 +270,10 @@ return WebRequest ; ------------------------------------------------------------------------------------------------------------------- -Confluence_ViewInHierachy(sUrl :=""){ ; @fun_Confluence_ViewInHierachy@ -; Confluence_ViewInHierachy(sUrl*) +Confluence_ViewInHierarchy(sUrl :=""){ ; @fun_Confluence_ViewInHierachy@ +; Confluence_ViewInHierarchy(sUrl*) If GetKeyState("Ctrl") and !GetKeyState("Shift") { - PowerTools_OpenDoc("Confluence_ViewInHierachy") + PowerTools_OpenDoc("Confluence_ViewInHierarchy") return } If (sUrl="") diff --git a/Lib/Connections.ahk b/Lib/Connections.ahk index 588946a..0f8f4df 100644 --- a/Lib/Connections.ahk +++ b/Lib/Connections.ahk @@ -403,10 +403,8 @@ TotalCount := 0 LoopPage: sPageUrl = %sUrl%&ps=%pagesize%&page=%pagecnt% -;sXml_page := BrowserGetPage(sPageUrl) ; will flash a browser window sXml_page := CNGet(sPageUrl) - If (sXml_page ~= "Error.*") { return sXml_page } diff --git a/Lib/DateConv.ahk b/Lib/DateConv.ahk index 79303c3..9bc0dc7 100644 --- a/Lib/DateConv.ahk +++ b/Lib/DateConv.ahk @@ -3,7 +3,7 @@ RegTimeZones := GetTimeZones() DateConvZ(sDate){ global RegTimeZones -; Convert ConNext Event date to standard Format 2020-01-31T23:30:00.000Z -> 2020-01-31 23:00:00 +; Convert Connections Event date to standard Format 2020-01-31T23:30:00.000Z -> 2020-01-31 23:00:00 ; Convert Zulu date to Date format sUTCDate := RegExReplace(sDate,"\.000.*","") ; independent of time zone diff --git a/Lib/FindText.ahk b/Lib/FindText.ahk index 80a829c..2b85a87 100644 --- a/Lib/FindText.ahk +++ b/Lib/FindText.ahk @@ -1,13 +1,13 @@ ;/* ;=========================================== ; FindText - Capture screen image into text and then find it -; https://autohotkey.com/boards/viewtopic.php?f=6&t=17834 +; https://www.autohotkey.com/boards/viewtopic.php?f=6&t=17834 ; ; Author : FeiYue -; Version : 8.9 -; Date : 2022-05-28 +; Version : 9.3 +; Date : 2023-11-05 ; -; Usage: (required AHK v1.1.31+) +; Usage: (required AHK v1.1.34+) ; 1. Capture the image to text string. ; 2. Test find the text string on full Screen. ; 3. When test is successful, you may copy the code @@ -26,17 +26,52 @@ ;*/ -if (!A_IsCompiled and A_LineFile=A_ScriptFullPath) +if (!A_IsCompiled && A_LineFile=A_ScriptFullPath) FindText().Gui("Show") ;===== Copy The Following Functions To Your Own Code Just once ===== +FindText(ByRef x:="FindTextClass", ByRef y:="", args*) +{ + static init, obj + if (!VarSetCapacity(init) && init:="1") + obj:=new FindTextClass() + return (x=="FindTextClass" && !args.Length()) ? obj : obj.FindText(x, y, args*) +} + +Class FindTextClass +{ ;// Class Begin + +__New() +{ + this.bits:={ Scan0: 0, hBM: 0, oldzw: 0, oldzh: 0 } + this.bind:={ id: 0, mode: 0, oldStyle: 0 } + this.Lib:=[] + this.Cursor:=0 +} + +__Delete() +{ + if (this.bits.hBM) + DllCall("DeleteObject", "Ptr",this.bits.hBM) +} + +New() +{ + return new FindTextClass() +} + +help() +{ +return " +( ;-------------------------------- ; FindText - Capture screen image into text and then find it +; Version : 9.3 (2023-11-05) ;-------------------------------- -; returnArray := FindText( +; returnArray:=FindText( ; OutputX --> The name of the variable used to store the returned X coordinate ; , OutputY --> The name of the variable used to store the returned Y coordinate ; , X1 --> the search scope's upper left corner X coordinates @@ -45,7 +80,7 @@ if (!A_IsCompiled and A_LineFile=A_ScriptFullPath) ; , Y2 --> the search scope's lower right corner Y coordinates ; , err1 --> Fault tolerance percentage of text (0.1=10%) ; , err0 --> Fault tolerance percentage of background (0.1=10%) -; , Text --> can be a lot of text parsed into images, separated by "|" +; , Text --> can be a lot of text parsed into images, separated by '|' ; , ScreenShot --> if the value is 0, the last screenshot will be used ; , FindAll --> if the value is 0, Just find one result and return ; , JoinText --> if you want to combine find, it can be 1, or an array of words to find @@ -56,114 +91,83 @@ if (!A_IsCompiled and A_LineFile=A_ScriptFullPath) ; , zoomH --> Zoom percentage of image height (1.0=100%) ; ) ; -; The function returns a second-order array containing -; all lookup results, Any result is an associative array +; The function returns an Array containing all lookup results, +; any result is a object with the following values: ; {1:X, 2:Y, 3:W, 4:H, x:X+W//2, y:Y+H//2, id:Comment} -; if no image is found, the function returns 0. +; If no image is found, the function returns 0. ; All coordinates are relative to Screen, colors are in RGB format ; -; If the return variable is set to "ok", ok[1] is the first result found. -; ok[1][1], ok[1][2] is the X, Y coordinate of the upper left corner of the found image, -; ok[1][3] is the width of the found image, and ok[1][4] is the height of the found image, -; ok[1].x <==> ok[1][1]+ok[1][3]//2 ( is the Center X coordinate of the found image ), -; ok[1].y <==> ok[1][2]+ok[1][4]//2 ( is the Center Y coordinate of the found image ), +; If the return variable is set to 'ok', ok[1] is the first result found. +; ok[1].1, ok[1].2 is the X, Y coordinate of the upper left corner of the found image, +; ok[1].3 is the width of the found image, and ok[1].4 is the height of the found image, +; ok[1].x <==> ok[1].1+ok[1].3//2 ( is the Center X coordinate of the found image ), +; ok[1].y <==> ok[1].2+ok[1].4//2 ( is the Center Y coordinate of the found image ), ; ok[1].id is the comment text, which is included in the <> of its parameter. ; -; If OutputX is equal to "wait" or "wait1"(appear), or "wait0"(disappear) +; If OutputX is equal to 'wait' or 'wait1'(appear), or 'wait0'(disappear) ; it means using a loop to wait for the image to appear or disappear. ; the OutputY is the wait time in seconds, time less than 0 means infinite waiting ; Timeout means failure, return 0, and return other values means success ; If you want to appear and the image is found, return the found array object ; If you want to disappear and the image cannot be found, return 1 -; Example 1: FindText(X:="wait", Y:=3, 0,0,0,0,0,0,Text) ; Wait 3 seconds for appear -; Example 2: FindText(X:="wait0", Y:=-1, 0,0,0,0,0,0,Text) ; Wait indefinitely for disappear +; Example 1: FindText(X:='wait', Y:=3, 0,0,0,0,0,0,Text) ; Wait 3 seconds for appear +; Example 2: FindText(X:='wait0', Y:=-1, 0,0,0,0,0,0,Text) ; Wait indefinitely for disappear +; +; : FindColor is FindMultiColor with only one point +; Text:='|<>##DRDGDB $ 0/0/RRGGBB1-DRDGDB1/RRGGBB2/-RRGGBB3/-RRGGBB4, xn/yn/...' +; Color behind '##' (0xDRDGDB) is the default allowed variation for all colors +; Initial point (0,0) match 0xRRGGBB1(+/-0xDRDGDB1) or 0xRRGGBB2(+/-0xDRDGDB) +; or not 0xRRGGBB3(+/-0xDRDGDB) or not 0xRRGGBB4(+/-0xDRDGDB) +; The color starting with '-' means that all but this color is successful +; Each point can take up to 10 sets of colors (xn/yn/RRGGBB1/.../RRGGBB10) +; +; : Text parameter require manual input +; Text:='|<>##DRDGDB-RRGGBB1-RRGGBB2... $ d:\a.bmp' +; the 0xRRGGBB1(+/-0xDRDGDB)... all as transparent color +; ;-------------------------------- - -FindText(ByRef x:="FindTextClass", ByRef y:="", args*) -{ - global FindTextClass - if (x=="FindTextClass") - return FindTextClass - else - return FindTextClass.FindText(x, y, args*) -} - -Class FindTextClass -{ ;// Class Begin - -static bind:=[], bits:=[], Lib:=[], Cursor:=0 - -__New() -{ - this.bind:=[], this.bits:=[], this.Lib:=[], this.Cursor:=0 -} - -__Delete() -{ - if (this.bits.hBM) - DllCall("DeleteObject", "Ptr",this.bits.hBM) +)" } FindText(ByRef OutputX:="", ByRef OutputY:="" - , x1:="", y1:="", x2:="", y2:="", err1:="", err0:="" - , text:="", ScreenShot:="", FindAll:="" - , JoinText:="", offsetX:="", offsetY:="", dir:="" - , zoomW:=1, zoomH:=1) + , x1:=0, y1:=0, x2:=0, y2:=0, err1:=0, err0:=0, text:="" + , ScreenShot:=1, FindAll:=1, JoinText:=0, offsetX:=20, offsetY:=10 + , dir:=1, zoomW:=1, zoomH:=1) { local - if RegExMatch(OutputX, "i)^\s*wait[10]?\s*$") + if (OutputX ~= "i)^\s*wait[10]?\s*$") { - found:=!InStr(OutputX,"0"), time:=OutputY + found:=!InStr(OutputX,"0"), time:=Round(OutputY,15) , timeout:=A_TickCount+Round(time*1000) - , OutputX:=OutputY:="" Loop { - ; Wait for the image to remain stable - While (ok:=this.FindText(OutputX, OutputY - , x1, y1, x2, y2, err1, err0, text, ScreenShot, FindAll - , JoinText, offsetX, offsetY, dir, zoomW, zoomH)) - and (found) + ok:=this.FindText(,, x1, y1, x2, y2, err1, err0, text, ScreenShot + , FindAll, JoinText, offsetX, offsetY, dir, zoomW, zoomH) + if (found && ok) { - v:=ok[1], x:=v[1], y:=v[2], w:=v[3], h:=v[4] - Sleep, 10 - if this.FindText(0, 0, x, y, x+w-1, y+h-1 - , err1, err0, text, ScreenShot, FindAll - , JoinText, offsetX, offsetY, dir, zoomW, zoomH) - return (this.ok:=ok) + OutputX:=ok[1].x, OutputY:=ok[1].y + return ok } - if (!found and !ok) + if (!found && !ok) return 1 - if (time>=0 and A_TickCount>=timeout) + if (time>=0 && A_TickCount>=timeout) Break - Sleep, 50 + Sleep 50 } return 0 } SetBatchLines, % (bch:=A_BatchLines)?"-1":"-1" - if InStr(err1,"$") and !InStr(text,"$") - { - dir:=offsetX, offsetY:=JoinText, offsetX:=FindAll - , JoinText:=ScreenShot, FindAll:=text, ScreenShot:=err0 - , text:=err1, err0:=y2, err1:=x2 - , y2:=y1, x2:=x1, y1:=OutputY, x1:=OutputX - } - (err1="" && err1:=0), (err0="" && err0:=0) - , (ScreenShot="" && ScreenShot:=1) - , (FindAll="" && FindAll:=1) - , (JoinText="" && JoinText:=0) - , (offsetX="" && offsetX:=20) - , (offsetY="" && offsetY:=10) - , (dir="" && dir:=1) - if (x1*x1+y1*y1+x2*x2+y2*y2<=0) + x1:=Floor(x1), y1:=Floor(y1), x2:=Floor(x2), y2:=Floor(y2) + if (x1=0 && y1=0 && x2=0 && y2=0) n:=150000, x:=y:=-n, w:=h:=2*n else x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x2-x1)+1, h:=Abs(y2-y1)+1 - bits:=this.GetBitsFromScreen(x,y,w,h,ScreenShot,zx,zy,zw,zh) - , x-=zx, y-=zy, info:=[], this.ok:=0 + bits:=this.GetBitsFromScreen(x,y,w,h,ScreenShot,zx,zy), x-=zx, y-=zy + , this.ok:=0, info:=[] Loop Parse, text, | if IsObject(j:=this.PicInfo(A_LoopField)) info.Push(j) - if (w<1 or h<1 or !(num:=info.Length()) or !bits.Scan0) + if (w<1 || h<1 || !(num:=info.Length()) || !bits.Scan0) { SetBatchLines, %bch% return 0 @@ -172,54 +176,54 @@ FindText(ByRef OutputX:="", ByRef OutputY:="" , mode:=(IsObject(JoinText) ? 2 : JoinText ? 1 : 0) For i,j in info { - k:=Max(k, j[2]*j[3]), v:=(mode=1 ? i : j[11]) - if (mode and v!="") - s.="|" v, (!info2[v] && info2[v]:=[]), info2[v].Push(j) + k:=Max(k, (j[7]=5 && j[8]=0 ? j[9] : j[2]*j[3])) + if (mode) + v:=(mode=2 ? j[10] : i) . "", s.="|" v + , (!info2.HasKey(v) && info2[v]:=[]), (v!="" && info2[v].Push(j)) } - JoinText:=(mode=1 ? [s] : JoinText) + sx:=x, sy:=y, sw:=w, sh:=h + , JoinText:=(mode=1 ? [s] : JoinText) , VarSetCapacity(s1, k*4), VarSetCapacity(s0, k*4) - , VarSetCapacity(ss, 2*(w+2)*(h+2)) + , VarSetCapacity(ss, sw*(sh+2)) , FindAll:=(dir=9 ? 1 : FindAll) - , allpos_max:=(FindAll or JoinText ? 10240 : 1) - , ini:={sx:x, sy:y, sw:w, sh:h, zx:zx, zy:zy, zw:zw, zh:zh + , allpos_max:=(FindAll || JoinText ? 10240 : 1) + , ini:={ sx:sx, sy:sy, sw:sw, sh:sh, zx:zx, zy:zy , mode:mode, bits:bits, ss:&ss, s1:&s1, s0:&s0 - , allpos_max:allpos_max, zoomW:zoomW, zoomH:zoomH} + , err1:err1, err0:err0, allpos_max:allpos_max + , zoomW:zoomW, zoomH:zoomH } Loop 2 { - if (err1=0 and err0=0) and (num>1 or A_Index>1) - err1:=0.05, err0:=0.05 - ini.err1:=err1, ini.err0:=err0 + if (err1=0 && err0=0) && (num>1 || A_Index>1) + ini.err1:=err1:=0.05, ini.err0:=err0:=0.05 if (!JoinText) { - VarSetCapacity(allpos, allpos_max*8) + VarSetCapacity(allpos, allpos_max*4), allpos_ptr:=&allpos For i,j in info - Loop % this.PicFind(ini, j, dir, allpos - , ini.sx, ini.sy, ini.sw, ini.sh) + Loop % this.PicFind(ini, j, dir, sx, sy, sw, sh, allpos_ptr) { - x:=NumGet(allpos, 8*A_Index-8, "uint") + zx - , y:=NumGet(allpos, 8*A_Index-4, "uint") + zy - , w:=j[2], h:=j[3], comment:=j[11] + pos:=NumGet(allpos, 4*(A_Index-1), "uint") + , x:=(pos&0xFFFF)+zx, y:=(pos>>16)+zy + , w:=Floor(j[2]*zoomW), h:=Floor(j[3]*zoomH), comment:=j[10] , arr.Push({1:x, 2:y, 3:w, 4:h, x:x+w//2, y:y+h//2, id:comment}) if (!FindAll) - Break, 3 + Break 3 } } else For k,v in JoinText { - v:=RegExReplace(v, "\s*\|[|\s]*", "|") - , v:=StrSplit(Trim(v,"|"), (InStr(v,"|")?"|":""), " `t") - , this.JoinText(ini, arr, info2, v, offsetX, offsetY, FindAll - , 1, v.Length(), dir, 0, 0, ini.sx, ini.sy, ini.sw, ini.sh) - if (!FindAll and arr.Length()) - Break, 2 + v:=StrSplit(Trim(RegExReplace(v, "\s*\|[|\s]*" + , "|"), "|"), (InStr(v,"|")?"|":""), " `t") + , this.JoinText(arr, ini, info2, v, 1, offsetX, offsetY + , FindAll, dir, 0, 0, 0, sx, sy, sw, sh) + if (!FindAll && arr.Length()) + Break 2 } - if (err1!=0 or err0!=0 or arr.Length() - or info[1][8]=5 or info[1][12]) + if (err1!=0 || err0!=0 || arr.Length() || info[1][4] || info[1][7]=5) Break } - if (dir=9) - arr:=this.Sort2(arr, Round(x1+x2)//2, Round(y1+y2)//2) + if (dir=9 && arr.Length()) + arr:=this.Sort2(arr, (x1+x2)//2, (y1+y2)//2) SetBatchLines, %bch% if (arr.Length()) { @@ -231,315 +235,661 @@ FindText(ByRef OutputX:="", ByRef OutputY:="" ; the join text object <==> [ "abc", "xyz", "a1|a2|a3" ] -JoinText(ini, arr, info2, text, offsetX, offsetY, FindAll - , index:="", Len:="", dir:="", minY:="", maxY:="" - , sx:="", sy:="", sw:="", sh:="") +JoinText(arr, ini, info2, text, index, offsetX, offsetY + , FindAll, dir, minX, minY, maxY, sx, sy, sw, sh) { local - VarSetCapacity(allpos, ini.allpos_max*8) + if !(Len:=text.Length()) + return 0 + VarSetCapacity(allpos, ini.allpos_max*4), allpos_ptr:=&allpos + , zoomW:=ini.zoomW, zoomH:=ini.zoomH, mode:=ini.mode For i,j in info2[text[index]] - if (ini.mode=1 or text[index]==j[11]) - Loop % this.PicFind(ini, j, dir, allpos, sx, sy - , (index=1 ? sw : Min(sx+offsetX+j[2],ini.sx+ini.sw)-sx), sh) - { - x:=NumGet(allpos, 8*A_Index-8, "uint") - , y:=NumGet(allpos, 8*A_Index-4, "uint"), w:=j[2], h:=j[3] - , (index=1) && (ini.x:=x, minY:=y, maxY:=y+h) + if (mode!=2 || text[index]==j[10]) + Loop % this.PicFind(ini, j, dir, sx, sy, (index=1 ? sw + : Min(sx+offsetX+Floor(j[2]*zoomW),ini.sx+ini.sw)-sx), sh, allpos_ptr) + { + pos:=NumGet(allpos, 4*(A_Index-1), "uint") + , x:=pos&0xFFFF, y:=pos>>16 + , w:=Floor(j[2]*zoomW), h:=Floor(j[3]*zoomH) + , (index=1 && (minX:=x, minY:=y, maxY:=y+h)) + , minY1:=Min(y, minY), maxY1:=Max(y+h, maxY), sx1:=x+w if (index1 or !FindAll) + sy1:=Max(minY1-offsetY, ini.sy) + , sh1:=Min(maxY1+offsetY, ini.sy+ini.sh)-sy1 + if this.JoinText(arr, ini, info2, text, index+1, offsetX, offsetY + , FindAll, 5, minX, minY1, maxY1, sx1, sy1, 0, sh1) + && (index>1 || !FindAll) return 1 } else { comment:="" For k,v in text - comment.=(ini.mode=1 ? info2[v][1][11] : v) - w:=x+w-ini.x, x:=ini.x+ini.zx - , h:=Max(y+h,maxY)-Min(y,minY), y:=Min(y,minY)+ini.zy + comment.=(mode=2 ? v : info2[v][1][10]) + x:=minX+ini.zx, y:=minY1+ini.zy, w:=sx1-minX, h:=maxY1-minY1 , arr.Push({1:x, 2:y, 3:w, 4:h, x:x+w//2, y:y+h//2, id:comment}) - if (index>1 or !FindAll) + if (index>1 || !FindAll) return 1 } } + return 0 } -PicFind(ini, j, dir, ByRef allpos, sx, sy, sw, sh) +PicFind(ini, j, dir, sx, sy, sw, sh, allpos_ptr) { local static MyFunc:="" if (!MyFunc) { - x32:="" - . "5557565383EC6C83BC2480000000058BBC24C00000000F84E60800008BAC24C4" - . "00000085ED0F8ECE0D0000C744240400000000C74424140000000031EDC74424" - . "0800000000C7442418000000008D76008B8424BC0000008B4C241831F631DB01" - . "C885FF894424107F3DE99100000066900FAF8424A800000089C189F099F7FF01" - . "C18B442410803C1831744D8B8424B800000083C30103B424D8000000890CA883" - . "C50139DF74558B44240499F7BC24C400000083BC24800000000375B40FAF8424" - . "9400000089C189F099F7FF8D0C818B442410803C183175B38B4424088B9424B4" - . "00000083C30103B424D8000000890C8283C00139DF8944240875AB017C241883" - . "442414018B9C24DC0000008B442414015C2404398424C40000000F8530FFFFFF" - . "896C241031C08B74240839B424C80000008B5C24100F4DF0399C24CC00000089" - . "7424080F4CC339C6894424100F4DC683BC248000000003894424040F846C0800" - . "008BAC24940000008B8424A00000000FAFAC24A40000008BB42494000000C1E0" - . "028944243801C58B8424A8000000896C2434F7D88D0486894424248B84248000" - . "000085C00F858A0300008B842484000000C744242000000000C7442428000000" - . "00C1E8100FB6E88B8424840000000FB6C4894424140FB6842484000000894424" - . "188B8424A8000000C1E002894424308B8424AC00000085C00F8EC60000008B7C" - . "240C8B442434896C241C8BAC24A800000085ED0F8E8D0000008BB42490000000" - . "8B6C242803AC24B000000001C6034424308944242C038424900000008944240C" - . "0FB67E028B4C241C0FB6160FB646012B5424182B44241489FB01CF29CB8D8F00" - . "0400000FAFC00FAFCBC1E00B0FAFCBBBFE05000029FB0FAFDA01C10FAFD301CA" - . "399424880000000F93450083C60483C5013B74240C75A98B9C24A8000000015C" - . "24288B44242C8344242001034424248B74242039B424AC0000000F854AFFFFFF" - . "897C240C8B8424A80000002B8424D8000000C644244F00C644244E00C7442454" - . "00000000C744246000000000894424588B8424AC0000002B8424DC0000008944" - . "243C8B84248C00000083E80183F8070F87D005000083F803894424440F8ECB05" - . "00008B4424608B74245489442454897424608B742458397424540F8FCE0A0000" - . "8B4424588B742408C7442430000000008944245C8B8424B40000008D04B08B74" - . "24448944245089F083E0018944244889F08BB4249000000083E003894424648B" - . "4424608B7C243C39F80F8F7F010000837C2464018B5C24540F4F5C245C897C24" - . "2C89442420895C24408DB426000000008B7C24488B44242C85FF0F4444242083" - . "7C244403894424240F8FD5020000807C244E008B442440894424288B4424280F" - . "85DD020000807C244F000F85800300000FAF8424A80000008B5424048B5C2424" - . "85D28D2C180F8E840000008BBC24CC0000008B9424B000000031C08B9C24C800" - . "0000896C24348B4C24088974241C01EA897C24188B6C24048B7C2410895C2414" - . "39C17E1C8B9C24B40000008B348301D6803E00750B836C2414010F8860040000" - . "39C77E1C8B9C24B80000008B348301D6803E00740B836C2418010F8840040000" - . "83C00139E875B98B6C24348B74241C8B44240885C074278BBC24B00000008B84" - . "24B40000008B5C24508D0C2F8D7426008B1083C00401CA39D8C6020075F28B44" - . "2424038424A00000008B5C24308BBC24D00000008904DF8B442428038424A400" - . "00008944DF0483C3013B9C24D4000000895C24307D308344242001836C242C01" - . "8B4424203944243C0F8DA2FEFFFF8344245401836C245C018B44245439442458" - . "0F8D59FEFFFF8B44243083C46C5B5E5F5DC2600083BC2480000000010F84E007" - . "000083BC2480000000020F843B0500008B8424840000000FB6BC2484000000C7" - . "44242C00000000C744243000000000C1E8100FB6D08B84248400000089D50FB6" - . "DC8B842488000000C1E8100FB6C88B84248800000029CD01D1896C243C89DD89" - . "4C24140FB6F40FB684248800000029F501DE896C241889FD8974241C29C501F8" - . "894424288B8424A8000000896C2420C1E002894424388B8424AC00000085C00F" - . "8EDFFCFFFF8B4C24348B6C243C8B8424A800000085C00F8E880000008B842490" - . "0000008B542430039424B000000001C8034C243889CF894C243403BC24900000" - . "00EB34395C24147C3D394C24187F37394C241C7C3189F30FB6F3397424200F9E" - . "C3397424280F9DC183C00483C20121D9884AFF39C7741E0FB658020FB648010F" - . "B63039DD7EBD31C983C00483C201884AFF39C775E28BB424A800000001742430" - . "8B4C24348344242C01034C24248B44242C398424AC0000000F854FFFFFFFE921" - . "FCFFFF8B442424807C244E00894424288B442440894424248B4424280F8423FD" - . "FFFF0FAF8424940000008B5C24248D2C988B5C240485DB0F8EE1FDFFFF8BBC24" - . "C800000031C9896C24148DB6000000008B8424B40000008B5C2414031C888B84" - . "24B80000008B2C880FB6441E0289EAC1EA100FB6D229D00FB6541E010FB61C1E" - . "0FAFC03B44240C7F2789E80FB6C429C20FAFD23B54240C7F1789E80FB6C029C3" - . "0FAFDB3B5C240C7E108DB4260000000083EF010F887701000083C1013B4C2404" - . "758E89AC2484000000E950FDFFFF66900FAF8424940000008B7C24248B4C2404" - . "8D04B8894424140384248400000085C90FB65C06010FB67C06020FB60406895C" - . "24188944241C0F8E12FDFFFF8B8424CC00000031DB894424388B8424C8000000" - . "894424348B44240C897C240C8D742600395C24087E658B8424B40000008B4C24" - . "148B7C240C030C980FB6440E020FB6540E010FB60C0E2B5424182B4C241C89C5" - . "01F829FD8DB8000400000FAFD20FAFFDC1E20B0FAFFDBDFE05000029C50FAFE9" - . "01FA0FAFCD01D1398C2488000000730B836C2434010F88A1000000395C24107E" - . "618B8424B80000008B4C24148B7C240C030C980FB6440E020FB6540E010FB60C" - . "0E2B5424182B4C241C89C501F829FD8DB8000400000FAFD20FAFFDC1E20B0FAF" - . "FDBDFE05000029C50FAFE901FA0FAFCD01D1398C24880000007207836C243801" - . "783A83C3013B5C24040F8521FFFFFF8944240CE906FCFFFF908DB42600000000" - . "8B74241CE92DFCFFFF8DB4260000000089AC2484000000E91AFCFFFF8944240C" - . "E911FCFFFFC7442444000000008B44243C8B742458894424588974243CE930FA" - . "FFFF8B8424880000008BB424BC00000031C931DB31ED89BC24C0000000894424" - . "048B8424840000000FAFC08944240CEB1AB80A0000006BDB0AF7E189F901DA89" - . "FBC1FB1F01C111D383C6010FBE0685C00F84B80000008D78D083FF0976D383F8" - . "2F75E58D04AD000000008944241489C80FACD8100FB7C00FAF8424DC00000099" - . "F7BC24C40000000FAF84249400000089C70FB7C131C90FAF8424D800000099F7" - . "BC24C00000008B9424B40000008D04878B7C24148904AA89D88B9C24B8000000" - . "83C50189043B31DBE97BFFFFFF8B842484000000C1E8100FAF8424DC00000099" - . "F7BC24C40000000FAF84249400000089C10FB78424840000000FAF8424D80000" - . "0099F7FF8D04818984248400000083BC2480000000058B8424A80000000F9444" - . "244E83BC2480000000030F9444244F038424A00000002B8424D8000000894424" - . "588B8424A4000000038424AC0000002B8424DC0000008944243C8B8424A40000" - . "00C78424A400000000000000894424548B8424A0000000C78424A00000000000" - . "000089442460E977F8FFFF8B8424A8000000038424A00000008BAC24A8000000" - . "8BB424A40000000FAFAC24AC000000894424208B8424A400000083EE01038424" - . "AC00000003AC24B00000008974241439F0896C241C0F8C0E0100008BB424A000" - . "000083C001C7442428000000008944242C8B8424800000002B8424A000000083" - . "EE01897424308B7424140FAFB4249400000089C7897424248B74242001F78D6E" - . "01897C24348B442430394424200F8C980000008B7C24148B5C24248B74242803" - . "5C24382BB424A0000000039C2490000000C1EF1F0374241C897C2418EB4D6690" - . "398424980000007E4B807C24180075448B7C241439BC249C0000007E370FB64B" - . "FE0FB653FD83C3040FB67BF86BD24B6BC92601D189FAC1E20429FA01CAC1FA07" - . "8854060183C00139E8741889C2C1EA1F84D274ACC64406010083C00183C30439" - . "E875E88B7424340174242883442414018BBC24940000008B442414017C242439" - . "44242C0F853CFFFFFF8B8424A80000008B8C24AC00000083C00285C989442420" - . "0F8EBEF6FFFF8B8424AC0000008B6C241C036C2420C744241C01000000C74424" - . "240000000083C001894424288B8424A8000000896C241883C0048944242C8B84" - . "24880000008B9424A800000085D20F8EA70000008B4424188B5C24248B74242C" - . "039C24B000000089C12B8C24A800000089C201C6894C2414908DB42600000000" - . "0FB642010FB62ABF010000000384248400000039E8723D0FB66A0239E872358B" - . "4C24140FB669FF39E872290FB66EFF39E872210FB669FE39E872190FB62939E8" - . "72120FB66EFE39E8720A0FB63E39F80F92C189CF89F9834424140183C201880B" - . "83C60183C3018B7C2414397C241875908BBC24A8000000017C24248344241C01" - . "8B5C24208B74241C015C2418397424280F852FFFFFFF89842488000000E9A2F5" - . "FFFF8B8424840000008BB424AC000000C744241400000000C744241800000000" - . "83C001C1E007898424840000008B8424A8000000C1E00285F68944241C0F8E61" - . "F5FFFF8B4424348BAC24840000008B9C24A800000085DB7E618B8C2490000000" - . "8B5C2418039C24B000000001C10344241C894424200384249000000089C76690" - . "0FB651020FB641010FB6316BC04B6BD22601C289F0C1E00429F001D039C50F97" - . "0383C10483C30139F975D58BBC24A8000000017C24188B442420834424140103" - . "4424248B74241439B424AC0000000F857AFFFFFFE9CBF4FFFFC7442410000000" - . "00C744240800000000E916F3FFFFC744243000000000E90BF7FFFF9090909090" - x64:="" - . "4157415641554154555756534881EC88000000488BBC24F0000000488BB42430" - . "01000083F905898C24D000000089542468448944240444898C24E80000004C8B" - . "AC2438010000488B9C2440010000448B942450010000448B9C24580100000F84" - . "5909000031ED4531E44585DB0F8E1901000044897424104C89AC243801000031" - . "C0448BBC2420010000448BAC24D000000031ED448BB424800100004889B42430" - . "0100004531E4C744240800000000C74424380000000089C64889BC24F0000000" - . "48637C24384531C94531C04803BC24480100004585D27F33EB7B660F1F440000" - . "410FAFC789C14489C89941F7FA01C142803C0731743C4983C0014863C54501F1" - . "83C5014539C2890C837E4589F09941F7FB4183FD0375C90FAF8424F800000089" - . "C14489C89941F7FA42803C07318D0C8175C4488B9424380100004983C0014963" - . "C44501F14183C4014539C2890C827FBB4401542438834424080103B424880100" - . "008B4424084139C30F8552FFFFFF448B742410488BBC24F0000000488BB42430" - . "0100004C8BAC243801000031C04439A42460010000440F4DE039AC2468010000" - . "0F4DE84139EC4189EF450F4DFC83BC24D0000000030F849A0800008B8424F800" - . "00008B8C24100100000FAF8424180100008D04888B8C24F8000000894424208B" - . "842420010000F7D88D0481894424088B8424D000000085C00F859E0300008B4C" - . "24684889C84189CB0FB6C441C1EB1089C20FB6C1450FB6DB4189C28B84242801" - . "000085C00F8E300100008B842420010000448964242831C94889B42430010000" - . "4C89AC2438010000448B6424048BB42420010000448B6C2420C1E00244897C24" - . "18896C24304889BC24F00000004489D5C744243800000000894424104189CF89" - . "D748899C244001000085F60F8E84000000488B9C24F00000004963C54531D24C" - . "8D4C030248635C243848039C2430010000450FB631410FB651FE410FB641FF29" - . "EA4489F14501DE4189D0418D96000400004429D929F80FAFD10FAFC00FAFD1C1" - . "E00B8D0402BAFE0500004429F2410FAFD0410FAFD001D04139C4420F93041349" - . "83C2014983C1044439D67FA544036C2410017424384183C70144036C24084439" - . "BC24280100000F855DFFFFFF448B7C2418448B6424288B6C2430488BBC24F000" - . "0000488BB424300100004C8BAC2438010000488B9C24400100008B8424200100" - . "002B842480010000C644245700C644245600C744246C00000000C74424780000" - . "0000894424708B8424280100002B842488010000894424448B8424E800000083" - . "E80183F8070F87F505000083F8038944244C0F8EF00500008B4424788B4C246C" - . "8944246C894C24788B4C2470394C246C0F8F600B00008B4424708B4C244C4889" - . "9C24400100004889F34C89EEC74424300000000089442474418D4424FF498D44" - . "85044589E54C8BA42440010000488944246089C883E0018944245089C883E003" - . "8944247C8B4424788B4C244439C80F8F38010000837C247C018B54246C0F4F54" - . "2474894C2428894424088954244866908B44245085C08B4424280F4444240883" - . "7C244C03894424380F8FD2020000807C2456008B442448894424100F85DA0200" - . "00807C2457000F85740300008B4C24100FAF8C2420010000034C24384585FF7E" - . "50448B942468010000448B8C246001000031C04139C589C27E184189C8440304" - . "8642803C0300750A4183E9010F888200000039D57E1289CA41031484803C1300" - . "74064183EA01786C4883C0014139C77FC24585ED741B4C8B4424604889F06690" - . "89CA03104883C0044C39C0C604130075EF8B4C24308B54243803942410010000" - . "4C8B94247001000089C801C04898418914828B54241003942418010000418954" - . "820489C883C0013B842478010000894424307D308344240801836C2428018B44" - . "2408394424440F8DE4FEFFFF8344246C01836C2474018B44246C394424700F8D" - . "A0FEFFFF8B4424304881C4880000005B5E5F5D415C415D415E415FC383BC24D0" - . "000000010F84AC08000083BC24D0000000020F84520500008B542468448B5424" - . "04C744241000000000C74424180000000089D0440FB6C2C1E810440FB6C84889" - . "D00FB6CC4489D04589CBC1E810894C24380FB6D04C89D00FB6C44129D34401CA" - . "89C18B44243829C8034C243889442430410FB6C24589C24129C24401C0448B84" - . "2428010000894424388B842420010000C1E0024585C0894424280F8E1AFDFFFF" - . "448974243C896C24484C89AC2438010000448B7424208BAC2420010000448B6C" - . "243044897C244044896424444189CF48899C24400100004189D44489D385ED7E" - . "724C635424184963C631D2488D4407024901F2EB314539C47C3E4139CD7F3941" - . "39CF7C344439CB410F9EC044394C24380F9DC14883C0044421C141880C124883" - . "C20139D57E24440FB6000FB648FF440FB648FE4539C37EBD31C94883C0044188" - . "0C124883C20139D57FDC4403742428016C2418834424100144037424088B4424" - . "10398424280100000F856FFFFFFF448B74243C448B7C2440448B6424448B6C24" - . "484C8BAC2438010000488B9C2440010000E924FCFFFF662E0F1F840000000000" - . "8B442438807C245600894424108B442448894424380F8426FDFFFF8B4424108B" - . "4C24380FAF8424F80000004585FF448D14880F8E99FDFFFF448B8C2460010000" - . "4531C04989DB662E0F1F840000000000428B1486438B1C844401D289D98D4202" - . "C1E9100FB6C948980FB6040729C88D4A014863D20FAFC00FB614174863C90FB6" - . "0C0F4439F07F1A0FB6C729C10FAFC94439F17F0D0FB6C329C20FAFD24439F27E" - . "0A4183E9010F88950100004983C0014539C77F9C895C24684C89DBE911FDFFFF" - . "8B4424108B4C24380FAF8424F80000008D048889C1034424684585FF8D500248" - . "63D2440FB614178D500148980FB604074863D20FB614170F8ED4FCFFFF448B9C" - . "246801000048895C24584531C948897424184C8964242089CB89C64189D44489" - . "5C2440448B9C246001000044895C243C4539CD4589C87E6E488B442418428B14" - . "8801DA8D42024898440FB634078D42014863D20FB6141748980FB604074589F3" - . "4501D6418D8E000400004529D329F2410FAFCB4429E00FAFC0410FAFCB41BBFE" - . "050000C1E00B4529F3440FAFDA01C8410FAFD301C239542404730B836C243C01" - . "0F88A60000004439C57E6A488B442420428B148801DA8D42024898440FB63407" - . "8D42014863D20FB6141748980FB604074589F04501D6418D8E000400004529D0" - . "29F2410FAFC84429E00FAFC0410FAFC841B8FE050000C1E00B4529F0440FAFC2" - . "01C8410FAFD001C2395424047207836C24400178374983C1014539CF0F8F0EFF" - . "FFFF488B5C2458488B7424184C8B642420E99BFBFFFF662E0F1F840000000000" - . "895C24684C89DBE9C8FBFFFF488B5C2458488B7424184C8B642420E9B4FBFFFF" - . "C744244C000000008B4424448B4C247089442470894C2444E90BFAFFFF8B4424" - . "68448B7C24044531C04C8B8C244801000031C94189C6440FAFF0EB0F4B8D0480" - . "4863D24C8D04424983C101410FBE0185C00F84960000008D50D083FA0976DD83" - . "F82F75E34C89C048C1E8100FB7C00FAF8424880100009941F7FB0FAF8424F800" - . "000089442408410FB7C049C1E8200FAF8424800100009941F7FA8B5424088D04" - . "824863D183C1014189449500448904934531C0EB92448B4C24684489C8C1E810" - . "0FAF8424880100009941F7FB0FAF8424F800000089C1410FB7C10FAF84248001" - . "00009941F7FA8D04818944246883BC24D0000000058B8424200100000F944424" - . "5683BC24D0000000030F94442457038424100100002B84248001000089442470" - . "8B842418010000038424280100002B842488010000894424448B842418010000" - . "C7842418010000000000008944246C8B842410010000C7842410010000000000" - . "0089442478E98EF8FFFF8B8424200100008B8C24180100000FAF842428010000" - . "83E90189CA48984801F048894424088B84242001000003842410010000894424" - . "388B8424180100000384242801000039C80F8C750100008B8C241001000083C0" - . "0148899C244001000089442420C74424180000000089D3448974244444897C24" - . "4883E901448964244C4889B424300100004189CA894C243C8B8C24F800000042" - . "8D0495000000000FAFCA89442430489848894424288B8424D00000002B842410" - . "010000894C24108B4C24384189C3448D51014101CB44895C2440448B9C240001" - . "00008B44243C394424380F8CA50000008B4C24108B5424304189DE488B742428" - . "4C6344241841C1EE1F4C0344240801CA4C63F94863D24C8D0C174829D6EB5190" - . "4139C37E544584F6754F399C24080100007E46410FB64902410FB6510183C001" - . "4983C0016BD24B6BC92601D14A8D140E4983C104460FB6243A4489E2C1E20444" - . "29E201D1C1F907418848FF4139C2741D89C2C1EA1F84D274A783C00141C60000" - . "4983C1044983C0014139C275E38B7424400174241883C3018BB424F800000001" - . "742410395C24200F8535FFFFFF448B742444448B7C2448448B64244C488BB424" - . "30010000488B9C24400100008B842420010000448B94242801000083C0024585" - . "D20F8E73F6FFFF488B4C2408489844897C24404889442410448B7C246848899C" - . "2440010000C744240801000000488D440101C744243800000000448974243C48" - . "89C18B8424280100004889CB83C001894424184863842420010000488D500348" - . "F7D048894424288B84242001000048895424208B54240483E8014883C0014889" - . "442430448B8C24200100004585C90F8EAF000000488B44242048634C24384C8D" - . "0C18488B4424284801F14C8D0418488B4424304C8D34184889D8660F1F440000" - . "0FB610440FB650FF41BB010000004401FA4439D2724A440FB650014439D27240" - . "450FB650FF4439D27236450FB651FF4439D2722C450FB650FE4439D27222450F" - . "B6104439D27219450FB651FE4439D2720F450FB6114439D2410F92C30F1F4000" - . "4883C0014488194983C1014883C1014983C0014C39F075888B8C242001000001" - . "4C2438834424080148035C24108B442408394424180F8528FFFFFF448B74243C" - . "448B7C244089542404488B9C2440010000E904F5FFFF8B4424684531DBC74424" - . "380000000083C001C1E007894424688B842420010000C1E002894424108B8424" - . "2801000085C00F8ECEF4FFFF44897C242848899C2440010000448B7C2468448B" - . "9424200100008B5C242044897424184585D27E594C637424384863C34531C048" - . "8D4C07024901F6660F1F8400000000000FB6110FB641FF440FB649FE6BC04B6B" - . "D22601C24489C8C1E0044429C801D04139C7430F9704064983C0014883C10445" - . "39C27FCC035C241044015424384183C301035C240844399C2428010000759044" - . "8B742418448B7C2428488B9C2440010000E924F4FFFFC744243000000000E941" - . "F6FFFF90909090909090909090909090" + x32:="VVdWU4PEgIO8JJQAAAAFi6wkzAAAAA+EoAoAAIu8JNAAAACF/w+O7RAAAMcEJAAA" + . "AADHRCQQAAAAADH/x0QkHAAAAADHRCQUAAAAAIuEJMgAAACLTCQUMfYx2wHIhe2J" + . "RCQMf0HplAAAAI22AAAAAA+vhCS0AAAAicGJ8Jn3/QHBi0QkDIA8GDF0TIuEJMQA" + . "AACDwwEDtCTkAAAAiQy4g8cBOd10VIsEJJn3vCTQAAAAg7wklAAAAAR1tQ+vhCSo" + . "AAAAicGJ8Jn3/Y0MgYtEJAyAPBgxdbSLRCQci5QkwAAAAIPDAQO0JOQAAACJDIKD" + . "wAE53YlEJBx1rAFsJBSDRCQQAYuMJOgAAACLRCQQAQwkOYQk0AAAAA+FLv///4tM" + . "JBy7rYvbaIl8JCQPr4wk1AAAAInIwfkf9+vB+gwpyouMJNgAAACJVCQYD6/PicjB" + . "+R/368H6DCnKiVQkKIO8JJQAAAAED4RNCgAAi4QkqAAAAIu0JKwAAAAPr4QksAAA" + . "AIuMJKgAAACNPLCLhCS0AAAA99iNBIGJRCQwi4QklAAAAIXAD4VWAwAAi4QkmAAA" + . "AIusJLgAAADHRCQsAAAAAMdEJDQAAAAAwegQD7bAiUQkDIuEJJgAAAAPtsSJRCQQ" + . "D7aEJJgAAACJRCQUi4QktAAAAMHgAoXtiUQkPA+OvQAAAIu0JLQAAACF9g+OlAAA" + . "AIu0JKQAAACLbCQ0A6wkvAAAAAH+A3wkPIl8JDgDvCSkAAAAiTwkifaNvCcAAAAA" + . "D7ZOAotcJAwPtkYBD7YWK0QkECtUJBSJzwHZKd+NmQAEAAAPr8APr9/B4AsPr98B" + . "w7j+BQAAKcgPr8IPr9AB0zmcJJwAAAAPk0UAg8YEg8UBOzQkdaqLjCS0AAAAAUwk" + . "NIt8JDiDRCQsAQN8JDCLRCQsOYQkuAAAAA+FQ////4tEJBiJRCREi0QkKIlEJFyL" + . "dCQci0wkRDHAOc6LTCRcD07wiXQkHIt0JCQ5zg9PxolEJCSLdCQki0QkHDnGD03G" + . "iUQkFIuEJJQAAACD6ASD+AEPhnQHAADHRCRkAAAAAMdEJHAAAAAAi0QkcAOEJLQA" + . "AAArhCTkAAAAiUQkdItEJGQDhCS4AAAAK4Qk6AAAAIlEJEyLhCSgAAAAg+gBg/gH" + . "D4fpBgAAg/gDiUQkVA+O5AYAAIt0JGSLRCRwiXQkcIlEJGSLdCR0OXQkZA+P5AYA" + . "AItEJHSLTCQci3QkVMdEJDwAAAAAiUQkeIuEJMAAAACNBIiJRCRgifCD4AGJRCRY" + . "ifCD4AOJRCR8i0QkcIt0JEw58A+PAQEAAIN8JHwBi0wkZA9PTCR4iXQkQIlEJCyJ" + . "TCRQi0QkWIXAi0QkQA9ERCQsg3wkVAOJRCQ0D49PAgAAg7wklAAAAAWLRCRQiUQk" + . "OItEJDgPhFcCAACDvCSUAAAABA+EKwQAAA+vhCS0AAAAi0wkFIt0JDSFyY0sMA+E" + . "4AMAAIt0JFyLXCREMcCLlCS8AAAAiWwkEItMJByLfCQkiRwkiXQkDAHqi2wkFOsL" + . "g8ABOcUPhKUDAAA5yH0Xi5wkwAAAAIs0gwHWgD4AdQaDLCQBeBw5x37Wi5wkxAAA" + . "AIs0gwHWgD4BdcWDbCQMAXm+g0QkLAGDbCRAAYtEJCw5RCRMD40Z////g0QkZAGD" + . "bCR4AYtEJGQ5RCR0D43X/v//i0QkPIPsgFteX13CWACDvCSUAAAAAQ+EQgsAAIO8" + . "JJQAAAACD4QtCQAAi4QkmAAAAA+2jCScAAAAx0QkFAAAAADHRCQsAAAAAMHoEA+2" + . "wIkEJIuEJJgAAAAPtsSJRCQMD7aEJJgAAACJRCQQi4QknAAAAMHoEA+26IuEJJwA" + . "AACJ7g+v9Q+2xIl0JCCJxg+v8InID6/BiXQkCIlEJASLhCS0AAAAweACiUQkNIuE" + . "JLgAAACFwA+OEv3//4uEJLQAAACFwA+OfgAAAIuUJKQAAACLXCQsA5wkvAAAAAH6" + . "A3wkNIl8JDgDvCSkAAAAif0PtkICMf8PtkoBKwQkD7YyD6/AOUQkIHwiK0wkDA+v" + . "yTlMJAh8FYnwD7bwK3QkEA+v9jl0JAQPncCJx4n4g8IEg8MBiEP/Oep1touMJLQA" + . "AAABTCQsi3wkOINEJBQBA3wkMItEJBQ5hCS4AAAAD4VZ////6Wb8//+NtCYAAAAA" + . "i0QkNIO8JJQAAAAFiUQkOItEJFCJRCQ0i0QkOA+Fqf3//w+vhCSoAAAAi0wkNIts" + . "JGiF7Y0EiIlEJDAPhQUDAACLRCRsi3wkFMdEJBgAAAAAiUQkKItEJESF/4lEJEgP" + . "hBsBAACLfCQgjbQmAAAAAItMJBiLtCTAAAAAi0QkMAMEjou0JMQAAACNFImNHJGL" + . "VCQoizSOi4wkpAAAAIkUJIm0JJwAAACLtCSkAAAAD7Z0BgKJdCQMi7QkpAAAAA+2" + . "dAYBD7YEAYl0JBCJRCQgid7reYsEJIPGAosIi1gEiciJ38HoEMHvEA+2wCtEJAyJ" + . "+g+2+g+21w+224n9iVwkBDHbD6/viVQkCA+vwDnofysPtsUrRCQQidUPr+oPr8A5" + . "6H8Yi1QkBA+2wStEJCCJ0w+v2g+vwDnYD57DgwQkCIH5////AA+XwDjYdRg5tCSc" + . "AAAAD4d6////g2wkSAEPiIICAACDRCQYAYNEJChUi0QkGDlEJBQPhfT+//+JfCQg" + . "i4Qk3AAAAINEJDwBi0wkPIXAD4TK/P//i1QkOAOUJLAAAACLRCQ0A4QkrAAAAIu0" + . "JNwAAADB4hAJ0DuMJOAAAACJRI78D4yX/P//6cL8//+LbCQQi1QkHIXSdKSLtCS8" + . "AAAAi4QkwAAAAItcJGCNDC6LEIPABAHKOdjGAgB18ul8////D6+EJKgAAACLdCQ0" + . "i1wkFI0EsIu0JKQAAACJBCQDhCSYAAAAhduJ8Q+2bAYCD7Z0BgEPtgQBiXQkDIlE" + . "JBAPhDj///+LRCRcMduJbCQYiUQkMItEJESJRCQoZpA7XCQcfWSLhCTAAAAAixQk" + . "i3wkGAMUmA+2dBECD7ZEEQErRCQMD7YUEStUJBCJ9QH+Kf2NvgAEAAAPr8APr/3B" + . "4AsPr/0Bx7j+BQAAKfAPr8IPr9AB1zu8JJwAAAB2C4NsJCgBD4iY+///OVwkJH5k" + . "i4QkxAAAAIsUJIt8JBgDFJgPtnQRAg+2RBEBK0QkDA+2FBErVCQQifUB/in9jb4A" + . "BAAAD6/AD6/9weALD6/9Ace4/gUAACnwD6/CD6/QAdc7vCScAAAAdwuDbCQwAQ+I" + . "Lvv//4PDATlcJBQPhR/////pOv7//4t0JBSF9g+ELv7//4t0JESLnCSkAAAAMdKQ" + . "i4QkwAAAAIt8JDADPJCLhCTEAAAAiyyQD7ZEOwKJ6cHpEA+2ySnID7ZMOwEPtjw7" + . "D6/AO0QkIH8niegPtsQpwQ+vyTtMJAh/F4n4D7b4iegPtsApxw+v/zt8JAR+B2aQ" + . "g+4BeBWDwgE5VCQUdZKJrCSYAAAA6ab9//+JrCSYAAAA6Xz6//+JfCQg6XP6///H" + . "RCRUAAAAAIt0JHSLRCRMiXQkTIlEJHSLdCR0OXQkZA+OHPn//8dEJDwAAAAAi0Qk" + . "PIPsgFteX13CWACLhCSwAAAAx4QksAAAAAAAAACJRCRki4QkrAAAAMeEJKwAAAAA" + . "AAAAiUQkcOlr+P//i7QkmAAAADHAhfYPlcCJRCRoD4U6AQAAi5wknAAAAIXbD4R/" + . "BgAAi7QknAAAAIu8JMAAAACLnCTEAAAAjQS3MfaJBCSLhCTIAAAAMdKDxwSDwwSL" + . "BLCJhCSYAAAAwegE9/UPr4Qk6AAAAIlUJAyZ97wk0AAAAA+vhCSoAAAAicGLRCQM" + . "D6+EJOQAAACZ9/2NBIGJR/yLhCSYAAAAg+APjQRGg8YViUP8OzwkdZeLhCScAAAA" + . "i4wk1AAAALqti9toD6/IiUQkHInIwfkf9+qJ0MH4DCnIi7QkyAAAAIlEJETHRCRc" + . "AAAAAMdEJCQAAAAAg8YEiXQkbOkX9///i4QkmAAAAMHoEA+vhCToAAAAmfe8JNAA" + . "AAAPr4QkqAAAAInBD7eEJJgAAAAPr4Qk5AAAAJn3/Y0EgYmEJJgAAACLRCQYiUQk" + . "RItEJCiJRCRc6cH2//+LhCTQAAAAi7QkyAAAAA+2lCSYAAAAD6/FjQSGiUQkbIuE" + . "JJgAAADB6BAPtsiLhCSYAAAAic4Pr/GLjCTQAAAAD7bEiXQkIInGD6/widAPr8KF" + . "yYl0JAiJRCQED47OBAAAi3QkbI0ErQAAAACJrCTMAAAAi5wkmAAAAIu8JJwAAACL" + . "bCQgiUQkNDHAx0QkLAAAAADHRCQwAAAAAMdEJBwAAAAAiTQki5QkzAAAAIXSD44a" + . "AQAAi4wkyAAAAIs0JMdEJBQAAAAAiVwkKAHBA0QkNIlMJBCJRCQ4A4QkyAAAAIlE" + . "JCSLRCQQhf8PtlABD7ZIAg+2AIkUJIlEJAx0RjHSZpCLHJaJ2MHoEA+2wCnID6/A" + . "OcV8Iw+2xysEJA+vwDlEJAh8FA+2wytEJAwPr8A5RCQED435AAAAg8IBOfp1wolc" + . "JCiLRCQcweEQweACiUQkGItEJCyZ97wk0AAAAA+vhCSoAAAAicOLRCQUmfe8JMwA" + . "AACLVCQcjQSDi5wkwAAAAIkEk4sEJIPCAYucJMQAAACJVCQcweAICcELTCQMi0Qk" + . "GIkMA4NEJBAEi5Qk5AAAAItEJBABVCQUO0QkJA+FIP///4tcJCiLRCQ4iTQkg0Qk" + . "MAGLtCToAAAAi0wkMAF0JCw5jCTQAAAAD4W2/v//i0wkHLqti9toiZwkmAAAAA+v" + . "jCTUAAAAx0QkXAAAAADHRCQkAAAAAInIwfkf9+rB+gwpyolUJETplPT//5CNdCYA" + . "iVwkKOlr////i4wktAAAAIuEJLwAAAAx7YuUJLgAAADHBCQAAAAAjQRIiUQkNInI" + . "weAChdKJRCQMD45A9P//i4QktAAAAIXAfleLjCSkAAAAi0QkNAH5A3wkDI0cKIl8" + . "JBADvCSkAAAAD7ZRAg+2QQGDwQQPtnH8g8MBa8BLa9ImAcKJ8MHgBCnwAdDB+AeI" + . "Q/85+XXTA6wktAAAAIt8JBCDBCQBA3wkMIsEJDmEJLgAAAB1iouEJLQAAACLvCSc" + . "AAAAMfbHRCQMAAAAAIPoAYlEJCyLhCS4AAAAg+gBiUQkMIuEJLQAAACFwA+O7QAA" + . "AItEJAyLjCS0AAAAi6wkvAAAAIXAi0QkNA+URCQUAfGJTCQ4icONFDABy4nxK4wk" + . "tAAAAAHuiXQkEAHBMcCJDCTpkgAAAIB8JBQAD4WPAAAAOUQkLA+EhQAAAItMJAw5" + . "TCQwdHsPtjoPtmr/vgEAAAADvCSYAAAAOe9yPA+2agE573I0iwwkD7YpOe9yKg+2" + . "KznvciMPtmn/Oe9yGw+2aQE573ITD7Zr/znvcgsPtnMBOfcPksGJzotsJBCJ8YhM" + . "BQCDwAGDwgGDwwGDBCQBOYQktAAAAHQShcAPhWb///+LdCQQxgQGAuvYi3QkOINE" + . "JAwBi0QkDDmEJLgAAAAPhe7+//+LRCQYibwknAAAAIlEJESLRCQoiUQkXOl/8v//" + . "i4QkmAAAAIucJLgAAAAx7ccEJAAAAACDwAHB4AeJhCSYAAAAi4QktAAAAMHgAoXb" + . "iUQkDA+ONfL//4uMJLQAAACFyX5mi4wkpAAAAIucJLwAAACJbCQUAfkDfCQMAeuL" + . "rCSYAAAAiXwkEAO8JKQAAAAPtlECD7ZBAQ+2MWvAS2vSJgHCifDB4AQp8AHCOdUP" + . "lwODwQSDwwE5+XXVi2wkFAOsJLQAAACLfCQQgwQkAQN8JDCLBCQ5hCS4AAAAD4V3" + . "////6afx///HRCQoAAAAAMdEJBgAAAAAx0QkJAAAAADHRCQcAAAAAOkg8P//x0Qk" + . "RAAAAADHRCQcAAAAAMdEJFwAAAAAx0QkJAAAAADpkfH//zHAx0QkHAAAAADpIPr/" + . "/5CQkJCQkJCQkJCQkJCQkA==" + x64:="QVdBVkFVQVRVV1ZTSIHsuAAAAEiLtCQgAQAAi5wkcAEAAIP5BYmMJAABAACJ1UWJ" + . "xUSJjCQYAQAARIu8JHgBAAAPhDIMAABFhf8PjlASAABEiXQkEIl8JBgxwIu8JAAB" + . "AABEi6wkQAEAAEUx0kyLtCRgAQAAi6wkoAEAAEUx20SJZCQgx0QkCAAAAABBicTH" + . "RCQoAAAAAImUJAgBAABEiYQkEAEAAEiJtCQgAQAASGN0JChFMclFMcBIA7QkaAEA" + . "AIXbfzfrfWYPH4QAAAAAAEEPr8WJwUSJyJn3+wHBQoA8BjF0PUmDwAFJY8NBAelB" + . "g8MBRDnDQYkMhn5ERInQmUH3/4P/BHXID6+EJCgBAACJwUSJyJn3+0KAPAYxjQyB" + . "dcNIi5QkWAEAAEmDwAFJY8RBAelBg8QBRDnDiQyCf7wBXCQog0QkCAFEA5QkqAEA" + . "AItEJAhBOccPhVD///9EieFBuK2L22hEi3QkEA+vjCSAAQAARIlkJFSLrCQIAQAA" + . "RItkJCBEi6wkEAEAAEiLtCQgAQAAi3wkGESJXCQIicjB+R9B9+jB+gwpyouMJIgB" + . "AACJVCQQQQ+vy4nIwfkfQffowfoMKcqJVCQYg7wkAAEAAAQPhIMLAACLhCQoAQAA" + . "i5wkMAEAAA+vhCQ4AQAAjQSYi5wkKAEAAIlEJCiLhCRAAQAA99iNBIOLnCQAAQAA" + . "iUQkLIXbD4X6AwAAiehEi5wkSAEAAMHoEA+22EiJ6A+2xEWF24nBQA+2xYnCD44X" + . "BQAAi4QkQAEAAImsJAgBAABEi3wkKIusJEABAABEiXQkQESJZCRIQYnWweACx0Qk" + . "IAAAAADHRCQwAAAAAIlEJDiJfCRQQYnMhe0PjooAAABIY3wkMEljx0Ux20gDvCRQ" + . "AQAATI1UBgIPH4QAAAAAAEEPtlL+RQ+2CkEPtkL/RCnyRInJQYnQQo0UCynZRCng" + . "RI2KAAQAAA+vwEQPr8nB4AtED6/Juf4FAAAp0YnKQQ+v0EGNBAFBD6/QAdBBOcVC" + . "D5MEH0mDwwFJg8IERDndf59EA3wkOAFsJDCDRCQgAUQDfCQsi0QkIDmEJEgBAAAP" + . "hVP///+LRCQQRIt0JECLfCRQRItkJEiLrCQIAQAAiUQkWItEJBiJhCSAAAAAi1wk" + . "VItMJFgxwDnLi4wkgAAAAA9O2IlcJFSLXCQIOcsPT8OJRCQIi1wkCItEJFQ5ww9N" + . "w0GJw4uEJAABAACD6ASD+AEPhpsIAADHhCSMAAAAAAAAAMeEJKAAAAAAAAAAi4Qk" + . "oAAAAAOEJEABAAArhCSgAQAAiYQkpAAAAIuEJIwAAAADhCRIAQAAK4QkqAEAAIlE" + . "JGCLhCQYAQAAg+gBg/gHD4f+BwAAg/gDiUQkaA+O+QcAAIucJIwAAACLhCSgAAAA" + . "iZwkoAAAAImEJIwAAACLnCSkAAAAOZwkjAAAAA+P8wcAAIuEJKQAAABIi5wkWAEA" + . "AImsJAgBAABEieVFidxEibQkhAAAAMdEJEAAAAAARYnuiYQkqAAAAItEJFSJvCSI" + . "AAAAg+gBSI1EgwRIiUQkeEGNQ/9JifNIi7QkUAEAAEiNRIMEi1wkaEiJRCRIidiD" + . "4AGJRCRsidiD4AOJhCSsAAAAi4QkoAAAAIt8JGA5+A+PBQEAAIO8JKwAAAABi5wk" + . "jAAAAA9PnCSoAAAAiXwkUIlEJCCJXCRkDx+EAAAAAACLTCRsi0QkUIXJD0REJCCD" + . "fCRoA4lEJCwPj1QCAACDvCQAAQAABYtEJGSJRCQwD4RcAgAAg7wkAAEAAAQPhFQE" + . "AACLTCQwD6+MJEABAAADTCQsRYXkD4QJBAAARIuUJIAAAABEi0wkWDHARItEJFSL" + . "fCQITIusJFgBAABMi7wkYAEAAOsNSIPAAUE5xA+O0gMAAEE5wInCfhOJy0EDXIUA" + . "gDweAHUGQYPpAXgWOdd+1YnKQQMUh4A8FgF1yUGD6gF5w4NEJCABg2wkUAGLRCQg" + . "OUQkYA+NJv///4OEJIwAAAABg6wkqAAAAAGLhCSMAAAAOYQkpAAAAA+NxP7//4tE" + . "JEBIgcS4AAAAW15fXUFcQV1BXkFfw4O8JAABAAABD4S3CwAAg7wkAAEAAAIPhIcJ" + . "AABIiehEi4QkSAEAAEEPts0PtsSJ60GJzEGJw0APtsXB6xCJRCQgRInoD7bbwegQ" + . "x0QkMAAAAADHRCQ4AAAAAA+20EyJ6A+2xEGJ1onHD6/4i4QkQAEAAEQPr/JEjTyF" + . "AAAAAEQPr+FFhcAPjrkAAACJrCQIAQAAi6wkQAEAAESJrCQQAQAARYndhe1+b0hj" + . "RCQoTGNcJDhFMcBMA5wkUAEAAEiNVAYCDx+EAAAAAAAPtgJFMdIPtkr/RA+2Sv4p" + . "2A+vwEE5xnwaRCnpD6/JOc98EEQrTCQgRQ+vyUU5zEEPncJHiBQDSYPAAUiDwgRE" + . "OcV/vEQBfCQoAWwkOItUJCyDRCQwAQFUJCiLRCQwOYQkSAEAAA+Fb////4usJAgB" + . "AABEi6wkEAEAAItEJBCJRCRYi0QkGImEJIAAAADp6/v//4tEJCyDvCQAAQAABYlE" + . "JDCLRCRkiUQkLA+FpP3//4tEJDCLfCQsD6+EJCgBAACLlCSQAAAAhdKNBLiJRCQ4" + . "D4VVAwAARYXkD4RRAQAASIu8JGABAABIi4QkWAEAAESLrCSEAAAASIm0JJgAAADH" + . "RCQoAAAAAESJpCSUAAAASIl8JBBIi3wkcEiJxkiJfCQYi3wkWIl8JFyLvCSIAAAA" + . "i0QkOAMGSItcJBBEi0QkKEiLVCQYjUgBRIszRI1IAkiYSGPJTWPJRQ+2JANBD7Yc" + . "C0cPthQLQYnZ63QPH0QAAItKBIsaQYPAAkGJzYnYD7b9wegQQcHtEA+26UUPtu0P" + . "tsAxyUQp0EWJ7w+vwEUPr/1EOfh/KA+2x0GJ/0QpyA+vwEQPr/9EOfh/Ew+2w4np" + . "RCngD6/ND6/AOcgPnsFIg8IIgfv///8AD5fAOMh1EEU5xneMg2wkXAEPiBADAABI" + . "g8YESINEJBAEg0QkKBVIg0QkGFRIO3QkSA+FIf///0SLpCSUAAAASIu0JJgAAABE" + . "iawkhAAAAIm8JIgAAABmkINEJEABSIO8JJABAAAAi3wkQA+Emvz//4tEJDADhCQ4" + . "AQAASGPXi0wkLAOMJDABAABIi5wkkAEAAMHgEAnIO7wkmAEAAIlEk/wPjGP8///p" + . "mvz//4tEJFSFwHSkSIuEJFgBAABMi0QkeA8fgAAAAACJygMQSIPABEw5wMYEFgB1" + . "7+l6////i0QkMIt8JCwPr4QkKAEAAI0EuInBA4QkCAEAAEWF5I1QAkhj0kEPthwT" + . "jVABSJhBD7YEA0hj0kEPtjwTQYn9D4Q1////i7wkgAAAAIlsJBhFMcmJzUGJx0iJ" + . "dCQ4iXwkEIt8JFiJfCQoi3wkVEQ5z0WJyn5uSIuEJFgBAABCixSIAeqNQgJImEEP" + . "tgwDjUIBSGPSQQ+2FBNImEEPtgQDic4B2USNgQAEAAAp3kQp+kQPr8ZEKegPr8BE" + . "D6/GweALQQHAuP4FAAApyA+vwg+v0EEB0EU58HYLg2wkKAEPiEcBAABEOVQkCH5w" + . "SIuEJGABAABCixSIAeqNQgJImEEPtgwDjUIBSGPSQQ+2FBNImEEPtgQDQYnKAdlE" + . "jYEABAAAQSnaRCn6RQ+vwkQp6A+vwEUPr8LB4AtBAcC4/gUAACnID6/CD6/QQQHQ" + . "RTnwdwuDbCQQAQ+I0AAAAEmDwQFFOcwPjwb///+LbCQYSIt0JDjpBf7//0WF5A+E" + . "/P3//0SJdCQoRItMJFgxyUSLrCSEAAAAi7wkiAAAAESLVCQ4TIu0JFgBAABMi7wk" + . "YAEAAEGLFI5BixyPRAHSQYnYjUICQcHoEEUPtsBImEEPtgQDRCnARI1CAUhj0g+v" + . "wEEPthQTTWPARw+2BANEOeh/HQ+2x0EpwEUPr8BBOfh/Dg+2wynCD6/SOep+CGaQ" + . "QYPpAXgoSIPBAUE5zH+ViZwkCAEAAESLdCQo6VD9//+LbCQYSIt0JDjp9Pn//4mc" + . "JAgBAABEi3QkKOnj+f//RImsJIQAAACJvCSIAAAARIukJJQAAABIi7QkmAAAAOm/" + . "+f//x0QkaAAAAACLnCSkAAAAi0QkYIlcJGCJhCSkAAAAi5wkpAAAADmcJIwAAAAP" + . "jg34///HRCRAAAAAAOm8+f//i4QkOAEAAMeEJDgBAAAAAAAAiYQkjAAAAIuEJDAB" + . "AADHhCQwAQAAAAAAAImEJKAAAADpRPf//zHAhdIPlcCJhCSQAAAAD4UTAQAARTHJ" + . "RTHbRYXATIuUJGgBAAAPhEkGAABBiyox0kmDwlSJ6MHoBPfzD6+EJKgBAACJ0ZlB" + . "9/8Pr4QkKAEAAEGJwIuEJKABAAAPr8FIi4wkWAEAAJn3+0GNBIBCiQSJiehIi4wk" + . "YAEAAIPgD0GNBENBg8MVQokEiUmDwQFFOc13mIuMJIABAAC6rYvbaESJbCRUQQ+v" + . "zYnIwfkf9+qJ0MH4DCnISIucJGgBAACJRCRYx4QkgAAAAAAAAADHRCQIAAAAAEiD" + . "wwRIiVwkcOkB9v//iejB6BAPr4QkqAEAAJlB9/8Pr4QkKAEAAInBD7fFD6+EJKAB" + . "AACZ9/uNLIGLRCQQiUQkWItEJBiJhCSAAAAA6b31//+J2EEPr8fB4AJImEgDhCRo" + . "AQAASIlEJHCJ0A+20sHoEEGJ1A+2yEiJ6A+2xEGJzonHRA+v8Q+v+EQPr+JFhf8P" + . "juAEAACNQ/9Ii0wkcEGNUP/HRCQoAAAAAMdEJBAAAAAASI0EhQYAAADHRCQYAAAA" + . "AESJhCQQAQAATI1UkQQx0onpSIlEJCCNBJ0AAAAAQYnVSIm0JCABAACJnCRwAQAA" + . "iUQkLESJvCR4AQAAi7QkcAEAAIX2D47tAAAASGNEJBhIi7QkaAEAAEiNXAYCSANE" + . "JCBIAfAx9kiJRCQIDx9AAIusJBABAABED7YDRA+2S/9ED7Zb/oXtdEBIi1QkcGaQ" + . "iwqJyMHoEA+2wEQpwA+vwEE5xnwbD7bFRCnID6/AOcd8Dg+2wUQp2A+vwEE5xH1a" + . "SIPCBEw50nXHi0QkKE1j/UHB4BBBweEIQYPFAUUJyJlFCdj3vCR4AQAAD6+EJCgB" + . "AACJxYnwmfe8JHABAABIi5QkWAEAAI1EhQBCiQS6SIuEJGABAABGiQS4SIPDBAO0" + . "JKABAABIOVwkCA+FQP///4t0JCwBdCQYg0QkEAGLnCSoAQAAi0QkEAFcJCg5hCR4" + . "AQAAD4Xj/v//RIlsJFSJzYtMJFQPr4wkgAEAALqti9toRIusJBABAABIi7QkIAEA" + . "AMeEJIAAAAAAAAAAx0QkCAAAAACJyMH5H/fqwfoMKcqJVCRY6aTz//+LhCRAAQAA" + . "RIuMJEgBAABFMdsx2wHASJhIA4QkUAEAAEWFyUiJRCQwi4QkQAEAAESNPIUAAAAA" + . "D45k9///iXwkIIu8JEABAACF/35PSGNEJChMY9NMA1QkMEUxwEiNTAYCD7YRD7ZB" + . "/0iDwQRED7ZJ+mvAS2vSJgHCRInIweAERCnIAdDB+AdDiAQCSYPAAUQ5x3/NRAF8" + . "JCgB+0GDwwGLTCQsAUwkKEQ5nCRIAQAAdZdIY4QkQAEAALoBAAAASIm0JCABAACL" + . "tCRAAQAAi3wkIEUx28dEJCwAAAAASI1YAUgpwouEJEABAABIiVQkQEiJXCQ4g+gB" + . "iUQkKIuEJEgBAACD6AGJRCQghfYPjt8AAABMY0wkLEiLTCQ4RYXbSItEJDBMi5Qk" + . "UAEAAA+Uw06NBAlIi0wkQEqNVAgBTQHKSQHATAHJSAHBMcDpjgAAAITbD4WOAAAA" + . "OUQkKA+EhAAAAEQ5XCQgdH1ED7Zq/0QPtnr+QbkBAAAAQQHtRTn9ckVED7Y6RTn9" + . "cjxED7Z5/0U5/XIyRQ+2eP9FOf1yKEQPtnn+RTn9ch5ED7Y5RTn9chVFD7Z4/kU5" + . "/XILRQ+2CEU5zUEPksFFiAwCSIPAAUiDwgFJg8ABSIPBATnGfg+FwA+Fav///0HG" + . "BAIC690BdCQsQYPDAUQ5nCRIAQAAD4UH////i0QkEEiLtCQgAQAAiUQkWItEJBiJ" + . "hCSAAAAA6YLx//+NRQFEi5QkSAEAAEUx2zHbweAHicWLhCRAAQAARYXSRI08hQAA" + . "AAAPjlL1//9EiXQkIESLtCRAAQAARYX2flNIY0QkKExj00wDlCRQAQAARTHASI1M" + . "BgIPthEPtkH/RA+2Sf5rwEtr0iYBwkSJyMHgBEQpyAHQOcVDD5cEAkmDwAFIg8EE" + . "RTnGf81EAXwkKEQB80GDwwGLTCQsAUwkKEQ5nCRIAQAAdZKLRCQQRIt0JCCJRCRY" + . "i0QkGImEJIAAAADpvfD//8dEJBgAAAAAx0QkEAAAAADHRCQIAAAAAMdEJFQAAAAA" + . "6Qbv///HRCRYAAAAAMeEJIAAAAAAAAAAx0QkVAAAAADHRCQIAAAAAOmX8P//McDH" + . "RCRUAAAAAOkz+v//kJCQkA==" this.MCode(MyFunc, A_PtrSize=8 ? x64:x32) } text:=j[1], w:=j[2], h:=j[3] - , e1:=(j[12] ? j[6] : Floor(j[4] * ini.err1)) - , e0:=(j[12] ? j[7] : Floor(j[5] * ini.err0)) - , mode:=j[8], color:=j[9], n:=j[10] + , err1:=(j[4] ? j[5] : ini.err1) + , err0:=(j[4] ? j[6] : ini.err0) + , mode:=j[7], color:=j[8], n:=j[9] return (!ini.bits.Scan0) ? 0 : DllCall(&MyFunc , "int",mode, "uint",color, "uint",n, "int",dir , "Ptr",ini.bits.Scan0, "int",ini.bits.Stride - , "int",ini.zw, "int",ini.zh , "int",sx, "int",sy, "int",sw, "int",sh , "Ptr",ini.ss, "Ptr",ini.s1, "Ptr",ini.s0 - , "AStr",text, "int",w, "int",h, "int",e1, "int",e0 - , "Ptr",&allpos, "int",ini.allpos_max - , "int",w*ini.zoomW, "int",h*ini.zoomH) + , (mode=5 ? "Ptr":"AStr"),text, "int",w, "int",h + , "int",Floor(err1*10000), "int",Floor(err0*10000) + , "Ptr",allpos_ptr, "int",ini.allpos_max + , "int",Floor(w*ini.zoomW), "int",Floor(h*ini.zoomH)) +} + +code() +{ +return " +( + +//***** C source code of machine code ***** + +int __attribute__((__stdcall__)) PicFind( + int mode, unsigned int c, unsigned int n, int dir + , unsigned char * Bmp, int Stride + , int sx, int sy, int sw, int sh + , unsigned char * ss, unsigned int * s1, unsigned int * s0 + , unsigned char * text, int w, int h, int err1, int err0 + , unsigned int * allpos, int allpos_max + , int new_w, int new_h ) +{ + int ok, o, i, j, k, v, e1, e0, len1, len0, max; + int x, y, x1, y1, x2, y2, x3, y3; + int r, g, b, rr, gg, bb, dR, dG, dB; + unsigned int c1, c2; + unsigned char * gs; + unsigned int * cors; + ok=0; o=0; len1=0; len0=0; + //---------------------- + if (mode==5) + { + if (k=(c!=0)) // FindPic + { + cors=(unsigned int *)(text+w*h*4); + r=(c>>16)&0xFF; g=(c>>8)&0xFF; b=c&0xFF; + dR=r*r; dG=g*g; dB=b*b; + for (y=0; y>16)&0xFF)-rr; + g=((c>>8)&0xFF)-gg; b=(c&0xFF)-bb; + if (r*r<=dR && g*g<=dG && b*b<=dB) goto NoMatch1; + } + s1[len1]=(y*new_h/h)*Stride+(x*new_w/w)*4; + s0[len1++]=(rr<<16)|(gg<<8)|bb; + NoMatch1:; + } + } + } + else // FindMultiColor or FindColor + { + cors=(unsigned int *)text; + for (; len1>4)/w; x=(c>>4)%w; + s1[len1]=(y*new_h/h)*Stride+(x*new_w/w)*4; + s0[len1]=o+(c&0xF)*2; + } + cors++; + } + goto StartLookUp; + } + //---------------------- + // Generate Lookup Table + for (y=0; y>16; x=c&0xFFFF; + c=(y*new_h/h)*Stride+(x*new_w/w)*4; + goto StartLookUp; + } + //---------------------- + // Generate Two Value Image + o=sy*Stride+sx*4; j=Stride-sw*4; i=0; + if (mode==0) // Color Mode + { + rr=(c>>16)&0xFF; gg=(c>>8)&0xFF; bb=c&0xFF; + for (y=0; y>7; + } + for (i=0, y=0; yn || gs[i+1]>n + || gs[i-sw]>n || gs[i+sw]>n + || gs[i-sw-1]>n || gs[i-sw+1]>n + || gs[i+sw-1]>n || gs[i+sw+1]>n) ? 1:0; + } + } + } + else // (mode==3) Color Difference Mode + { + rr=(c>>16)&0xFF; gg=(c>>8)&0xFF; bb=c&0xFF; + r=(n>>16)&0xFF; g=(n>>8)&0xFF; b=n&0xFF; + dR=r*r; dG=g*g; dB=b*b; + for (y=0; y=len1) len1=0; + if (err0>=len0) len0=0; + max=(len1>len0) ? len1 : len0; + if (mode==5 || mode==4) + { + x1=sx; y1=sy; sx=0; sy=0; + } + else + { + x1=0; y1=0; + } + x2=x1+sw-new_w; y2=y1+sh-new_h; + // 1 ==> ( Left to Right ) Top to Bottom + // 2 ==> ( Right to Left ) Top to Bottom + // 3 ==> ( Left to Right ) Bottom to Top + // 4 ==> ( Right to Left ) Bottom to Top + // 5 ==> ( Top to Bottom ) Left to Right + // 6 ==> ( Bottom to Top ) Left to Right + // 7 ==> ( Top to Bottom ) Right to Left + // 8 ==> ( Bottom to Top ) Right to Left + if (dir<1 || dir>8) dir=1; + if (--dir>3) { r=y1; y1=x1; x1=r; r=y2; y2=x2; x2=r; } + for (y3=y1; y3<=y2; y3++) + { + for (x3=x1; x3<=x2; x3++) + { + y=((dir&3)>1) ? y1+y2-y3 : y3; + x=(dir&1) ? x1+x2-x3 : x3; + if (dir>3) { r=y; y=x; x=r; } + //---------------------- + e1=err1; e0=err0; + if (mode==5) + { + o=y*Stride+x*4; + if (k) + { + for (i=0; i>16)&0xFF); + g=Bmp[1+j]-((c>>8)&0xFF); b=Bmp[j]-(c&0xFF); + if ((r*r>dR || g*g>dG || b*b>dB) && (--e1)<0) goto NoMatch; + } + } + else + { + for (i=0; i>16)&0xFF)-rr; g=((c1>>8)&0xFF)-gg; b=(c1&0xFF)-bb; + dR=(c2>>16)&0xFF; dG=(c2>>8)&0xFF; dB=c2&0xFF; + if ((r*r<=dR*dR && g*g<=dG*dG && b*b<=dB*dB)^(c1>0xFFFFFF)) + goto MatchOK; + } + if ((--e1)<0) goto NoMatch; + MatchOK:; + } + } + } + else if (mode==4) + { + o=y*Stride+x*4; + j=o+c; rr=Bmp[2+j]; gg=Bmp[1+j]; bb=Bmp[j]; + for (i=0; in && (--e1)<0) goto NoMatch; + } + if (i=allpos_max) goto Return1; + } + NoMatch:; + } + } + //---------------------- + Return1: + return ok; +} + +)" +} + +PicInfo(text) +{ + local + if !InStr(text, "$") + return + static init, info, bmp + if (!VarSetCapacity(init) && init:="1") + info:=[], bmp:=[] + key:=(r:=StrLen(text))<10000 ? text + : DllCall("ntdll\RtlComputeCrc32", "uint",0 + , "Ptr",&text, "uint",r*(1+!!A_IsUnicode), "uint") + if info.HasKey(key) + return info[key] + v:=text, comment:="", seterr:=err1:=err0:=0 + ; You Can Add Comment Text within The <> + if RegExMatch(v, "O)<([^>\n]*)>", r) + v:=StrReplace(v,r[0]), comment:=Trim(r[1]) + ; You can Add two fault-tolerant in the [], separated by commas + if RegExMatch(v, "O)\[([^\]\n]*)]", r) + { + v:=StrReplace(v,r[0]), r:=StrSplit(r[1] ",", ",") + , seterr:=1, err1:=r[1], err0:=r[2] + } + color:=SubStr(v,1,InStr(v,"$")-1), v:=Trim(SubStr(v,InStr(v,"$")+1)) + mode:=InStr(color,"##") ? 5 + : InStr(color,"#") ? 4 : InStr(color,"-") ? 3 + : InStr(color,"**") ? 2 : InStr(color,"*") ? 1 : 0 + color:=RegExReplace(color, "[*#\s]") + (mode=0 || mode=3 || mode=5) && color:=StrReplace(color,"0x") + if (mode=5) + { + if !(v~="/[\s\-\w]+/[\s\-\w,/]+$") ; FindPic + { + ; Text:="|<>##DRDGDB-RRGGBB1-RRGGBB2... $ d:\a.bmp" + ; the 0xRRGGBB1(+/-0xDRDGDB)... all as transparent color + if !(hBM:=LoadPicture(v)) + return + this.GetBitmapWH(hBM, w, h) + if (w<1 || h<1) + return + hBM2:=this.CreateDIBSection(w, h, 32, Scan0) + this.CopyHBM(hBM2, 0, 0, hBM, 0, 0, w, h) + DllCall("DeleteObject", "Ptr",hBM) + if (!Scan0) + return + ; All images used for Search are cached + StrReplace(color, "-",, n) + bmp.Push(buf:=this.Buffer(w*h*4+n*4)), v:=buf.Ptr + DllCall("RtlMoveMemory", "Ptr",v, "Ptr",Scan0, "Ptr",w*h*4) + DllCall("DeleteObject", "Ptr",hBM2) + p:=v+w*h*4-4 + , tab:=Object("Black", "000000", "White", "FFFFFF" + , "Red", "FF0000", "Green", "008000", "Blue", "0000FF" + , "Yellow", "FFFF00", "Silver", "C0C0C0", "Gray", "808080" + , "Teal", "008080", "Navy", "000080", "Aqua", "00FFFF" + , "Olive", "808000", "Lime", "00FF00", "Fuchsia", "FF00FF" + , "Purple", "800080", "Maroon", "800000") + For k1,v1 in StrSplit(color, "-") + if (k1>1) + NumPut(Floor("0x" (tab.HasKey(v1)?tab[v1]:v1)), 0|p+=4, "uint") + color:=Floor("0x" StrSplit(color "-", "-")[1])|0x1000000 + } + else ; FindMultiColor or FindColor + { + ; Text:='|<>##DRDGDB $ 0/0/RRGGBB1-DRDGDB1/RRGGBB2/-RRGGBB3/-RRGGBB4, xn/yn/...' + ; Color behind '##' (0xDRDGDB) is the default allowed variation for all colors + ; Initial point (0,0) match 0xRRGGBB1(+/-0xDRDGDB1) or 0xRRGGBB2(+/-0xDRDGDB) + ; or not 0xRRGGBB3(+/-0xDRDGDB) or not 0xRRGGBB4(+/-0xDRDGDB) + ; The color starting with '-' means that all but this color is successful + ; Each point can take up to 10 sets of colors (xn/yn/RRGGBB1/.../RRGGBB10) + arr:=StrSplit(Trim(RegExReplace(v, "i)\s|0x"), ","), ",") + if !(n:=arr.Length()) + return + bmp.Push(buf:=this.Buffer(n*(1+10+10)*4)), v:=buf.Ptr + , color:=StrSplit(color "-", "-")[1] + For k1,v1 in arr + { + r:=StrSplit(v1 "/", "/") + , x:=Floor(r[1]), y:=Floor(r[2]) + , (A_Index=1) ? (x1:=x2:=x, y1:=y2:=y) + : (x1:=Min(x1,x), x2:=Max(x2,x) + , y1:=Min(y1,y), y2:=Max(y2,y)) + } + w:=x2-x1+1, h:=y2-y1+1 + For k1,v1 in arr + { + r:=StrSplit(v1 "/", "/") + , x:=Floor(r[1])-x1, y:=Floor(r[2])-y1 + , n1:=Min(Max(r.Length()-3, 0), 10) + , NumPut((y*w+x)<<4|n1, 0|p:=v+(A_Index-1)*84, "uint") + Loop % n1 + k1:=(InStr(v1:=r[2+A_Index], "-")=1 ? 0x1000000:0) + , c:=StrSplit(Trim(v1,"-") "-" color, "-") + , NumPut(Floor("0x" c[1])&0xFFFFFF|k1, 0|p+=4, "uint") + , NumPut(Floor("0x" c[2]), 0|p+=4, "uint") + } + color:=0 + } + } + else + { + r:=StrSplit(v ".", "."), w:=Floor(r[1]) + , v:=this.base64tobit(r[2]), h:=StrLen(v)//w + if (w<1 || h<1 || StrLen(v)!=w*h) + return + if (mode=3) + { + r:=StrSplit(color, "-") + , color:=Floor("0x" r[1]), n:=Floor("0x" r[2]) + } + else + { + r:=StrSplit(color "@1", "@") + , color:=Floor((mode=0?"0x":"") r[1]), n:=r[2] + , n:=(n<=0||n>1?1:n), n:=Floor(512*9*255*255*(1-n)*(1-n)) + , (mode=4) && color:=((color-1)//w)<<16|Mod(color-1,w) + } + } + return info[key]:=[v, w, h, seterr, err1, err0, mode, color, n, comment] +} + +Buffer(size, FillByte:="") +{ + local + buf:={}, buf.SetCapacity("a", size), p:=buf.GetAddress("a") + , (FillByte!="" && DllCall("RtlFillMemory","Ptr",p,"Ptr",size,"uchar",FillByte)) + , buf.Ptr:=p, buf.Size:=size + return buf } GetBitsFromScreen(ByRef x:=0, ByRef y:=0, ByRef w:=0, ByRef h:=0 - , ScreenShot:=1, ByRef zx:="", ByRef zy:="", ByRef zw:="", ByRef zh:="") + , ScreenShot:=1, ByRef zx:=0, ByRef zy:=0, ByRef zw:=0, ByRef zh:=0) { local static CAPTUREBLT:="" - (!IsObject(this.bits) && this.bits:=[]), bits:=this.bits - if (!ScreenShot and bits.Scan0) + (!IsObject(this.bits) && this.bits:={Scan0:0, hBM:0, oldzw:0, oldzh:0}) + , bits:=this.bits + if (!ScreenShot && bits.Scan0) { zx:=bits.zx, zy:=bits.zy, zw:=bits.zw, zh:=bits.zh - if IsByRef(x) - w:=Min(x+w,zx+zw), x:=Max(x,zx), w-=x - , h:=Min(y+h,zy+zh), y:=Max(y,zy), h-=y + , w:=Min(x+w,zx+zw), x:=Max(x,zx), w-=x + , h:=Min(y+h,zy+zh), y:=Max(y,zy), h-=y return bits } bch:=A_BatchLines, cri:=A_IsCritical @@ -556,26 +906,20 @@ GetBitsFromScreen(ByRef x:=0, ByRef y:=0, ByRef w:=0, ByRef h:=0 SysGet, zw, 78 SysGet, zh, 79 } - bits.zx:=zx, bits.zy:=zy, bits.zw:=zw, bits.zh:=zh + this.UpdateBits(bits, zx, zy, zw, zh) , w:=Min(x+w,zx+zw), x:=Max(x,zx), w-=x , h:=Min(y+h,zy+zh), y:=Max(y,zy), h-=y - if (zw>bits.oldzw or zh>bits.oldzh or !bits.hBM) - { - DllCall("DeleteObject", "Ptr",bits.hBM) - , bits.hBM:=this.CreateDIBSection(zw, zh, bpp:=32, ppvBits) - , bits.Scan0:=(!bits.hBM ? 0:ppvBits) - , bits.Stride:=((zw*bpp+31)//32)*4 - , bits.oldzw:=zw, bits.oldzh:=zh - } - if (!ScreenShot or w<1 or h<1 or !bits.hBM) + if (!ScreenShot || w<1 || h<1 || !bits.hBM) { Critical, %cri% SetBatchLines, %bch% return bits } if IsFunc(k:="GetBitsFromScreen2") - and %k%(bits, x-zx, y-zy, w, h) + && %k%(bits, x-zx, y-zy, w, h) { + ; Each small range of data obtained from DXGI must be + ; copied to the screenshot cache using this.CopyBits() zx:=bits.zx, zy:=bits.zy, zw:=bits.zw, zh:=bits.zh Critical, %cri% SetBatchLines, %bch% @@ -583,8 +927,8 @@ GetBitsFromScreen(ByRef x:=0, ByRef y:=0, ByRef w:=0, ByRef h:=0 } if (CAPTUREBLT="") ; thanks Descolada { - DllCall("Dwmapi\DwmIsCompositionEnabled", "Int*",compositionEnabled:=0) - CAPTUREBLT:=compositionEnabled ? 0 : 0x40000000 + DllCall("Dwmapi\DwmIsCompositionEnabled", "Int*",i:=0) + CAPTUREBLT:=i ? 0 : 0x40000000 } mDC:=DllCall("CreateCompatibleDC", "Ptr",0, "Ptr") oBM:=DllCall("SelectObject", "Ptr",mDC, "Ptr",bits.hBM, "Ptr") @@ -592,10 +936,10 @@ GetBitsFromScreen(ByRef x:=0, ByRef y:=0, ByRef w:=0, ByRef h:=0 { if (mode:=this.BindWindow(0,0,0,1))<2 { - hDC2:=DllCall("GetDCEx", "Ptr",id, "Ptr",0, "int",3, "Ptr") + hDC:=DllCall("GetDCEx", "Ptr",id, "Ptr",0, "int",3, "Ptr") DllCall("BitBlt","Ptr",mDC,"int",x-zx,"int",y-zy,"int",w,"int",h - , "Ptr",hDC2, "int",x-zx, "int",y-zy, "uint",0xCC0020|CAPTUREBLT) - DllCall("ReleaseDC", "Ptr",id, "Ptr",hDC2) + , "Ptr",hDC, "int",x-zx, "int",y-zy, "uint",0xCC0020|CAPTUREBLT) + DllCall("ReleaseDC", "Ptr",id, "Ptr",hDC) } else { @@ -612,11 +956,10 @@ GetBitsFromScreen(ByRef x:=0, ByRef y:=0, ByRef w:=0, ByRef h:=0 } else { - win:=DllCall("GetDesktopWindow", "Ptr") - hDC:=DllCall("GetWindowDC", "Ptr",win, "Ptr") + hDC:=DllCall("GetWindowDC","Ptr",id:=DllCall("GetDesktopWindow","Ptr"),"Ptr") DllCall("BitBlt","Ptr",mDC,"int",x-zx,"int",y-zy,"int",w,"int",h , "Ptr",hDC, "int",x, "int",y, "uint",0xCC0020|CAPTUREBLT) - DllCall("ReleaseDC", "Ptr",win, "Ptr",hDC) + DllCall("ReleaseDC", "Ptr",id, "Ptr",hDC) } if this.CaptureCursor(0,0,0,0,0,1) this.CaptureCursor(mDC, zx, zy, zw, zh) @@ -627,8 +970,23 @@ GetBitsFromScreen(ByRef x:=0, ByRef y:=0, ByRef w:=0, ByRef h:=0 return bits } -CreateDIBSection(w, h, bpp:=32, ByRef ppvBits:=0, ByRef bi:="") +UpdateBits(bits, zx, zy, zw, zh) +{ + local + if (zw>bits.oldzw || zh>bits.oldzh || !bits.hBM) + { + Try DllCall("DeleteObject", "Ptr",bits.hBM) + bits.hBM:=this.CreateDIBSection(zw, zh, bpp:=32, ppvBits) + , bits.Scan0:=(!bits.hBM ? 0:ppvBits) + , bits.Stride:=((zw*bpp+31)//32)*4 + , bits.oldzw:=zw, bits.oldzh:=zh + } + bits.zx:=zx, bits.zy:=zy, bits.zw:=zw, bits.zh:=zh +} + +CreateDIBSection(w, h, bpp:=32, ByRef ppvBits:=0) { + local VarSetCapacity(bi, 40, 0), NumPut(40, bi, 0, "int") , NumPut(w, bi, 4, "int"), NumPut(-h, bi, 8, "int") , NumPut(1, bi, 12, "short"), NumPut(bpp, bi, 14, "short") @@ -636,145 +994,91 @@ CreateDIBSection(w, h, bpp:=32, ByRef ppvBits:=0, ByRef bi:="") , "int",0, "Ptr*",ppvBits:=0, "Ptr",0, "int",0, "Ptr") } -PicInfo(text) -{ - local - static info:=[] - if !InStr(text,"$") - return - key:=(r:=StrLen(text))<10000 ? text - : DllCall("ntdll\RtlComputeCrc32", "uint",0 - , "Ptr",&text, "uint",r*(1+!!A_IsUnicode), "uint") - if (info[key]) - return info[key] - v:=text, comment:="", seterr:=e1:=e0:=0 - ; You Can Add Comment Text within The <> - if RegExMatch(v,"<([^>\n]*)>",r) - v:=StrReplace(v,r), comment:=Trim(r1) - ; You can Add two fault-tolerant in the [], separated by commas - if RegExMatch(v,"\[([^\]\n]*)]",r) - { - v:=StrReplace(v,r), r:=StrSplit(r1, ",") - , seterr:=1, e1:=r[1], e0:=r[2] - } - color:=StrSplit(v,"$")[1], v:=Trim(SubStr(v,InStr(v,"$")+1)) - mode:=InStr(color,"##") ? 5 - : InStr(color,"-") ? 4 : InStr(color,"#") ? 3 - : InStr(color,"**") ? 2 : InStr(color,"*") ? 1 : 0 - color:=RegExReplace(color, "[*#\s]") - if (mode=5) - { - if (v~="[^\s\w/]") and FileExist(v) ; ImageSearch - { - if !(hBM:=LoadPicture(v)) - return - this.GetBitmapWH(hBM, w, h) - if (w<1 or h<1) - return - hBM2:=this.CreateDIBSection(w, h, 32, Scan0) - this.CopyHBM(hBM2, 0, 0, hBM, 0, 0, w, h) - DllCall("DeleteObject", "Ptr",hBM) - if (!Scan0) - return - c1:=NumGet(Scan0+0,"uint")&0xFFFFFF - c2:=NumGet(Scan0+(w-1)*4,"uint")&0xFFFFFF - c3:=NumGet(Scan0+(w*h-w)*4,"uint")&0xFFFFFF - c4:=NumGet(Scan0+(w*h-1)*4,"uint")&0xFFFFFF - if (c1!=c2 or c1!=c3 or c1!=c4) - c1:=-1 - VarSetCapacity(v, w*h*18*(1+!!A_IsUnicode)), i:=-4, y:=-1 - SetFormat, IntegerFast, d - Loop % h - Loop % w+0*(++y) - if (c:=NumGet(Scan0+(i+=4),"uint")&0xFFFFFF)!=c1 - v.=(A_Index-1)|y<<16|c<<32 . "/" - StrReplace(v, "/", "", n) - DllCall("DeleteObject", "Ptr",hBM2) - } - else - { - v:=Trim(StrReplace(RegExReplace(v,"\s"),",","/"),"/") - r:=StrSplit(v,"/"), n:=r.Length()//3 - if (!n) - return - VarSetCapacity(v, n*18*(1+!!A_IsUnicode)) - x1:=x2:=r[1], y1:=y2:=r[2] - SetFormat, IntegerFast, d - Loop % n + (i:=-2)*0 - x:=r[i+=3], y:=r[i+1] - , (xx2 && x2:=x) - , (yy2 && y2:=y) - Loop % n + (i:=-2)*0 - v.=(r[i+=3]-x1)|(r[i+1]-y1)<<16|(Floor("0x" - . StrReplace(r[i+2],"0x"))&0xFFFFFF)<<32 . "/" - w:=x2-x1+1, h:=y2-y1+1 - } - len1:=n, len0:=0 - } - else - { - r:=StrSplit(v,"."), w:=r[1] - , v:=this.base64tobit(r[2]), h:=StrLen(v)//w - if (w<1 or h<1 or StrLen(v)!=w*h) - return - if (mode=4) - { - r:=StrSplit(StrReplace(color,"0x"),"-") - , color:=Floor("0x" r[1]), n:=Floor("0x" r[2]) - } - else - { - r:=StrSplit(color,"@") - , color:=r[1], n:=Round(r[2],2)+(!r[2]) - , n:=Floor(512*9*255*255*(1-n)*(1-n)) - if (mode=3) - color:=(((color-1)//w)<<16)|Mod(color-1,w) - } - StrReplace(v,"1","",len1), len0:=StrLen(v)-len1 - } - e1:=Floor(len1*e1), e0:=Floor(len0*e0) - return info[key]:=[v, w, h, len1, len0, e1, e0 - , mode, color, n, comment, seterr] -} - GetBitmapWH(hBM, ByRef w, ByRef h) { local - VarSetCapacity(bm, size:=(A_PtrSize=8 ? 32:24), 0) - r:=DllCall("GetObject", "Ptr",hBM, "int",size, "Ptr",&bm) - w:=NumGet(bm,4,"int"), h:=Abs(NumGet(bm,8,"int")) - return r + VarSetCapacity(bm, size:=(A_PtrSize=8 ? 32:24)) + , DllCall("GetObject", "Ptr",hBM, "int",size, "Ptr",&bm) + , w:=NumGet(bm,4,"int"), h:=Abs(NumGet(bm,8,"int")) } -CopyHBM(hBM1, x1, y1, hBM2, x2, y2, w2, h2) +CopyHBM(hBM1, x1, y1, hBM2, x2, y2, w, h, Clear:=0, trans:=0, alpha:=255) { local - if (w2<1 or h2<1 or !hBM1 or !hBM2) + if (w<1 || h<1 || !hBM1 || !hBM2) return mDC1:=DllCall("CreateCompatibleDC", "Ptr",0, "Ptr") oBM1:=DllCall("SelectObject", "Ptr",mDC1, "Ptr",hBM1, "Ptr") mDC2:=DllCall("CreateCompatibleDC", "Ptr",0, "Ptr") oBM2:=DllCall("SelectObject", "Ptr",mDC2, "Ptr",hBM2, "Ptr") - DllCall("BitBlt", "Ptr",mDC1 - , "int",x1, "int",y1, "int",w2, "int",h2, "Ptr",mDC2 - , "int",x2, "int",y2, "uint",0xCC0020) - DllCall("SelectObject", "Ptr",mDC2, "Ptr",oBM2) - DllCall("DeleteDC", "Ptr",mDC2) + if (trans) + DllCall("GdiAlphaBlend", "Ptr",mDC1, "int",x1, "int",y1, "int",w, "int",h + , "Ptr",mDC2, "int",x2, "int",y2, "int",w, "int",h, "uint",alpha<<16) + else + DllCall("BitBlt", "Ptr",mDC1, "int",x1, "int",y1, "int",w, "int",h + , "Ptr",mDC2, "int",x2, "int",y2, "uint",0xCC0020) + if (Clear) + DllCall("BitBlt", "Ptr",mDC1, "int",x1, "int",y1, "int",w, "int",h + , "Ptr",mDC1, "int",x1, "int",y1, "uint",MERGECOPY:=0xC000CA) DllCall("SelectObject", "Ptr",mDC1, "Ptr",oBM1) DllCall("DeleteDC", "Ptr",mDC1) + DllCall("SelectObject", "Ptr",mDC2, "Ptr",oBM2) + DllCall("DeleteDC", "Ptr",mDC2) } -CopyBits(Scan01,Stride1,x1,y1,Scan02,Stride2,x2,y2,w2,h2,Reverse:=0) +CopyBits(Scan01,Stride1,x1,y1,Scan02,Stride2,x2,y2,w,h,Reverse:=0) { local - if (w2<1 or h2<1 or !Scan01 or !Scan02) + if (w<1 || h<1 || !Scan01 || !Scan02) return + static init, MFCopyImage + if (!VarSetCapacity(init) && init:="1") + { + MFCopyImage:=DllCall("GetProcAddress", "Ptr" + , DllCall("LoadLibrary", "Str","Mfplat.dll", "Ptr") + , "AStr","MFCopyImage", "Ptr") + } + if (MFCopyImage && !Reverse) ; thanks QQ:RenXing + { + return DllCall(MFCopyImage + , "Ptr",Scan01+y1*Stride1+x1*4, "int",Stride1 + , "Ptr",Scan02+y2*Stride2+x2*4, "int",Stride2 + , "uint",w*4, "uint",h) + } + ListLines % (lls:=A_ListLines)?0:0 + SetBatchLines, % (bch:=A_BatchLines)?"-1":"-1" p1:=Scan01+(y1-1)*Stride1+x1*4 - , p2:=Scan02+(y2-1)*Stride2+x2*4, w2*=4 + , p2:=Scan02+(y2-1)*Stride2+x2*4, w*=4 if (Reverse) - p2+=(h2+1)*Stride2, Stride2:=-Stride2 - Loop % h2 - DllCall("RtlMoveMemory","Ptr",p1+=Stride1,"Ptr",p2+=Stride2,"Ptr",w2) + p2+=(h+1)*Stride2, Stride2:=-Stride2 + Loop % h + DllCall("RtlMoveMemory","Ptr",p1+=Stride1,"Ptr",p2+=Stride2,"Ptr",w) + SetBatchLines, %bch% + ListLines %lls% +} + +DrawHBM(hBM, lines) +{ + local + mDC:=DllCall("CreateCompatibleDC", "Ptr",0, "Ptr") + oBM:=DllCall("SelectObject", "Ptr",mDC, "Ptr",hBM, "Ptr") + oldc:="", brush:=0, VarSetCapacity(rect, 16) + For k,v in lines ; [ [x, y, w, h, color] ] + if IsObject(v) + { + if (oldc!=v[5]) + { + oldc:=v[5], BGR:=(oldc&0xFF)<<16|oldc&0xFF00|(oldc>>16)&0xFF + DllCall("DeleteObject", "Ptr",brush) + brush:=DllCall("CreateSolidBrush", "UInt",BGR, "Ptr") + } + DllCall("SetRect", "Ptr",&rect, "int",v[1], "int",v[2] + , "int",v[1]+v[3], "int",v[2]+v[4]) + DllCall("FillRect", "Ptr",mDC, "Ptr",&rect, "Ptr",brush) + } + DllCall("DeleteObject", "Ptr",brush) + DllCall("SelectObject", "Ptr",mDC, "Ptr",oBM) + DllCall("DeleteObject", "Ptr",mDC) } ; Bind the window so that it can find images when obscured @@ -784,7 +1088,8 @@ CopyBits(Scan01,Stride1,x1,y1,Scan02,Stride2,x2,y2,w2,h2,Reverse:=0) BindWindow(bind_id:=0, bind_mode:=0, get_id:=0, get_mode:=0) { local - (!IsObject(this.bind) && this.bind:=[]), bind:=this.bind + (!IsObject(this.bind) && this.bind:={id:0, mode:0, oldStyle:0}) + , bind:=this.bind if (get_id) return bind.id if (get_mode) @@ -794,12 +1099,12 @@ BindWindow(bind_id:=0, bind_mode:=0, get_id:=0, get_mode:=0) bind.id:=bind_id, bind.mode:=bind_mode, bind.oldStyle:=0 if (bind_mode & 1) { - WinGet, oldStyle, ExStyle, ahk_id %bind_id% - bind.oldStyle:=oldStyle + WinGet, i, ExStyle, ahk_id %bind_id% + bind.oldStyle:=i WinSet, Transparent, 255, ahk_id %bind_id% Loop 30 { - Sleep, 100 + Sleep 100 WinGet, i, Transparent, ahk_id %bind_id% } Until (i=255) @@ -822,25 +1127,25 @@ CaptureCursor(hDC:=0, zx:=0, zy:=0, zw:=0, zh:=0, get_cursor:=0) local if (get_cursor) return this.Cursor - if (hDC=1 or hDC=0) and (zw=0) + if (hDC=1 || hDC=0) && (zw=0) { this.Cursor:=hDC return } VarSetCapacity(mi, 40, 0), NumPut(16+A_PtrSize, mi, "int") DllCall("GetCursorInfo", "Ptr",&mi) - bShow := NumGet(mi, 4, "int") - hCursor := NumGet(mi, 8, "Ptr") - x := NumGet(mi, 8+A_PtrSize, "int") - y := NumGet(mi, 12+A_PtrSize, "int") - if (!bShow) or (x=zx+zw or y>=zy+zh) + bShow:=NumGet(mi, 4, "int") + hCursor:=NumGet(mi, 8, "Ptr") + x:=NumGet(mi, 8+A_PtrSize, "int") + y:=NumGet(mi, 12+A_PtrSize, "int") + if (!bShow) || (x=zx+zw || y>=zy+zh) return VarSetCapacity(ni, 40, 0) DllCall("GetIconInfo", "Ptr",hCursor, "Ptr",&ni) - xCenter := NumGet(ni, 4, "int") - yCenter := NumGet(ni, 8, "int") - hBMMask := NumGet(ni, (A_PtrSize=8?16:12), "Ptr") - hBMColor := NumGet(ni, (A_PtrSize=8?24:16), "Ptr") + xCenter:=NumGet(ni, 4, "int") + yCenter:=NumGet(ni, 8, "int") + hBMMask:=NumGet(ni, (A_PtrSize=8?16:12), "Ptr") + hBMColor:=NumGet(ni, (A_PtrSize=8?24:16), "Ptr") DllCall("DrawIconEx", "Ptr",hDC , "int",x-xCenter-zx, "int",y-yCenter-zy, "Ptr",hCursor , "int",0, "int",0, "int",0, "int",0, "int",3) @@ -851,64 +1156,61 @@ CaptureCursor(hDC:=0, zx:=0, zy:=0, zw:=0, zh:=0, get_cursor:=0) MCode(ByRef code, hex) { local - SetBatchLines, % (bch:=A_BatchLines)?"-1":"-1" - VarSetCapacity(code, len:=StrLen(hex)//2) - Loop % len - NumPut("0x" SubStr(hex,2*A_Index-1,2),code,A_Index-1,"uchar") - DllCall("VirtualProtect","Ptr",&code,"Ptr",len,"uint",0x40,"Ptr*",0) - SetBatchLines, %bch% + flag:=((hex~="[^\s\da-fA-F]")?1:4), hex:=RegExReplace(hex, "[\s=]") + VarSetCapacity(code, len:=(flag=1 ? StrLen(hex)//4*3+3 : StrLen(hex)//2)) + DllCall("crypt32\CryptStringToBinary", "Str",hex, "uint",0 + , "uint",flag, "Ptr",&code, "uint*",len, "Ptr",0, "Ptr",0) + DllCall("VirtualProtect", "Ptr",&code, "Ptr",len, "uint",0x40, "Ptr*",0) +} + +bin2hex(addr, size, base64:=1) +{ + local + flag:=(base64 ? 1|0x40000000 : 4|0x0000000C) + Loop 2 + p:=(A_Index=1 ? 0 : VarSetCapacity(hex,len*2)*0 + &hex) + , DllCall("Crypt32\CryptBinaryToString", "Ptr",addr, "uint",size + , "uint",flag, "Ptr",p, "uint*",len) + return RegExReplace(StrGet(p, len), "\s+") } base64tobit(s) { local - Chars:="0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZ" - . "abcdefghijklmnopqrstuvwxyz" + ListLines % (lls:=A_ListLines)?0:0 + Chars:="0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" SetFormat, IntegerFast, d Loop Parse, Chars - { - s:=RegExReplace(s, "[" A_LoopField "]" - , ((i:=A_Index-1)>>5&1) . (i>>4&1) - . (i>>3&1) . (i>>2&1) . (i>>1&1) . (i&1)) - } - return RegExReplace(RegExReplace(s,"[^01]+"),"10*$") + if InStr(s, A_LoopField, 1) + s:=RegExReplace(s, "[" A_LoopField "]", ((i:=A_Index-1)>>5&1) + . (i>>4&1) . (i>>3&1) . (i>>2&1) . (i>>1&1) . (i&1)) + s:=RegExReplace(RegExReplace(s,"[^01]+"),"10*$") + ListLines %lls% + return s } bit2base64(s) { local + ListLines % (lls:=A_ListLines)?0:0 s:=RegExReplace(s,"[^01]+") s.=SubStr("100000",1,6-Mod(StrLen(s),6)) s:=RegExReplace(s,".{6}","|$0") - Chars:="0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZ" - . "abcdefghijklmnopqrstuvwxyz" + Chars:="0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" SetFormat, IntegerFast, d Loop Parse, Chars - { s:=StrReplace(s, "|" . ((i:=A_Index-1)>>5&1) - . (i>>4&1) . (i>>3&1) . (i>>2&1) . (i>>1&1) . (i&1) - , A_LoopField) - } + . (i>>4&1) . (i>>3&1) . (i>>2&1) . (i>>1&1) . (i&1), A_LoopField) + ListLines %lls% return s } -xywh2xywh(x1,y1,w1,h1, ByRef x, ByRef y, ByRef w, ByRef h - , ByRef zx:="", ByRef zy:="", ByRef zw:="", ByRef zh:="") -{ - SysGet, zx, 76 - SysGet, zy, 77 - SysGet, zw, 78 - SysGet, zh, 79 - w:=Min(x1+w1,zx+zw), x:=Max(x1,zx), w-=x - , h:=Min(y1+h1,zy+zh), y:=Max(y1,zy), h-=y -} - ASCII(s) { local - if RegExMatch(s,"\$(\d+)\.([\w+/]+)",r) + if RegExMatch(s, "O)\$(\d+)\.([\w+/]+)", r) { - s:=RegExReplace(this.base64tobit(r2),".{" r1 "}","$0`n") + s:=RegExReplace(this.base64tobit(r[2]),".{" r[1] "}","$0`n") s:=StrReplace(StrReplace(s,"0","_"),"1","0") } else s:="" @@ -923,17 +1225,17 @@ PicLib(comments, add_to_Lib:=0, index:=1) { local (!IsObject(this.Lib) && this.Lib:=[]), Lib:=this.Lib - , (!Lib[index] && Lib[index]:=[]), Lib:=Lib[index] + , (!Lib.HasKey(index) && Lib[index]:=[]), Lib:=Lib[index] if (add_to_Lib) { - re:="<([^>\n]*)>[^$\n]+\$[^""\r\n]+" + re:="O)<([^>\n]*)>[^$\n]+\$[^""\r\n]+" Loop Parse, comments, | - if RegExMatch(A_LoopField,re,r) + if RegExMatch(A_LoopField, re, r) { - s1:=Trim(r1), s2:="" + s1:=Trim(r[1]), s2:="" Loop Parse, s1 s2.="_" . Format("{:d}",Ord(A_LoopField)) - Lib[s2]:=r + Lib[s2]:=r[0] } Lib[""]:="" } @@ -945,7 +1247,8 @@ PicLib(comments, add_to_Lib:=0, index:=1) s1:=Trim(A_LoopField), s2:="" Loop Parse, s1 s2.="_" . Format("{:d}",Ord(A_LoopField)) - Text.="|" . Lib[s2] + if Lib.HasKey(s2) + Text.="|" . Lib[s2] } return Text } @@ -964,11 +1267,11 @@ PicN(Number, index:=1) PicX(Text) { local - if !RegExMatch(Text,"(<[^$\n]+)\$(\d+)\.([\w+/]+)",r) + if !RegExMatch(Text, "O)(<[^$\n]+)\$(\d+)\.([\w+/]+)", r) return Text - v:=this.base64tobit(r3), Text:="" + v:=this.base64tobit(r[3]), Text:="" c:=StrLen(StrReplace(v,"0"))<=StrLen(v)//2 ? "1":"0" - txt:=RegExReplace(v,".{" r2 "}","$0`n") + txt:=RegExReplace(v,".{" r[2] "}","$0`n") While InStr(txt,c) { While !(txt~="m`n)^" c) @@ -979,7 +1282,7 @@ PicX(Text) v:=RegExReplace(txt,"m`n)^(.{" i "}).*","$1") txt:=RegExReplace(txt,"m`n)^.{" i "}") if (v!="") - Text.="|" r1 "$" i "." this.bit2base64(v) + Text.="|" r[1] "$" i "." this.bit2base64(v) } return Text } @@ -988,7 +1291,7 @@ PicX(Text) ScreenShot(x1:=0, y1:=0, x2:=0, y2:=0) { - this.FindText(0, 0, x1, y1, x2, y2) + this.FindText(,, x1, y1, x2, y2) } ; Get the RGB color of a point from the last screenshot. @@ -998,8 +1301,8 @@ ScreenShot(x1:=0, y1:=0, x2:=0, y2:=0) GetColor(x, y, fmt:=1) { local - bits:=this.GetBitsFromScreen(0,0,0,0,0,zx,zy,zw,zh) - , c:=(x=zx+zw or y=zy+zh or !bits.Scan0) + bits:=this.GetBitsFromScreen(,,,,0,zx,zy,zw,zh) + , c:=(x=zx+zw || y=zy+zh || !bits.Scan0) ? 0xFFFFFF : NumGet(bits.Scan0+(y-zy)*bits.Stride+(x-zx)*4,"uint") return (fmt ? Format("0x{:06X}",c&0xFFFFFF) : c) } @@ -1009,9 +1312,9 @@ GetColor(x, y, fmt:=1) SetColor(x, y, color:=0x000000) { local - bits:=this.GetBitsFromScreen(0,0,0,0,0,zx,zy,zw,zh) - if !(x=zx+zw or y=zy+zh or !bits.Scan0) - NumPut(color,bits.Scan0+(y-zy)*bits.Stride+(x-zx)*4,"uint") + bits:=this.GetBitsFromScreen(,,,,0,zx,zy,zw,zh) + if !(x=zx+zw || y=zy+zh || !bits.Scan0) + NumPut(color, bits.Scan0+(y-zy)*bits.Stride+(x-zx)*4, "uint") } ; Identify a line of text or verification code @@ -1027,33 +1330,35 @@ Ocr(ok, offsetX:=20, offsetY:=20, overlapW:=0) local ocr_Text:=ocr_X:=ocr_Y:=min_X:=dx:="" For k,v in ok - x:=v[1] - , min_X:=(A_Index=1 or xmax_X ? x : max_X) - While (min_X!="" and min_X<=max_X) + x:=v.1 + , min_X:=(A_Index=1 || xmax_X ? x : max_X) + While (min_X!="" && min_X<=max_X) { LeftX:="" For k,v in ok { - x:=v[1], y:=v[2] - if (xoffsetY + x:=v.1, y:=v.2 + if (xoffsetY) Continue ; Get the leftmost X coordinates - if (LeftX="" or xdx ? "*":"") . LeftOCR + ocr_Text.=(ocr_Text!="" && LeftX>dx ? "*":"") . LeftOCR ; Update for next search min_X:=LeftX+LeftW-(overlapW>LeftW//2 ? LeftW//2:overlapW) , dx:=LeftX+LeftW+offsetX, ocr_Y:=LeftY , (LeftYmax_Y && max_Y:=LeftY+LeftH) } + if (ocr_X="") + ocr_X:=0, min_Y:=0, min_X:=0, max_Y:=0 return {text:ocr_Text, x:ocr_X, y:min_Y , w: min_X-ocr_X, h: max_Y-min_Y} } @@ -1084,7 +1389,7 @@ Sort(ok, dy:=10) Sort, s, N D| ok2:=[] Loop Parse, s, | - ok2.Push( ok[(StrSplit(A_LoopField,".")[2])] ) + ok2.Push( ok[StrSplit(A_LoopField,".")[2]] ) return ok2 } @@ -1102,7 +1407,7 @@ Sort2(ok, px, py) Sort, s, N D| ok2:=[] Loop Parse, s, | - ok2.Push( ok[(StrSplit(A_LoopField,".")[2])] ) + ok2.Push( ok[StrSplit(A_LoopField,".")[2]] ) return ok2 } @@ -1115,7 +1420,7 @@ Sort3(ok, dir:=1) return ok s:="", n:=150000 For k,v in ok - x:=v[1], y:=v[2] + x:=v.1, y:=v.2 , s.=(dir=1 ? y*n+x : dir=2 ? y*n-x : dir=3 ? -y*n+x @@ -1128,70 +1433,474 @@ Sort3(ok, dir:=1) Sort, s, N D| ok2:=[] Loop Parse, s, | - ok2.Push( ok[(StrSplit(A_LoopField,".")[2])] ) + ok2.Push( ok[StrSplit(A_LoopField,".")[2]] ) return ok2 } -; Prompt mouse position in remote assistance +; Prompt mouse position in remote assistance + +MouseTip(x:="", y:="", w:=10, h:=10, d:=3) +{ + local + if (x="") + { + VarSetCapacity(pt,16,0), DllCall("GetCursorPos","Ptr",&pt) + x:=NumGet(pt,0,"uint"), y:=NumGet(pt,4,"uint") + } + Loop 4 + { + this.RangeTip(x-w, y-h, 2*w+1, 2*h+1, (A_Index & 1 ? "Red":"Blue"), d) + Sleep 500 + } + this.RangeTip() +} + +; Shows a range of the borders, similar to the ToolTip + +RangeTip(x:="", y:="", w:="", h:="", color:="Red", d:=3) +{ + local + static id:="" + if (x="") + { + id:=0 + Loop 4 + Gui, Range_%A_Index%: Destroy + return + } + if (!id) + { + Loop 4 + Gui, Range_%A_Index%: +Hwndid +AlwaysOnTop -Caption +ToolWindow -DPIScale +E0x08000000 + } + x:=Floor(x), y:=Floor(y), w:=Floor(w), h:=Floor(h), d:=Floor(d) + Loop 4 + { + i:=A_Index + , x1:=(i=2 ? x+w : x-d) + , y1:=(i=3 ? y+h : y-d) + , w1:=(i=1 || i=3 ? w+2*d : d) + , h1:=(i=2 || i=4 ? h+2*d : d) + Gui, Range_%i%: Color, %color% + Gui, Range_%i%: Show, NA x%x1% y%y1% w%w1% h%h1% + } +} + +; Use RButton to select the screen range + +GetRange(ww:=25, hh:=8, key:="RButton") +{ + local + static Gui_Off:="", hk + if (!Gui_Off) + Gui_Off:=this.GetRange.Bind(this, "Off") + if (ww="Off") + return hk:=Trim(A_ThisHotkey, "*") + ;--------------------- + Gui, FindText_HotkeyIf: New + Gui, -Caption +ToolWindow +E0x80000 + Gui, Show, NA x0 y0 w0 h0, FindText_HotkeyIf + ;--------------------- + Hotkey, IfWinExist, FindText_HotkeyIf + keys:=key "|Up|Down|Left|Right" + For k,v in StrSplit(keys, "|") + { + KeyWait, %v% + Hotkey, *%v%, %Gui_Off%, On UseErrorLevel + } + KeyWait, Ctrl + Hotkey, IfWinExist + ;--------------------- + Critical % (cri:=A_IsCritical)?"Off":"Off" + CoordMode, Mouse + tip:=this.Lang("s5") + hk:="", oldx:=oldy:="", keydown:=0 + Loop + { + Sleep 50 + MouseGetPos, x, y + if (hk=key) || GetKeyState(key,"P") || GetKeyState("Ctrl","P") + { + keydown++ + if (keydown=1) + MouseGetPos, x1, y1, Bind_ID + KeyWait, % key + KeyWait, Ctrl + hk:="" + if (keydown>1) + Break + } + else if (hk="Up") || GetKeyState("Up","P") + (hh>1 && hh--), hk:="" + else if (hk="Down") || GetKeyState("Down","P") + hh++, hk:="" + else if (hk="Left") || GetKeyState("Left","P") + (ww>1 && ww--), hk:="" + else if (hk="Right") || GetKeyState("Right","P") + ww++, hk:="" + this.RangeTip((keydown?x1:x)-ww, (keydown?y1:y)-hh + , 2*ww+1, 2*hh+1, (A_MSec<500?"Red":"Blue")) + if (oldx=x && oldy=y) + Continue + oldx:=x, oldy:=y + ToolTip % "x: " (keydown?x1:x) " y: " (keydown?y1:y) "`n" tip + } + ToolTip + this.RangeTip() + Hotkey, IfWinExist, FindText_HotkeyIf + For k,v in StrSplit(keys, "|") + Hotkey, *%v%, %Gui_Off%, Off UseErrorLevel + Hotkey, IfWinExist + Gui, FindText_HotkeyIf: Destroy + Critical %cri% + return [x1-ww, y1-hh, x1+ww, y1+hh, Bind_ID] +} + +; Take a screenshot to Clipboard or File, or only get Range + +SnapShot(ScreenShot:=1, key:="LButton") +{ + local + static Gui_Off:="", hk + if (!Gui_Off) + Gui_Off:=this.SnapShot.Bind(this, "Off") + if (ScreenShot="Off") + return hk:=Trim(A_ThisHotkey, "*") + n:=150000, x:=y:=-n, w:=h:=2*n + hBM:=this.BitmapFromScreen(x,y,w,h,ScreenShot,zx,zy,zw,zh) + ;--------------- + Gui, SnapShot_HotkeyIf: New + Gui, +AlwaysOnTop -Caption +ToolWindow -DPIScale +E0x08000000 + Gui, Margin, 0, 0 + Gui, Add, Pic, w%zw% h%zh%, % "HBITMAP:*" hBM + Gui, Show, NA x%zx% y%zy% w%zw% h%zh%, SnapShot_HotkeyIf + ;--------------- + Gui, SnapShot_Box: New + Gui, +Hwndbox_id +AlwaysOnTop -Caption +ToolWindow -DPIScale +E0x08000000 + Gui, Margin, 0, 0 + Gui, Font, s12 + For k,v in StrSplit(this.Lang("s15"), "|") + Gui, Add, Button, % (k=1 ? "":"x+0") " Hwndid", %v% + GuiControlGet, p, Pos, %id% + box_w:=pX+pW+10, box_h:=pH+10 + Gui, Show, Hide, SnapShot_Box + ;--------------- + Hotkey, IfWinExist, SnapShot_HotkeyIf + keys:=key "|RButton|Esc|Up|Down|Left|Right" + For k,v in StrSplit(keys, "|") + { + KeyWait, %v% + Hotkey, *%v%, %Gui_Off%, On UseErrorLevel + } + Hotkey, IfWinExist + ;--------------- + Critical % (cri:=A_IsCritical)?"Off":"Off" + CoordMode, Mouse + Loop + { ;// For ReTry + tip:=this.Lang("s16") + hk:="", oldx:=oldy:="", ok:=0, d:=10, oldt:=0, oldf:="" + x:=y:=w:=h:=0 + Loop + { + Sleep 50 + if (hk="RButton") || (hk="Esc") + || GetKeyState("RButton","P") || GetKeyState("Esc","P") + Break 2 + MouseGetPos, x1, y1 + if (oldx=x1 && oldy=y1) + Continue + oldx:=x1, oldy:=y1 + ToolTip % "x: " x1 " y: " y1 " w: 0 h: 0`n" tip + } + Until (hk=key) || GetKeyState(key,"P") + Loop + { + Sleep 50 + MouseGetPos, x2, y2 + x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x1-x2)+1, h:=Abs(y1-y2)+1 + this.RangeTip(x, y, w, h, (A_MSec<500 ? "Red":"Blue")) + if (oldx=x2 && oldy=y2) + Continue + oldx:=x2, oldy:=y2 + ToolTip % "x: " x " y: " y " w: " w " h: " h "`n" tip + } + Until !GetKeyState(key,"P") + hk:="" + Loop + { + Sleep 50 + MouseGetPos, x3, y3 + x1:=x, y1:=y, x2:=x+w-1, y2:=y+h-1 + , d1:=Abs(x3-x1)<=d, d2:=Abs(x3-x2)<=d + , d3:=Abs(y3-y1)<=d, d4:=Abs(y3-y2)<=d + , d5:=x3>x1+d && x3y1+d && y3zx+zw-box_w && x1:=zx+zw-box_w) + , y1:=y+h+10, (y1>zy+zh-box_h && y1:=y-box_h), (y1<10 && y1:=10) + Gui, SnapShot_Box: Show, NA x%x1% y%y1% + ;------------- + if (oldx=x3 && oldy=y3) + Continue + oldx:=x3, oldy:=y3 + ToolTip % "x: " x " y: " y " w: " w " h: " h "`n" tip + } + Break + } ;// For ReTry + Hotkey, IfWinExist, SnapShot_HotkeyIf + For k,v in StrSplit(keys, "|") + { + KeyWait, %v% + Hotkey, *%v%, %Gui_Off%, Off UseErrorLevel + } + Hotkey, IfWinExist + ToolTip + this.RangeTip() + this.SetCursor() + Gui, SnapShot_Box: Destroy + Gui, SnapShot_HotkeyIf: Destroy + Critical %cri% + ;--------------- + w:=Min(x+w,zx+zw), x:=Max(x,zx), w-=x + h:=Min(y+h,zy+zh), y:=Max(y,zy), h-=y + if (ok=1) + this.SaveBitmapToFile(0, hBM, x-zx, y-zy, w, h) + else if (ok=2) + { + FileSelectFile, file, S18, %A_Desktop%\1.bmp, SaveAs, Image (*.bmp) + this.SaveBitmapToFile(file, hBM, x-zx, y-zy, w, h) + } + DllCall("DeleteObject", "Ptr",hBM) + return [x, y, x+w-1, y+h-1] +} + +SetCursor(cursor:="", args*) +{ + local + static init, tab + if (!VarSetCapacity(init) && init:="1") + { + tab:=[], OnExit(this.SetCursor.Bind(this,"")), this.SetCursor() + s:="ARROW,32512, SIZENWSE,32642, SIZENESW,32643" + . ", SIZEWE,32644, SIZENS,32645, SIZEALL,32646" + . ", IBEAM,32513, WAIT,32514, CROSS,32515, UPARROW,32516" + . ", NO,32648, HAND,32649, APPSTARTING,32650, HELP,32651" + For i,v in StrSplit(s, ",", " ") + (i&1) ? (k:=v) : (tab[k]:=DllCall("CopyImage", "Ptr" + , DllCall("LoadCursor", "Ptr",0, "Ptr",v, "Ptr") + , "int",2, "int",0, "int",0, "int",0, "Ptr")) + } + if (cursor!="") && tab.HasKey(cursor) + DllCall("SetSystemCursor", "Ptr", DllCall("CopyImage", "Ptr",tab[cursor] + , "int",2, "int",0, "int",0, "int",0, "Ptr"), "int",32512) + else + DllCall("SystemParametersInfo", "int",0x57, "int",0, "Ptr",0, "int",0) +} + +BitmapFromScreen(ByRef x:=0, ByRef y:=0, ByRef w:=0, ByRef h:=0 + , ScreenShot:=1, ByRef zx:=0, ByRef zy:=0, ByRef zw:=0, ByRef zh:=0) +{ + local + bits:=this.GetBitsFromScreen(x,y,w,h,ScreenShot,zx,zy,zw,zh) + if (w<1 || h<1 || !bits.hBM) + return + hBM:=this.CreateDIBSection(w, h) + this.CopyHBM(hBM, 0, 0, bits.hBM, x-zx, y-zy, w, h, 1) + return hBM +} + +; Quickly save screen image to BMP file for debugging +; if file = 0 or "", save to Clipboard + +SavePic(file:=0, x1:=0, y1:=0, x2:=0, y2:=0, ScreenShot:=1) +{ + local + x1:=Floor(x1), y1:=Floor(y1), x2:=Floor(x2), y2:=Floor(y2) + if (x1=0 && y1=0 && x2=0 && y2=0) + n:=150000, x:=y:=-n, w:=h:=2*n + else + x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x2-x1)+1, h:=Abs(y2-y1)+1 + hBM:=this.BitmapFromScreen(x, y, w, h, ScreenShot) + this.SaveBitmapToFile(file, hBM) + DllCall("DeleteObject", "Ptr",hBM) +} + +; Save Bitmap To File, if file = 0 or "", save to Clipboard +; hBM_or_file can be a bitmap handle or file path, eg: "c:\1.bmp" -MouseTip(x:="", y:="", w:=10, h:=10, d:=4) +SaveBitmapToFile(file, hBM_or_file, x:=0, y:=0, w:=0, h:=0) { local - if (x="") + if hBM_or_file is Number + hBM_or_file:="HBITMAP:*" hBM_or_file + if !hBM:=DllCall("CopyImage", "Ptr",LoadPicture(hBM_or_file) + , "int",0, "int",0, "int",0, "uint",0x2008) + return + if (file) || (w!=0 && h!=0) + { + (w=0 || h=0) && this.GetBitmapWH(hBM, w, h) + hBM2:=this.CreateDIBSection(w, -h, bpp:=(file ? 24 : 32)) + this.CopyHBM(hBM2, 0, 0, hBM, x, y, w, h) + DllCall("DeleteObject", "Ptr",hBM), hBM:=hBM2 + } + VarSetCapacity(dib, dib_size:=(A_PtrSize=8 ? 104:84)) + , DllCall("GetObject", "Ptr",hBM, "int",dib_size, "Ptr",&dib) + , pbi:=&dib+(bitmap_size:=A_PtrSize=8 ? 32:24) + , size:=NumGet(pbi+20, "uint"), pBits:=NumGet(pbi-A_PtrSize, "Ptr") + if (!file) + { + hdib:=DllCall("GlobalAlloc", "uint",2, "Ptr",40+size, "Ptr") + pdib:=DllCall("GlobalLock", "Ptr",hdib, "Ptr") + DllCall("RtlMoveMemory", "Ptr",pdib, "Ptr",pbi, "Ptr",40) + DllCall("RtlMoveMemory", "Ptr",pdib+40, "Ptr",pBits, "Ptr",size) + DllCall("GlobalUnlock", "Ptr",hdib) + DllCall("OpenClipboard", "Ptr",0) + DllCall("EmptyClipboard") + if !DllCall("SetClipboardData", "uint",8, "Ptr",hdib) + DllCall("GlobalFree", "Ptr",hdib) + DllCall("CloseClipboard") + } + else { - VarSetCapacity(pt,16,0), DllCall("GetCursorPos","ptr",&pt) - x:=NumGet(pt,0,"uint"), y:=NumGet(pt,4,"uint") + VarSetCapacity(bf, 14, 0), NumPut(0x4D42, bf, "short") + NumPut(54+size, bf, 2, "uint"), NumPut(54, bf, 10, "uint") + f:=FileOpen(file, "w"), f.RawWrite(bf, 14) + , f.RawWrite(pbi+0, 40), f.RawWrite(pBits+0, size), f.Close() } - Loop 4 + DllCall("DeleteObject", "Ptr",hBM) +} + +; Show the saved Picture file + +ShowPic(file:="", show:=1, ByRef x:="", ByRef y:="", ByRef w:="", ByRef h:="") +{ + local + if (file="") { - this.RangeTip(x-w, y-h, 2*w+1, 2*h+1, (A_Index & 1 ? "Red":"Blue"), d) - Sleep, 500 + this.ShowScreenShot() + return } - this.RangeTip() + if !(hBM:=LoadPicture(file)) + return + this.GetBitmapWH(hBM, w, h) + this.GetBitsFromScreen(,,,,0,x,y) + bits:=this.GetBitsFromScreen(x,y,w,h,0) + this.CopyHBM(bits.hBM, 0, 0, hBM, 0, 0, w, h) + DllCall("DeleteObject", "Ptr",hBM) + if (show) + this.ShowScreenShot(x, y, x+w-1, y+h-1, 0) } -; Shows a range of the borders, similar to the ToolTip +; Show the memory Screenshot for debugging -RangeTip(x:="", y:="", w:="", h:="", color:="Red", d:=2) +ShowScreenShot(x1:=0, y1:=0, x2:=0, y2:=0, ScreenShot:=1) { local - static id:=0 - if (x="") + static hPic, oldx, oldy, oldw, oldh + x1:=Floor(x1), y1:=Floor(y1), x2:=Floor(x2), y2:=Floor(y2) + if (x1=0 && y1=0 && x2=0 && y2=0) { - id:=0 - Loop 4 - Gui, Range_%A_Index%: Destroy + Gui, FindText_Screen: Destroy return } - if (!id) + x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x2-x1)+1, h:=Abs(y2-y1)+1 + if !hBM:=this.BitmapFromScreen(x,y,w,h,ScreenShot) + return + ;--------------- + Gui, FindText_Screen: +LastFoundExist + IfWinNotExist { - Loop 4 - Gui, Range_%A_Index%: +Hwndid +AlwaysOnTop -Caption +ToolWindow - -DPIScale +E0x08000000 + Gui, FindText_Screen: New ; WS_EX_NOACTIVATE:=0x08000000 + Gui, +AlwaysOnTop -Caption +ToolWindow -DPIScale +E0x08000000 + Gui, Margin, 0, 0 + Gui, Add, Pic, HwndhPic w%w% h%h% + Gui, Show, NA x%x% y%y% w%w% h%h%, Show Pic + oldx:=x, oldy:=y, oldw:=w, oldh:=h } - x:=Floor(x), y:=Floor(y), w:=Floor(w), h:=Floor(h), d:=Floor(d) - Loop 4 + else if (oldx!=x || oldy!=y || oldw!=w || oldh!=h) { - i:=A_Index - , x1:=(i=2 ? x+w : x-d) - , y1:=(i=3 ? y+h : y-d) - , w1:=(i=1 or i=3 ? w+2*d : d) - , h1:=(i=2 or i=4 ? h+2*d : d) - Gui, Range_%i%: Color, %color% - Gui, Range_%i%: Show, NA x%x1% y%y1% w%w1% h%h1% + if (oldw!=w || oldh!=h) + GuiControl, FindText_Screen: Move, %hPic%, w%w% h%h% + Gui, FindText_Screen: Show, NA x%x% y%y% w%w% h%h% + oldx:=x, oldy:=y, oldw:=w, oldh:=h } + this.BitmapToWindow(hPic, 0, 0, hBM, 0, 0, w, h) + DllCall("DeleteObject", "Ptr",hBM) +} + +BitmapToWindow(hwnd, x1, y1, hBM, x2, y2, w, h) +{ + local + mDC:=DllCall("CreateCompatibleDC", "Ptr",0, "Ptr") + oBM:=DllCall("SelectObject", "Ptr",mDC, "Ptr",hBM, "Ptr") + hDC:=DllCall("GetDC", "Ptr",hwnd, "Ptr") + DllCall("BitBlt", "Ptr",hDC, "int",x1, "int",y1, "int",w, "int",h + , "Ptr",mDC, "int",x2, "int",y2, "uint",0xCC0020) + DllCall("ReleaseDC", "Ptr",hwnd, "Ptr",hDC) + DllCall("SelectObject", "Ptr",mDC, "Ptr",oBM) + DllCall("DeleteDC", "Ptr",mDC) } ; Quickly get the search data of screen image GetTextFromScreen(x1, y1, x2, y2, Threshold:="" - , ScreenShot:=1, ByRef rx:="", ByRef ry:="") + , ScreenShot:=1, ByRef rx:="", ByRef ry:="", cut:=1) { local SetBatchLines, % (bch:=A_BatchLines)?"-1":"-1" x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x2-x1)+1, h:=Abs(y2-y1)+1 - this.GetBitsFromScreen(x,y,w,h,ScreenShot,zx,zy,zw,zh) - if (w<1 or h<1) + this.GetBitsFromScreen(x,y,w,h,ScreenShot) + if (w<1 || h<1) { SetBatchLines, %bch% return @@ -1243,7 +1952,7 @@ GetTextFromScreen(x1, y1, x2, y2, Threshold:="" Loop % LastThreshold+1 k:=A_Index-1, IP1+=k*pp[k], IS1+=pp[k] IP2:=IP0-IP1, IS2:=IS0-IS1 - if (IS1!=0 and IS2!=0) + if (IS1!=0 && IS2!=0) Threshold:=Floor((IP1/IS1+IP2/IS2)/2) if (Threshold=LastThreshold) Break @@ -1256,12 +1965,15 @@ GetTextFromScreen(x1, y1, x2, y2, Threshold:="" } ;-------------------- w:=Format("{:d}",w), CutUp:=CutDown:=0 - re1:="(^0{" w "}|^1{" w "})" - re2:="(0{" w "}$|1{" w "}$)" - While RegExMatch(s,re1) - s:=RegExReplace(s,re1), CutUp++ - While RegExMatch(s,re2) - s:=RegExReplace(s,re2), CutDown++ + if (cut=1) + { + re1:="(^0{" w "}|^1{" w "})" + re2:="(0{" w "}$|1{" w "}$)" + While (s~=re1) + s:=RegExReplace(s,re1), CutUp++ + While (s~=re2) + s:=RegExReplace(s,re2), CutDown++ + } rx:=x+w//2, ry:=y+CutUp+(h-CutUp-CutDown)//2 s:="|<>" Threshold "$" w "." this.bit2base64(s) ;-------------------- @@ -1269,107 +1981,6 @@ GetTextFromScreen(x1, y1, x2, y2, Threshold:="" return s } -; Quickly save screen image to BMP file for debugging - -SavePic(file, x1:=0, y1:=0, x2:=0, y2:=0, ScreenShot:=1) -{ - local - if (x1*x1+y1*y1+x2*x2+y2*y2<=0) - n:=150000, x:=y:=-n, w:=h:=2*n - else - x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x2-x1)+1, h:=Abs(y2-y1)+1 - bits:=this.GetBitsFromScreen(x,y,w,h,ScreenShot,zx,zy), x-=zx, y-=zy - if (w<1 or h<1 or !bits.Scan0) - return - hBM:=this.CreateDIBSection(w, -h, bpp:=24, ppvBits, bi) - hBM2:=this.CreateDIBSection(w, h, 32, Scan0), Stride:=w*4 - this.CopyBits(Scan0,Stride,0,0,bits.Scan0,bits.Stride,x,y,w,h) - this.CopyHBM(hBM, 0, 0, hBM2, 0, 0, w, h) - DllCall("DeleteObject", "Ptr",hBM2) - size:=((w*bpp+31)//32)*4*h, NumPut(size, bi, 20, "uint") - VarSetCapacity(bf, 14, 0), StrPut("BM", &bf, "CP0") - NumPut(54+size, bf, 2, "uint"), NumPut(54, bf, 10, "uint") - f:=FileOpen(file,"w"), f.RawWrite(bf,14), f.RawWrite(bi,40) - , f.RawWrite(ppvBits+0, size), f.Close() - DllCall("DeleteObject", "Ptr",hBM) -} - -; Show the saved Picture file - -ShowPic(file:="", show:=1, ByRef x:="", ByRef y:="", ByRef w:="", ByRef h:="") -{ - local - if (file="") - { - this.ShowScreenShot() - return - } - if !FileExist(file) or !(hBM:=LoadPicture(file)) - return - this.GetBitmapWH(hBM, w, h) - bits:=this.GetBitsFromScreen(0,0,0,0,0,x,y) - if (w<1 or h<1 or !bits.Scan0) - { - DllCall("DeleteObject", "Ptr",hBM) - return - } - hBM2:=this.CreateDIBSection(w, h, 32, Scan0), Stride:=w*4 - this.CopyHBM(hBM2, 0, 0, hBM, 0, 0, w, h) - this.CopyBits(bits.Scan0,bits.Stride,0,0,Scan0,Stride,0,0,w,h) - DllCall("DeleteObject", "Ptr",hBM2) - DllCall("DeleteObject", "Ptr",hBM) - if (show) - this.ShowScreenShot(x, y, x+w-1, y+h-1, 0) -} - -; Show the memory Screenshot for debugging - -ShowScreenShot(x1:=0, y1:=0, x2:=0, y2:=0, ScreenShot:=1) -{ - local - static hPic, oldw, oldh - if (x1*x1+y1*y1+x2*x2+y2*y2<=0) - { - Gui, FindText_Screen: Destroy - return - } - x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x2-x1)+1, h:=Abs(y2-y1)+1 - bits:=this.GetBitsFromScreen(x,y,w,h,ScreenShot,zx,zy), x-=zx, y-=zy - if (w<1 or h<1 or !bits.Scan0) - return - hBM:=this.CreateDIBSection(w, h, 32, Scan0), Stride:=w*4 - this.CopyBits(Scan0,Stride,0,0,bits.Scan0,bits.Stride,x,y,w,h) - ;--------------- - Gui, FindText_Screen: +LastFoundExist - IfWinNotExist - { - Gui, FindText_Screen: +AlwaysOnTop -Caption +ToolWindow -DPIScale +E0x08000000 - Gui, FindText_Screen: Margin, 0, 0 - Gui, FindText_Screen: Add, Pic, HwndhPic w%w% h%h% - Gui, FindText_Screen: Show, NA x%zx% y%zy% w%w% h%h%, Show Pic - oldw:=w, oldh:=h - } - else if (oldw!=w or oldh!=h) - { - oldw:=w, oldh:=h - GuiControl, FindText_Screen: Move, %hPic%, w%w% h%h% - Gui, FindText_Screen: Show, NA w%w% h%h% - } - mDC:=DllCall("CreateCompatibleDC", "Ptr",0, "Ptr") - oBM:=DllCall("SelectObject", "Ptr",mDC, "Ptr",hBM, "Ptr") - DllCall("BitBlt", "Ptr",mDC, "int",0, "int",0, "int",w, "int",h - , "Ptr",mDC, "int",0, "int",0, "uint",0xC000CA) ; MERGECOPY - ;--------------- - hDC:=DllCall("GetDC", "Ptr",hPic, "Ptr") - DllCall("BitBlt", "Ptr",hDC, "int",0, "int",0, "int",w, "int",h - , "Ptr",mDC, "int",0, "int",0, "uint",0xCC0020) - DllCall("ReleaseDC", "Ptr",hPic, "Ptr",hDC) - ;--------------- - DllCall("SelectObject", "Ptr",mDC, "Ptr",oBM) - DllCall("DeleteDC", "Ptr",mDC) - DllCall("DeleteObject", "Ptr",hBM) -} - ; Wait for the screen image to change within a few seconds ; Take a Screenshot before using it: FindText().ScreenShot() @@ -1382,23 +1993,43 @@ WaitChange(time:=-1, x1:=0, y1:=0, x2:=0, y2:=0) { if (hash!=this.GetPicHash(x1, y1, x2, y2, 1)) return 1 - if (time>=0 and A_TickCount>=timeout) + if (time>=0 && A_TickCount>=timeout) Break - Sleep, 10 + Sleep 10 } return 0 } +; Wait for the screen image to stabilize + +WaitNotChange(time:=1, timeout:=30, x1:=0, y1:=0, x2:=0, y2:=0) +{ + local + oldhash:="", timeout:=A_TickCount+Round(timeout*1000) + Loop + { + hash:=this.GetPicHash(x1, y1, x2, y2, 1), t:=A_TickCount + if (hash!=oldhash) + oldhash:=hash, timeout2:=t+Round(time*1000) + if (t>=timeout2) + return 1 + if (t>=timeout) + return 0 + Sleep 10 + } +} + GetPicHash(x1:=0, y1:=0, x2:=0, y2:=0, ScreenShot:=1) { local - static h:=DllCall("LoadLibrary", "Str","ntdll", "Ptr") - if (x1*x1+y1*y1+x2*x2+y2*y2<=0) + static init:=DllCall("LoadLibrary", "Str","ntdll", "Ptr") + x1:=Floor(x1), y1:=Floor(y1), x2:=Floor(x2), y2:=Floor(y2) + if (x1=0 && y1=0 && x2=0 && y2=0) n:=150000, x:=y:=-n, w:=h:=2*n else x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x2-x1)+1, h:=Abs(y2-y1)+1 bits:=this.GetBitsFromScreen(x,y,w,h,ScreenShot,zx,zy), x-=zx, y-=zy - if (w<1 or h<1 or !bits.Scan0) + if (w<1 || h<1 || !bits.Scan0) return 0 hash:=0, Stride:=bits.Stride, p:=bits.Scan0+(y-1)*Stride+x*4, w*=4 Loop % h @@ -1410,14 +2041,17 @@ GetPicHash(x1:=0, y1:=0, x2:=0, y2:=0, ScreenShot:=1) WindowToScreen(ByRef x, ByRef y, x1, y1, id:="") { local - WinGetPos, winx, winy,,, % id ? "ahk_id " id : "A" - x:=x1+Floor(winx), y:=y1+Floor(winy) + if (!id) + WinGet, id, ID, A + VarSetCapacity(rect, 16, 0) + , DllCall("GetWindowRect", "Ptr",id, "Ptr",&rect) + , x:=x1+NumGet(rect,"int"), y:=y1+NumGet(rect,4,"int") } ScreenToWindow(ByRef x, ByRef y, x1, y1, id:="") { local - this.WindowToScreen(dx,dy,0,0,id), x:=x1-dx, y:=y1-dy + this.WindowToScreen(dx, dy, 0, 0, id), x:=x1-dx, y:=y1-dy } ClientToScreen(ByRef x, ByRef y, x1, y1, id:="") @@ -1425,7 +2059,7 @@ ClientToScreen(ByRef x, ByRef y, x1, y1, id:="") local if (!id) WinGet, id, ID, A - VarSetCapacity(pt,8,0), NumPut(0,pt,"int64") + VarSetCapacity(pt, 8, 0), NumPut(0, pt, "int64") , DllCall("ClientToScreen", "Ptr",id, "Ptr",&pt) , x:=x1+NumGet(pt,"int"), y:=y1+NumGet(pt,4,"int") } @@ -1433,30 +2067,43 @@ ClientToScreen(ByRef x, ByRef y, x1, y1, id:="") ScreenToClient(ByRef x, ByRef y, x1, y1, id:="") { local - this.ClientToScreen(dx,dy,0,0,id), x:=x1-dx, y:=y1-dy + this.ClientToScreen(dx, dy, 0, 0, id), x:=x1-dx, y:=y1-dy } ; It is not like FindText always use Screen Coordinates, ; But like built-in command ImageSearch using CoordMode Settings +; ImageFile can use "*n *TransBlack-White-RRGGBB... d:\a.bmp" -ImageSearch(ByRef rx, ByRef ry, x1, y1, x2, y2, text - , ScreenShot:=1, FindAll:=0) +ImageSearch(ByRef rx:="", ByRef ry:="", x1:=0, y1:=0, x2:=0, y2:=0 + , ImageFile:="", ScreenShot:=1, FindAll:=0) { local dx:=dy:=0 if (A_CoordModePixel="Window") - this.WindowToScreen(dx,dy,0,0) + this.WindowToScreen(dx, dy, 0, 0) else if (A_CoordModePixel="Client") - this.ClientToScreen(dx,dy,0,0) - if FileExist(pic:=RegExReplace(text,"\*\S+\s+")) - text:="|<>##10$" pic - if (ok:=this.FindText(x, y, x1+dx, y1+dy, x2+dx, y2+dy + this.ClientToScreen(dx, dy, 0, 0) + text:="" + Loop Parse, ImageFile, | + if (v:=Trim(A_LoopField))!="" + { + text.=InStr(v,"$") ? "|" v : "|##" + . (RegExMatch(v, "O)(^|\s)\*(\d+)\s", r) + ? Format("{:06X}", r[2]<<16|r[2]<<8|r[2]) : "000000") + . (RegExMatch(v, "Oi)(^|\s)\*Trans([\-\w]+)\s", r) + ? "-" . Trim(r[2],"-") : "") . "$" + . Trim(RegExReplace(v, "(?<=^|\s)\*\S+")) + } + x1:=Floor(x1), y1:=Floor(y1), x2:=Floor(x2), y2:=Floor(y2) + if (x1=0 && y1=0 && x2=0 && y2=0) + n:=150000, x1:=y1:=-n, x2:=y2:=n + if (ok:=this.FindText(,, x1+dx, y1+dy, x2+dx, y2+dy , 0, 0, text, ScreenShot, FindAll)) { For k,v in ok ; you can use ok:=FindText().ok - v[1]-=dx, v[2]-=dy, v.x-=dx, v.y-=dy - rx:=x-dx, ry:=y-dy, ErrorLevel:=0 - return 1 + v.1-=dx, v.2-=dy, v.x-=dx, v.y-=dy + rx:=ok[1].1, ry:=ok[1].2, ErrorLevel:=0 + return ok } else { @@ -1465,16 +2112,85 @@ ImageSearch(ByRef rx, ByRef ry, x1, y1, x2, y2, text } } -Click(x:="", y:="", other:="") +; It is not like FindText always use Screen Coordinates, +; But like built-in command PixelSearch using CoordMode Settings +; ColorID can use "RRGGBB-DRDGDB|RRGGBB-DRDGDB", Variation in 0-255 + +PixelSearch(ByRef rx:="", ByRef ry:="", x1:=0, y1:=0, x2:=0, y2:=0 + , ColorID:="", Variation:=0, ScreenShot:=1, FindAll:=0) +{ + local + n:=Floor(Variation), text:=Format("##{:06X}$0/0", n<<16|n<<8|n) + Loop Parse, ColorID, | + if (v:=Trim(A_LoopField))!="" + text.="/" v + return this.ImageSearch(rx, ry, x1, y1, x2, y2, text, ScreenShot, FindAll) +} + +; Pixel count of certain colors within the range indicated by Screen Coordinates +; ColorID can use "RRGGBB-DRDGDB|RRGGBB-DRDGDB", Variation in 0-255 + +PixelCount(x1:=0, y1:=0, x2:=0, y2:=0, ColorID:="", Variation:=0, ScreenShot:=1) +{ + local + SetBatchLines, % (bch:=A_BatchLines)?"-1":"-1" + x1:=Floor(x1), y1:=Floor(y1), x2:=Floor(x2), y2:=Floor(y2) + if (x1=0 && y1=0 && x2=0 && y2=0) + n:=150000, x:=y:=-n, w:=h:=2*n + else + x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x2-x1)+1, h:=Abs(y2-y1)+1 + bits:=this.GetBitsFromScreen(x,y,w,h,ScreenShot,zx,zy), x-=zx, y-=zy + sum:=0, VarSetCapacity(s1,4), VarSetCapacity(s0,4) + , ini:={ bits:bits, ss:0, s1:&s1, s0:&s0 + , err1:0, err0:0, allpos_max:0, zoomW:1, zoomH:1 } + , n:=Floor(Variation), text:=Format("##{:06X}$0/0", n<<16|n<<8|n) + Loop Parse, ColorID, | + if (v:=Trim(A_LoopField))!="" + text.="/" v + if (w>0 && h>0 && bits.Scan0) && IsObject(j:=this.PicInfo(text)) + sum:=this.PicFind(ini, j, 1, x, y, w, h, 0) + SetBatchLines, %bch% + return sum +} + +Click(x:="", y:="", other1:="", other2:="", GoBack:=0) { local - bak:=A_CoordModeMouse - CoordMode, Mouse, Screen + CoordMode, Mouse, % (bak:=A_CoordModeMouse)?"Screen":"Screen" + if GoBack + MouseGetPos, oldx, oldy MouseMove, x, y, 0 - Click, %x%, %y%, %other% + Click % x "," y "," other1 "," other2 + if GoBack + MouseMove, oldx, oldy, 0 CoordMode, Mouse, %bak% } +; Using ControlClick instead of Click, Use Screen Coordinates, +; If you want to click on the background window, please provide hwnd + +ControlClick(x, y, WhichButton:="", ClickCount:=1, Opt:="", hwnd:="") +{ + local + if !hwnd + hwnd:=DllCall("WindowFromPoint", "int64",y<<32|x&0xFFFFFFFF, "Ptr") + VarSetCapacity(pt,8,0), ScreenX:=x, ScreenY:=y + Loop + { + NumPut(0,pt,"int64"), DllCall("ClientToScreen", "Ptr",hwnd, "Ptr",&pt) + , x:=ScreenX-NumGet(pt,"int"), y:=ScreenY-NumGet(pt,4,"int") + , id:=DllCall("ChildWindowFromPoint", "Ptr",hwnd, "int64",y<<32|x, "Ptr") + if (!id || id=hwnd) + Break + else hwnd:=id + } + DetectHiddenWindows, % (bak:=A_DetectHiddenWindows)?1:1 + PostMessage, 0x200, 0, y<<16|x,, ahk_id %hwnd% ; WM_MOUSEMOVE + SetControlDelay -1 + ControlClick, x%x% y%y%, ahk_id %hwnd%,, %WhichButton%, %ClickCount%, NA Pos %Opt% + DetectHiddenWindows, % bak +} + ; Running AHK code dynamically with new threads Class Thread @@ -1485,43 +2201,37 @@ Class Thread } __Delete() { - DetectHiddenWindows, On - WinWait, % "ahk_pid " this.pid,, 0.5 - IfWinExist, % "ahk_class AutoHotkey ahk_pid " this.pid - { - PostMessage, 0x111, 65307 - WinWaitClose,,, 0.5 - } Process, Close, % this.pid } - Exec(s, Ahk:="", args:="") + Exec(s, Ahk:="", args:="") ; required AHK v1.1.34+ { local - Ahk:=Ahk ? Ahk:A_IsCompiled ? A_ScriptDir "\AutoHotkey.exe":A_AhkPath + Ahk:=Ahk ? Ahk : A_IsCompiled ? A_ScriptFullPath : A_AhkPath + add:=A_IsCompiled ? " /script " : "" s:="`nDllCall(""SetWindowText"",""Ptr"",A_ScriptHwnd,""Str"","""")`n" - . "`nSetBatchLines,-1`n" . StrReplace(s,"`r") + . "`nSetBatchLines,-1`n" . s, s:=RegExReplace(s, "\R", "`r`n") Try { shell:=ComObjCreate("WScript.Shell") - oExec:=shell.Exec("""" Ahk """ /force * " args) + oExec:=shell.Exec("""" Ahk """" add " /force /CP0 * " args) oExec.StdIn.Write(s) oExec.StdIn.Close(), pid:=oExec.ProcessID } Catch { f:=A_Temp "\~ahk.tmp" - s:="`n FileDelete, " f "`n" s - FileDelete, %f% - FileAppend, %s%, %f% + s:="`r`nTry FileDelete " f "`r`n" s + Try FileDelete %f% + FileAppend %s%, %f% r:=this.Clear.Bind(this) - SetTimer, %r%, -3000 - Run, "%Ahk%" /force "%f%" %args%,, UseErrorLevel, pid + SetTimer %r%, -3000 + Run "%Ahk%" %add% /force /CP0 "%f%" %args%,, UseErrorLevel, pid } return pid } Clear() { - FileDelete, % A_Temp "\~ahk.tmp" + Try FileDelete % A_Temp "\~ahk.tmp" SetTimer,, Off } } @@ -1530,7 +2240,8 @@ Class Thread QPC() { - static f:=0, c:=DllCall("QueryPerformanceFrequency","Int*",f)+(f/=1000) + static f:="", c + (!f) && DllCall("QueryPerformanceFrequency","Int*",f)+(f/=1000) return (!DllCall("QueryPerformanceCounter","Int64*",c))*0+(c/f) } @@ -1539,309 +2250,163 @@ QPC() ToolTip(s:="", x:="", y:="", num:=1, arg:="") { local - static ini:=[], ToolTipOff:="" - f:= "ToolTip_" . Round(num) + static init, ini, timer + if (!VarSetCapacity(init) && init:="1") + ini:=[], timer:=[] + f:="ToolTip_" . Floor(num) if (s="") { - ini.Delete(f) + ini[f]:="" Gui, %f%: Destroy return } ;----------------- r1:=A_CoordModeToolTip r2:=A_CoordModeMouse - CoordMode, Mouse, Screen - MouseGetPos, x1, y1 - CoordMode, Mouse, %r1% - MouseGetPos, x2, y2 - CoordMode, Mouse, %r2% - x:=Round(x="" ? x1+16 : x+x1-x2) - y:=Round(y="" ? y1+16 : y+y1-y2) + CoordMode Mouse, Screen + MouseGetPos x1, y1 + CoordMode Mouse, %r1% + MouseGetPos x2, y2 + CoordMode Mouse, %r2% + (x!="" && x:="x" (Floor(x)+x1-x2)) + , (y!="" && y:="y" (Floor(y)+y1-y2)) + , (x="" && y="" && x:="x" (x1+16) " y" (y1+16)) ;----------------- bgcolor:=arg.bgcolor!="" ? arg.bgcolor : "FAFBFC" color:=arg.color!="" ? arg.color : "Black" font:=arg.font ? arg.font : "Consolas" size:=arg.size ? arg.size : "10" bold:=arg.bold ? arg.bold : "" - trans:=arg.trans!="" ? Round(arg.trans & 255) : 255 + trans:=arg.trans!="" ? arg.trans & 255 : 255 timeout:=arg.timeout!="" ? arg.timeout : "" ;----------------- - r:=bgcolor "|" color "|" font "|" size "|" bold "|" trans "|" s - if (ini[f]!=r) - { - ini[f]:=r - Gui, %f%: Destroy - Gui, %f%: +AlwaysOnTop -Caption +ToolWindow - -DPIScale +Hwndid +E0x80020 - Gui, %f%: Margin, 2, 2 - Gui, %f%: Color, %bgcolor% - Gui, %f%: Font, c%color% s%size% %bold%, %font% - Gui, %f%: Add, Text,, %s% - Gui, %f%: Show, Hide, %f% - ;------------------ - dhw:=A_DetectHiddenWindows - DetectHiddenWindows, On - WinSet, Transparent, %trans%, ahk_id %id% - DetectHiddenWindows, %dhw% - } - Gui, %f%: +AlwaysOnTop - Gui, %f%: Show, NA x%x% y%y% - if (timeout) - { - if (!ToolTipOff) - ToolTipOff:=this.ToolTip.Bind(this,"") - SetTimer, %ToolTipOff%, % -Round(Abs(timeout*1000))-1 - } -} - -; FindText().ObjView() view object values for Debug - -ObjView(obj, keyname="") -{ - local - if IsObject(obj) ; thanks lexikos's type(v) - { - s:="" - For k,v in obj - s.=this.ObjView(v, keyname "[" (StrLen(k)>1000 - || [k].GetCapacity(1) ? """" k """":k) "]") - } - else - s:=keyname ": " (StrLen(obj)>1000 - || [obj].GetCapacity(1) ? """" obj """":obj) "`n" - if (keyname!="") - return s - ;------------------ - Gui, Gui_DeBug_Gui: Destroy - Gui, Gui_DeBug_Gui: +AlwaysOnTop +Hwndid - Gui, Gui_DeBug_Gui: Add, Button, y270 w350 gCancel Default, OK - Gui, Gui_DeBug_Gui: Add, Edit, xp y10 w350 h250 -Wrap -WantReturn - GuiControl, Gui_DeBug_Gui:, Edit1, %s% - Gui, Gui_DeBug_Gui: Show,, Debug view object values - DetectHiddenWindows, Off - WinWaitClose, ahk_id %id% - Gui, Gui_DeBug_Gui: Destroy -} - - -/***** C source code of machine code ***** - -int __attribute__((__stdcall__)) PicFind( - int mode, unsigned int c, unsigned int n, int dir - , unsigned char * Bmp, int Stride, int zw, int zh - , int sx, int sy, int sw, int sh - , char * ss, unsigned int * s1, unsigned int * s0 - , char * text, int w, int h, int err1, int err0 - , unsigned int * allpos, int allpos_max - , int new_w, int new_h ) -{ - int ok=0, o, i, j, k, v, r, g, b, rr, gg, bb; - int x, y, x1, y1, x2, y2, len1, len0, e1, e0, max; - int r_min, r_max, g_min, g_max, b_min, b_max, x3, y3; - unsigned char * gs; - unsigned long long sum; - //---------------------- - // MultiColor or PixelSearch or ImageSearch Mode - if (mode==5) - { - max=n; v=c*c; - for (i=0, sum=0, o=0; (j=text[o++])!='\0';) - { - if (j>='0' && j<='9') - sum = sum*10 + (j-'0'); - else if (j=='/') - { - y=(sum>>16)&0xFFFF; x=sum&0xFFFF; - s1[i]=(y*new_h/h)*Stride+(x*new_w/w)*4; - s0[i++]=sum>>32; sum=0; - } - } - goto StartLookUp; - } - //---------------------- - // Generate Lookup Table - o=0; len1=0; len0=0; - for (y=0; y=len1) len1=0; - if (err0>=len0) len0=0; - max=(len1>len0) ? len1 : len0; - //---------------------- - // Color Position Mode - // only used to recognize multicolored Verification Code - if (mode==3) - { - y=c>>16; x=c&0xFFFF; - c=(y*new_h/h)*Stride+(x*new_w/w)*4; - goto StartLookUp; - } - //---------------------- - // Generate Two Value Image - o=sy*Stride+sx*4; j=Stride-sw*4; i=0; - if (mode==0) // Color Mode - { - rr=(c>>16)&0xFF; gg=(c>>8)&0xFF; bb=c&0xFF; - for (y=0; y=zw || y<0 || y>=zh) - gs[i]=0; - else - { - o=y*Stride+x*4; - gs[i]=(Bmp[2+o]*38+Bmp[1+o]*75+Bmp[o]*15)>>7; - } - } - k=sw+2; i=0; - for (y=1; y<=sh; y++) - for (x=1; x<=sw; x++, i++) - { - o=y*k+x; n=gs[o]+c; - ss[i]=(gs[o-1]>n || gs[o+1]>n - || gs[o-k]>n || gs[o+k]>n - || gs[o-k-1]>n || gs[o-k+1]>n - || gs[o+k-1]>n || gs[o+k+1]>n) ? 1:0; - } + (!timer.HasKey(f) && timer[f]:=this.ToolTip.Bind(this,"","","",num)) + , r:=timer[f] + SetTimer, %r%, % -Round(Abs(timeout*1000))-1 } - else // (mode==4) Color Difference Mode +} + +; FindText().ObjView() view object values for Debug + +ObjView(obj, keyname:="") +{ + local + if IsObject(obj) ; thanks lexikos's type(v) { - r=(c>>16)&0xFF; g=(c>>8)&0xFF; b=c&0xFF; - rr=(n>>16)&0xFF; gg=(n>>8)&0xFF; bb=n&0xFF; - r_min=r-rr; g_min=g-gg; b_min=b-bb; - r_max=r+rr; g_max=g+gg; b_max=b+bb; - for (y=0; y=r_min && r<=r_max - && g>=g_min && g<=g_max - && b>=b_min && b<=b_max) ? 1:0; - } + s:="" + For k,v in obj + s.=this.ObjView(v, keyname "[" (StrLen(k)>1000 + || [k].GetCapacity(1) ? """" k """":k) "]") } - //---------------------- - StartLookUp: - w=new_w; h=new_h; - if (mode==5 || mode==3) - { x1=sx; y1=sy; x2=sx+sw-w; y2=sy+sh-h; sx=0; sy=0; } else - { x1=0; y1=0; x2=sw-w; y2=sh-h; } - if (dir<1 || dir>8) dir=1; - // 1 ==> ( Left to Right ) Top to Bottom - // 2 ==> ( Right to Left ) Top to Bottom - // 3 ==> ( Left to Right ) Bottom to Top - // 4 ==> ( Right to Left ) Bottom to Top - // 5 ==> ( Top to Bottom ) Left to Right - // 6 ==> ( Bottom to Top ) Left to Right - // 7 ==> ( Top to Bottom ) Right to Left - // 8 ==> ( Bottom to Top ) Right to Left - if (--dir>3) { i=y1; y1=x1; x1=i; i=y2; y2=x2; x2=i; } - for (y3=y1; y3<=y2; y3++) + s:=keyname ": " (StrLen(obj)>1000 + || [obj].GetCapacity(1) ? """" obj """":obj) "`n" + if (keyname!="") + return s + ;------------------ + Gui, Gui_DeBug_Gui: New + Gui, +LastFound +AlwaysOnTop + Gui, Add, Button, y270 w350 gCancel Default, OK + Gui, Add, Edit, xp y10 w350 h250 -Wrap -WantReturn + GuiControl,, Edit1, %s% + Gui, Show,, Debug view object values + DetectHiddenWindows, 0 + WinWaitClose, % "ahk_id " WinExist() + Gui, Destroy +} + +; Get Script from Compiled programs + +GetScript() ; thanks TAC109 +{ + local + if (!A_IsCompiled) + return + For i,ahk in ["#1", ">AUTOHOTKEY SCRIPT<"] + if (rc:=DllCall("FindResource", "Ptr",0, "Str",ahk, "Ptr",10, "Ptr")) + && (sz:=DllCall("SizeofResource", "Ptr",0, "Ptr",rc, "Uint")) + && (pt:=DllCall("LoadResource", "Ptr",0, "Ptr",rc, "Ptr")) + && (pt:=DllCall("LockResource", "Ptr",pt, "Ptr")) + && (DllCall("VirtualProtect", "Ptr",pt, "Ptr",sz, "UInt",0x4, "UInt*",0)) + && (InStr(StrGet(pt, 20, "utf-8"), "1) ? y1+y2-y3 : y3; - x=(dir&1) ? x1+x2-x3 : x3; - if (dir>3) { i=y; y=x; x=i; } - //---------------------- - e1=err1; e0=err0; - if (mode==5) - { - o=y*Stride+x*4; - for (i=0; i>16)&0xFF); - g=Bmp[1+j]-((c>>8)&0xFF); b=Bmp[j]-(c&0xFF); - if ((r*r>v || g*g>v || b*b>v) && (--e1)<0) - goto NoMatch; - } - } - else if (mode==3) - { - o=y*Stride+x*4; - j=o+c; rr=Bmp[2+j]; gg=Bmp[1+j]; bb=Bmp[j]; - for (i=0; in && (--e1)<0) - goto NoMatch; - } - if (i=allpos_max) goto Return1; - NoMatch:; - } + WinMinimize + WinHide + ToolTip + DetectHiddenWindows, 0 + WinWaitClose, % "ahk_id " WinExist() } - //---------------------- - Return1: - return ok; } -*/ - ;==== Optional GUI interface ==== -Gui(cmd, arg1:="") +Gui(cmd, arg1:="", args*) { local static - local bch, cri - static init:=0 - if (!init) + local bch, cri, lls + ListLines, % InStr("MouseMove|ToolTipOff",cmd)?0:A_ListLines + static init + if (!VarSetCapacity(init) && init:="1") { - init:=1 + SavePicDir:=A_Temp "\Ahk_ScreenShot" Gui_ := this.Gui.Bind(this) Gui_G := this.Gui.Bind(this, "G") Gui_Run := this.Gui.Bind(this, "Run") @@ -1856,10 +2421,11 @@ Gui(cmd, arg1:="") Gui_ToolTip := this.Gui.Bind(this, "ToolTip") Gui_ToolTipOff := this.Gui.Bind(this, "ToolTipOff") Gui_SaveScr := this.Gui.Bind(this, "SaveScr") + Gui_SetColor := this.Gui.Bind(this, "SetColor") bch:=A_BatchLines, cri:=A_IsCritical Critical #NoEnv - %Gui_%("Load_Language_Text") + Lang:=this.Lang(,1), Tip_Text:=this.Lang(,2) %Gui_%("MakeCaptureWindow") %Gui_%("MakeMainWindow") OnMessage(0x100, Gui_KeyDown) @@ -1867,7 +2433,7 @@ Gui(cmd, arg1:="") OnMessage(0x200, Gui_MouseMove) Menu, Tray, Add Menu, Tray, Add, % Lang["s1"], %Gui_Show% - if (!A_IsCompiled and A_LineFile=A_ScriptFullPath) + if (!A_IsCompiled && A_LineFile=A_ScriptFullPath) { Menu, Tray, Default, % Lang["s1"] Menu, Tray, Click, 1 @@ -1875,12 +2441,17 @@ Gui(cmd, arg1:="") } Critical, %cri% SetBatchLines, %bch% + Gui, New, +LastFound + Gui, Destroy + ;------------------- + Pics:="", PrevControl:="" } Switch cmd { Case "Off": - return hk:=SubStr(A_ThisHotkey,2) + return hk:=Trim(A_ThisHotkey, "*") Case "G": + id:=this.LastCtrl() GuiControl, +g, %id%, %Gui_Run% return Case "Run": @@ -1888,72 +2459,65 @@ Gui(cmd, arg1:="") %Gui_%(A_GuiControl) return Case "Show": - Gui, FindText_Main: Default - Gui, Show, Center - GuiControl, Focus, scr + Gui, FindText_Main: Show, % arg1 ? "Center" : "" + GuiControl, Focus, %hscr% + return + Case "Cancel", "Cancel2": + WinHide return Case "MakeCaptureWindow": WindowColor:="0xDDEEFF" Gui, FindText_Capture: New - Gui, +AlwaysOnTop -DPIScale + Gui, +LastFound +AlwaysOnTop -DPIScale Gui, Margin, 15, 15 Gui, Color, %WindowColor% Gui, Font, s12, Verdana - Gui, -Theme - ww:=35, hh:=12, nW:=71, nH:=25, w:=11, C_:=[], Cid_:=[] - Loop % nW*(nH+1) - { - i:=A_Index, j:=i=1 ? "" : Mod(i,nW)=1 ? "xm y+1":"x+1" - Gui, Add, Progress, w%w% h%w% %j% Hwndid - Control, ExStyle, -0x20000,, ahk_id %id% - C_[i]:=id, Cid_[id]:=i - } - Gui, +Theme - GuiControlGet, p, Pos, %id% - w:=pX+pW-15, h:=pY+pH-15 - Gui, Add, Slider, xm w%w% vMySlider1 Hwndid Disabled + ww:=35, hh:=12, nW:=71, nH:=25, w:=h:=12 + w:=nW*(w+1), h:=(nH+1)*(h+1) + Gui, Add, Text, w%w% h%h% + Gui, Add, Slider, xm w%w% vMySlider1 Disabled +Center Page20 Line10 NoTicks AltSubmit %Gui_G%() - Gui, Add, Slider, ym h%h% vMySlider2 Hwndid Disabled + Gui, Add, Slider, ym h%h% vMySlider2 Disabled +Center Page20 Line10 NoTicks AltSubmit +Vertical %Gui_G%() - GuiControlGet, p, Pos, %id% + GuiControlGet, p, Pos, % this.LastCtrl() k:=pX+pW, MySlider1:=MySlider2:=dx:=dy:=0 ;-------------- - Gui, Add, Button, xm Hwndid Hidden Section, % Lang["Auto"] - GuiControlGet, p, Pos, %id% + Gui, Add, Button, xm Hidden Section, % Lang["Auto"] + GuiControlGet, p, Pos, % this.LastCtrl() w:=Round(pW*0.75), i:=Round(w*3+15+pW*0.5-w*1.5) - Gui, Add, Button, xm+%i% yp w%w% hp -Wrap vRepU Hwndid, % Lang["RepU"] + Gui, Add, Button, xm+%i% yp w%w% hp -Wrap vRepU, % Lang["RepU"] %Gui_G%() - Gui, Add, Button, x+0 wp hp -Wrap vCutU Hwndid, % Lang["CutU"] + Gui, Add, Button, x+0 wp hp -Wrap vCutU, % Lang["CutU"] %Gui_G%() - Gui, Add, Button, x+0 wp hp -Wrap vCutU3 Hwndid, % Lang["CutU3"] + Gui, Add, Button, x+0 wp hp -Wrap vCutU3, % Lang["CutU3"] %Gui_G%() - Gui, Add, Button, xm wp hp -Wrap vRepL Hwndid, % Lang["RepL"] + Gui, Add, Button, xm wp hp -Wrap vRepL, % Lang["RepL"] %Gui_G%() - Gui, Add, Button, x+0 wp hp -Wrap vCutL Hwndid, % Lang["CutL"] + Gui, Add, Button, x+0 wp hp -Wrap vCutL, % Lang["CutL"] %Gui_G%() - Gui, Add, Button, x+0 wp hp -Wrap vCutL3 Hwndid, % Lang["CutL3"] + Gui, Add, Button, x+0 wp hp -Wrap vCutL3, % Lang["CutL3"] %Gui_G%() - Gui, Add, Button, x+15 w%pW% hp -Wrap vAuto Hwndid, % Lang["Auto"] + Gui, Add, Button, x+15 w%pW% hp -Wrap vAuto, % Lang["Auto"] %Gui_G%() - Gui, Add, Button, x+15 w%w% hp -Wrap vRepR Hwndid, % Lang["RepR"] + Gui, Add, Button, x+15 w%w% hp -Wrap vRepR, % Lang["RepR"] %Gui_G%() - Gui, Add, Button, x+0 wp hp -Wrap vCutR Hwndid, % Lang["CutR"] + Gui, Add, Button, x+0 wp hp -Wrap vCutR, % Lang["CutR"] %Gui_G%() - Gui, Add, Button, x+0 wp hp -Wrap vCutR3 Hwndid, % Lang["CutR3"] + Gui, Add, Button, x+0 wp hp -Wrap vCutR3, % Lang["CutR3"] %Gui_G%() - Gui, Add, Button, xm+%i% wp hp -Wrap vRepD Hwndid, % Lang["RepD"] + Gui, Add, Button, xm+%i% wp hp -Wrap vRepD, % Lang["RepD"] %Gui_G%() - Gui, Add, Button, x+0 wp hp -Wrap vCutD Hwndid, % Lang["CutD"] + Gui, Add, Button, x+0 wp hp -Wrap vCutD, % Lang["CutD"] %Gui_G%() - Gui, Add, Button, x+0 wp hp -Wrap vCutD3 Hwndid, % Lang["CutD3"] + Gui, Add, Button, x+0 wp hp -Wrap vCutD3, % Lang["CutD3"] %Gui_G%() ;-------------- - Gui, Add, Text, x+80 ys+3 Section, % Lang["SelGray"] + Gui, Add, Text, x+60 ys+3 Section, % Lang["SelGray"] Gui, Add, Edit, x+3 yp-3 w60 vSelGray ReadOnly Gui, Add, Text, x+15 ys, % Lang["SelColor"] - Gui, Add, Edit, x+3 yp-3 w120 vSelColor ReadOnly + Gui, Add, Edit, x+3 yp-3 w150 vSelColor ReadOnly Gui, Add, Text, x+15 ys, % Lang["SelR"] Gui, Add, Edit, x+3 yp-3 w60 vSelR ReadOnly Gui, Add, Text, x+5 ys, % Lang["SelG"] @@ -1966,28 +2530,26 @@ Gui(cmd, arg1:="") Gui, Tab, 1 Gui, Add, Text, x+15 y+15, % Lang["Threshold"] Gui, Add, Edit, x+15 w100 vThreshold - Gui, Add, Button, x+15 yp-3 vGray2Two Hwndid, % Lang["Gray2Two"] + Gui, Add, Button, x+15 yp-3 vGray2Two, % Lang["Gray2Two"] %Gui_G%() Gui, Tab, 2 Gui, Add, Text, x+15 y+15, % Lang["GrayDiff"] Gui, Add, Edit, x+15 w100 vGrayDiff, 50 - Gui, Add, Button, x+15 yp-3 vGrayDiff2Two Hwndid, % Lang["GrayDiff2Two"] + Gui, Add, Button, x+15 yp-3 vGrayDiff2Two, % Lang["GrayDiff2Two"] %Gui_G%() Gui, Tab, 3 Gui, Add, Text, x+15 y+15, % Lang["Similar1"] " 0" - Gui, Add, Slider, x+0 w120 vSimilar1 Hwndid - +Center Page1 NoTicks ToolTip, 100 + Gui, Add, Slider, x+0 w120 vSimilar1 +Center Page1 NoTicks ToolTip, 100 %Gui_G%() Gui, Add, Text, x+0, 100 - Gui, Add, Button, x+15 yp-3 vColor2Two Hwndid, % Lang["Color2Two"] + Gui, Add, Button, x+15 yp-3 vColor2Two, % Lang["Color2Two"] %Gui_G%() Gui, Tab, 4 Gui, Add, Text, x+15 y+15, % Lang["Similar2"] " 0" - Gui, Add, Slider, x+0 w120 vSimilar2 Hwndid - +Center Page1 NoTicks ToolTip, 100 + Gui, Add, Slider, x+0 w120 vSimilar2 +Center Page1 NoTicks ToolTip, 100 %Gui_G%() Gui, Add, Text, x+0, 100 - Gui, Add, Button, x+15 yp-3 vColorPos2Two Hwndid, % Lang["ColorPos2Two"] + Gui, Add, Button, x+15 yp-3 vColorPos2Two, % Lang["ColorPos2Two"] %Gui_G%() Gui, Tab, 5 Gui, Add, Text, x+10 y+15, % Lang["DiffR"] @@ -1999,110 +2561,123 @@ Gui(cmd, arg1:="") Gui, Add, Text, x+5, % Lang["DiffB"] Gui, Add, Edit, x+5 w80 vDiffB Limit3 Gui, Add, UpDown, vdB Range0-255 Wrap - Gui, Add, Button, x+15 yp-3 vColorDiff2Two Hwndid, % Lang["ColorDiff2Two"] + Gui, Add, Button, x+15 yp-3 vColorDiff2Two, % Lang["ColorDiff2Two"] %Gui_G%() Gui, Tab, 6 Gui, Add, Text, x+10 y+15, % Lang["DiffRGB"] Gui, Add, Edit, x+5 w80 vDiffRGB Limit3 Gui, Add, UpDown, vdRGB Range0-255 Wrap - Gui, Add, Checkbox, x+15 yp+5 vMultiColor Hwndid, % Lang["MultiColor"] + Gui, Add, Checkbox, x+15 yp+5 vMultiColor, % Lang["MultiColor"] %Gui_G%() - Gui, Add, Button, x+15 yp-5 vUndo Hwndid, % Lang["Undo"] + Gui, Add, Button, x+15 yp-5 vUndo, % Lang["Undo"] %Gui_G%() Gui, Tab ;-------------- - Gui, Add, Button, xm vReset Hwndid, % Lang["Reset"] + Gui, Add, Button, xm vReset, % Lang["Reset"] %Gui_G%() - Gui, Add, Checkbox, x+15 yp+5 vModify Hwndid, % Lang["Modify"] + Gui, Add, Checkbox, x+15 yp+5 vModify, % Lang["Modify"] %Gui_G%() Gui, Add, Text, x+30, % Lang["Comment"] Gui, Add, Edit, x+5 yp-2 w150 vComment - Gui, Add, Button, x+30 yp-3 vSplitAdd Hwndid, % Lang["SplitAdd"] + Gui, Add, Button, x+10 yp-3 vSplitAdd, % Lang["SplitAdd"] %Gui_G%() - Gui, Add, Button, x+10 vAllAdd Hwndid, % Lang["AllAdd"] + Gui, Add, Button, x+10 vAllAdd, % Lang["AllAdd"] %Gui_G%() - Gui, Add, Button, x+10 wp vOK Hwndid, % Lang["OK"] + Gui, Add, Button, x+30 wp vOK, % Lang["OK"] %Gui_G%() - Gui, Add, Button, x+10 wp vCancel gCancel, % Lang["Cancel"] - Gui, Add, Button, xm vBind0 Hwndid, % Lang["Bind0"] + Gui, Add, Button, x+10 wp vCancel, % Lang["Cancel"] %Gui_G%() - Gui, Add, Button, x+10 vBind1 Hwndid, % Lang["Bind1"] + Gui, Add, Button, xm vBind0, % Lang["Bind0"] %Gui_G%() - Gui, Add, Button, x+10 vBind2 Hwndid, % Lang["Bind2"] + Gui, Add, Button, x+10 vBind1, % Lang["Bind1"] %Gui_G%() - Gui, Add, Button, x+10 vBind3 Hwndid, % Lang["Bind3"] + Gui, Add, Button, x+10 vBind2, % Lang["Bind2"] %Gui_G%() - Gui, Add, Button, x+10 vBind4 Hwndid, % Lang["Bind4"] + Gui, Add, Button, x+10 vBind3, % Lang["Bind3"] %Gui_G%() - Gui, Add, Button, x+30 vSave Hwndid, % Lang["Save"] + Gui, Add, Button, x+10 vBind4, % Lang["Bind4"] %Gui_G%() + Gui, Add, Button, x+30 vSavePic2, % Lang["SavePic2"] + %Gui_G%() + Gui, -Theme + w:=h:=12, C_:=[] + Loop % nW*(nH+1) + { + i:=A_Index, j:=i=1 ? "xm ym" : Mod(i,nW)=1 ? "xm y+1":"x+1" + Gui, Add, Progress, %j% w%w% h%h% Hwndid -E0x20000 Smooth + C_[i]:=id + } + Gui, +Theme Gui, Show, Hide, % Lang["s3"] return Case "MakeMainWindow": Gui, FindText_Main: New - Gui, +AlwaysOnTop -DPIScale + Gui, +LastFound +AlwaysOnTop -DPIScale Gui, Margin, 15, 10 Gui, Color, %WindowColor% Gui, Font, s12, Verdana Gui, Add, Text, xm, % Lang["NowHotkey"] - Gui, Add, Edit, x+5 w200 vNowHotkey ReadOnly - Gui, Add, Hotkey, x+5 w200 vSetHotkey1 - Gui, Add, DDL, x+5 w180 vSetHotkey2 - , % "||F1|F2|F3|F4|F5|F6|F7|F8|F9|F10|F11|F12|LWin|MButton" + Gui, Add, Edit, x+5 w160 vNowHotkey ReadOnly + Gui, Add, Hotkey, x+5 w160 vSetHotkey1 + s:="F1|F2|F3|F4|F5|F6|F7|F8|F9|F10|F11|F12|LWin|MButton" . "|ScrollLock|CapsLock|Ins|Esc|BS|Del|Tab|Home|End|PgUp|PgDn" . "|NumpadDot|NumpadSub|NumpadAdd|NumpadDiv|NumpadMult" + Gui, Add, DDL, x+5 w160 vSetHotkey2, % s + Gui, Add, Button, x+15 vApply, % Lang["Apply"] + %Gui_G%() Gui, Add, GroupBox, xm y+0 w280 h55 vMyGroup cBlack Gui, Add, Text, xp+15 yp+20 Section, % Lang["Myww"] ": " - Gui, Add, Text, x+0 w60, %ww% + Gui, Add, Text, x+0 w80, %ww% Gui, Add, UpDown, vMyww Range1-100, %ww% Gui, Add, Text, x+15 ys, % Lang["Myhh"] ": " - Gui, Add, Text, x+0 w60, %hh% - Gui, Add, UpDown, vMyhh Hwndid Range1-100, %hh% - GuiControlGet, p, Pos, %id% + Gui, Add, Text, x+0 w80, %hh% + Gui, Add, UpDown, vMyhh Range1-100, %hh% + GuiControlGet, p, Pos, % this.LastCtrl() GuiControl, Move, MyGroup, % "w" (pX+pW) " h" (pH+30) - x:=pX+pW+15*2 - Gui, Add, Button, x%x% ys-8 w150 vApply Hwndid, % Lang["Apply"] + Gui, Add, Checkbox, x+100 ys vAddFunc, % Lang["AddFunc"] " FindText()" + GuiControlGet, p, Pos, % this.LastCtrl() + pW:=pX+pW-15, pW:=(pW<720?720:pW), w:=pW//5 + Gui, Add, Button, xm y+18 w%w% vCutL2, % Lang["CutL2"] %Gui_G%() - Gui, Add, Checkbox, x+30 ys vAddFunc, % Lang["AddFunc"] " FindText()" - Gui, Add, Button, xm y+18 w144 vCutL2 Hwndid, % Lang["CutL2"] + Gui, Add, Button, x+0 wp vCutR2, % Lang["CutR2"] %Gui_G%() - Gui, Add, Button, x+0 wp vCutR2 Hwndid, % Lang["CutR2"] + Gui, Add, Button, x+0 wp vCutU2, % Lang["CutU2"] %Gui_G%() - Gui, Add, Button, x+0 wp vCutU2 Hwndid, % Lang["CutU2"] + Gui, Add, Button, x+0 wp vCutD2, % Lang["CutD2"] %Gui_G%() - Gui, Add, Button, x+0 wp vCutD2 Hwndid, % Lang["CutD2"] - %Gui_G%() - Gui, Add, Button, x+0 wp vUpdate Hwndid, % Lang["Update"] + Gui, Add, Button, x+0 wp vUpdate, % Lang["Update"] %Gui_G%() Gui, Font, s6 bold, Verdana - Gui, Add, Edit, xm y+10 w720 r20 vMyPic -Wrap + Gui, Add, Edit, xm y+10 w%pW% h260 vMyPic -Wrap Gui, Font, s12 norm, Verdana - Gui, Add, Button, xm w240 vCapture Hwndid, % Lang["Capture"] + w:=pW//3 + Gui, Add, Button, xm w%w% vCapture, % Lang["Capture"] %Gui_G%() - Gui, Add, Button, x+0 wp vTest Hwndid, % Lang["Test"] + Gui, Add, Button, x+0 wp vTest, % Lang["Test"] %Gui_G%() - Gui, Add, Button, x+0 wp vCopy Hwndid, % Lang["Copy"] + Gui, Add, Button, x+0 wp vCopy, % Lang["Copy"] %Gui_G%() - Gui, Add, Button, xm y+0 wp vCaptureS Hwndid, % Lang["CaptureS"] + Gui, Add, Button, xm y+0 wp vCaptureS, % Lang["CaptureS"] %Gui_G%() - Gui, Add, Button, x+0 wp vGetRange Hwndid, % Lang["GetRange"] + Gui, Add, Button, x+0 wp vGetRange, % Lang["GetRange"] %Gui_G%() - Gui, Add, Button, x+0 wp vGetOffset Hwndid, % Lang["GetOffset"] + Gui, Add, Button, x+0 wp vGetOffset, % Lang["GetOffset"] %Gui_G%() - Gui, Add, Edit, xm y+10 w180 hp vClipText - Gui, Add, Button, x+0 vPaste Hwndid, % " " Lang["Paste"] " " + Gui, Add, Edit, xm y+10 w130 hp vClipText + Gui, Add, Button, x+0 vPaste, % Lang["Paste"] %Gui_G%() - Gui, Add, Button, x+0 vTestClip Hwndid, % " " Lang["TestClip"] " " + Gui, Add, Button, x+0 vTestClip, % Lang["TestClip"] %Gui_G%() - Gui, Add, Button, x+0 vGetClipOffset Hwndid, % " " Lang["GetClipOffset"] " " + Gui, Add, Button, x+0 vGetClipOffset, % Lang["GetClipOffset"] %Gui_G%() - Gui, Add, Edit, x+0 hp w150 hp vOffset Hwndid - GuiControlGet, p, Pos, %id% - w:=720+15-(pX+pW) - Gui, Add, Button, x+0 w%w% hp vCopyOffset Hwndid, % Lang["CopyOffset"] + r:=pW + GuiControlGet, p, Pos, % this.LastCtrl() + w:=((r+15)-(pX+pW))//2, pW:=r + Gui, Add, Edit, x+0 w%w% hp vOffset + Gui, Add, Button, x+0 wp vCopyOffset, % Lang["CopyOffset"] %Gui_G%() - Gui, Font, s12 cBlue, Verdana - Gui, Add, Edit, xm w720 h300 vscr Hwndhscr -Wrap HScroll + Gui, Font, cBlue + Gui, Add, Edit, xm w%pW% h250 vscr Hwndhscr -Wrap HScroll Gui, Show, Hide, % Lang["s4"] %Gui_%("LoadScr") OnExit(Gui_SaveScr) @@ -2118,132 +2693,53 @@ Gui(cmd, arg1:="") FileDelete, %f% FileAppend, %s%, %f% return - Case "Capture","CaptureS": + Case "Capture", "CaptureS": Gui, FindText_Main: +Hwndid - if (show_gui:=(WinExist()=id)) - { - WinMinimize - Gui, FindText_Main: Hide - } - ShowScreenShot:=InStr(cmd,"CaptureS") - if (ShowScreenShot) + if WinExist()!=id + return this.GetRange() + this.Hide() + if (ShowScreenShot:=InStr(cmd, "CaptureS")) { this.ScreenShot(), f:=%Gui_%("SelectPic") - if (f="") or !FileExist(f) - { - if (show_gui) - { - Gui, FindText_Main: Show - GuiControl, FindText_Main: Focus, scr - } - Exit - } + if (f="") || !FileExist(f) + return %Gui_Show%() this.ShowPic(f) } - ;---------------------- - if GetKeyState("Ctrl") - Send {Ctrl Up} - Gui, FindText_HotkeyIf: New, -Caption +ToolWindow +E0x80000 - Gui, Show, NA x0 y0 w0 h0, FindText_HotkeyIf - Hotkey, IfWinExist, FindText_HotkeyIf - For k,v in StrSplit("RButton|Up|Down|Left|Right","|") - { - if GetKeyState(v) - Send {%v% Up} - Hotkey, *%v%, %Gui_Off%, On UseErrorLevel - } - CoordMode, Mouse GuiControlGet, w, FindText_Main:, Myww GuiControlGet, h, FindText_Main:, Myhh - oldx:=oldy:="", r:=StrSplit(Lang["s5"],"|") - if (!show_gui) - w:=20, h:=8 - Critical, Off - hk:="", State:=%Gui_%("State") - Loop - { - Sleep, 50 - MouseGetPos, x, y, Bind_ID - if GetKeyState("Up","P") || (hk="Up") - (h>1 && h--), hk:="" - else if GetKeyState("Down","P") || (hk="Down") - h++, hk:="" - else if GetKeyState("Left","P") || (hk="Left") - (w>1 && w--), hk:="" - else if GetKeyState("Right","P") || (hk="Right") - w++, hk:="" - this.RangeTip(x-w,y-h,2*w+1,2*h+1,(A_MSec<500?"Red":"Blue")) - if (oldx=x and oldy=y) - Continue - oldx:=x, oldy:=y - ToolTip, % r[1] " : " x "," y "`n" r[2] - } - Until (hk="RButton") or (State!=%Gui_%("State")) - timeout:=A_TickCount+3000 - While (A_TickCount1 && h--), hk:="" - else if GetKeyState("Down","P") || (hk="Down") - h++, hk:="" - else if GetKeyState("Left","P") || (hk="Left") - (w>1 && w--), hk:="" - else if GetKeyState("Right","P") || (hk="Right") - w++, hk:="" - this.RangeTip(x-w,y-h,2*w+1,2*h+1,(A_MSec<500?"Red":"Blue")) - MouseGetPos, x1, y1 - if (oldx=x1 and oldy=y1) - Continue - oldx:=x1, oldy:=y1 - ToolTip, % r[1] " : " x "," y "`n" r[2] - } - Until (hk="RButton") or (State!=%Gui_%("State")) - timeout:=A_TickCount+3000 - While (A_TickCount>16) + ListLines % (lls:=A_ListLines)?0:0 Loop % nW*(nH+1) - SendMessage, 0x2001, 0, (A_Index>nW*nH ? 0xAAFFFF:c) - ,, % "ahk_id " C_[A_Index] - ww:=w, hh:=h, nW:=2*ww+1, nH:=2*hh+1 - i:=nW>71, j:=nH>25 + SendMessage, 0x2001, 0, (A_Index>nW*nH ? 0xAAFFFF:c),, % "ahk_id " C_[A_Index] + ListLines % lls + nW:=2*ww+1, nH:=2*hh+1, i:=nW>71, j:=nH>25 Gui, FindText_Capture: Default GuiControl, Enable%i%, MySlider1 GuiControl, Enable%j%, MySlider2 GuiControl,, MySlider1, % MySlider1:=0 GuiControl,, MySlider2, % MySlider2:=0 ;------------------------ - %Gui_%("getcors", !ShowScreenShot) - %Gui_%("Reset") - Loop 6 - GuiControl,, Edit%A_Index% + %Gui_%("getcors", !ShowScreenShot), %Gui_%("Reset") + Loop Parse, % "SelGray|SelColor|SelR|SelG|SelB|Threshold|Comment", | + GuiControl,, % A_LoopField GuiControl,, Modify, % Modify:=0 GuiControl,, MultiColor, % MultiColor:=0 GuiControl,, GrayDiff, 50 GuiControl, Focus, Gray2Two GuiControl, +Default, Gray2Two + Gui, +LastFound Gui, Show, Center Event:=Result:="" - DetectHiddenWindows, Off + DetectHiddenWindows, 0 Critical, Off - Gui, +LastFound WinWaitClose, % "ahk_id " WinExist() Critical ToolTip @@ -2255,50 +2751,42 @@ Gui(cmd, arg1:="") WinGetClass, tc, ahk_id %Bind_ID% tt:=Trim(SubStr(tt,1,30) (tc ? " ahk_class " tc:"")) tt:=StrReplace(RegExReplace(tt,"[;``]","``$0"),"""","""""") - Result:="`nSetTitleMatchMode, 2`nid:=WinExist(""" tt """)" + Result:="`nSetTitleMatchMode 2`nid:=WinExist(""" tt """)" . "`nFindText().BindWindow(id" (cors.bind=0 ? "":"," cors.bind) - . ") `; " Lang["s6"] " this.BindWindow(0)`n`n" Result + . ") `; " Lang["s6"] " FindText().BindWindow(0)`n`n" Result } if (Event="OK") { if (!A_IsCompiled) - { FileRead, s, %A_LineFile% - s:=SubStr(s, s~="i)\n[;=]+ Copy The") - } - else s:="" + else + s:=this.GetScript() + re:="Oi)\n\s*FindText[^\n]+args\*[\s\S]*?Script_End[(){\s]+}" + if RegExMatch(s, re, r) + s:="`n;==========`n" r[0] "`n" GuiControl,, scr, % Result "`n" s - if !InStr(Result,"##") - GuiControl,, MyPic, % Trim(this.ASCII(Result),"`n") + GuiControl,, MyPic, % Trim(this.ASCII(Result),"`n") Result:=s:="" } - else if (Event="SplitAdd") or (Event="AllAdd") + else if (Event="SplitAdd") || (Event="AllAdd") { GuiControlGet, s,, scr r:=SubStr(s, 1, InStr(s,"=FindText(")) i:=j:=0, re:="<[^>\n]*>[^$\n]+\$[^""\r\n]+" - While j:=RegExMatch(r, re, "", j+1) - i:=InStr(r,"`n",0,j) + While j:=RegExMatch(r, re,, j+1) + i:=InStr(r, "`n", 0, j) GuiControl,, scr, % SubStr(s,1,i) . Result . SubStr(s,i+1) - if !InStr(Result,"##") - GuiControl,, MyPic, % Trim(this.ASCII(Result),"`n") + GuiControl,, MyPic, % Trim(this.ASCII(Result),"`n") Result:=s:="" } ;---------------------- - Gui, Show - GuiControl, Focus, scr + %Gui_Show%() return - Case "State": - return GetKeyState((arg1?"LButton":"RButton"),"P") - . "|" GetKeyState((arg1?"LButton":"RButton")) - . "|" GetKeyState("Ctrl","P") - . "|" GetKeyState("Ctrl") Case "SelectPic": - Gui, FindText_SelectPic: +LastFoundExist - IfWinExist + if IsObject(Pics) return Pics:=[], Names:=[], s:="" - Loop Files, % A_Temp "\Ahk_ScreenShot\*.bmp" + Loop Files, % SavePicDir "\*.bmp" Pics.Push(LoadPicture(v:=A_LoopFileFullPath)) , Names.Push(v), s.="|" RegExReplace(v,"i)^.*\\|\.bmp$") Gui, FindText_SelectPic: New @@ -2306,56 +2794,42 @@ Gui(cmd, arg1:="") Gui, Margin, 15, 15 Gui, Font, s12, Verdana Gui, Add, Pic, HwndhPic w800 h500 +Border - Gui, Add, ListBox, % "x+15 w120 hp vSelectBox Hwndid" + Gui, Add, ListBox, % "x+15 w120 hp vSelectBox" . " AltSubmit 0x100 Choose1", % Trim(s,"|") %Gui_G%() - Gui, Add, Button, xm w170 vOK2 Hwndid Default, % Lang["OK2"] + Gui, Add, Button, xm w170 vOK2 Default, % Lang["OK2"] %Gui_G%() - Gui, Add, Button, x+15 wp vCancel2 gCancel, % Lang["Cancel2"] - Gui, Add, Button, x+15 wp vClearAll Hwndid, % Lang["ClearAll"] + Gui, Add, Button, x+15 wp vCancel2, % Lang["Cancel2"] %Gui_G%() - Gui, Add, Button, x+15 wp vOpenDir Hwndid, % Lang["OpenDir"] + Gui, Add, Button, x+15 wp vClearAll, % Lang["ClearAll"] %Gui_G%() - Gui, Add, Button, x+15 wp vSavePic Hwndid, % Lang["SavePic"] + Gui, Add, Button, x+15 wp vOpenDir, % Lang["OpenDir"] + %Gui_G%() + Gui, Add, Button, x+15 wp vSavePic, % Lang["SavePic"] %Gui_G%() GuiControl, Focus, SelectBox %Gui_%("SelectBox") Gui, Show,, Select ScreenShot ;----------------------- - DetectHiddenWindows, Off + DetectHiddenWindows, 0 Critical, Off - file:="" + SelectFile:="" WinWaitClose, % "ahk_id " WinExist() Critical - Gui, Destroy + Gui, FindText_SelectPic: Destroy Loop % Pics.Length() DllCall("DeleteObject", "Ptr",Pics[A_Index]) Pics:="", Names:="" - return file + return SelectFile Case "SavePic": GuiControlGet, SelectBox f:=Names[SelectBox] - Gui, Destroy - Loop % Pics.Length() - DllCall("DeleteObject", "Ptr",Pics[A_Index]) - Pics:="", Names:="", show_gui_bak:=show_gui + Gui, Hide this.ShowPic(f) - Gui, FindText_Screen: +OwnDialogs - Loop - { - pos:=%Gui_%("GetRange") - MsgBox, 4100, Tip, % Lang["s15"] " !" - IfMsgBox, Yes - Break - } + pos:=this.SnapShot(0) %Gui_%("ScreenShot", pos[1] "|" pos[2] "|" pos[3] "|" pos[4] "|0") this.ShowPic() - if (show_gui_bak) - { - GuiControl, FindText_Main: Focus, scr - Gui, FindText_Main: Show - } - Exit + return Case "SelectBox": GuiControlGet, SelectBox if (hBM:=Pics[SelectBox]) @@ -2367,184 +2841,117 @@ Gui(cmd, arg1:="") return Case "OK2": GuiControlGet, SelectBox - file:=Names[SelectBox] + SelectFile:=Names[SelectBox] Gui, Hide return Case "ClearAll": - FileDelete, % A_Temp "\Ahk_ScreenShot\*.bmp" + FileDelete, % SavePicDir "\*.bmp" Gui, Hide return Case "OpenDir": - Run, % A_Temp "\Ahk_ScreenShot\" + Run, % SavePicDir return Case "getcors": - this.xywh2xywh(px-ww,py-hh,2*ww+1,2*hh+1,x,y,w,h) - if (w<1 or h<1) + x:=px-ww, y:=py-hh, w:=2*ww+1, h:=2*hh+1 + this.GetBitsFromScreen(x,y,w,h,arg1) + if (w<1 || h<1) return - SetBatchLines, % (bch:=A_BatchLines)?"-1":"-1" - if (arg1) - this.ScreenShot() - cors:=[], gray:=[], k:=0 + cors:=[], gray:=[], k:=0, j:=py-hh-1 + ListLines % (lls:=A_ListLines)?0:0 Loop %nH% { - j:=py-hh+A_Index-1, i:=px-ww + j++, i:=px-ww Loop %nW% cors[++k]:=c:=this.GetColor(i++,j,0) , gray[k]:=(((c>>16)&0xFF)*38+((c>>8)&0xFF)*75+(c&0xFF)*15)>>7 } + ListLines % lls cors.CutLeft:=Abs(px-ww-x) cors.CutRight:=Abs(px+ww-(x+w-1)) cors.CutUp:=Abs(py-hh-y) cors.CutDown:=Abs(py+hh-(y+h-1)) - SetBatchLines, %bch% return Case "GetRange": - Gui, FindText_Main: +Hwndid - if (show_gui:=(WinExist()=id)) - Gui, FindText_Main: Hide - ;--------------------- - Gui, FindText_GetRange: New - Gui, +LastFound +AlWaysOnTop +ToolWindow -Caption -DPIScale +E0x08000000 - Gui, Color, White - WinSet, Transparent, 10 - this.xywh2xywh(0,0,0,0,0,0,0,0,x,y,w,h) - Gui, Show, NA x%x% y%y% w%w% h%h%, GetRange - ;--------------------- - if GetKeyState("LButton") - Send {LButton Up} - if GetKeyState("Ctrl") - Send {Ctrl Up} - hk:="", State:=%Gui_%("State",1) - Gui, FindText_HotkeyIf: New, -Caption +ToolWindow +E0x80000 - Gui, Show, NA x0 y0 w0 h0, FindText_HotkeyIf - Hotkey, IfWinExist, FindText_HotkeyIf - Hotkey, *LButton, %Gui_Off%, On UseErrorLevel - Hotkey, *LButton Up, %Gui_Off%, On UseErrorLevel - CoordMode, Mouse - oldx:=oldy:="", r:=Lang["s7"] - Critical, Off - Loop - { - Sleep, 50 - MouseGetPos, x, y - if (oldx=x and oldy=y) - Continue - oldx:=x, oldy:=y - ToolTip, %r% - } - Until (hk!="") or (State!=%Gui_%("State",1)) - hk:="", State:=%Gui_%("State",1) - x1:=x, y1:=y, oldx:=oldy:="" - Loop - { - Sleep, 50 - MouseGetPos, x2, y2 - x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x1-x2), h:=Abs(y1-y2) - this.RangeTip(x, y, w, h, (A_MSec<500 ? "Red":"Blue")) - if (oldx=x2 and oldy=y2) - Continue - oldx:=x2, oldy:=y2 - ToolTip, %r% - } - Until (hk!="") or (State!=%Gui_%("State",1)) - timeout:=A_TickCount+3000 - While (A_TickCount\n]*>[^$\n]+\$[^""\r\n]+",r) - , v:=this.FindText(X, Y, -n, -n, n, n, 0, 0, r) - r:=StrSplit(Lang["s8"],"|") - MsgBox, 4096, Tip, % r[1] ":`t" Round(v.Length()) "`n`n" + t:=A_TickCount, v:=X:=Y:="" + if RegExMatch(s, "O)<[^>\n]*>[^$\n]+\$[^""\r\n]+", r) + v:=this.FindText(X, Y, 0,0,0,0, 0,0, r[0]) + r:=StrSplit(Lang["s8"] "||||", "|") + MsgBox, 4096, Tip, % r[1] ":`t" (IsObject(v)?v.Length():v) "`n`n" . r[2] ":`t" (A_TickCount-t) " " r[3] "`n`n" . r[4] ":`t" X ", " Y "`n`n" - . r[5] ":`t<" (Comment:=v[1].id) ">", 3 - for i,j in v + . r[5] ":`t<" (IsObject(v)?v[1].id:"") ">", 3 + Try For i,j in v if (i<=2) this.MouseTip(j.x, j.y) v:="", Clipboard:=X "," Y } ;---------------------- - Gui, Show - GuiControl, Focus, scr + %Gui_Show%() return - Case "GetOffset","GetClipOffset": + Case "GetOffset", "GetClipOffset": Gui, FindText_Main: Hide - Gui, FindText_Capture: +LastFound - %Gui_%("Capture") + p:=this.GetRange() Gui, FindText_Main: Default if (cmd="GetOffset") GuiControlGet, s,, scr else GuiControlGet, s,, ClipText - RegExMatch(s, "<[^>\n]*>[^$\n]+\$[^""\r\n]+", r) - n:=150000, v:=this.FindText(X, Y, -n, -n, n, n, 0, 0, r) - r:=StrReplace("X+" (px-X) ", Y+" (py-Y), "+-", "-") - if (cmd="GetOffset") + if RegExMatch(s, "O)<[^>\n]*>[^$\n]+\$[^""\r\n]+", r) + && this.FindText(X, Y, 0,0,0,0, 0,0, r[0]) { - s:=RegExReplace(s, "i)(\.Click\()[^,\n""]*,[^,)\n]*" - , "$1" r, 0, 1) - GuiControl,, scr, %s% + r:=StrReplace("X+" ((p[1]+p[3])//2-X) + . ", Y+" ((p[2]+p[4])//2-Y), "+-", "-") + if (cmd="GetOffset") + { + re:="i)(\(\)\.\w*Click\w*\()[^,\n]*,[^,)\n]*" + if SubStr(s,1,s~="i)\n\s*FindText[^\n]+args\*")~=re + s:=RegExReplace(s, re, "$1" r,, 1) + GuiControl,, scr, %s% + } + GuiControl,, Offset, %r% } - else - GuiControl,, Offset, % v ? r:"" - Gui, Show - GuiControl, Focus, scr - s:=v:="" + s:="", %Gui_Show%() return Case "Paste": - if RegExMatch(Clipboard, "\|?<[^>\n]*>[^$\n]+\$[^""\r\n]+", r) + if RegExMatch(Clipboard, "O)<[^>\n]*>[^$\n]+\$[^""\r\n]+", r) { - GuiControl,, ClipText, %r% - GuiControl,, MyPic, % Trim(this.ASCII(r),"`n") + GuiControl,, ClipText, % r[0] + GuiControl,, MyPic, % Trim(this.ASCII(r[0]),"`n") } return Case "CopyOffset": @@ -2559,9 +2966,9 @@ Gui(cmd, arg1:="") GuiControlGet, s,, scr GuiControlGet, r,, AddFunc if (r != 1) - s:=RegExReplace(s,"\n\K[\s;=]+ Copy The[\s\S]*") - , s:=RegExReplace(s, "\n; ok:=FindText[\s\S]*") - , s:=SubStr(s, (s~="\n[^\n]*?Text")) + s:=RegExReplace(s, "i)\n\s*FindText[^\n]+args\*[\s\S]*") + , s:=RegExReplace(s, "i)\n; ok:=FindText[\s\S]*") + , s:=SubStr(s, (s~="i)\n[ \t]*Text")) } Clipboard:=RegExReplace(s,"\R","`r`n") GuiControl, Focus, scr @@ -2582,7 +2989,7 @@ Gui(cmd, arg1:="") return Case "ScreenShot": Critical - f:=A_Temp "\Ahk_ScreenShot" + f:=SavePicDir if !InStr(r:=FileExist(f), "D") { if (r) @@ -2593,71 +3000,65 @@ Gui(cmd, arg1:="") FileCreateDir, %f% } Loop - f:=A_Temp "\Ahk_ScreenShot\" Format("{:03d}",A_Index) ".bmp" + f:=SavePicDir . Format("\{:03d}.bmp",A_Index) Until !FileExist(f) this.SavePic(f, StrSplit(arg1,"|")*) - Gui, FindText_Tip: New - ; WS_EX_NOACTIVATE:=0x08000000, WS_EX_TRANSPARENT:=0x20 - Gui, +LastFound +AlwaysOnTop +ToolWindow -Caption -DPIScale +E0x08000020 - Gui, Color, Yellow - Gui, Font, cRed s48 bold - Gui, Add, Text,, % Lang["s9"] - WinSet, Transparent, 200 - Gui, Show, NA y0, ScreenShot Tip - Sleep, 100 - Gui, Destroy + CoordMode, ToolTip + this.ToolTip(Lang["s9"],, 0,, { bgcolor:"Yellow", color:"Red" + , size:48, bold:"bold", trans:200, timeout:0.2 }) return - Case "Bind0","Bind1","Bind2","Bind3","Bind4": + Case "Bind0", "Bind1", "Bind2", "Bind3", "Bind4": this.BindWindow(Bind_ID, bind_mode:=SubStr(cmd,5)) - if GetKeyState("RButton") - Send {RButton Up} - if GetKeyState("Ctrl") - Send {Ctrl Up} - hk:="", State:=%Gui_%("State") - Gui, FindText_HotkeyIf: New, -Caption +ToolWindow +E0x80000 + ;----------------- + Gui, FindText_HotkeyIf: New + Gui, -Caption +ToolWindow +E0x80000 Gui, Show, NA x0 y0 w0 h0, FindText_HotkeyIf + ;----------------- + key:="RButton" + KeyWait, % key + KeyWait, Ctrl Hotkey, IfWinExist, FindText_HotkeyIf - Hotkey, *RButton, %Gui_Off%, On UseErrorLevel - CoordMode, Mouse - oldx:=oldy:="" + Hotkey, *%key%, %Gui_Off%, On UseErrorLevel + Hotkey, IfWinExist + ;----------------- Critical, Off + CoordMode, Mouse + hk:="", oldx:=oldy:="" Loop { - Sleep, 50 + Sleep 50 MouseGetPos, x, y - if (oldx=x and oldy=y) + if (oldx=x && oldy=y) Continue oldx:=x, oldy:=y - ;--------------- - px:=x, py:=y, %Gui_%("getcors",1) - %Gui_%("Reset"), r:=StrSplit(Lang["s10"],"|") - ToolTip, % r[1] " : " x "," y "`n" r[2] - } - Until (hk!="") or (State!=%Gui_%("State")) - timeout:=A_TickCount+3000 - While (A_TickCount71 ? Round((nW-71)*MySlider1/100) : 0 dy:=nH>25 ? Round((nH-25)*MySlider2/100) : 0 - if (oldx=dx and oldy=dy) + if (oldx=dx && oldy=dy) return oldy:=dy, k:=0 Loop % nW*nH - c:=(!show[++k] ? WindowColor - : bg="" ? cors[k] : ascii[k] - ? "Black":"White"), %Gui_%("SetColor") + c:=(!show[++k] ? WindowColor : bg="" ? cors[k] : ascii[k] + ? "Black":"White"), %Gui_SetColor%() Loop % nW*(oldx!=dx) { i:=A_Index-dx @@ -2673,7 +3074,7 @@ Gui(cmd, arg1:="") show:=[], ascii:=[], bg:=color:="" CutLeft:=CutRight:=CutUp:=CutDown:=k:=0 Loop % nW*nH - show[++k]:=1, c:=cors[k], %Gui_%("SetColor") + show[++k]:=1, c:=cors[k], %Gui_SetColor%() Loop % cors.CutLeft %Gui_%("CutL") Loop % cors.CutRight @@ -2698,29 +3099,27 @@ Gui(cmd, arg1:="") SendMessage, 0x2001, 0, c,, % "ahk_id " . C_[tk] return Case "RepColor": - show[k]:=1, c:=(bg="" ? cors[k] : ascii[k] - ? "Black":"White"), %Gui_%("SetColor") + show[k]:=1, c:=(bg="" ? cors[k] : ascii[k] ? "Black":"White") + , %Gui_SetColor%() return Case "CutColor": - show[k]:=0, c:=WindowColor, %Gui_%("SetColor") + show[k]:=0, c:=WindowColor, %Gui_SetColor%() return Case "RepL": if (CutLeft<=cors.CutLeft) - or (bg!="" and InStr(color,"**") - and CutLeft=cors.CutLeft+1) + || (bg!="" && InStr(color,"**") + && CutLeft=cors.CutLeft+1) return k:=CutLeft-nW, CutLeft-- Loop %nH% - k+=nW, (A_Index>CutUp and A_IndexCutUp && A_Index=nW) return CutLeft++, k:=CutLeft-nW Loop %nH% - k+=nW, (A_Index>CutUp and A_IndexCutUp && A_IndexCutUp and A_IndexCutUp && A_Index=nW) return CutRight++, k:=1-CutRight Loop %nH% - k+=nW, (A_Index>CutUp and A_IndexCutUp && A_IndexCutLeft and A_IndexCutLeft && A_Index=nH) return CutUp++, k:=(CutUp-1)*nW Loop %nW% - k++, (A_Index>CutLeft and A_IndexCutLeft && A_IndexCutLeft and A_IndexCutLeft && A_Index=nH) return CutDown++, k:=(nH-CutDown)*nW Loop %nW% - k++, (A_Index>CutLeft and A_IndexCutLeft && A_Index0 ? "1":"0" return @@ -2854,16 +3247,16 @@ Gui(cmd, arg1:="") Loop % nW*nH { j:=gray[++k]+GrayDiff - , ascii[k]:=v:=( gray[k-1]>j or gray[k+1]>j - or gray[k-nW]>j or gray[k+nW]>j - or gray[k-nW-1]>j or gray[k-nW+1]>j - or gray[k+nW-1]>j or gray[k+nW+1]>j ) + , ascii[k]:=v:=( gray[k-1]>j || gray[k+1]>j + || gray[k-nW]>j || gray[k+nW]>j + || gray[k-nW-1]>j || gray[k-nW+1]>j + || gray[k+nW-1]>j || gray[k+nW+1]>j ) if (show[k]) - i:=(v?i+1:i-1), c:=(v?"Black":"White"), %Gui_%("SetColor") + i:=(v?i+1:i-1), c:=(v?"Black":"White"), %Gui_SetColor%() } bg:=i>0 ? "1":"0" return - Case "Color2Two","ColorPos2Two": + Case "Color2Two", "ColorPos2Two": Gui, FindText_Capture: Default GuiControlGet, c,, SelColor if (c="") @@ -2872,9 +3265,9 @@ Gui(cmd, arg1:="") MsgBox, 4096, Tip, % Lang["s12"] " !", 1 return } - UsePos:=(cmd="ColorPos2Two") ? 1:0 - GuiControlGet, n,, Similar1 - n:=Round(n/100,2), color:=c "@" n + UsePos:=(cmd="ColorPos2Two") + GuiControlGet, n,, % UsePos ? "Similar2" : "Similar1" + n:=Round(n/100,2), color:=StrReplace(c,"0x") "@" n , n:=Floor(512*9*255*255*(1-n)*(1-n)), k:=i:=0 , rr:=(c>>16)&0xFF, gg:=(c>>8)&0xFF, bb:=c&0xFF Loop % nW*nH @@ -2883,7 +3276,7 @@ Gui(cmd, arg1:="") , g:=((c>>8)&0xFF)-gg, b:=(c&0xFF)-bb, j:=r+rr+rr , ascii[k]:=v:=((1024+j)*r*r+2048*g*g+(1534-j)*b*b<=n) if (show[k]) - i:=(v?i+1:i-1), c:=(v?"Black":"White"), %Gui_%("SetColor") + i:=(v?i+1:i-1), c:=(v?"Black":"White"), %Gui_SetColor%() } bg:=i>0 ? "1":"0" return @@ -2906,9 +3299,9 @@ Gui(cmd, arg1:="") { c:=cors[++k], r:=(c>>16)&0xFF, g:=(c>>8)&0xFF , b:=c&0xFF, ascii[k]:=v:=(Abs(r-rr)<=dR - and Abs(g-gg)<=dG and Abs(b-bb)<=dB) + && Abs(g-gg)<=dG && Abs(b-bb)<=dB) if (show[k]) - i:=(v?i+1:i-1), c:=(v?"Black":"White"), %Gui_%("SetColor") + i:=(v?i+1:i-1), c:=(v?"Black":"White"), %Gui_SetColor%() } bg:=i>0 ? "1":"0" return @@ -2921,8 +3314,8 @@ Gui(cmd, arg1:="") ToolTip return Case "Undo": - Result:=RegExReplace(Result,",[^/]+/[^/]+/[^/]+$") - ToolTip, % Trim(Result,"/,") + Result:=RegExReplace(Result, ",[^/]+/[^/]+/[^/]+$") + ToolTip % Trim(Result,"/,") return Case "Similar1": GuiControl,, Similar2, %Similar1% @@ -2954,27 +3347,27 @@ Gui(cmd, arg1:="") While InStr(txt,bg) { if (txt~="^" bg "+\n") - txt:=RegExReplace(txt,"^" bg "+\n"), %Gui_%("CutU") + txt:=RegExReplace(txt, "^" bg "+\n"), %Gui_%("CutU") else if !(txt~="m`n)[^\n" bg "]$") - txt:=RegExReplace(txt,"m`n)" bg "$"), %Gui_%("CutR") + txt:=RegExReplace(txt, "m`n)" bg "$"), %Gui_%("CutR") else if (txt~="\n" bg "+\n$") - txt:=RegExReplace(txt,"\n\K" bg "+\n$"), %Gui_%("CutD") + txt:=RegExReplace(txt, "\n\K" bg "+\n$"), %Gui_%("CutD") else if !(txt~="m`n)^[^\n" bg "]") - txt:=RegExReplace(txt,"m`n)^" bg), %Gui_%("CutL") + txt:=RegExReplace(txt, "m`n)^" bg), %Gui_%("CutL") else Break } txt:="" return - Case "OK","SplitAdd","AllAdd": + Case "OK", "SplitAdd", "AllAdd": Gui, FindText_Capture: Default Gui, +OwnDialogs %Gui_%("GetTxt") - if (txt="") and (!MultiColor) + if (txt="") && (!MultiColor) { MsgBox, 4096, Tip, % Lang["s13"] " !", 1 return } - if InStr(color,"@") and (UsePos) and (!MultiColor) + if InStr(color,"@") && (UsePos) && (!MultiColor) { r:=StrSplit(color,"@") k:=i:=j:=0 @@ -2997,7 +3390,7 @@ Gui(cmd, arg1:="") color:="#" j "@" r[2] } GuiControlGet, Comment - if (cmd="SplitAdd") and (!MultiColor) + if (cmd="SplitAdd") && (!MultiColor) { if InStr(color,"#") { @@ -3010,7 +3403,7 @@ Gui(cmd, arg1:="") Loop % w:=nW-CutLeft-CutRight { i++ - if (!show[k++] and A_Index" color "$" txt """`n" if (cmd="AllAdd") @@ -3058,31 +3453,35 @@ Gui(cmd, arg1:="") } x:=px-ww+CutLeft+(nW-CutLeft-CutRight)//2 y:=py-hh+CutUp+(nH-CutUp-CutDown)//2 - s:=StrReplace(s, "Text.=", "Text:="), r:=StrSplit(Lang["s8"],"|") + s:=StrReplace(s, "Text.=", "Text:="), r:=StrSplit(Lang["s8"] "|||||||", "|") s:="`; #Include `n" . "`nt1:=A_TickCount, Text:=X:=Y:=""""`n" s . "`nif (ok:=FindText(X, Y, " x "-150000, " . y "-150000, " x "+150000, " y "+150000, 0, 0, Text))" . "`n{" - . "`n `; FindText().Click(" . "X, Y, ""L"")" + . "`n `; FindText()." . "Click(" . "X, Y, ""L"")" . "`n}`n" . "`n`; ok:=FindText(X:=""wait"", Y:=3, 0,0,0,0,0,0,Text) `; " r[7] . "`n`; ok:=FindText(X:=""wait0"", Y:=-1, 0,0,0,0,0,0,Text) `; " r[8] - . "`n`nMsgBox, 4096, Tip, `% """ r[1] ":``t"" Round(ok.Length())" + . "`n`nMsgBox, 4096, Tip, `% """ r[1] ":``t"" (IsObject(ok)?ok.Length():ok)" . "`n . ""``n``n" r[2] ":``t"" (A_TickCount-t1) "" " r[3] """" - . "`n . ""``n``n" r[4] ":``t"" ok[1].x "", "" ok[1].y" - . "`n . ""``n``n" r[5] ":``t<"" (Comment:=ok[1].id) "">""`n" - . "`nfor i,v in ok `; ok " r[6] " ok:=FindText().ok" + . "`n . ""``n``n" r[4] ":``t"" X "", "" Y" + . "`n . ""``n``n" r[5] ":``t<"" (IsObject(ok)?ok[1].id:"""") "">""`n" + . "`nTry For i,v in ok `; ok " r[6] " ok:=FindText().ok" . "`n if (i<=2)" . "`n FindText().MouseTip(ok[i].x, ok[i].y)`n" Event:=cmd, Result:=s Gui, Hide return - Case "Save": + Case "SavePic2": x:=px-ww+CutLeft, w:=nW-CutLeft-CutRight y:=py-hh+CutUp, h:=nH-CutUp-CutDown - %Gui_%("ScreenShot" - , x "|" y "|" (x+w-1) "|" (y+h-1) "|0") + %Gui_%("ScreenShot", x "|" y "|" (x+w-1) "|" (y+h-1) "|0") + return + Case "ShowPic": + ControlGet, i, CurrentLine,,, ahk_id %hscr% + ControlGet, s, Line, %i%,, ahk_id %hscr% + GuiControl, FindText_Main:, MyPic, % Trim(this.ASCII(s),"`n") return Case "KeyDown": Critical @@ -3096,19 +3495,19 @@ Gui(cmd, arg1:="") GuiControl, FindText_Main:, MyPic, % Trim(this.ASCII(s),"`n") } return - Case "ShowPic": - ControlGet, i, CurrentLine,,, ahk_id %hscr% - ControlGet, s, Line, %i%,, ahk_id %hscr% - GuiControl, FindText_Main:, MyPic, % Trim(this.ASCII(s),"`n") - return Case "LButtonDown": Critical if (A_Gui!="FindText_Capture") return %Gui_%("KeyDown") MouseGetPos,,,, k2, 2 - if (k1:=Round(Cid_[k2]))<1 + k1:=0 + ListLines % (lls:=A_ListLines)?0:0 + For k_,v_ in C_ + if (v_=k2) && (k1:=k_) + Break + ListLines % lls + if (k1<1) return - Gui, FindText_Capture: Default if (k1>71*25) { k3:=nW*nH+(k1-71*25)+dx @@ -3117,24 +3516,24 @@ Gui(cmd, arg1:="") return } k2:=Mod(k1-1,71)+dx, k3:=(k1-1)//71+dy - if (k2>=nW || k3>=nH) + if (k2<0 || k2>=nW || k3<0 || k3>=nH) return k1:=k, k:=k3*nW+k2+1, k2:=c - if (MultiColor and show[k]) + if (MultiColor && show[k]) { c:="," Mod(k-1,nW) "/" k3 "/" . Format("{:06X}",cors[k]&0xFFFFFF) , Result.=InStr(Result,c) ? "":c - ToolTip, % Trim(Result,"/,") + ToolTip % Trim(Result,"/,") } - else if (Modify and bg!="" and show[k]) + if (Modify && bg!="" && show[k]) { - c:=((ascii[k]:=!ascii[k]) ? "Black":"White") - , %Gui_%("SetColor") + c:=((ascii[k]:=!ascii[k]) ? "Black":"White"), %Gui_SetColor%() } else { c:=cors[k], cors.SelPos:=k + Gui, FindText_Capture: Default GuiControl,, SelGray, % gray[k] GuiControl,, SelColor, % Format("0x{:06X}",c&0xFFFFFF) GuiControl,, SelR, % (c>>16)&0xFF @@ -3144,24 +3543,26 @@ Gui(cmd, arg1:="") k:=k1, c:=k2 return Case "MouseMove": - static PrevControl:="" if (PrevControl!=A_GuiControl) { - PrevControl:=A_GuiControl - SetTimer, %Gui_ToolTip%, % PrevControl ? -500 : "Off" - SetTimer, %Gui_ToolTipOff%, % PrevControl ? -5500 : "Off" ToolTip + PrevControl:=A_GuiControl + if (Gui_ToolTip) + { + SetTimer, %Gui_ToolTip%, % PrevControl ? -500 : "Off" + SetTimer, %Gui_ToolTipOff%, % PrevControl ? -5500 : "Off" + } } return Case "ToolTip": MouseGetPos,,, _TT IfWinExist, ahk_id %_TT% ahk_class AutoHotkeyGUI - ToolTip, % Tip_Text[PrevControl] + ToolTip % Tip_Text[PrevControl] return Case "ToolTipOff": ToolTip return - Case "CutL2","CutR2","CutU2","CutD2": + Case "CutL2", "CutR2", "CutU2", "CutD2": Gui, FindText_Main: Default GuiControlGet, s,, MyPic s:=Trim(s,"`n") . "`n", v:=SubStr(cmd,4,1) @@ -3180,18 +3581,26 @@ Gui(cmd, arg1:="") GuiControl, Focus, scr ControlGet, i, CurrentLine,,, ahk_id %hscr% ControlGet, s, Line, %i%,, ahk_id %hscr% - if !RegExMatch(s,"(<[^>\n]*>[^$\n]+\$)\d+\.[\w+/]+",r) + if !RegExMatch(s, "O)(<[^>\n]*>[^$\n]+\$)\d+\.[\w+/]+", r) return GuiControlGet, v,, MyPic v:=Trim(v,"`n") . "`n", w:=Format("{:d}",InStr(v,"`n")-1) v:=StrReplace(StrReplace(v,"0","1"),"_","0") - s:=StrReplace(s,r,r1 . w "." this.bit2base64(v)) + s:=StrReplace(s, r[0], r[1] . w "." this.bit2base64(v)) v:="{End}{Shift Down}{Home}{Shift Up}{Del}" ControlSend,, %v%, ahk_id %hscr% Control, EditPaste, %s%,, ahk_id %hscr% ControlSend,, {Home}, ahk_id %hscr% return - Case "Load_Language_Text": + } +} + +Lang(text:="", getLang:=0) +{ + local + static init, Lang1, Lang2 + if (!VarSetCapacity(init) && init:="1") + { s:=" ( Myww = Width = Adjust the width of the capture range @@ -3206,7 +3615,7 @@ CutL2 = CutL = Cut the Left Edge of the text in the edit box below CutR2 = CutR = Cut the Right Edge of the text in the edit box below CutD2 = CutD = Cut the Lower Edge of the text in the edit box below Update = Update = Update the text in the edit box below to the line of Code -GetRange = GetRange = Get screen range to clipboard and update the search range of the Code +GetRange = GetRange = Get screen range and update the search range of the Code GetOffset = GetOffset = Get position offset relative to the Text from the Code and update FindText().Click() GetClipOffset = GetOffset2 = Get position offset relative to the Text from the Left Box Capture = Capture = Initiate Image Capture Sequence @@ -3219,9 +3628,6 @@ Copy = Copy = Copy the selected or all of the code to the clipboard Reset = Reset = Reset to Original Captured Image SplitAdd = SplitAdd = Using Markup Segmentation to Generate Text Library AllAdd = AllAdd = Append Another FindText Search Text into Previously Generated Code -OK = OK = Create New FindText Code for Testing -Cancel = Cancel = Close the Window Don't Do Anything -Save = SavePic = Save the trimmed original image to the default directory Gray2Two = Gray2Two = Converts Image Pixels from Gray Threshold to Black or White GrayDiff2Two = GrayDiff2Two = Converts Image Pixels from Gray Difference to Black or White Color2Two = Color2Two = Converts Image Pixels from Color Similar to Black or White @@ -3262,18 +3668,22 @@ Bind1 = BindWin1+ = Bind the window Use GetDCEx() and Modify the window to Bind2 = BindWin2 = Bind the window and Use PrintWindow() to get the image of background window Bind3 = BindWin2+ = Bind the window Use PrintWindow() and Modify the window to support transparency Bind4 = BindWin3 = Bind the window and Use PrintWindow(,,3) to get the image of background window -OK2 = OK = Restore this ScreenShot +OK = OK = Create New FindText Code for Testing +OK2 = OK = Restore this ScreenShot then Capturing +Cancel = Cancel = Close the Window Don't Do Anything Cancel2 = Cancel = Close the Window Don't Do Anything ClearAll = ClearAll = Clean up all saved ScreenShots OpenDir = OpenDir = Open the saved screenshots directory SavePic = SavePic = Select a range and save as a picture +SavePic2 = SavePic = Save the trimmed original image as a picture ClipText = = Displays the Text data from clipboard -Offset = = Displays the results of GetOffset2 +Offset = = Displays the results of GetOffset2 or GetRange +SelectBox = = Select a screenshot to display in the upper left corner of the screen s1 = FindText s2 = Gray|GrayDiff|Color|ColorPos|ColorDiff|MultiColor s3 = Capture Image To Text -s4 = Capture Image To Text And Find Text Tool -s5 = Position|First click RButton\nMove the mouse away\nSecond click RButton +s4 = Capture Image To Text and Find Text Tool +s5 = First click RButton\nMove the mouse away\nSecond click RButton s6 = Unbind Window using s7 = Please drag a range with the LButton\nCoordinates are copied to clipboard s8 = Found|Time|ms|Pos|Result|value can be get from|Wait 3 seconds for appear|Wait indefinitely for disappear @@ -3283,19 +3693,23 @@ s11 = Please Set Gray Difference First s12 = Please select the core color first s13 = Please convert the image to black or white first s14 = Can't be used in ColorPos mode, because it can cause position errors -s15 = Are you sure about the scope of your choice?\n\nIf not, you can choose again +s15 = ReTry|ToFile|GetRange|ToClipboard +s16 = LButton Drag to select range\nDirection keys to fine tune\nRButton or ESC to get range\nDouble-Click copy to Clipboard )" - Lang:=[], Tip_Text:=[] + Lang1:=[], Lang2:=[] Loop Parse, s, `n, `r if InStr(v:=A_LoopField, "=") - r:=StrSplit(StrReplace(v,"\n","`n"), "=", "`t ") - , Lang[r[1]]:=r[2], Tip_Text[r[1]]:=r[3] - return + r:=StrSplit(StrReplace(v "==","\n","`n"), "=", "`t ") + , Lang1[r[1]]:=r[2], Lang2[r[1]]:=r[3] } + return getLang=1 ? Lang1 : getLang=2 ? Lang2 : Lang1[text] } } ;// Class End +Script_End() { +} + ;================= The End ================= ; \ No newline at end of file diff --git a/Lib/Group.ahk b/Lib/Group.ahk new file mode 100644 index 0000000..32c0e56 --- /dev/null +++ b/Lib/Group.ahk @@ -0,0 +1,85 @@ +; Reference: https://www.autohotkey.com/boards/viewtopic.php?t=60272 + +/* +;Uses a combined list & array Groups index,for ease of use & efficiency,respectively. +; Example: +Group_Add("Browser", "ahk_exe iexplore.exe","ahk_exe chrome.exe","ahk_exe sidekick.exe","ahk_exe firefox.exe","ahk_exe palemoon.exe","ahk_exe waterfox.exe","ahk_exe vivaldi.exe","ahk_exe msedge.exe","ahk_exe opera.exe") +Order: last in the list is checked first + +;create new group and make it a 'real' group... +GroupAdd("browsers", "ahk_exe chrome.exe", "ahk_exe firefox.exe") +GroupTranspose("browsers") +SetTimer, listGroups, 300 +;toogle group member +x::IsInGroup("mediaPlayers","vlc.exe") ? GroupDelete("mediaPlayers", "ahk_exe vlc.exe") : GroupAdd("mediaPlayers", "ahk_exe vlc.exe") + +;(de)activate a group... of course group members can't be removed from the transposed 'real' group,only from the custom group they were inherited from... +a::GroupActivate % GroupTranspose("browsers") +d::GroupDeactivate % GroupTranspose("browsers") + +#If GroupActive("mediaPlayers") +g::MsgBox 0x40040,, MEDIA PLAYER GROUP ACTIVE +#If + +#IfWinActive ahk_group browsers ;Custom Group transformed to real group... +g::MsgBox 0x40040,, BROWSER GROUP ACTIVE +#IfWinActive + +listGroups: +ToolTip % A_Groups "`n`n" GroupActive("mediaPlayers") "`n" GroupActive("browsers") +Return + */ +;==================================================================================================== + +Group_Add(groupName,groupMembers*){ + Global A_Groups,A_GroupsArr + ( !InStr(A_Groups, groupName ",") ? (A_Groups .= A_Groups ? "`n" groupName "," : groupName ",") : "" ) ;initialise group if it doesn't exist... + For i,groupMember in groupMembers + ( !InStr(A_Groups, groupMember) ? (A_Groups := StrReplace(A_Groups, groupName ",", groupName "," groupMember ",")) : ) ;append to or create new group... + A_Groups := RegExReplace(RegExReplace(A_Groups, "(^|\R)\K\s+"), "\R+\R", "`r`n") ;clean up groups to remove any possible blank lines + ,ArrayFromList(A_GroupsArr,A_Groups) ;rebuild group as array for most efficient cycling through groups... +} + +Group_Delete(groupName, groupMember:=""){ + Global A_Groups,A_GroupsArr + For i,group in StrSplit(A_Groups,"`n") + ( groupMember && group && InStr(A_Groups,groupMember) && groupName = StrSplit(group,",")[1] ? (A_Groups:=StrReplace(A_Groups,group,StrReplace(group,groupMember ","))) : !groupMember && groupName = StrSplit(group,",")[1] ? (A_Groups:=StrReplace(A_Groups,group)) ) ;remove group member from group & update group in A_Groups + A_Groups := RegExReplace(RegExReplace(A_Groups, "(^|\R)\K\s+"), "\R+\R", "`r`n") ;clean up groups to remove any possible blank lines + ,ArrayFromList(A_GroupsArr,A_Groups) ;rebuild group as array for most efficient cycling through groups... +} + +ArrayFromList(ByRef larray, ByRef list, listDelim := "`n", lineDelim:=","){ + larray := [] + Loop, Parse, list, % listDelim + larray.Push(StrSplit(A_LoopField,lineDelim)) +} + +;Functions below are subject to a performance overhead & hence use A_GroupsArr...as they are repeatedly called... +Group_Active(groupName){ + Global A_GroupsArr + For i,group in A_GroupsArr + If (group.1 = groupName) + For iG,groupMember in group + If (iG > 1 && groupMember && (firstMatchId := WinActive(groupMember))) + Return firstMatchId ;Return group.1 "," firstMatchId + return 0 ; compatible with WinActive function +} + +Group_Transpose(groupName){ ;makes this custom group,a 'real' group,some use cases.... + Global A_GroupsArr + For i,group in A_GroupsArr + If (group.1 = groupName) + For iG,groupMember in group + If (iG > 1 && groupMember) + GroupAdd, % group.1, % groupMember + Return groupName +} + +IsInGroup(groupName, groupMember){ + Global A_Groups + Loop, Parse, A_Groups, `n + If (StrSplit(A_LoopField,",")[1] = groupName && InStr(A_LoopField,groupMember)) + Return True +} + +;==================================================================================================== \ No newline at end of file diff --git a/Lib/IntelliPaste.ahk b/Lib/IntelliPaste.ahk index 1969647..f3482f6 100644 --- a/Lib/IntelliPaste.ahk +++ b/Lib/IntelliPaste.ahk @@ -276,21 +276,20 @@ IntelliPaste_CleanUrl(url,encode:= False) { ; Convert Teams file links to SharePoint links ; ; Calls: Lib/GetSharepointUrl, GetFileLink, UriDecode -; Call: SubFunctions: GetGoogleUrl, IsGoogleUrl +; Call: SubFunctions: Google_IsUrl, Google_CleanUrl url := Trim(url) - ; Teams Beautifier url := Teams_FileLinkBeautifier(url) ; will decode url If Connections_IsUrl(url) url := Connections_CleanUrl(url) -Else If (SharePoint_IsUrl(url)) +Else If SharePoint_IsUrl(url) url := SharePoint_CleanUrl(url) -Else If (IsGoogleUrl(url)) - url := GetGoogleUrl(url) -Else If (Confluence_IsUrl(url)) +Else If Google_IsUrl(url) + url := Google_CleanUrl(url) +Else If Confluence_IsUrl(url) url := Confluence_CleanUrl(url) @@ -322,22 +321,21 @@ If !(encode) { } return url -} +} ;eofun ; ------------------------------------------------------------------------------------------------------------------- -GetGoogleUrl(url){ -; Calls: IsGoogleUrl +Google_CleanUrl(url){ url := uriDecode(url) RegExMatch(url,"&url=(.*)&usg=",newurl) ; exclude & escape ? return newurl1 } ;eofun ; ------------------------------------------------------------------------------------------------------------------- -IsGoogleUrl(url){ +Google_IsUrl(url){ If RegExMatch(url,"https://www\.google\.[a-z]{2,3}/url\?.*") = 0 return false Else return true -} +} ;eofun ; ------------------------------------------------------------------------------------------------------------------- OnIntelliPasteMultiStyleMsgBox() { @@ -416,6 +414,7 @@ If FileExist("Lib/Connections.ahk") { */ If !InStr(sClipboard,"`n") { ; single input + If InStr(sClipboard,"https://github.com/") { sFile := StrReplace(sClipboard,"/blob/","/raw/") sFullText = @@ -435,22 +434,39 @@ If !InStr(sClipboard,"`n") { ; single input } } ; eif Text editors + + ; Confluence Web Images + If Confluence_IsWinActive() { + If RegExMatch(sClipboard, "^http.*\.(png|jpg|jpeg|gif)$") { + imglink = ![ALT TEXT](%sClipboard%) + Clip_Paste2(imglink) + ; Clip_Paste(imglink) ; does not work + return + } + } + sLink := sClipboard - If (Confluence_IsUrl(sLink)) { + If Confluence_IsUrl(sLink) { link := Confluence_CleanLink(sLink) Clip_PasteLink(link[1],link[2]) return - } Else If (Jira_IsUrl(sLink)) { + } Else If Jira_IsUrl(sLink) { link := Jira_CleanLink(sLink) Clip_PasteLink(link[1],link[2]) return - } Else If (Connections_IsUrl(sLink)) { + } Else If Connections_IsUrl(sLink) { link := Connections_CleanLink(sLink) Clip_PasteLink(link[1],link[2]) return } + link := BitBucket_CleanLink(sLink) + If !(link="") { + Clip_PasteLink(link[1],link[2]) + return + } + If RegExMatch(sClipboard,"^http") { ; only for links - exclude script, html code sLink := IntelliPaste_CleanUrl(sLink) } diff --git a/Lib/OSDTIP.ahk b/Lib/OSDTIP.ahk new file mode 100644 index 0000000..58bfc02 --- /dev/null +++ b/Lib/OSDTIP.ahk @@ -0,0 +1,366 @@ +OSDTIP_Alert(P*) { ; OSDTIP_Alert v0.54 by SKAN on D37P/D383 @ tiny.cc/osdtip +Local +Static FN:="", ID:=0, PS:="", PM:="", P8:=(A_PtrSize=8 ? "Ptr" : "") + If !IsObject(FN) + FN := Func(A_ThisFunc).Bind(A_ThisFunc) + + If (P.Count()=0 || P[1]==A_ThisFunc) { + If (P[4]=0x201) ; WM_NCLBUTTONDOWN=0xA1, HTCAPTION=2 ; WM_LBUTTONDOWN=0x201 + Return DllCall("SendMessage", "Ptr",ID, "Int",0xA1,"Ptr",2, "Ptr",0) ; + OnMessage(0x201, FN, 0), OnMessage(0x010, FN, 0) ; WM_LBUTTONDOWN, WM_CLOSE + SetTimer, %FN%, OFF + Progress, 6:OFF + Return ID:=0 + } + + MT:=P[1], ST:=P[2], OP := P[4] . A_Space, TMR:=P[3], FONT:=P[5] ? P[5] : "Segoe UI", + TRN :=Round(P[6]) ? P[6] & 255 : 255, Title := (TMR=0 ? "0x0" : A_ScriptHwnd) . ":" . A_ThisFunc + OP.= InStr(OP,"V1") ? "CWFFFFE2 CT856442 CBEBB800" : InStr(OP,"V2") ? "CWF0F8FF CT1A4482 CB3399FF" + : InStr(OP,"V3") ? "CWF0FFE9 CT155724 CB429300" : InStr(OP,"V4") ? "CWFFEEED CT721C24 CBE40000" + : InStr(OP,"V0") ? "CW3F3F3F CTDADADA CB797979" : "" + PBG := (F := InStr(OP,"CB",1)) ? SubStr(OP, F+2, 6) : "797979" + PBG := Format("0x{5:}{6:}{3:}{4:}{1:}{2:}", StrSplit(PBG)*) + + WinClose, ahk_id %ID% + DetectHiddenWindows, % ("On", DHW:=A_DetectHiddenWindows) + SetWinDelay, % (-1, SWD:=A_WinDelay) + SetControlDelay, % (0, SCD:=A_WinDelay) + + DllCall("uxtheme\SetThemeAppProperties", "Int",0) + Progress, 6: ZX6 ZY4 ZH16 FS10 FM11 WS400 WM800 C00 CT222222 %OP% B1 M Hide + , %ST%, %MT%, %Title%, %FONT% + DllCall("uxtheme\SetThemeAppProperties", "Int",7) + WinWait, %Title% ahk_class AutoHotkey2 + ControlGetPos,,,, PBS, msctls_progress321 + ControlGetPos, X1,,,, Static1 + ControlGetPos, X2,,,, Static2 + NM := X1+Round(PBS//2) + Progress, 6: ZY4 ZH16 FS10 FM11 WS400 WM800 C00 CT222222 CB797979 %OP% ZX%NM% B1 M Hide + , %ST%, %MT%, %Title%, %FONT% + WinWait, %Title% ahk_class AutoHotkey2 + + WinSet, Transparent, %TRN%, % "ahk_id" . (ID:=WinExist()) + WinGetPos, WX, WY, WW, WH + ControlGetPos,,,, PBS, msctls_progress321 + ControlGetPos,, Y1, W1, H1, Static1 + ControlGetPos,, Y2, W2, H2, Static2 + WH := Y1 + H1 + Round(H2) + 2 + + SysGet, M, MonitorWorkArea, % Round(P[9]) + mX := mLeft, mY := mTop, mW := mRight-mLeft, mH := mBottom-mTop + WX := mX + ( P[7]="" ? (mW//2)-(WW//2) : P[7]<0 ? mW-WW+P[7]+1 : P[7] ) + WY := mY + ( P[8]="" ? (mH//2)-(WH//2) : P[8]<0 ? mH-WH+P[8]+1 : P[8] ) + WinMove,,, % WX , % WY , % WW, % WH + + ControlMove, Static1, % X1+PBS, % Y1, % W1, % H1 + ControlMove, Static2, % X2+PBS, % Y1+H1+2, % W2, % H2 + Control, ExStyle, -0x20000, msctls_progress321 ; WS_EX_STATICEDGE, removed + SendMessage, 0x2001, 1, % PBG, msctls_progress321 ; PBM_SETBACKCOLOR + ControlMove, msctls_progress321, 0, 0, % PBS, % WH + + SetControlDelay, %SCD% + SetWinDelay, %SWD% + DetectHiddenWindows, %DHW% + SC := DllCall("GetClassLong" . P8, "Ptr",ID, "Int",-26, "UInt") ; GCL_STYLE + DllCall("SetClassLong" . P8, "Ptr",ID, "Int",-26, "Ptr",SC|0x20000) ; GCL_STYLE, CS_DROPSHADOW + Progress, 6:SHOW + DllCall("SetClassLong" . P8, "Ptr",ID, "Int",-26, "Ptr",SC) ; GCL_STYLE + + If (Round(TMR)<0) + SetTimer, %FN%, %TMR% + OnMessage(0x202, FN, TMR=0 ? 0 : -1), OnMessage(0x010, FN) ; WM_LBUTTONUP, WM_CLOSE +Return ID := WinExist() +} + +;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +OSDTIP_Desktop(P*) { ; OSDTIP_Desktop v0.50 by SKAN on D35P/D36E @ tiny.cc/osdtip +Local +Static FN:="", ID:=0, PS:="", PM:="", P8:=(A_PtrSize=8 ? "Ptr" : "") + + If !IsObject(FN) + FN := Func(A_ThisFunc).Bind(A_ThisFunc) + + If (P.Count()=0 || P[1]==A_ThisFunc) { + If (P[4]=0x201) ; WM_NCLBUTTONDOWN=0xA1, HTCAPTION=2 ; WM_LBUTTONDOWN=0x201 + Return DllCall("SendMessage", "Ptr",ID, "Int",0xA1,"Ptr",2, "Ptr",0) ; + OnMessage(0x201, FN, 0), OnMessage(0x010, FN, 0) ; WM_LBUTTONDOWN, WM_CLOSE + SetTimer, %FN%, OFF + Progress, 7:OFF + Return ID:=0 + } + + MT:=P[1], ST:=P[2], TMR:=P[3], OP:=P[4], FONT:=P[5] ? P[5] : "Segoe UI" + TRN:=P[6] ? P[6] : "A0A0A0 127", Title := (TMR=0 ? "0x0" : A_ScriptHwnd) . ":" . A_ThisFunc + + If (ID) { + Progress, 7:, % (ST=PS ? "" : PS:=ST), % (MT=PM ? "" : PM:=MT), %Title% + SetTimer, %FN%, % Round(TMR)<0 ? TMR : "OFF" + OnMessage(0x201, FN, TMR=0 ? 0 : -1) ; WM_LBUTTONDOWN + Return ID + } + + DetectHiddenWindows, % ("Off", DHW:=A_DetectHiddenWindows) + If !hSDV:=DllCall("GetWindow", "Ptr",WinExist("ahk_class Progman"), "UInt",5, "Ptr") ; GW_CHILD=5 + hSDV:=DllCall("GetWindow", "Ptr",WinExist("ahk_class WorkerW"), "UInt",5, "Ptr") ; GW_CHILD=5 + DetectHiddenWindows, On + SetWinDelay, % (-1, SWD:=A_WinDelay) + + DllCall("uxtheme\SetThemeAppProperties", "Int",0) + Progress, 7: ZX0 ZY0 ZH1 w200 FS14 FM28 CWA0A0A0 CTFEFEFE B %OP% M HIDE + , %ST%, %MT%, %Title%, %FONT% + DllCall("uxtheme\SetThemeAppProperties", "Int",7) + WinWait %Title% ahk_class AutoHotkey2 + + Control, Style, 0x50000000, msctls_progress321 ; WS_VISIBLE | WS_CHILD + Control, ExStyle,-0x20000, msctls_progress321 ; WS_EX_STATICEDGE + If !InStr(OP,"U4") { + Control, Style, 0x50000002, Static1 ; WS_VISIBLE | WS_CHILD + Control, Style, 0x50000002, Static2 ; | SS_RIGHT + } + SendMessage, 0x2001, 0, P[9]!="" ? P[9] : 0xFFFFFF, msctls_progress321 ; PBM_SETBACKCOLOR=0x2001 + WinSet, TransColor, %TRN% + WinGetPos, X, Y, W, H + SysGet, M, MonitorWorkArea + If !InStr(OP,"U5") + X:=MRight-W-14, Y:=MBottom-H-14 + Else + X := P[7]="" ? (MRight/2) -(W/2) : P[7]<0 ? MRight -W+P[7] : P[7] + , Y := P[8]="" ? (MBottom/2)-(H/2) : P[8]<0 ? MBottom-H+P[8] : P[8] + ID:=WinExist() ; SetWindowPos HWND_BOTTOM=1, SWP_SHOWWINDOW=0x40 SWP_NOACTIVATE=0x10 + DllCall("SetWindowPos", "Ptr",ID, "Ptr",1, "Int",X, "Int",Y, "Int",W+2, "Int",H, "UInt",0x40|0x10) + DllCall("SetWindowPos", "Ptr",ID, "Ptr",1, "Int",X, "Int",Y, "Int",W+0, "Int",H, "UInt",0x40|0x10) + DllCall("SetWindowLong" . P8, "Ptr",ID, "Int",-8, "Ptr",hSDV) ; GWL_HWNDPARENT + SetWinDelay, %SWD% + DetectHiddenWindows, %DHW% + Progress, 7:SHOW + If (Round(TMR)<0) + SetTimer, %FN%, %TMR% + OnMessage(0x201, FN, TMR=0 ? 0 : -1), OnMessage(0x010, FN) ; WM_LBUTTONDOWN, WM_CLOSE +Return ID +} + +;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +OSDTIP_Volume(P*) { ; OSDTIP_Volume v0.50 by SKAN on D35P/D369 @ tiny.cc/osdtip +Local +Static FN:="", ID:=0, PV:=0, P8:=(A_PtrSize=8 ? "Ptr" : "") + + If !IsObject(FN) + FN := Func(A_ThisFunc).Bind(A_ThisFunc) + + If (P.Count()=0 || P[1]==A_ThisFunc) { + OnMessage(0x202, FN, 0), OnMessage(0x010, FN, 0) ; WM_LBUTTONUP, WM_CLOSE + SetTimer, %FN%, OFF + Progress, 8:OFF + Return ID:=0 + } + + M:=P[1], V:=P[2], VSigned:=InStr("+-",SubStr(V,1,1)), TMR:=P[3] + OP:=P[4], FONT:=P[5] ? P[5] : "Trebuchet MS", TRN:=Round(P[6]) ? P[6] & 255 : 222 + Title := (TMR=0 ? "0x0" : A_ScriptHwnd) . ":" . A_ThisFunc + + If (M!="") + SoundSet, %M%,, MUTE + SoundGet, M,, MUTE + If ( V!="" && !VSigned) + SoundSet, %V% + SoundGet, VOL + VOL:=Round(VOL) + + If WinExist("ahk_id" . ID) + { + If (V && VSigned) + SoundSet, % VOL:=(VOL:=V ? Round((VOL+V)/V)*V : VOL)>100 ? 100 : VOL<0 ? 0 : Round(VOL) + SendMessage, 0x0409, 1, % (M="On" ? 0x0030FF:0x00FFAA), msctls_progress321 ; PBM_SETBARCOLOR + SendMessage, 0x2001, 0, % (M="On" ? 0x00175A:0x00402E), msctls_progress321 ; PBM_SETBACKCOLOR + Progress, 8:%VOL%, % PV!=VOL ? PV:=VOL : "",, %Title% + SetTimer, %FN%, % Round(TMR)<0 ? TMR : "OFF" + Return ID + } + + DetectHiddenWindows, % ("On", DHW:=A_DetectHiddenWindows) + SetWinDelay, % (-1, SWD:=A_WinDelay) + DllCall("uxtheme\SetThemeAppProperties", "Int",0) + Progress, 8:C11 w318 ZH24 ZX28 ZY4 WM400 WS600 FM16 FS22 CT111111 CWF0F0F0 %OP% B1 HIDE + , % PV:=VOL, V O L U M E, %Title%, %FONT% + DllCall("uxtheme\SetThemeAppProperties", "Int",7) + WinWait, %Title% ahk_class AutoHotkey2 + + WinSet, Transparent, %TRN%, % "ahk_id" . (ID:=WinExist()) + SendMessage, 0x0409, 1, % (M="On" ? 0x0030FF:0x00FFAA), msctls_progress321 ; PBM_SETBARCOLOR + SendMessage, 0x2001, 0, % (M="On" ? 0x00175A:0x00402E), msctls_progress321 ; PBM_SETBACKCOLOR + Control, ExStyle, -0x20000, msctls_progress321 + DetectHiddenWindows, %DHW% + Progress, 8:%VOL% + SC := DllCall("GetClassLong" . P8, "Ptr",ID, "Int",-26, "UInt") ; GCL_STYLE + DllCall("SetClassLong" . P8, "Ptr",ID, "Int",-26, "Ptr",SC|0x20000) ; GCL_STYLE, CS_DROPSHADOW + Progress, 8:SHOW + DllCall("SetClassLong" . P8, "Ptr",ID, "Int",-26, "Ptr",SC) ; GCL_STYLE + If (Round(TMR)<0) + SetTimer, %FN%, %TMR% + OnMessage(0x202, FN, TMR=0 ? 0 : -1), OnMessage(0x010, FN) ; WM_LBUTTONUP, WM_CLOSE +Return ID := WinExist() +} + +;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +OSDTIP_KBLeds(P*) { ; OSDTIP_KBLeds v0.50 by SKAN on D361/D367 @ tiny.cc/osdtip +Local +Static FN:="", ID:=0 + + If !IsObject(FN) + FN := Func(A_ThisFunc).Bind(A_ThisFunc) + + If (P.Count()=0 || P[1]==A_ThisFunc) { + OnMessage(0x202, FN, 0), OnMessage(0x010, FN, 0) ; WM_LBUTTONUP, WM_CLOSE + SetTimer, %FN%, OFF + Progress, 9:OFF + Return ID:=0 + } + + Key := P[1], ST:=P[2], TMR:=P[3], OP:=P[4], FONT:=P[5] ? P[5] : "Trebuchet MS" + Title := (TMR=0 ? "0x0" : A_ScriptHwnd) . ":" . A_ThisFunc, TRN:=Round(P[6]) ? P[6] & 255 : 222 + + If WinExist("ahk_id" . ID) { + ST.=InStr(ST,"off") || InStr(ST,"on") ? "" : GetKeyState(Key,"T") ? "Off" : "On" + Switch (Key) { + Case "CapsLock" : SetCapsLockState, %ST% + Case "ScrollLock" : SetScrollLockState, %ST% + Case "NumLock" : SetNumLockState, %ST% + } + C:=GetKeyState("CapsLock","T"), S:=GetKeyState("ScrollLock","T"), N:=GetKeyState("NumLock","T") + SendMessage, 0x2001, 1,% C ? 0x00FFAA:0x808080, msctls_progress321 ; PBM_SETBACKCOLOR + SendMessage, 0x2001, 1,% S ? 0x00AAFF:0x808080, msctls_progress322 ; PBM_SETBACKCOLOR + SendMessage, 0x2001, 1,% N ? 0x00FFAA:0x808080, msctls_progress323 ; PBM_SETBACKCOLOR + + If (Key="CapsLock" && C=1) || (Key="NumLock" && N=0) + If ( InStr(OP,"U2",1) && FileExist(WAV:=A_WinDir . "\Media\Windows Default.wav") ) + DllCall("winmm\PlaySoundW", "WStr",WAV, "Ptr",0, "Int",0x220013) ; SND_FILENAME | SND_ASYNC + + SetTimer, %FN%, % Round(TMR)<0 ? TMR : "OFF" + Progress, 9:,,,%Title% + Return ID + } + + DetectHiddenWindows, % ("On", DHW:=A_DetectHiddenWindows) + SetWinDelay, % (-1, SWD:=A_WinDelay) + SetControlDelay, % (0, SCD:=A_ControlDelay) + DllCall("uxtheme\SetThemeAppProperties", "Int",0) + Progress, 9:ZX32 ZY6 ZH32 W172 WM600 WS400 FM16 FS16 CT101010 CWF0F0F0 %OP% C00 B1 HIDE + , ScrollLock, CapsLock, %Title%, %FONT% + WinWait %Title% ahk_class AutoHotkey2 + + WinGetPos, WX, WY, WW, WH, % "ahk_id" . (ID:=WinExist()) + Loop, Parse, % "msctls_progress32|msctls_progress32|Static", | + DllCall("CreateWindowEx", "Int",0, "Str",A_LoopField, "Str","NumLock" ; WS_VISIBLE | WS_CHILD + ,"Int",0x50000000, "Int",0, "Int",0, "Int",10, "Int",10, "Ptr",ID, "Ptr",0, "Ptr",0, "Ptr",0) + DllCall("uxtheme\SetThemeAppProperties", "Int",7) + SendMessage, 0x31, 0, 0, Static1 ; WM_GETFONT + SendMessage, 0x30, %ErrorLevel%, 1, Static3 ; WM_SETFONT + ControlGetPos, CX, CY, CW, CH, Static1 + YM:=CY-1, NX:=CX+CH+24, WW:=WW+CH+24, WH:=(CH*3)+(YM*4)+2, PH:=Round(CH/2), PY:=CY+(PH/2) + WX:=(A_ScreenWidth/2)-(WW/2), WY := (A_ScreenHeight/2)-(WH/2) + WinMove,% "ahk_id" WinExist(),,% WX,% WY,% WW, % WH + ControlMove, Static1, % NX, % CY, % CW, % CH + ControlMove, Static2, % NX, % CY+CH+YM, % CW, % CH + ControlMove, Static3, % NX, % CY+CH+YM+CH+YM, % CW, % CH + ControlMove, msctls_progress321, % CX, % PY, % CH, % PH + ControlMove, msctls_progress322, % CX, % PY+CH+YM, % CH, % PH + ControlMove, msctls_progress323, % CX, % PY+CH+YM+CH+YM, % CH, % PH + Loop 3 + Control, Style, +0x202, Static%A_Index% ; SS_RIGHT | SS_CENTERIMAGE + WinSet, Transparent, %TRN% + SetControlDelay, %SCD% + SetWinDelay, %SWD% + DetectHiddenWindows, %DHW% + + P8 := (A_PtrSize=8 ? "Ptr":"") + SC := DllCall("GetClassLong" . P8, "Ptr",ID, "Int",-26, "UInt") ; GCL_STYLE + DllCall("SetClassLong" . P8, "Ptr",ID, "Int",-26, "Ptr",SC|0x20000) ; GCL_STYLE, CS_DROPSHADOW + Progress, 9:SHOW + DllCall("SetClassLong" . P8, "Ptr",ID, "Int",-26, "Ptr",SC) ; GCL_STYLE + + P[3]:=0, n:=%A_ThisFunc%(P*) + If (Round(TMR)<0) + SetTimer, %FN%, %TMR% + OnMessage(0x202, FN, TMR=0 ? 0 : -1), OnMessage(0x010, FN) ; WM_LBUTTONUP, WM_CLOSE +Return ID +} + +;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +OSDTIP_Pop(P*) { ; OSDTIP_Pop v0.55 by SKAN on D361/D36E @ tiny.cc/osdtip +Local +Static FN:="", ID:=0, PM:="", PS:="" + + If !IsObject(FN) + FN := Func(A_ThisFunc).Bind(A_ThisFunc) + + If (P.Count()=0 || P[1]==A_ThisFunc) { + OnMessage(0x202, FN, 0), OnMessage(0x010, FN, 0) ; WM_LBUTTONUP, WM_CLOSE + SetTimer, %FN%, OFF + DllCall("AnimateWindow", "Ptr",ID, "Int",200, "Int",0x50004) ; AW_VER_POSITIVE | AW_SLIDE + Progress, 10:OFF ; | AW_HIDE + Return ID:=0 + } + + MT:=P[1], ST:=P[2], TMR:=P[3], OP:=P[4], FONT:=P[5] ? P[5] : "Segoe UI" + Title := (TMR=0 ? "0x0" : A_ScriptHwnd) . ":" . A_ThisFunc + + If (ID) { + Progress, 10:, % (ST=PS ? "" : PS:=ST), % (MT=PM ? "" : PM:=MT), %Title% + OnMessage(0x202, FN, TMR=0 ? 0 : -1) ; v0.55 + SetTimer, %FN%, % Round(TMR)<0 ? TMR : "OFF" + Return ID + } + + If ( InStr(OP,"U2",1) && FileExist(WAV:=A_WinDir . "\Media\Windows Notify.wav") ) + DllCall("winmm\PlaySoundW", "WStr",WAV, "Ptr",0, "Int",0x220013) ; SND_FILENAME | SND_ASYNC + ; | SND_NODEFAULT + DetectHiddenWindows, % ("On", DHW:=A_DetectHiddenWindows) ; | SND_NOSTOP | SND_SYSTEM + SetWinDelay, % (-1, SWD:=A_WinDelay) + DllCall("uxtheme\SetThemeAppProperties", "Int",0) + Progress, 10:C00 ZH1 FM9 FS10 CWF0F0F0 CT101010 %OP% B1 M HIDE,% PS:=ST, % PM:=MT, %Title%, %FONT% + DllCall("uxtheme\SetThemeAppProperties", "Int",7) ; STAP_ALLOW_NONCLIENT + ; | STAP_ALLOW_CONTROLS + WinWait, %Title% ahk_class AutoHotkey2 ; | STAP_ALLOW_WEBCONTENT + WinGetPos, X, Y, W, H + SysGet, M, MonitorWorkArea + WinMove,% "ahk_id" . WinExist(),,% MRight-W,% MBottom-(H:=InStr(OP,"U1",1) ? H : Max(H,100)), W, H + If ( TRN:=Round(P[6]) & 255 ) + WinSet, Transparent, %TRN% + ControlGetPos,,,,H, msctls_progress321 + If (H>2) { + ColorMQ:=Round(P[7]), ColorBG:=P[8]!="" ? Round(P[8]) : 0xF0F0F0, SpeedMQ:=Round(P[9]) + Control, ExStyle, -0x20000, msctls_progress321 ; v0.55 WS_EX_STATICEDGE + Control, Style, +0x8, msctls_progress321 ; PBS_MARQUEE + SendMessage, 0x040A, 1, %SpeedMQ%, msctls_progress321 ; PBM_SETMARQUEE + SendMessage, 0x0409, 1, %ColorMQ%, msctls_progress321 ; PBM_SETBARCOLOR + SendMessage, 0x2001, 1, %ColorBG%, msctls_progress321 ; PBM_SETBACKCOLOR + } + DllCall("AnimateWindow", "Ptr",WinExist(), "Int",200, "Int",0x40008) ; AW_VER_NEGATIVE | AW_SLIDE + SetWinDelay, %SWD% + DetectHiddenWindows, %DHW% + If (Round(TMR)<0) + SetTimer, %FN%, %TMR% + OnMessage(0x202, FN, TMR=0 ? 0 : -1), OnMessage(0x010, FN) ; WM_LBUTTONUP, WM_CLOSE +Return ID:=WinExist() +} + +;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +OSDTIP(hWnd:="") { +Local OSDTIP + If (hWnd="") + Return A_ScriptHwnd . ":OSDTIP_" . "ahk_class AutoHotkey2" + If !WinExist("ahk_id" . hWnd) + Return 0 + WinGetTitle, OSDTIP + OSDTIP := StrSplit(OSDTIP,":") + If ( OSDTIP[1] = A_ScriptHwnd ) + OSDTIP[2]() + +} + +;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Lib/PowerTools.ahk b/Lib/PowerTools.ahk index 268c103..5801f77 100644 --- a/Lib/PowerTools.ahk +++ b/Lib/PowerTools.ahk @@ -1,23 +1,25 @@ ; PowerTools Lib -#Include +;#Include -AppList = ConnectionsEnhancer,MO,NWS,OutlookShortcuts,PeopleConnector,TeamsShortcuts +; ---------------------------------------------------------------------- PowerTools_CheckForUptate(ToolName :="") { If !a_iscompiled { - Run, https://github.com/tdalon/ahk ; no direct link because of Lib dependencies + Run, https://github.com/tdalon/ahk ; no direct link because of Lib dependencies return } +/* ; warning if connected via VPN If (Login_IsVPN()) { MsgBox, 0x1011, CheckForUpdate with VPN?,It seems you are connected with VPN.`nCheck for update might not work. Consider disconnecting VPN.`nContinue now? IfMsgBox Cancel return -} +} +*/ -If !ToolName +If (ToolName ="") ScriptName := A_ScriptName Else ScriptName = %ToolName%.exe @@ -37,7 +39,7 @@ If Not FileExist(guExe) sCmd = %guExe% %ScriptName% RunWait, %sCmd%,,Hide -} ; eof +} ; eofun ; ---------------------------------------------------------------------- PowerTools_Help(ScriptName,doOpen := True){ @@ -69,7 +71,7 @@ Case "Chromy": Case "Edgy": sUrl = https://tdalon.github.io/ahk/Edgy Case "Atlasy": - sUrl = https://tdalon.github.io/ahk/Atlasy + sUrl := "https://tdalon.github.io/ahk/Atlasy" Case "all": Default: sUrl := "https://tdalon.github.io/ahk/PowerTools" @@ -77,6 +79,7 @@ Default: If doOpen Run, %sUrl% + return sUrl } ; eofun @@ -93,6 +96,8 @@ Case "PeopleConnector": sFileName = People-Connector-Changelog Case "NWS": sFileName = NWS-PowerTool-Changelog +Case "Atlasy": + sFileName = Atlasy-Changelog Case "Mute": sFileName = Mute-PowerTool-Changelog Case "Bundler": @@ -114,7 +119,6 @@ If Not doOpen { return sUrl } - If !A_IsCompiled { sFile = %A_ScriptDir%\docs\_pages\%sFileName%.md If FileExist(sFile) { @@ -146,6 +150,8 @@ Case "OutlookShortcuts": sUrl := sUrl . "%20%23MicrosoftOutlook" Case "Teamsy": sUrl := sUrl . "%20%23MicrosoftTeams" +Case "Atlasy": + sUrl := sUrl . "%20%23Atlasy" } Run, %sUrl% @@ -155,46 +161,61 @@ Run, %sUrl% PowerTools_RunBundler(){ If a_iscompiled { - ExeFile = %A_ScriptDir%\PowerToolsBundler.exe - If Not FileExist(ExeFile) { + ExeFile = %A_ScriptDir%\PowerToolsBundler.exe + If Not FileExist(ExeFile) { sUrl = https://raw.githubusercontent.com/tdalon/ahk/main/PowerTools/PowerToolsBundler.exe - UrlDownloadToFile, %sUrl%, PowerToolsBundler.exe - } - Run %ExeFile% -} Else - Run %A_AHKPath% "%A_ScriptDir%\PowerToolsBundler.ahk" - + UrlDownloadToFile, %sUrl%, PowerToolsBundler.exe + } + Run %ExeFile% +} Else { + Run %A_AHKPath% "%A_ScriptDir%\PowerToolsBundler.ahk" +} } ; eofun ; ---------------------------------------------------------------------- - - - ; ---------------------------------------------------------------------- PowerTools_OpenDoc(key:=""){ - IniRead, DocRootUrl, PowerTools.ini,Doc,DocRootUrl - If (DocRootUrl="ERROR") { - PowerTools_ErrDlg("DocRootUrl key not found in PowerTools.ini file [Doc] section!") - return - } - If (key ="") { - sUrl := "https://github.com/tdalon/ahk" - Run, "%sUrl%" - return - } - - IniRead, DocMap, PowerTools.ini,Doc,DocMap - If (DocMap="ERROR") { - PowerTools_ErrDlg("DocMap key not found in PowerTools.ini file [Doc] section!") - return - } +IniRead, DocRootUrl, PowerTools.ini,Doc,DocRootUrl +If (DocRootUrl="ERROR") { + PowerTools_ErrDlg("DocRootUrl key not found in PowerTools.ini file [Doc] section!") + return +} +IniRead, DocMap, PowerTools.ini,Doc,DocMap +If !(DocMap="ERROR") { JsonObj := Jxon_Load(DocMap) sUrl := JsonObj[key] If !(sUrl) sUrl := DocRootUrl - Run, "%sUrl%" + ;PowerTools_ErrDlg("DocMap key not found in PowerTools.ini file [Doc] section!") + ;return +} Else { + sUrl := "https://github.com/tdalon/ahk" + Switch key ; TODO + { + Case "r4j_CopyChildrenJql": ; gui/ launcher + sUrl:= "https://tdalon.blogspot.com/2024/02/r4j-copy-children-jql.html" + Case "atlasy": + sUrl := "https://tdalon.github.io/ahk/Atlasy" + Case "R4J_OpenPathJql": + sUrl :="https://tdalon.blogspot.com/2024/02/r4j-bulk-edit-folder.html" + Case "Jira_ViewLinkedIssues": + Case "Jira_OpenIssuesNav": + Case "Jira_CreateIssue": + Case "atlasy_openissue": + Case "r4j_CV" : + Case "r4j_CopyPathJql": + Case "Jira_BulkEdit": + Case "Confluence_ViewInHierachy": + Case "Confluence_ViewAttachments": + Case "Confluence_PageInfo": + Case "Confluence_ViewPageHistory": + Default: + + } ; end Switch +} +Run, "%sUrl%" } ; eofun @@ -222,7 +243,7 @@ return Setting } ; eofun ; ---------------------------------------------------------------------- -PowerTools_GetConfig(){ +PowerTools_GetConfig() { RegRead, Config, HKEY_CURRENT_USER\Software\PowerTools, Config If (Config=""){ Config := PowerTools_LoadConfig() @@ -230,59 +251,56 @@ If (Config=""){ return Config } ; ---------------------------------------------------------------------- -PowerTools_SetConfig(){ +PowerTools_SetConfig() { ; Config := PowerTools_SetConfig() - RegRead, Config, HKEY_CURRENT_USER\Software\PowerTools, Config - DefListConfig := "Default|Ini" - If FileExist("Lib/ET.ahk") - DefListConfig := DefListConfig . "|ET" - If FileExist("Lib/Conti.ahk") - DefListConfig := DefListConfig . "|Conti|Vitesco" - Select := 0 - Loop, parse, DefListConfig, | - { - If (A_LoopField = Config) { - Select := A_Index - break - } +RegRead, Config, HKEY_CURRENT_USER\Software\PowerTools, Config +DefListConfig := "Default|Ini" +If FileExist("Lib/ET.ahk") + DefListConfig := DefListConfig . "|ET" +If FileExist("Lib/Conti.ahk") + DefListConfig := DefListConfig . "|Conti|Vitesco" +Select := 0 +Loop, parse, DefListConfig, | +{ + If (A_LoopField = Config) { + Select := A_Index + break } - Config := ListBox("PowerTools Config","Select your configuration:",DefListConfig,Select) - If (Config="") - return - PowerTools_RegWrite("Config",Config) - return Config +} +Config := ListBox("PowerTools Config","Select your configuration:",DefListConfig,Select) +If (Config="") + return +PowerTools_RegWrite("Config",Config) +return Config } ; eofun ; ------------------------------------------------------------------------------------------------------------------- PowerTools_IniRead(Section,Key) { - ; PowerTools_IniRead(Section,Key) - ; return "ERROR" if key was not found in PowerTools.ini File - IniRead, OutputVar, PowerTools.ini,%Section%,%Key% - return OutputVar - } ; eofun - ; ------------------------------------------------------------------------------------------------------------------- - ; ------------------------------------------------------------------------------------------------------------------- - PowerTools_IniWrite(Var,Section,Key) { - ; PowerTools_IniWrite(Var,Section,Key) - ; ErrorLevel is returned - IniWrite, %Var%, PowerTools.ini, %Section%, %Key% - } ; eofun +; PowerTools_IniRead(Section,Key) +; return "ERROR" if key was not found in PowerTools.ini File +IniRead, OutputVar, PowerTools.ini,%Section%,%Key% +return OutputVar +} ; eofun +; ------------------------------------------------------------------------------------------------------------------- +PowerTools_IniWrite(Var,Section,Key) { + ; PowerTools_IniWrite(Var,Section,Key) + ; ErrorLevel is returned + IniWrite, %Var%, PowerTools.ini, %Section%, %Key% +} ; eofun ; ------------------------------------------------------------------------------------------------------------------- ; ------------------------------------------------------------------------------------------------------------------- -PowerTools_RegRead(Prop){ +PowerTools_RegRead(Prop) { RegRead, OutputVar, HKEY_CURRENT_USER\Software\PowerTools, %Prop% return OutputVar } ; eofun - ; ------------------------------------------------------------------------------------------------------------------- -PowerTools_RegWrite(Prop, Value){ +PowerTools_RegWrite(Prop, Value) { RegWrite, REG_SZ, HKEY_CURRENT_USER\Software\PowerTools, %Prop%, %Value% } - ; ------------------------------------------------------------------------------------------------------------------- -PowerTools_RegGet(Prop,sPrompt :=""){ +PowerTools_RegGet(Prop,sPrompt :="") { Prop := StrReplace(Prop," ","") ; remove blanks RegRead, Value, HKEY_CURRENT_USER\Software\PowerTools, %Prop% If (sPrompt = "") @@ -295,144 +313,140 @@ return Value } ;eofun ; ------------------------------------------------------------------------------------------------------------------- -PowerTools_RegSet(Prop,sPrompt :=""){ - +PowerTools_RegSet(Prop,sPrompt :="") { If (sPrompt = "") sPrompt = Enter value for %Prop%: - Prop := StrReplace(Prop," ","") RegRead, Value, HKEY_CURRENT_USER\Software\PowerTools, %Prop% InputBox, Value, %Prop%, %sPrompt%, , 200, 150, , , , , %Value% If ErrorLevel return PowerTools_RegWrite(Prop,Value) - return Value } ;eofun ; ---------------------------------------------------------------------- -PowerTools_LoadConfig(Config :=""){ +PowerTools_LoadConfig(Config :="") { If (Config=""){ Config := PowerTools_SetConfig() } - IniFile = %A_ScriptDir%\PowerTools.ini - Switch Config { - Case "Default": ; Global default settings - sEmpty= - PowerTools_RegWrite("Domain","") - IniWrite,%sEmpty% , %IniFile%, Main, Domain +Case "Default": ; Global default settings + sEmpty= + PowerTools_RegWrite("Domain","") + IniWrite,%sEmpty% , %IniFile%, Main, Domain - PowerTools_RegWrite("TenantName","") - IniWrite, %sEmpty%, %IniFile%, Main, TenantName + PowerTools_RegWrite("TenantName","") + IniWrite, %sEmpty%, %IniFile%, Main, TenantName - PowerTools_RegWrite("ProxyServer","n/a") - IniWrite, n/a, %IniFile%, Main, ProxyServer + PowerTools_RegWrite("ProxyServer","n/a") + IniWrite, n/a, %IniFile%, Main, ProxyServer - PowerTools_RegWrite("ConnectionsRootUrl","") - IniWrite, %sEmpty%, %IniFile%, Connections, ConnectionsRootUrl + PowerTools_RegWrite("ConnectionsRootUrl","") + IniWrite, %sEmpty%, %IniFile%, Connections, ConnectionsRootUrl - PowerTools_RegWrite("TeamsOnly",1) - IniWrite, 1, %IniFile%, Teams, TeamsOnly + PowerTools_RegWrite("TeamsOnly",1) + IniWrite, 1, %IniFile%, Teams, TeamsOnly - IniWrite, https://tdalon.blogspot.com/, %IniFile%, Doc, DocRootUrl + IniWrite, https://tdalon.blogspot.com/, %IniFile%, Doc, DocRootUrl - ; Load Parameters - ParamList = TeamsMentionDelay,TeamsCommandDelay,TeamsClickDelay - ; FindText - TeamsFindTextList = Mute,Muted,Leave,Resume,MeetingActions,MeetingReactions,MeetingReactionHeart,MeetingReactionLaugh,MeetingReactionApplause,MeetingReactionLike,MeetingActionFullScreen,MeetingActionTogetherMode,MeetingActionBackgrounds,MeetingActionShare,MeetingActionUnShare - Loop, Parse,TeamsFindTextList, `, - { - ParamList = %ParamList%,TeamsFindText%A_LoopField% - } + ; Load Parameters + ParamList = TeamsMentionDelay,TeamsCommandDelay,TeamsClickDelay + ; FindText + TeamsFindTextList = Mute,Muted,Leave,Resume,MeetingActions,MeetingReactions,MeetingReactionHeart,MeetingReactionLaugh,MeetingReactionApplause,MeetingReactionLike,MeetingActionFullScreen,MeetingActionTogetherMode,MeetingActionBackgrounds,MeetingActionShare,MeetingActionUnShare + Loop, Parse,TeamsFindTextList, `, + { + ParamList = %ParamList%,TeamsFindText%A_LoopField% + } - Loop, Parse, ParamList, `, - { - If RegExMatch(A_LoopField,"[A-Z][a-z]*",sMatch) - { - IniVal := PowerTools_GetParam(A_LoopField) - IniWrite, %IniVal%, %IniFile%, %sMatch%, %A_LoopField% - } - } - - ; Teams Global Hotkeys - HotkeyIDList = Launcher,Mute,Video,Mute App,Share,Raise Hand,Push To Talk - Loop, Parse, HotkeyIDList, `, + Loop, Parse, ParamList, `, + { + If RegExMatch(A_LoopField,"[A-Z][a-z]*",sMatch) { - HKid := A_LoopField - HKid := StrReplace(HKid," ","") - Param = TeamsHotkey%HKid% - RegRead, HK, HKEY_CURRENT_USER\Software\PowerTools, %Param% - IniWrite, %HK%, %IniFile%, Teams, %Param% - } - - - Case "Ini": - If !FileExist(IniFile) { - MSgBox 0x10, PowerTools: Error, PowerTools.ini can not be found! - return - } - - IniRead, IniVal, %IniFile%, Main, Domain - PowerTools_RegWrite("Domain",IniVal) - IniRead, IniVal, %IniFile%, Teams, TeamsOnly - PowerTools_RegWrite("TeamsOnly",IniVal) - IniRead, IniVal, %IniFile%, Connections, ConnectionsRootUrl - If (IniVal != "ERROR") - PowerTools_RegWrite("ConnectionsRootUrl",IniVal) - Else - PowerTools_RegWrite("ConnectionsRootUrl","") - - IniRead, IniVal, %IniFile%, Jira, JiraUserName - If (IniVal != "ERROR") - PowerTools_RegWrite("JiraUserName",IniVal) - IniRead, IniVal, %IniFile%, Confluence, ConfluenceUserName - If (IniVal != "ERROR") - PowerTools_RegWrite("ConfluenceUserName",IniVal) - + IniVal := PowerTools_GetParam(A_LoopField) + IniWrite, %IniVal%, %IniFile%, %sMatch%, %A_LoopField% + } + } - ; Load Parameters - ParamList = TeamsMentionDelay,TeamsCommandDelay,TeamsClickDelay - ; FindText - TeamsFindTextList = MeetingActions,MeetingReactions,MeetingReactionHeart,MeetingReactionLaugh,MeetingReactionApplause,MeetingReactionLike,MeetingActionFullScreen,MeetingActionTogetherMode,MeetingActionBackgrounds,MeetingActionShare,MeetingActionUnShare - Loop, Parse,TeamsFindTextList, `, - { - ParamList = %ParamList%,TeamsFindText%A_LoopField% - } + ; Teams Global Hotkeys + HotkeyIDList = Launcher,Mute,Video,Mute App,Share,Raise Hand,Push To Talk + Loop, Parse, HotkeyIDList, `, + { + HKid := A_LoopField + HKid := StrReplace(HKid," ","") + Param = TeamsHotkey%HKid% + RegRead, HK, HKEY_CURRENT_USER\Software\PowerTools, %Param% + IniWrite, %HK%, %IniFile%, Teams, %Param% + } - Loop, Parse, ParamList, `, - { - If RegExMatch(A_LoopField,"[A-Z][a-z]*",sMatch) - { - IniRead, IniVal, %IniFile%, %sMatch%, %A_LoopField% - If (IniVal != "ERROR") - PowerTools_RegWrite(A_LoopField,IniVal) - } - } - - ; Teams Global Hotkeys - HotkeyIDList = Launcher,Mute,Video,Mute App,Share,Raise Hand,Push To Talk - Loop, Parse, HotkeyIDList, `, - { - HKid := A_LoopField - HKid := StrReplace(HKid," ","") - Param = TeamsHotkey%HKid% - IniRead, IniVal, %IniFile%, Teams, %Param% +Case "Ini": + If !FileExist(IniFile) { + MSgBox 0x10, PowerTools: Error, PowerTools.ini can not be found! + return + } + + IniRead, IniVal, %IniFile%, Main, Domain + PowerTools_RegWrite("Domain",IniVal) + IniRead, IniVal, %IniFile%, Teams, TeamsOnly + PowerTools_RegWrite("TeamsOnly",IniVal) + IniRead, IniVal, %IniFile%, Connections, ConnectionsRootUrl + If (IniVal != "ERROR") + PowerTools_RegWrite("ConnectionsRootUrl",IniVal) + Else + PowerTools_RegWrite("ConnectionsRootUrl","") + + IniRead, IniVal, %IniFile%, Jira, JiraUserName + If (IniVal != "ERROR") + PowerTools_RegWrite("JiraUserName",IniVal) + IniRead, IniVal, %IniFile%, Confluence, ConfluenceUserName + If (IniVal != "ERROR") + PowerTools_RegWrite("ConfluenceUserName",IniVal) + + ; Load Parameters + ParamList = TeamsMentionDelay,TeamsCommandDelay,TeamsClickDelay + ; FindText + TeamsFindTextList = MeetingActions,MeetingReactions,MeetingReactionHeart,MeetingReactionLaugh,MeetingReactionApplause,MeetingReactionLike,MeetingActionFullScreen,MeetingActionTogetherMode,MeetingActionBackgrounds,MeetingActionShare,MeetingActionUnShare + Loop, Parse,TeamsFindTextList, `, + { + ParamList = %ParamList%,TeamsFindText%A_LoopField% + } + + Loop, Parse, ParamList, `, + { + If RegExMatch(A_LoopField,"[A-Z][a-z]*",sMatch) + { + IniRead, IniVal, %IniFile%, %sMatch%, %A_LoopField% If (IniVal != "ERROR") - PowerTools_RegWrite(Param,IniVal) - } - Case "ET": - If FileExist("Lib/ET.ahk") - FunStr := "ET_LoadConfig" - %FunStr%() - Case "Conti","Vitesco": - If FileExist("Lib/Conti.ahk") - FunStr := "Conti_LoadConfig" - %FunStr%(Config) + PowerTools_RegWrite(A_LoopField,IniVal) + } + } + + ; Teams Global Hotkeys + HotkeyIDList = Launcher,Mute,Video,Mute App,Share,Raise Hand,Push To Talk + Loop, Parse, HotkeyIDList, `, + { + HKid := A_LoopField + HKid := StrReplace(HKid," ","") + Param = TeamsHotkey%HKid% + + IniRead, IniVal, %IniFile%, Teams, %Param% + If (IniVal != "ERROR") + PowerTools_RegWrite(Param,IniVal) + } +Case "ET": + If FileExist("Lib/ET.ahk") { + FunStr := "ET_LoadConfig" + %FunStr%() + } +Case "Conti","Vitesco": + If FileExist("Lib/Conti.ahk") { + FunStr := "Conti_LoadConfig" + %FunStr%(Config) + } } ; end switch } ; eofun @@ -440,7 +454,7 @@ Switch Config ; ---------------------------------------------------------------------- ; ---------------------------------------------------------------------- -PowerTools_CursorHighlighter(){ +PowerTools_CursorHighlighter() { CHFile= %A_ScriptDir%\Cursor Highlighter If a_iscompiled CHFile = %CHFile%.exe @@ -456,39 +470,39 @@ PowerTools_CursorHighlighter(){ PowerTools_MenuTray(){ ; SubMenuSettings := PowerTools_MenuTray() - Menu, Tray, NoStandard - Menu, Tray, Add, &Help, MenuCb_PTHelp - Menu, Tray, Add, Tweet for support, MenuCb_PowerTools_Tweet - Menu, Tray, Add, Check for update, MenuCb_PTCheckForUpdate - Menu, Tray, Add, Changelog, MenuCb_PTChangelog - Menu, Tray, Add, News, MenuCb_PTNews - - - If !a_iscompiled { - IcoFile := PathX(A_ScriptFullPath, "Ext:.ico").Full - If (FileExist(IcoFile)) - Menu,Tray,Icon, %IcoFile% - } +Menu, Tray, NoStandard +Menu, Tray, Add, &Help, MenuCb_PTHelp +Menu, Tray, Add, Tweet for support, MenuCb_PowerTools_Tweet +Menu, Tray, Add, Check for update, MenuCb_PTCheckForUpdate +Menu, Tray, Add, Changelog, MenuCb_PTChangelog +Menu, Tray, Add, News, MenuCb_PTNews - If (A_ScriptName = "Teamsy.exe") or (A_ScriptName = "Teamsy.ahk") - return - ; ------------------------------------------------------------------------------------------------------------------- - ; SETTINGS - Menu, SubMenuSettings, Add, Launch on Startup, MenuCb_ToggleSettingLaunchOnStartup - SettingLaunchOnStartup := ToStartup(A_ScriptFullPath) - If (SettingLaunchOnStartup) - Menu,SubMenuSettings,Check, Launch on Startup - Else - Menu,SubMenuSettings,UnCheck, Launch on Startup +If !a_iscompiled { + IcoFile := PathX(A_ScriptFullPath, "Ext:.ico").Full + If (FileExist(IcoFile)) + Menu,Tray,Icon, %IcoFile% +} + +If (A_ScriptName = "Teamsy.exe") or (A_ScriptName = "Teamsy.ahk") + return + +; ------------------------------------------------------------------------------------------------------------------- +; SETTINGS +Menu, SubMenuSettings, Add, Launch on Startup, MenuCb_ToggleSettingLaunchOnStartup +SettingLaunchOnStartup := ToStartup(A_ScriptFullPath) +If (SettingLaunchOnStartup) + Menu,SubMenuSettings,Check, Launch on Startup +Else + Menu,SubMenuSettings,UnCheck, Launch on Startup - Menu, Tray, Add, Settings, :SubMenuSettings +Menu, Tray, Add, Settings, :SubMenuSettings - Menu,Tray,Add - Menu,Tray,Standard - Menu,Tray,Default,&Help +Menu,Tray,Add +Menu,Tray,Standard +Menu,Tray,Default,&Help - return SubMenuSettings +return SubMenuSettings } ; eofun ; ---------------------------------------------------------------------- STARTUP ------------------------------------------------- @@ -530,149 +544,147 @@ MenuCb_PTCheckForUpdate(ItemName, ItemPos, MenuName){ ; ------------------------------------------------------------------------------------------------------------------- PowerTools_TweetPush(ScriptName){ - sLogUrl := PowerTools_Changelog(ScriptName,False) - ;sToolUrl := PowerTools_Help(ScriptName,False) +sLogUrl := PowerTools_Changelog(ScriptName,False) +;sToolUrl := PowerTools_Help(ScriptName,False) - If (ScriptName ="NWS") - ScriptName = NWSPowerTool +If (ScriptName ="NWS") + ScriptName = NWSPowerTool - sText = New version of #%ScriptName%. See changelog %sLogUrl% +sText = New version of #%ScriptName%. See changelog %sLogUrl% - sUrl:= uriEncode(sUrl) - sText := uriEncode(sText) - sTweetUrl = https://twitter.com/intent/tweet?text=%sText% ;&hashtags=%ScriptName%&url=%sToolUrl% - Run, %sTweetUrl% +sUrl:= uriEncode(sUrl) +sText := uriEncode(sText) +sTweetUrl = https://twitter.com/intent/tweet?text=%sText% ;&hashtags=%ScriptName%&url=%sToolUrl% +Run, %sTweetUrl% } ;eofun ; ------------------------------------------------------------------------------------------------------------------- PowerTools_TweetMe(ScriptName){ - sLogUrl := PowerTools_Changelog(ScriptName,False) - ;sToolUrl := PowerTools_Help(ScriptName,False) +sLogUrl := PowerTools_Changelog(ScriptName,False) +;sToolUrl := PowerTools_Help(ScriptName,False) - If (ScriptName ="NWS") - ScriptName = NWSPowerTool +If (ScriptName ="NWS") + ScriptName := "NWSPowerTool" - sText = @tdalon +sText := "@tdalon" - sText := uriEncode(sText) - sTweetUrl = https://twitter.com/intent/tweet?text=%sText%&hashtags=%ScriptName% - Run, %sTweetUrl% +sText := uriEncode(sText) +sTweetUrl = https://twitter.com/intent/tweet?text=%sText%&hashtags=%ScriptName% +Run, "%sTweetUrl%" } ;eofun ; ------------------------------------------------------------------------------------------------------------------- PowerTools_GetParam(Param) { - ParamVal := PowerTools_RegRead(Param) - If !(ParamVal="") - return ParamVal +ParamVal := PowerTools_RegRead(Param) +If !(ParamVal="") + return ParamVal - Switch Param - { - Case "TeamsMentionDelay": - return 1300 - Case "TeamsCommandDelay": - return 800 - Case "TeamsClickDelay": - return 500 - Case "TeamsShareDelay": - return 1500 - } +Switch Param +{ + Case "TeamsMentionDelay": + return 1300 + Case "TeamsCommandDelay": + return 800 + Case "TeamsClickDelay": + return 500 + Case "TeamsShareDelay": + return 1500 +} } ;eofun ; ------------------------------------------------------------------------------------------------------------------- PowerTools_SetParam(Param) { - sPrompt = Enter value for %Param%: - Param := StrReplace(Param," ","") - ParamVal := PowerTools_GetParam(Param) - InputBox, Value, %Param%, %sPrompt%, , 200, 150, , , , ,%ParamVal% - If ErrorLevel - return - PowerTools_RegWrite(Param,ParamVal) - return ParamVal +sPrompt = Enter value for %Param%: +Param := StrReplace(Param," ","") +ParamVal := PowerTools_GetParam(Param) +InputBox, Value, %Param%, %sPrompt%, , 200, 150, , , , ,%ParamVal% +If ErrorLevel + return +PowerTools_RegWrite(Param,ParamVal) +return ParamVal } ;eofun - +; ------------------------------------------------------------------------------------------------------------------- PowerTools_ErrDlg(Text,sUrl:=""){ - If !sUrl { - MsgBox 0x10, %A_ScriptName%: Error, %Text% ; OK|Cancel - Return - } - SetTimer, ChangeButtonNames, 50 - - MsgBox 0x11, %A_ScriptName%: Error, %Text% ; OK|Cancel - - IfMsgBox, Cancel ; Help - Run, %sUrl% - return +If !sUrl { + MsgBox 0x10, %A_ScriptName%: Error, %Text% ; OK|Cancel + Return +} +SetTimer, ChangeButtonNames, 50 - ChangeButtonNames: - SetTitleMatchMode, RegEx - IfWinNotExist, .*: Error$ - return ; Keep waiting. - SetTimer, ChangeButtonNames, Off - WinActivate - ControlSetText, Button1, &OK - ControlSetText, Button2, &Help - return +MsgBox 0x11, %A_ScriptName%: Error, %Text% ; OK|Cancel +IfMsgBox, Cancel ; Help + Run, %sUrl% +return + +ChangeButtonNames: +SetTitleMatchMode, RegEx +IfWinNotExist, .*: Error$ + return ; Keep waiting. +SetTimer, ChangeButtonNames, Off +WinActivate +ControlSetText, Button1, &OK +ControlSetText, Button2, &Help +return } ; eofun ; ------------------------------------------------------------------------------------------------------------------- ; Open Link in Default browser - See https://tdalon.blogspot.com/2023/06/ahk-browser-link-redirector.html PowerTools_OpenLink(sUrl) { ; @fun_open_link@ - ; Based on PowerTools.ini files [Browsers] and [BrowserRules] definition - - ;sUrl := IntelliPaste_CleanUrl(sUrl) - - If InStr(sUrl,"teams.microsoft.com") { ; remove browser leftover window - Try { ; in case Teams library is not provided with this OpenLink function - FunStr := "Teams_OpenUrl" ; hide function from compiler - %FunStr%(sUrl) - Return - } - } - - If !FileExist("PowerTools.ini") { - PowerTools_ErrDlg("OpenLink: No PowerTools.ini file found!") - GoTo OpenDefault - } - - ProjectKey := RegExReplace(sKey,"\-.*$") - IniRead, BrowserRules, PowerTools.ini,BrowserRules - If (BrowserRules="ERROR") { ; Section [BrowserRules] not found - PowerTools_ErrDlg("No section [BrowserRules] in PowerTools.ini file was found!") - GoTo OpenDefault +; Based on PowerTools.ini files [Browsers] and [BrowserRules] definition + +;sUrl := IntelliPaste_CleanUrl(sUrl) + +If InStr(sUrl,"teams.microsoft.com") { ; remove browser leftover window + Try { ; in case Teams library is not provided with this OpenLink function + FunStr := "Teams_OpenUrl" ; hide function from compiler + %FunStr%(sUrl) + Return } - - Loop Parse, BrowserRules,`n,`r +} + +If !FileExist("PowerTools.ini") { + PowerTools_ErrDlg("OpenLink: No PowerTools.ini file found!") + GoTo OpenDefault +} + +ProjectKey := RegExReplace(sKey,"\-.*$") +IniRead, BrowserRules, PowerTools.ini,BrowserRules +If (BrowserRules="ERROR") { ; Section [BrowserRules] not found + PowerTools_ErrDlg("No section [BrowserRules] in PowerTools.ini file was found!") + GoTo OpenDefault +} + +Loop Parse, BrowserRules,`n,`r +{ + RegExMatch(A_LoopField,"(.*)=(.*)",sMatch) + Loop Parse, sMatch2, CSV { - RegExMatch(A_LoopField,"(.*)=(.*)",sMatch) - Loop Parse, sMatch2, CSV - { - If InStr(sUrl,A_LoopField) { - BrowserName := sMatch1 - break - } - } - If BrowserName + If InStr(sUrl,A_LoopField) { + BrowserName := sMatch1 break + } } - - If BrowserName { ; not empty - IniRead, BrowserCmd, PowerTools.ini,Browsers,%BrowserName% - If (BrowserCmd="ERROR") { ; Section [BrowserRules] not found - PowerTools_ErrDlg("OpenLink: No Browser Key matching BrowserName=" . BrowserName . " found in section [Browsers] in PowerTools.ini file!") - return - } - sCmd = "%BrowserCmd%" "%sUrl%" ; Reading String in Ini files removes trailing quotes - Run, %sCmd% + If BrowserName + break +} +If !(BrowserName="") { ; not empty + IniRead, BrowserCmd, PowerTools.ini,Browsers,%BrowserName% + If (BrowserCmd="ERROR") { ; Section [BrowserRules] not found + PowerTools_ErrDlg("OpenLink: No Browser Key matching BrowserName=" . BrowserName . " found in section [Browsers] in PowerTools.ini file!") return - } - - OpenDefault: - Run, "%sUrl%" ; Default Browser + } + sCmd = "%BrowserCmd%" "%sUrl%" ; Reading String in Ini files removes trailing quotes + Run, %sCmd% return +} + +OpenDefault: +Run, "%sUrl%" ; Default Browser +return - } ; eofun End Function OpenLink \ No newline at end of file +} ; eofun End Function OpenLink \ No newline at end of file diff --git a/Lib/Teams.ahk b/Lib/Teams.ahk index 62682b1..dffc7bc 100644 --- a/Lib/Teams.ahk +++ b/Lib/Teams.ahk @@ -2293,10 +2293,12 @@ Teams_MeetingShare(ShareMode := 2){ } SendInput {Tab}{Tab}{Tab}{Enter} ; Select first screen - New Share design requires 3 {Tab} - + ; Move Meeting Window to secondary screen SysGet, MonitorCount, MonitorCount ; or try: SysGet, var, 80 If (MonitorCount > 1) { + ; Wait for Window to be minimized + Sleep 500 ; Move to secondary monitor (activates window) Monitor_MoveToSecondary(WinId,false) ; bug: unshare on winactivate Sleep 500 ; Wait for move to Maximize @@ -2354,6 +2356,7 @@ return CacheDir Teams_ClearCache(){ ; @fun_teams_clearcache@ +; See https://learn.microsoft.com/en-us/microsoftteams/troubleshoot/teams-administration/clear-teams-cache If GetKeyState("Ctrl") { Teamsy_Help("clc") return diff --git a/Lib/Xray.ahk b/Lib/Xray.ahk new file mode 100644 index 0000000..731da16 --- /dev/null +++ b/Lib/Xray.ahk @@ -0,0 +1,363 @@ +#Include +#Include + +XrayCApiRootUrl := "https://eu.r4j-cloud.easesolutions.com" + +; --------------------------------------------------------------------------------- + +Xray_GetIssueKey(){ +; sIssueKey := R4J_GetIssueKey() +; Get IssueKey from current selection or from Browser url +; returns only one IssueKey even if multiple are selected + sSelection := Clip_GetSelection() + If (sSelection = "") { + If !Jira_IsWinActive() + return + sUrl := Browser_GetUrl() + return Jira_Url2IssueKey(sUrl) + } Else { ; selection + sPat := "([A-Z]{3,})-([\d]{1,})" + If RegExMatch(sSelection,sPat,sMatch) + return sMatch1 . "-" . sMatch2 + } + +} ; eofun +; --------------------------------------------------------------------------------- +Xray_OpenIssueSelection() { + ; Called by Hotkey Ctrl+Shift+V + sSelection := Clip_GetSelection() + If (sSelection = "") { + If !Jira_IsWinActive() + return + sUrl := Browser_GetUrl() + RegExMatch(sUrl,"https?://[^/]*",sRootUrl) + ; issue detailed view + If RegExMatch(sUrl,"/browse/([A-Z]*-\d*)",sIssueKey) { + R4J_OpenIssue(sIssueKey1) + return + } Else If R4J_IsUrl(sUrl) { ; tree view -> jira detailed view + sUrl := R4J_R2J(sUrl) + return sUrl + } + } Else { + ; Loop on selection issue keys + sPat := "([A-Z]{3,})-([\d]{1,})" + Pos = 1 + While Pos := RegExMatch(sSelection,sPat,sMatch,Pos+StrLen(sMatch)){ + sIssueKey := sMatch1 . "-" . sMatch2 + If InStr(sIssueKeyList,sIssueKey . ";") + continue + sIssueKeyList := sIssueKeyList . sIssueKey . ";" + R4J_OpenIssue(sIssueKey) + } + return SubStr(sIssueKeyList,1,-1) ; remove ending ; + } +} ; eofun +; --------------------------------------------------------------------------------- + +Xray_X2J(sUrl) { + RegExMatch(sUrl,"https?://[^/]*",sRootUrl) + If InStr(sUrl,".atlassian.net") { + ; .atlassian.net/plugins/servlet/ac/com.easesolutions.jira.plugins.requirements/requirements-page-jira?project.id=15315#!tree?issueKey=RDMO-5 + RegExMatch(sUrl,".*/plugins/servlet/ac/com\.easesolutions\.jira\.plugins\.requirements/.*\?issueKey=([A-Z]{3,}-[\d]{1,})" ,sMatch) + } Else + RegExMatch(sUrl,".*/plugins/servlet/com\.easesolutions\.jira\.plugins\.requirements/project\?detail=[A-Z]*&issueKey=([A-Z]{3,}-[\d]{1,})" ,sMatch) + sUrl := sRootUrl . "/browse/" . sMatch1 + + Atlasy_OpenUrl(sUrl) + return sUrl +} ; eofun +; --------------------------------------------------------------------------------- + +Xray_IsWinActive() { + If !Browser_IsWinActive() + return False + sUrl := Browser_GetUrl() + return Xray_IsUrl(sUrl) +} ; eofun +; --------------------------------------------------------------------------------- + +Xray_OpenIssues(IssueArray) { + If IsObject(IssueArray) { + for index, element in IssueArray + { + Xray_OpenIssue(element) + } + } Else { + Xray_OpenIssue(IssueArray) + } + +} ; eofun +; --------------------------------------------------------------------------------- + + +Xray_Open(kw:="gs",pj:="",JiraRootUrl :="") { + + If (JiraRootUrl="") + JiraRootUrl := Jira_GetRootUrl() + IsCloud := InStr(JiraRootUrl, "atlassian.net") + ; First switch for kw without JiraRootUrl required + Switch kw { + Case "doc": + + Switch pj { + Case "rn": + sUrl := "https://docs.getxray.app/display/XRAYCLOUD/Release+Notes" + Case "gs": + Xray_Open("gs") + return + Default: + If IsCloud + sUrl := "https://docs.getxray.app/category/xc" + Else + sUrl := "https://docs.getxray.app/category/xs" + } + + + Case "gs": + If IsCloud + sUrl := JiraRootUrl . "/plugins/servlet/ac/com.xpandit.plugins.xray/xray-get-started" + Else + sUrl := JiraRootUrl . "/secure/XrayGetStarted.jspa" + } + + If !(sUrl ="") { + Atlasy_OpenUrl(sUrl) + return + } + + If (kw="") + kw := "r" ; default to repository + If (pj="") + pj := Xray_GetProjectDef() + + + If IsCloud { ; cloud + + Switch kw + { + Case "r","p", "e": + sRootUrl := JiraRootUrl . "/projects/" . pj . "?selectedItem=com.atlassian.plugins.atlassian-connect-plugin:com.xpandit.plugins.xray__testing-board" + Case "trace","m","te","tp","tr","ts","t","c","cov": + sRootUrl := JiraRootUrl . "/plugins/servlet/ac/com.xpandit.plugins.xray" + pjid := Jira_ProjectKey2Id(pj) + } + + switch kw + { + Case "r": + sUrl := sRootUrl . "#!page=test-repository&selectedFolder=" + Case "p": + sUrl := sRootUrl . "#!page=test-plans" + Case "e": + sUrl := sRootUrl . "#!page=test-executions" + ;---------------------- + Case "trace": ; traceability report + sUrl := sRootUrl . "/traceability-report-page?project.key=" . pj . "&project.id=" . pjid + Case "m": + sUrl := sRootUrl . "/testplans-metrics-report-page?project.key=" . pj . "&project.id=" . pjid + Case "te": + sUrl := sRootUrl . "/testexecs-report-page?project.key=" . pj . "&project.id=" . pjid + Case "tp": + sUrl := sRootUrl . "/testplans-report-page?project.key=" . pj . "&project.id=" . pjid + Case "tr": + sUrl := sRootUrl . "/testruns-list-report-page?project.key=" . pj . "&project.id=" . pjid + Case "ts": + sUrl := sRootUrl . "/testsets-report-page?project.key=" . pj . "&project.id=" . pjid + Case "t": + sUrl := sRootUrl . "/tests-report-page?project.key=" . pj . "&project.id=" . pjid + Case "c","cov": + sUrl := sRootUrl . "/test-coverage-report-page?project.key=" . pj . "&project.id=" . pjid + } + + + } Else { ; server/dc TODO not implemented + sUrl := JiraRootUrl . "/secure/XrayTestRepositoryAction!default.jspa?entityKey=" . sInput . "&path=%5Craven_all_tests" + } + + Atlasy_OpenUrl(sUrl) + +} ; eofun +; --------------------------------------------------------------------------------- + +Xray_GetProjectDef() { + ; Project := Xray_GetProjectDef() + ; Return Xray default project key + + If InStr(A_ScriptName,"e.CoSys") + Project := "T" . PowerTools_GetSetting("ECProject") + Else + Project := PowerTools_GetSetting("JiraProject") + + return Project +} ; eofun + +Xray_OpenIssue(sIssueKey) { + ; Open Issue in Xray Repository tree + sJiraRootUrl := Jira_IssueKey2RootUrl(sIssueKey) + sProjectKey := RegExReplace(sIssueKey,"\-.*") + If InStr(sJiraRootUrl,".atlassian.net") { ; cloud version + sProjectId := Jira_ProjectKey2Id(sProjectKey) + sUrl := sJiraRootUrl . "/plugins/servlet/ac/com.easesolutions.jira.plugins.requirements/requirements-page-jira?project.id=" . sProjectId . "#!tree?issueKey=" . sIssueKey + } Else + sUrl := sJiraRootUrl . "/plugins/servlet/com.easesolutions.jira.plugins.requirements/project?detail=" . sProjectKey . "&issueKey=" . sIssueKey + + Atlasy_OpenUrl(sUrl) +} ; eofun + +Xray_J2X(sIssueKey) { + Xray_OpenIssue(sIssueKey) +} ; eofun + + +Xray_OpenProject(sProjectKey,view := "d") { + ; Open project R4J tree + sJiraRootUrl := Jira_IssueKey2RootUrl(sProjectKey) + If InStr(sJiraRootUrl,".atlassian.net") { ; cloud version + sProjectId := Jira_ProjectKey2Id(sProjectKey) + sUrl := sJiraRootUrl . "/plugins/servlet/ac/com.easesolutions.jira.plugins.requirements/requirements-page-jira?project.id=" . sProjectId + } Else ; server/dc + sUrl := sJiraRootUrl . "/plugins/servlet/com.easesolutions.jira.plugins.requirements/project?detail=" . sProjectKey + + + Switch view { + Case "d": + sUrl := sUrl . "#!tree" + Case "c": + sUrl := sUrl . "#!coverage" + Case "t": + sUrl := sUrl . "#!traceability" + } + + Atlasy_OpenUrl(sUrl) +} ; eofun + + +; ------------------------------------------------------------------------------------------------------------------- +Xray_IsUrl(sUrl){ +return InStr(sUrl,"/com.easesolutions.jira.plugins.requirements/") +} ;eofun +; ------------------------------------------------------------------------------------------------------------------- + +Xray_Url2IssueKey(sUrl){ + ; /com.easesolutions.jira.plugins.requirements/project?detail=RDMO&issueKey=RDMO-14 + sKeyPat := "([A-Z]{3,}\-\d{1,})" + if RegExMatch(sUrl,"&issueKey=" . sKeyPat,sMatch) ; url ending with Issue Key + return sMatch1 + sUrl := RegExReplace(sUrl,"\?.*$","") ; remove optional arguments after ? in url + if RegExMatch(sUrl,"/" . sKeyPat . "$",sMatch) ; url ending with Issue Key + return sMatch1 +} ; eofun + + +; ------------------------------------------------------------------------------------------------------------------- + + + +; ---------------------------------------------------------------------- +Xray_Auth(sUrl:="",sToken:="") { +; Get Auth String for R4J authentification for a specific instance +; sAuth := R4J_GetApiToken(sUrl:="",sToken:="") +; Default Url is Setting JiraRootUrl + + +If !RegExMatch(sUrl,"^http") ; missing root url or default url + sUrl := Jira_GetRootUrl() . sUrl + +; Read Jira PowerTools.ini setting +If !FileExist("PowerTools.ini") { + PowerTools_ErrDlg("No PowerTools.ini file found!") + return +} + +App := "Xray" +IniRead, Auth, PowerTools.ini,%App%,%App%Auth +If (Auth="ERROR") { ; + PowerTools_ErrDlg(App . "Auth key not found in PowerTools.ini file [" . App . "] section!") + return +} + +JsonObj := Jxon_Load(Auth) +For i, inst in JsonObj +{ + url := inst["url"] + If InStr(sUrl,url) { + ApiToken := inst["apitoken"] + If (ApiToken="") { + PowerTools_ErrDlg("ApiToken is not defined in PowerTools.ini file [" . App . "] section, " . App . "Auth key for url '" . url . "'!") + return + } + break + } +} +If (ApiToken="") { ; Section [Jira] Key JiraAuth not found + RegExMatch(sUrl,"https?://[^/]*",sRootUrl) + PowerTools_ErrDlg("No instance defined in PowerTools.ini file [" . App . "] section, " . App . "Auth key for url '" . sRootUrl . "'!") + return +} + +return ApiToken + +} ; eofun +; ---------------------------------------------------------------------- + + +Xray_Get(sPath,sToken:=""){ +; sResponse := Xray_Get(sPath) +; sPath starting with / + +; ; https://easesolutions.atlassian.net/wiki/spaces/R4JC/pages/2250506241/REST+API +If (sToken="") { + sToken := Xray_Auth() +} + +If (sToken="") { + TrayTip, Error, Xray Authentication not defined!,,3 + return +} + +WebRequest := ComObjCreate("WinHttp.WinHttpRequest.5.1") + +sUrl := "https://eu.r4j-cloud.easesolutions.com/rest/api/1" . sPath +WebRequest.Open("GET", sUrl, false) ; Async=false + +sAuth := "JWT " . sToken +WebRequest.setRequestHeader("Authorization", sAuth) +WebRequest.setRequestHeader("Content-Type", "application/json") +WebRequest.Send() +return WebRequest.responseText +} ; eofun + +; ------------------------------------------------------------------------------------------------------------------- + +Xray_Post(sPath,sBody,sToken:=""){ +; sResponse := Xray_Post(sPath,sBody) +; sPath without starting / + +; ; https://easesolutions.atlassian.net/wiki/spaces/R4JC/pages/2250506241/REST+API +If (sToken="") { + sToken := Xray_Auth() +} + +If (sToken="") { + TrayTip, Error, Xray Authentication not defined!,,3 + return +} + +WebRequest := ComObjCreate("WinHttp.WinHttpRequest.5.1") + +sUrl := "https://eu.r4j-cloud.easesolutions.com/rest/api/1" . sPath +WebRequest.Open("POST", sUrl, false) ; Async=false + +sAuth := "JWT " . sToken +WebRequest.setRequestHeader("Authorization", sAuth) +WebRequest.setRequestHeader("Content-Type", "application/json") +If (sBody = "") + WebRequest.Send() +Else + WebRequest.Send(sBody) +return WebRequest.responseText +} ; eofun + +; ------------------------------------------------------------------------------------------------------------------- +