Code: Select all
#NoEnv
SendMode Input
SetWorkingDir %A_ScriptDir%
#SingleInstance, force
T:=new Timer_Manager
T.NewTimer()
Return
#if GetSize(T.Examiners)
RButton::Return
MButton::Return
#if
GetSize(byref A){
i:=0
for k, v in A
i++
Return i
}
; Heterogenize,Remove Duplicates
Hetgen(Arr){
hash:={}, NewArr:=[]
for k, v in Arr
if (!hash[v])
hash[v]:=1, NewArr.Push(v)
Return NewArr
}
Obj2Str(object,f:="{1:s} = {2:s}`r`n") {
for k,v in object
s.=Format(f, k, v)
Return s
}
GetScreenRect1(f:="{1:} {2:} {3:} {4:}"){
Local WHMask ; Mask Window
Gui, New, +AlwaysOnTop -Caption +LastFound hwndWHMask, AHK GetScreenRect
WinSet, Transparent, 50
Gui, Maximize
t:="int",d:="gdi32.dll\Rectangle"
MDC:=DllCall( "GetDC", "uint", WHMask)
while (!GetKeyState("MButton", P)){
i:=GetKeyState("LButton", P)
MouseGetPos, x%i%, y%i%
DllCall( d, "uint", MDC, t, 0, t, 0, t, A_ScreenWidth, t, A_ScreenHeight)
DllCall( d, "uint", MDC, t, x0, t, y0, t, x1, t, y1)
ToolTip, % "(" x0 "." y0 "):(" x1 "." y1 ")`nW: " abs(x0-x1) " H: " abs(y0-y1)
Sleep, 50
}
ToolTip
Gui, Destroy
Return Format(f, Min(x0,x1), Min(y0,y1), Max(x0,x1), Max(y0,y1))
}
GetScreenRect2(f:="{1:} {2:} {3:} {4:}"){
Local WHMask ; Mask Window
Local BH1 ; Minimize Button
Local BH2 ; Maximize Button
Local BH3 ; Close Button
Local SHA ; Alpha Slider
A:=50, r:=1
ss:="x0 y+0 w60 hp +Range20-100 NoTicks +0x20"
Gui, Mask:New, +Resize +AlwaysOnTop -Caption +LastFound hwndWHMask, AHK GetScreenRect
Gui, Add, Button, x0 y0 w20 h20 hwndBH1, __
Gui, Add, Button, x+0 y0 wp hp hwndBH2, [ ]
Gui, Add, Button, x+0 y0 wp hp hwndBH3, X
Gui, Add, Slider, %ss% hwndSHA, % A
Gui, Color, BAFEDC
WinSet, Transparent, % A
Gui, Show, w200 h200
while (WinExist(Mask) and !GetKeyState("MButton", P)){
MouseGetPos, mx, my, whwnd, chwnd, 2
if (whwnd!=WHMask){
ToolTip,,,,2
Continue
}
WinGetPos, wx, wy, ww, wh, % Mask
if (GetKeyState("LButton", P)){
if (chwnd==SHA){
GuiControlGet, A,, % SHA
WinSet, Transparent, % A
}
Gui, % "Mask:" (chwnd==BH1 ? "Minimize"
:chwnd==BH2 ? (r:=!r)? "Restore":"Maximize"
:chwnd==BH3 ? "Destroy":)
PostMessage, 0xA1, 2,,, % Mask
}
ToolTip, % "(" wx "." wy "):(" wx+ww "." wy+wh ")`nW: " ww " H: " wh,,,2
Sleep, 50
}
ToolTip,,,,2
Gui, % "Mask:" (WinExist(Mask)? "Destroy":)
Return Format(f, wx, wy, wx+ww, wy+wh)
}
Class Timer_Manager {
__New(){
this.Timers:={}
this.Examiners:={}
this.Helpers:={}
this.RMBClk:=0
this.MMBClk:=0
this.Examine:=this.Examine.Bind(this)
this.Help:=this.Help.Bind(this)
}
NewTimer(){
o:=new Timer_Manager.Timer_GUI(this, "Timer","Send a","1s","a")
this.Timers[&o]:=o
}
InitExamine(){
ToolTip,,,,3
exam:=this.Examine
SetTimer, % exam, % GetSize(this.Examiners)? 50:"Off"
}
InitHelp(){
ToolTip,,,,4
help:=this.Help
SetTimer, % help, % GetSize(this.Helpers)? 50:"Off"
}
Examine(){
MouseGetPos,,, whwnd, chwnd, 2
s:=% "Window: " whwnd "`nControl: " chwnd "`nMMB - add window`nRMB - add control"
ToolTip, % s,,,3
i:=GetKeyState("RButton", "P")
j:=GetKeyState("MButton", "P")
hwnd:=0
if ((this.RMBClk+=i) && !i){
this.RMBClk:=0
hwnd:=chwnd
}
if ((this.MMBClk+=j) && !j){
this.MMBClk:=0
hwnd:=whwnd
}
if hwnd {
for k,v in this.Examiners {
GuiControlGet, EChwnd,, % v._H["EChwnd"]
GuiControl,, % v._H["EChwnd"], % Trim(EChwnd "," hwnd, ",")
GuiControl,, % v._H["EGeneral"], % hwnd
}
v.UpdateControls()
}
}
Help(){
MouseGetPos,,, whwnd, chwnd,2
for k,v in this.Helpers {
if (whwnd==v._H["WTimer"]){
ToolTip % %chwnd%_CH,,,4
Return
}
}
ToolTip,,,,4
}
Class Timer_GUI {
__New(Parent, a*){
; Window
Local WTimer ; Window: Timer
; Caption
Local TTfunc ; Text: Title gLabel
Local PTbgcol ; PBar: Title BgColor
Local TTtext ; Text: Title Text
Local BWhelp ; Button: Context Help
Local BWmin ; Button: Window Minimize
Local BWhide ; Button: Window Hide
Local BWshow ; Button: Show All Windows
Local BWdestroy ; Button: Window Destroy
; Body
Local TBPages ; Tab: Pages
Local EGeneral ; Edit: General
Local BNewcopy ; Button: Copy
Local BExamine ; Button: Examine
Local BRtimer ; Button: Run/Reset Timer
Local BRepeat ; Button: Repeat
Local BRoutine ; Button: Routine
; Timer Tab
Local ETitle ; Edit: Title
Local ENote ; Edit: Note
Local EPeriod ; Edit: Period
Local BFormat ; Button: Format
; Keys Tab
Local EKeys ; Edit: Keys
Local BClear1 ; Button: Clear
; HWND Tab
Local EChwnd ; Edit: Controls' HWNDs
Local BClear2 ; Button: Clear
Local BHetgen ; Button: Hetgen
; OCR Tab
Local BCoords1 ; Button: GetCoords
Local BCoords2 ; Button: GetCoords
Local BOCR ; Button: OCR
; Variables
this.__Parent:=&Parent
this._H:={} ; Handlers
this._F:={} ; Function Objects
this._M:={} ; Mode States
this._M["R"]:=1 ; Timer Repeat Toggle
this._M["E"]:=0 ; Examine Toggle
this._M["H"]:=0 ; Help Toggle
this._M["T"]:=0 ; Timer Toggle
this._M["O"]:=1 ; Routine Order Toggle
this.Name:=a[1]
this.Keys:=""
this.Period:=0
this.Target:=[]
this.Format:={h:"60m", m:"60s", s:"1000ms", ms:1}
this.ScrRect:=""
; Create GUI layout
;; Window
Gui, New, -Caption hwndWTimer, % Title
Gui, %WTimer%:Margin, 0, 0
;; Title Bar
;;; Caption
;;;; 0x200+0x80 = 0x280
s:="Backgroundtrans cFFFFFF +0x280"
Gui, Add, Text , x0 y0 w100 h20 hwndTTfunc Backgroundtrans
Gui, Add, Progress, xp wp hp hwndTHTbgcol Background66AAAA
Gui, Add, Text , xp wp hp hwndTTtext %s%, % " " a[1]
;;; Buttons
Gui, Add, Button , x+0 w20 h20 hwndBWhelp , ?
Gui, Add, Button , x+0 wp hp hwndBWmin , __
Gui, Add, Button , x+0 wp hp hwndBWhide ,
Gui, Add, Button , x+0 wp hp hwndBWshow , [ ]]
Gui, Add, Button , x+0 wp hp hwndBWdestroy , X
;; Body
Gui, Add, Tab3 , x0 y+0 w200 h105 hwndTBPages , Timer|Keys|HWND|OCR
Gui, Tab
Gui, Add, Edit , x0 y125 w160 h60 hwndEGeneral , % a[6]
;O---O
Gui, Add, Button , x+0 w20 h20 hwndBNewcopy , o|o
Gui, Add, Button , y+0 wp hp hwndBExamine , (o)
Gui, Add, Button , x+0 y125 wp hp hwndBRtimer , |>
Gui, Add, Button , y+0 wp hp hwndBRepeat , >>
Gui, Add, Button , y+0 wp hp hwndBRoutine , -->
;; Tabs
Gui, Tab, 1
Gui, Add, Edit , y+0 w175 h20 hwndETitle , % a[1]
Gui, Add, Edit , y+0 wp h40 hwndENote , % a[2]
Gui, Add, Edit , y+0 wp hwndEPeriod , % a[3]
Gui, Add, Button , x+0 w20 h20 hwndBFormat , |>o
Gui, Tab, 2
Gui, Add, Edit , x+0 y+0 w175 h80 hwndEKeys , % a[4]
Gui, Add, Button , x+0 w20 h20 hwndBClear1 ,
Gui, Tab, 3
Gui, Add, Edit , y+0 w175 h80 hwndEChwnd , % a[5]
Gui, Add, Button , x+0 w20 h20 hwndBClear2 ,
Gui, Add, Button , y+0 wp hp hwndBHetgen , ||>|
Gui, Tab, 4
Gui, Add, Edit , y+0 w175 h80 ,
Gui, Add, Button , x+0 w20 h20 hwndBCoords1 , * .
Gui, Add, Button , y+0 wp hp hwndBCoords2 , [_]
Gui, Add, Button , y+0 wp hp hwndBOCR , 1>l
Gui, Show, AutoSize
; Context Help Description
;; Caption
%BWhelp%_CH :="Help"
%BWmin%_CH :="Minimize"
%BWhide%_CH :="Hide"
%BWshow%_CH :="Show all"
%BWdestroy%_CH:="Destroy"
;; Body
%EGeneral%_CH :="General field used for various interaction"
%BNewcopy%_CH :="New Copy"
%BExamine%_CH :="Examine controls' HWND's"
%BRtimer%_CH :="Operate Timer"
%BRepeat%_CH :="Repeat Mode"
%BRoutine%_CH :="Routine Order:`n>-- do while`n--> while do"
;; Timer Tab
%ETitle%_CH :="Change title"
%ENote%_CH :="Custom note"
s:="Timer interval`nInput time units divided by + or Space"
s.="`nExample: 1.5m+1m 1 `; 2.5 'm' units + 1ms"
%EPeriod%_CH :=s
s:="Update interval format"
s.="`nFollowing examples show how to set traditional time format"
s.="`nExamples:`nd:24h:60m:60s:1000ms:1"
s.="`nd:24h h:60m m:60s s:1000ms ms:1"
s.="`nHour:3600000 Minute:60000 Second:1000"
s.="`nH:3600000 MS:0.001S:1000 M:0.0166666667h"
s.="`n`nDon't try this at home:`ns:1s"
%BFormat%_CH :=s
;; Keys Tab
%EKeys%_CH :="Key sequence to send`nExample: {Space}"
%BClear1%_CH :="Clear"
;; HWND Tab
%EChwnd%_CH :="Controls' HWND's to operate upon`nExample: 0x945b,0x3da23"
%BClear2%_CH :="Clear"
%BHetgen%_CH :="Remove Duplicates"
;; OCR Tab
s:="Get screen rectangle coordinates"
s.="`nLMB Up - set vertex1`nLMB Down - set vertex2`nMMB - Close"
%BCoords1%_CH :=s
s:="Get screen rectangle coordinates"
s.="`nLMB - operate rectangle`nMMB - Close"
%BCoords2%_CH :=s
%BOCR%_CH :="Run OCR routine"
; Bind Functions
;; Caption
;;; Title gLabel
this._F["WinMove"]:=f:=this.WinMove.Bind(this)
GuiControl, +g, % TTfunc, % f
;;; Context Help
this._F["InitHelp"]:=f:=this.InitHelp.Bind(this)
GuiControl, +g, % BWhelp, % f
;;; Minimize
this._F["WinMin"]:=f:=this.WinMin.Bind(this)
GuiControl, +g, % BWmin, % f
;;; Hide
this._F["WinHide"]:=f:=this.WinHide.Bind(this)
GuiControl, +g, % BWhide, % f
;;; Show All
this._F["WinShowAll"]:=f:=this.WinShowAll.Bind(this)
GuiControl, +g, %BWshow%, % f
;;; Destroy
this._F["WinDestroy"]:=f:=this.WinDestroy.Bind(this)
GuiControl, +g, %BWdestroy%, % f
;; Body
;;; Copy Button
this._F["NewCopy"]:=f:=this.NewCopy.Bind(this)
GuiControl, +g, %BNewcopy%, % f
;;; Examine Button
this._F["InitExamine"]:=f:=this.InitExamine.Bind(this)
GuiControl, +g, %BExamine%, % f
;;; Reset Button
this._F["ToggleTimer"]:=f:=this.ToggleTimer.Bind(this)
GuiControl, +g, %BRtimer%, % f
;;; Repeat
this._F["TRepeat"]:=f:=this.TRepeat.Bind(this)
GuiControl, +g, % BRepeat, % f
;;; Routine
this._F["TRoutine"]:=f:=this.TRoutine.Bind(this)
GuiControl, +g, % BRoutine, % f
;; Timer tab
;;; Title
this._F["UpdateTitle"]:=f:=this.UpdateTitle.Bind(this)
GuiControl, +g, %ETitle%, % f
;;; Period Edit
this._F["UpdatePeriod"]:=f:=this.UpdatePeriod.Bind(this)
GuiControl, +g, %EPeriod%, % f
;;; Format Button
this._F["UpdateFormat"]:=f:=this.UpdateFormat.Bind(this)
GuiControl, +g, %BFormat%, % f
;; Keys Tab
;;; Keys
this._F["UpdateKeys"]:=f:=this.UpdateKeys.Bind(this)
GuiControl, +g, %EKeys%, % f
;;; Clear Button
this._F["Clear"]:=f:=this.Clear.Bind(this)
GuiControl, +g, %BClear1%, % f
;; HWND Tab
;;; Controls' HWNDs
this._F["UpdateControls"]:=f:=this.UpdateControls.Bind(this)
GuiControl, +g, %EChwnd%, % f
;;; Clear Button
f:=this._F["Clear"]
GuiControl, +g, %BClear2%, % f
;;; Hetgen Button
this._F["BHetgen"]:=f:=this.HetgenHWND.Bind(this)
GuiControl, +g, %BHetgen%, % f
;; OCR Tab
;;; GetCoords Buttons
this._F["GetCoords"]:=f:=this.GetCoords.Bind(this)
GuiControl, +g, %BCoords1%, % f
GuiControl, +g, %BCoords2%, % f
;;; OCR Button
this._F["OCR"]:=f:=this.OCR.Bind(this)
GuiControl, +g, %BOCR%, % f
;; Routines
;;; Spam Routine
this._F["Spam"]:=this.Spam.Bind(this)
f:=""
; Store controls' HWND's
;; Window
this._H["WTimer"] :=WTimer ; Window: Timer
;; Caption
this._H["TTfunc"] :=TTfunc ; Text: Title gLabel
this._H["THTbgcol"] :=PTbgcol ; PBar: Title BgColor
this._H["THText"] :=TTtext ; Text: Title Text
this._H["BWhelp"] :=BWhelp ; Button: Context Help
this._H["BWmin"] :=BWmin ; Button: Window Minimize
this._H["BWhide"] :=BWhide ; Button: Window Hide
this._H["BWshow"] :=BWshow ; Button: Show All Windows
this._H["BWdestroy"]:=BWdestroy ; Button: Window Destroy
;; Body
this._H["TBPages"] :=TBPages ; Tab: Pages
this._H["EGeneral"] :=EGeneral ; Edit: General
this._H["BNewcopy"] :=BNewcopy ; Button: Copy
this._H["BExamine"] :=BExamine ; Button: Examine
this._H["BRtimer"] :=BRtimer ; Button: Run/Reset Timer
this._H["BRepeat"] :=BRepeat ; Button: Repeat
this._H["BRoutine"] :=BRoutine ; Button: Routine
;; Timer Tab
this._H["ETitle"] :=ETitle ; Edit: Title
this._H["ENote"] :=ENote ; Edit: Note
this._H["EPeriod"] :=EPeriod ; Edit: Period
this._H["BFormat"] :=BFormat ; Button: Format
;; Keys Tab
this._H["EKeys"] :=EKeys ; Edit: Keys
this._H["BClear1"] :=BClear1 ; Button: Clear
;; HWND Tab
this._H["EChwnd"] :=EChwnd ; Edit: Controls' HWNDs
this._H["BClear2"] :=BClear2 ; Button: Clear
this._H["BHetgen"] :=BHetgen ; Button: Hetgen
;; OCR Tab
this._H["BCoords1"] :=BCoords1 ; Button: GetCoords
this._H["BCoords2"] :=BCoords2 ; Button: GetCoords
this._H["BOCR"] :=BOCR ; Button: OCR
}
__Delete(){
MsgBox, % "Timer """ this.Name """ Destroyed"
if (!GetSize(this.Parent.Timers))
ExitApp
}
Parent[]{
Get {
if (NumGet(this.__Parent)==NumGet(&this))
Return Object(this.__Parent)
}
}
WinMove(){
PostMessage, 0xA1, 2,,, % "ahk_id " this._H["WTimer"]
}
InitHelp(){
if (GetSize(this.Parent.Examiners))
Return
i:=% (this._M["H"]:=!this._M["H"])
i ? this.Parent.Helpers[&this]:=this
:this.Parent.Helpers.Delete(&this)
GuiControl,, % this._H["BWhelp"], % i ? "!":"?"
this.Parent.InitHelp()
}
WinMin(){
Gui, % this._H["WTimer"] ":Minimize"
}
WinHide(){
if (GetSize(this.Parent.Timers)<2)
Return
Gui, % this._H["WTimer"] ":Hide"
}
WinShowAll(){
for k, v in this.Parent.Timers
Gui, % this.Parent.Timers[k]._H["WTimer"] ":Show"
}
WinDestroy(){
for k,v in this._F {
SetTimer, % v, Delete
this._F[k]:=""
}
this.Parent.Timers.Delete(&this)
this.Parent.Examiners.Delete(&this)
this.Parent.Helpers.Delete(&this)
Gui, % this._H["WTimer"]":Destroy"
this.Parent.InitExamine()
this.Parent.InitHelp()
}
UpdateTitle(){
GuiControlGet, ETitle,, % this._H["ETitle"]
GuiControl,, % this._H["THText"], % " " ETitle
this.Name:=ETitle
Gui, Show,, % ETitle
}
UpdatePeriod(){
if (this._M["T"])
Return
GuiControlGet, EPeriod,, % this._H["EPeriod"]
i:=0
Loop, parse, EPeriod, " +"
{
s:=A_LoopField, ms:=1
Loop {
v:=u:=""
Loop, parse, s
If A_LoopField in 0,1,2,3,4,5,6,7,8,9,.
v.=A_LoopField
else u.=A_LoopField
ms*=v
s:=this.Format[u]
} until (u=="")
i+=ms
}
this.Period:=floor(i)
GuiControl,, % this._H["EGeneral"], % this.Period " ms"
}
UpdateFormat(){
InputBox, format, Period Format, % Obj2Str(this.Format)
Loop, parse, format, " "
{
vp:="", up:=""
Loop, parse, A_LoopField, ":"
{
vp:=v, up:=u, v:=u:=""
Loop, parse, A_LoopField
If A_LoopField in 0,1,2,3,4,5,6,7,8,9,.
v.=A_LoopField
else u.=A_LoopField
if (A_Index>1)
this.Format[up]:=A_LoopField
}
}
this.UpdatePeriod()
}
UpdateKeys(){
if (this._M["T"])
Return
GuiControlGet, EKeys,, % this._H["EKeys"]
this.Keys:=EKeys
}
Clear(hwnd){
GuiControl,, % (hwnd=this._H["BClear1"])? this._H["EKeys"]
:(hwnd=this._H["BClear2"])? this._H["EChwnd"]:,
}
UpdateControls(){
if (this._M["T"])
Return
this.Target.RemoveAt(1,this.Target.MaxIndex())
GuiControlGet, EChwnd,, % this._H["EChwnd"]
Loop, parse, EChwnd, % ","
this.Target.Push(A_LoopField)
}
HetgenHWND(){
this.Target:=Hetgen(this.Target)
GuiControl,, % this._H["EChwnd"], % RTrim(Obj2Str(this.Target,"0x{2:x},"),",")
}
GetCoords(hwnd){
this.ScrRect:=((hwnd=this._H["BCoords1"])? GetScreenRect1()
:(hwnd=this._H["BCoords2"])? GetScreenRect2():)
GuiControl,, % this._H["EGeneral"], % "x1 y1 x2 y2`n" this.ScrRect
}
OCR(){
;Recognize text in selected area by pattern: "Turn <number>"
;Extract number and if it can be divided by 3 without reminder, send key
if (this._M["T"])
Return
this.UpdateControls()
this.UpdateKeys()
com.="d:\Capture2Text\Capture2Text.exe"
com.=" --screen-rect """ this.ScrRect """"
com.=" --whitelist ""Turn0123456789"""
com.=" --clipboard"
RunWait, % com
StringTrimLeft, s, clipboard, 5
GuiControl,, % this._H["EGeneral"], % s
s+=0
(!Mod(s,3))? this.Spam()
}
NewCopy(){
GuiControlGet, a,, % this._H["ETitle"]
GuiControlGet, b,, % this._H["ENote"]
GuiControlGet, c,, % this._H["EPeriod"]
GuiControlGet, d,, % this._H["EKeys"]
GuiControlGet, e,, % this._H["EChwnd"]
GuiControlGet, f,, % this._H["EGeneral"]
o:=new Timer_Manager.Timer_GUI(this.Parent, a, b, c, d, e, f)
this.Parent.Timers[&o]:=o
}
InitExamine(){
if (GetSize(this.Parent.Helpers))
Return
i:=% (this._M["E"]:=!this._M["E"])
i ? this.Parent.Examiners[&this]:=this
:this.Parent.Examiners.Delete(&this)
GuiControl,, % this._H["BExamine"], % i ? "( )":"(o)"
this.Parent.InitExamine()
}
ToggleTimer(){
spam:=this._F["Spam"]
if (!this._M["T"]){
this.UpdateKeys()
this.UpdateControls()
this.UpdatePeriod()
}
i:=% (this._M["T"]:=!this._M["T"])
GuiControl,, % this._H["BRtimer"], % i ? "[][]":"|>"
(!this._M["O"]*i)? this.Spam()
SetTimer, % spam, % !i ? "Off"
:(this._M["O"]+this._M["R"])? this.Period:"Off"
}
Spam(){
for k, v in this.Target {
ControlFocus,, % "ahk_id " v
ControlSend,, % this.Keys, % "ahk_id " v
}
(!this._M["R"])? this.ToggleTimer()
}
TRepeat(){
GuiControl,, % this._H["BRepeat"], % (this._M["R"]:=!this._M["R"])? ">>":"> "
}
TRoutine(){
GuiControl,, % this._H["BRoutine"], % (this._M["O"]:=!this._M["O"])? "-->":">--"
}
}
}