Code: Select all
;entry by jeeswg for: AHKathon! [AHK Hackathon] 1-8 Dec 2017
;(no prize needed) (please post me a score)
;auto-click MS Paint, requires the Gdip library:
;GDI+ standard library 1.45 by tic - AutoHotkey Community
;https://autohotkey.com/boards/viewtopic.php?f=6&t=6517
;this will look good with various MS Paint settings,
;some recommended settings are as follows:
;MS Paint (Windows XP):
;choose Brush, choose the biggest of the 3 circles,
;choose red as the primary colour
;choose light green as the secondary colour
;MS Paint (Windows 7):
;choose Brush, (this is chosen by default),
;under Size, choose the biggest size,
;choose red as the primary colour
;choose light green as the secondary colour
;settings:
vDelay := 1
;vDelay := 0 ;lower values mean faster clicks
;==================================================
ListLines, Off
#NoEnv
AutoTrim, Off
SetBatchLines, -1
;create Esc hotkey to reload script
OnMessage(0x5555, "MsgMonitor")
OnExit("ExitFunc")
;ID_FILE_RELOADSCRIPT := 65400 ;ID_TRAY_RELOADSCRIPT := 65303
vScriptPID := DllCall("kernel32\GetCurrentProcessId", UInt)
vScript := "DetectHiddenWindows, On"
. "`r`n" "PostMessage, 0x5555, % A_ScriptHwnd,,, % ""ahk_id "" " A_ScriptHwnd
. "`r`n"
. "`r`n" "#IfWinActive, ahk_class MSPaintApp"
. "`r`n" "Esc::"
. "`r`n" "PostMessage, 0x111, 65400,,, % ""ahk_id "" " A_ScriptHwnd
;. "`r`n" "MsgBox, % ""hotkey subroutine ended, script reloaded"""
. "`r`n" "ExitApp"
. "`r`n"
. "`r`n" "^Esc::"
. "`r`n" "Process, Close, " vScriptPID
. "`r`n" "MsgBox, % ""script terminated"""
. "`r`n" "ExitApp"
ExecScript(vScript, 0)
return
;==================================================
q::
WinGet, hWnd, ID, A
WinGetClass, vWinClass, % "ahk_id " hWnd
if !(vWinClass = "MSPaintApp")
{
MsgBox, % "error: MS Paint must be the active window"
return
}
ControlGet, hCtl, Hwnd,, AfxFrameOrView42u1, % "ahk_id " hWnd
;e.g. Afx:00000000FF7A0000:81
;e.g. Afx:00000000FF0E0000:81
if !hCtl
{
vCtlClassNN := JEE_WinGetCtlClassNNRegEx(hWnd, "Afx:00000000....0000:8")
ControlGet, hCtl, Hwnd,, % vCtlClassNN, % "ahk_id " hWnd
}
if !hCtl
{
MsgBox, % "error: no canvas control found"
return
}
WinGetPos, vWinX, vWinY, vWinW, vWinH, % "ahk_id " hCtl
if (vWinW < 925) || (vWinH < 180)
{
MsgBox, % "error: canvas size is too small, recommend at least: w925 h180"
return
}
CoordMode, Mouse, Screen
pToken := Gdip_Startup()
vText := "abcdefghijklmnopqrstuvwxyz"
vText := "AutoHotkey"
hFont := JEE_FontCreate("Courier New", 28, "b")
JEE_ImgTextToImg(vText, hFont, "", hBitmap, pBitmap)
Gdip_GetImageDimensions(pBitmap, vImgW, vImgH)
;MsgBox, % vImgW " " vImgH
oArray := []
oArray.SetCapacity(vImgW*vImgH)
Loop, % vImgH
{
vY := A_Index-1
Loop, % vImgW
{
vX := A_Index-1
vCol := Gdip_GetPixel(pBitmap, vX, vY)
if !(vCol = 0xFFFFFFFF)
oArray.Push([vX,vY])
}
}
;MsgBox, % oArray.Length()
if (vDelay = "")
vDelay := 1
SetMouseDelay, % vDelay
Loop, % oArray.Length()
{
WinGet, hWnd2, ID, A
if !(hWnd = hWnd2)
return
if !oArray.Length()
break
Random, vNum, 1, % oArray.Length()
Random, vNum2, 1, 2
vX := vWinX + 25 + oArray[vNum].1*4
vY := vWinY + 20 + oArray[vNum].2*4
vBtn := (vNum2 = 1) ? "L" : "R"
MouseClick, % vBtn, % vX, % vY, 1, 0
oArray.RemoveAt(vNum)
}
;MsgBox, % oArray.Length()
SoundBeep
DeleteObject(hBitmap)
Gdip_DisposeImage(pBitmap)
Gdip_Shutdown(pToken)
return
;==================================================
JEE_ImgTextToImg(vText, hFont, vOpt:="", ByRef hBitmap:="", ByRef pBitmap:="", vColText:="", vColBk:="")
{
if (vOpt = "x")
vFunc := "JEE_GdipStartup", pToken := %vFunc%()
;measure text as image
hDC := DllCall("gdi32\CreateCompatibleDC", Ptr,0, Ptr)
DllCall("gdi32\SelectObject", Ptr,hDC, Ptr,hFont, Ptr)
VarSetCapacity(RECT, 16, 0)
;didn't work
;if !(vColText = "")
; DllCall("gdi32\SetTextColor", Ptr,hDC, UInt,vColText)
;if !(vColBk = "")
; DllCall("gdi32\SetBkColor", Ptr,hDC, UInt,vColBk)
;DT_CALCRECT := 0x400
DllCall("user32\DrawText", Ptr,hDC, Str,vText, Int,-1, Ptr,&RECT, UInt,0x400)
vImgW := NumGet(&RECT, 8, "Int")
vImgH := NumGet(&RECT, 12, "Int")
;create text as image
hBitmap := DllCall("gdi32\CreateCompatibleBitmap", Ptr,hDC, Int,vImgW, Int,vImgH, Ptr)
DllCall("gdi32\SelectObject", Ptr,hDC, Ptr,hBitmap, Ptr)
VarSetCapacity(RECT, 16, 0)
;DT_NOCLIP := 0x100
DllCall("user32\DrawText", Ptr,hDC, Str,vText, Int,-1, Ptr,&RECT, UInt,0x100)
DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", Ptr,hBitmap, Ptr,0, PtrP,pBitmap)
DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", Ptr,pBitmap, PtrP,hBitmap, UInt,0xffffffff)
if !IsByRef(pBitmap)
DllCall("gdiplus\GdipDisposeImage", Ptr,pBitmap)
if (vOpt = "x")
vFunc := "JEE_GdipShutdown", %vFunc%(pToken)
}
;==================================================
JEE_FontCreate(vName, vSize, vFontStyle:="", vWeight:="")
{
vHeight := -DllCall("kernel32\MulDiv", Int,vSize, Int,A_ScreenDPI, Int,72)
vWidth := 0
vEscapement := 0
vOrientation := 0
vWeight := (InStr(vFontStyle, "b") && (vWeight="")) ? 700 : 400
vItalic := InStr(vFontStyle, "i") ? 1 : 0
vUnderline := InStr(vFontStyle, "u") ? 1 : 0
vStrikeOut := InStr(vFontStyle, "s") ? 1 : 0
vCharSet := 0
vOutPrecision := 0
vClipPrecision := 0
vQuality := 0
vPitchAndFamily := 0
vFaceName := vName
vOutPrecision := 3
vClipPrecision := 2
vQuality := 1
vPitchAndFamily := 34
return DllCall("gdi32\CreateFont", Int,vHeight, Int,vWidth, Int,vEscapement, Int,vOrientation, Int,vWeight, UInt,vItalic, UInt,vUnderline, UInt,vStrikeOut, UInt,vCharSet, UInt,vOutPrecision, UInt,vClipPrecision, UInt,vQuality, UInt,vPitchAndFamily, Str,vFaceName, Ptr)
}
;==================================================
JEE_WinGetCtlClassNNRegEx(hWnd, vClassRegEx, vNum:=1)
{
vCount := 0
WinGet, vCtlList, ControlList, % "ahk_id " hWnd
Loop, Parse, vCtlList, `n
{
vCtlClassNN := A_LoopField
ControlGet, hCtl, Hwnd,, % vCtlClassNN, % "ahk_id " hWnd
WinGetClass, vCtlClass, % "ahk_id " hCtl
if RegExMatch(vCtlClass, vClassRegEx)
vCount++
if (vCount = vNum)
return vCtlClassNN
}
}
;==================================================
;Run / RunWait
;https://autohotkey.com/docs/commands/Run.htm
; ExecScript: Executes the given code as a new AutoHotkey process.
ExecScript(Script, Wait:=true)
{
shell := ComObjCreate("WScript.Shell")
exec := shell.Exec("AutoHotkey.exe /ErrorStdOut *")
exec.StdIn.Write(script)
exec.StdIn.Close()
if Wait
return exec.StdOut.ReadAll()
}
;==================================================
MsgMonitor(wParam, lParam, msg)
{
global vScriptHwnd2
vScriptHwnd2 := wParam
}
;==================================================
ExitFunc()
{
global vScriptHwnd2
DetectHiddenWindows, On
WinClose, % "ahk_id " vScriptHwnd2
}
;==================================================