Code: Select all
;===Auto-execute========================================================================
/*
How to use:
- Click, drag, release F1 to draw new line (multiple lines supported)
- Drag line start or end point to move it
- Press F2 to delete last line
- Press F3 to delete all lines
- Press Esc to exit
*/
CoordMode, mouse,Screen
MyLines := new c_DrawLinesOnScreen()
;MyLines := new c_DrawLinesOnScreen({PenColor: "88ff0000", PenWidth: 8}) ; example how to override defaults ...
return
;===Hotkeys=============================================================================
F1::MyLines.DrawLine() ; click, drag, release
F2::MyLines.DeleteLine() ; if LineNum is blank, last line will be deleted
F3::MyLines.DeleteAllLines()
Esc::ExitApp
#If (MyLines.IsClickOnLineEnd() = 1)
LButton::MyLines.MoveLine()
#If
;===Functions===========================================================================
#Include Gdip.ahk ; by Tic www.autohotkey.com/community/viewtopic.php?f=2&t=32238
;===Classes=============================================================================
Class c_DrawLinesOnScreen { ; demo by Learning one. http://www.autohotkey.com/community/viewtopic.php?p=572041#p572041
Lines := []
__New(o="") {
Gui, New, +Hwndhwnd
Gui %hwnd%: -Caption +E0x80000 +ToolWindow +AlwaysOnTop +OwnDialogs +Hwndhwnd
Gui %hwnd%: Show, NA
hbm := CreateDIBSection(A_ScreenWidth, A_ScreenHeight), hdc := CreateCompatibleDC(), obm := SelectObject(hdc, hbm)
G := Gdip_GraphicsFromHDC(hdc)
if (G < 1)
pToken := Gdip_Startup(), G := Gdip_GraphicsFromHDC(hdc), this.pToken := pToken
Gdip_SetSmoothingMode(G, 4), Gdip_SetInterpolationMode(G, 7)
PenColor := (o.PenColor) ? o.PenColor : "ff0000ff", PenWidth := (o.PenWidth) ? o.PenWidth : 3
pPen := Gdip_CreatePen("0x" PenColor, PenWidth)
UpdateLayeredWindow(hwnd, hdc, 0, 0, A_ScreenWidth, A_ScreenHeight)
this.hwnd := hwnd, this.hbm := hbm, this.hdc := hdc, this.obm := obm, this.G := G, this.pPen := pPen
}
DrawLine() {
Hotkey := RegExReplace(A_ThisHotkey, (A_IsUnicode = 1) ? "(*UCP)^(\w* & |\W*)" : "^(\w* & |\W*)")
MouseGetPos, StartX, StartY
While (GetKeyState(Hotkey, "p") = 1) {
Sleep, 20
MouseGetPos, EndX, EndY
Gdip_GraphicsClear(this.G)
For LineNum,pLine in this.Lines ; draw all lines in collection
Gdip_DrawLine(this.G, this.pPen, pLine.1, pLine.2, pLine.3, pLine.4)
Gdip_DrawLine(this.G, this.pPen, StartX, StartY, EndX, EndY) ; draw new line
UpdateLayeredWindow(this.hwnd, this.hdc)
}
this.Lines.Insert([ StartX, StartY, EndX, EndY]) ; insert new line in collection
}
MoveLine() {
Hotkey := RegExReplace(A_ThisHotkey, (A_IsUnicode = 1) ? "(*UCP)^(\w* & |\W*)" : "^(\w* & |\W*)")
StartX := this.LineToMove.2, StartY := this.LineToMove.3
this.Lines.Remove(this.LineToMove.1) ; remove LineToMove from collection and treat is as new line
While (GetKeyState(Hotkey, "p") = 1) {
Sleep, 20
MouseGetPos, EndX, EndY
Gdip_GraphicsClear(this.G)
For LineNum,pLine in this.Lines ; draw all lines in collection
Gdip_DrawLine(this.G, this.pPen, pLine.1, pLine.2, pLine.3, pLine.4)
Gdip_DrawLine(this.G, this.pPen, StartX, StartY, EndX, EndY) ; draw new line
UpdateLayeredWindow(this.hwnd, this.hdc)
}
this.Lines.Insert(this.LineToMove.1, [ StartX, StartY, EndX, EndY]), this.LineToMove := "" ; insert new line in collection, delete LineToMove info
}
DeleteAllLines() {
this.Lines := [], this.LineToMove := "", Gdip_GraphicsClear(this.G), UpdateLayeredWindow(this.hwnd, this.hdc)
}
DeleteLine(LineNum="") { ; if LineNum is blank, last line will be deleted
if (this.Lines.MaxIndex() = "") ; no lines in collection
return
LineNum := (LineNum = "") ? this.Lines.MaxIndex() : LineNum ; last or specified
this.Lines.Remove(LineNum) ; remove from collection
Gdip_GraphicsClear(this.G)
For LineNum,pLine in this.Lines ; draw all lines in collection
Gdip_DrawLine(this.G, this.pPen, pLine.1, pLine.2, pLine.3, pLine.4)
UpdateLayeredWindow(this.hwnd, this.hdc)
}
IsClickOnLineEnd(radius=6) {
if (this.Lines.MaxIndex() = "") ; no lines in collection
return
MouseGetPos, x, y
TotalLines := this.Lines.MaxIndex()
Loop % TotalLines ; Z-order. Reverse Z-order: For LineNum,pLine in this.Lines
{
LineNum := TotalLines-A_Index+1, pLine := this.Lines[LineNum]
if (this.IsInCircle(pLine.1, pLine.2, x, y, radius) = 1) {
this.LineToMove := [LineNum, pLine.3, pLine.4] ; LineNum | Coord3 | Coord4
return 1
}
else if (this.IsInCircle(pLine.3, pLine.4, x, y, radius) = 1) {
this.LineToMove := [LineNum, pLine.1, pLine.2] ; LineNum | Coord1 | Coord2
return 1
}
}
this.LineToMove := ""
}
IsInCircle(Xstart, Ystart, Xend, Yend, radius) {
a := Abs(Xend-Xstart), b := Abs(Yend-Ystart), c := Sqrt(a*a+b*b)
Return (c<radius) ? 1:0 ; if in circle returns 1, else 0
}
__Delete() {
Gdip_DeletePen(this.pPen)
Gdip_DeleteGraphics(this.G)
SelectObject(this.hdc, this.obm), DeleteObject(this.hbm), DeleteDC(this.hdc)
if (this.pToken != "")
Gdip_Shutdown(this.pToken)
}
}