2° put this plugin "SM_DrawShape.ahk" in the Lib folder of the main script (RUN_ScreenCLip.ahk)
3° insert this line "#Include SM_DrawShape.ahk" in the INCLUDE SECTION (footer) of the main script ---> RUN_ScreenCLip.ahk
Press " P " to activate the pen and start drawing mode. Press " P " again to save current drawing and close drawing mode.
Press Ctrl + " P " to abort current drawing and close drawing mode.
Don't forget to close the drawing mode as soon as you finish drawing. (press the P key again to save and close)
Code: Select all
/* ;--------------------------------------------------------------------------------------------------------------------
[Plugin] Draw Shapes (by Speedmaster)
File Name : SM_DrawShape.ahk
version: 2023 04 15 .002
topic: https://www.autohotkey.com/boards/viewtopic.php?p=506077#p506077
Help:
how to install this plugin ?
1° download FG ScreenClipper at https://www.autohotkey.com/boards/viewtopic.php?p=506077#p506077
2° put this plugin "SM_DrawShape.ahk" in the Lib folder of the main script (RUN_ScreenCLip.ahk)
3° insert this line "#Include SM_DrawShape.ahk" in the INCLUDE SECTION (footer) of the main script ---> RUN_ScreenCLip.ahk
--------------------
Help for shortcuts:
--------------------
Press " P " to activate the pen and start drawing mode. Press " P " again to save current drawing and close drawing mode.
Press Ctrl + " P " to abort current drawing and close drawing mode.
when drawing mode is activated:
Press Ctrl + left mouse to draw a rectangle
Press Ctrl + right mouse to draw a filed rectangle
Press Shift + left mouse for free hand drawing
Press Shift + right mouse to draw a line
Press Alt + left mouse to draw an arrow
Press Alt + right mouse to draw a double head arrow
Rotate the Wheel mouse to switch between colors
*/ ;---------------------------------------------------------------------------------------------------------------------
SetBatchLines -1
SetMouseDelay -1
; DEFAULT SHORTCUTS ---------------------------------------------------
#IfWinActive, ScreenClipperWindow ahk_class AutoHotkeyGUI
p:: ; activate the pen or save current drawing
tdrawshape:=!tdrawshape
#IfWinActive
if (!tdrawshape) {
SM_FixLines()
return
}
else if (tdrawshape) {
coordmode, mouse, screen
MaxGuis := SCW_Reg("MaxGuis"), i := SCW_Reg("StartAfter")
Loop % MaxGuis {
if (SCW_Reg("G" ++i "#HWND") = hwnd) {
currentgui := i
break
}
}
if (!currentgui) {
msgbox, not current gui found
return
}
imageput.gdiplusstartup()
Gui, gdraw: -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow ;+OwnDialogs
Gui, gdraw: Show, NA
;if !hwnd7
hwnd7 := WinExist()
;---------------------------------------------------- Gdip stuff ----------------------------------------------
Width := A_ScreenWidth, Height := A_ScreenHeight
hbm := CreateDIBSection(Width, Height) ;screen
hdc := CreateCompatibleDC() ;screen
obm := SelectObject(hdc, hbm) ;screen
hbm2 := CreateDIBSection(Width, Height)
hdc2 := CreateCompatibleDC()
obm2 := SelectObject(hdc2, hbm2)
G := Gdip_GraphicsFromHDC(hdc)
G2 := Gdip_GraphicsFromHDC(hdc2)
Gdip_SetSmoothingMode(G, 4)
Gdip_SetSmoothingMode(G2, 4)
;------------------------------------------------ create pencil and brush ------------------------------------
pPen := Gdip_CreatePen("0xFFFF0000" , 5)
pBrush := Gdip_BrushCreateSolid("0xFFFF0000")
tooltip, Drawing mode activated
sleep, 1000
tooltip
;------------------------------------------------ pencils with rounded caps ------------------------------------
Gdip_SetStartCap(pPen, 2)
Gdip_SetEndCap(pPen, 2)
}
Gdip_SetStartCap(pPen, cap=2)
{
return DllCall("gdiplus\GdipSetPenStartCap", "UPtr", pPen, "Uint", cap)
}
Gdip_SetEndCap(pPen, cap=2)
{
return DllCall("gdiplus\GdipSetPenEndCap", "UPtr", pPen, "Uint", cap)
}
return
;---------------------------------------------------- draw shapes -----------------------------------------------------
#IfWinActive, ScreenClipperWindow ahk_class AutoHotkeyGUI
!lbutton::
!Rbutton::
^Rbutton::
^Lbutton::
+Lbutton::
+Rbutton::
#IfWinActive
if !tdrawshape
return
MaxGuis := SCW_Reg("MaxGuis"), i := SCW_Reg("StartAfter")
Loop % MaxGuis {
if (SCW_Reg("G" ++i "#HWND") = WinExist()) {
currentgui := i
break
}
}
if (!currentgui)
return
Gui %currentgui%: -AlwaysOnTop
CoordMode, Mouse, Screen
MouseGetPos, x1, y1
;BitBlt(hdc3, 0, 0, Width, Height, hdc, 0, 0)
if (a_thishotkey="!Lbutton")
while (getKeyState("Alt", "P") && getkeystate("Lbutton", "P"))
{
MouseGetPos, x2, y2
Gdip_GraphicsClear(G2)
BitBlt(hdc2, 0, 0, Width, Height, hdc, 0, 0)
gdip_DrawArrow(G2,pPen,x2,y2,x1,y1,30,205,0)
UpdateLayeredWindow(hwnd7, hdc2, 0, 0, Width, Height)
double:=0
}
if (a_thishotkey="!Rbutton")
while (getKeyState("Alt", "P")) && getkeystate("Rbutton", "P")
{
MouseGetPos, x2, y2
Gdip_GraphicsClear(G2)
BitBlt(hdc2, 0, 0, Width, Height, hdc, 0, 0)
gdip_DrawArrow(G2,pPen,x1,y1,x2,y2,30,205,1) ; (Graphic,pen,EndPosX,EndPosY,StartPosX,StartPosY,headLength,degreeA:=205, double:=false)
UpdateLayeredWindow(hwnd7, hdc2, 0, 0, Width, Height)
double:=1
}
if (a_thishotkey="+Lbutton") {
while getKeyState("LButton", "P")
{
MouseGetPos, x2, y2
sleep, 10
MouseGetPos, x1, y1
Gdip_DrawLine(G2, pPen, x1, y1, x2, y2)
if x3
Gdip_DrawLine(G2, pPen, x3, y3, x1, y1)
BitBlt(hdc, 0, 0, Width, Height, hdc2, 0, 0)
x3:=x1, y3:=y1
UpdateLayeredWindow(hwnd7, hdc2, 0, 0, Width, Height)
}
x1:=X2:=x3:=y3:=y1:=y2:=""
}
if (a_thishotkey="+Rbutton") {
while (getKeyState("shift", "P")) && getkeystate("Rbutton", "P")
{
MouseGetPos, x2, y2
Gdip_GraphicsClear(G2)
BitBlt(hdc2, 0, 0, Width, Height, hdc, 0, 0)
Gdip_DrawLine(G2, pPen, x1, y1, x2, y2)
UpdateLayeredWindow(hwnd7, hdc2, 0, 0, Width, Height)
}
}
if (a_thishotkey="^Lbutton")
while (getKeyState("control", "P")) && getkeystate("Lbutton", "P")
{
MouseGetPos, x2, y2
Gdip_GraphicsClear(G2)
BitBlt(hdc2, 0, 0, Width, Height, hdc, 0, 0)
Gdip_DrawRectangle(G2, pPen, min(x1,x2), min(y1,y2), abs(x2-x1), abs(y2-y1))
UpdateLayeredWindow(hwnd7, hdc2, 0, 0, Width, Height)
double:=1
}
if (a_thishotkey="^Rbutton")
while (getKeyState("control", "P")) && getkeystate("Rbutton", "P")
{
MouseGetPos, x2, y2
Gdip_GraphicsClear(G2)
BitBlt(hdc2, 0, 0, Width, Height, hdc, 0, 0)
Gdip_FillRectangle(G2, pBrush, min(x1,x2), min(y1,y2), abs(x2-x1), abs(y2-y1))
UpdateLayeredWindow(hwnd7, hdc2, 0, 0, Width, Height)
double:=1
}
BitBlt(hdc, 0, 0, Width, Height, hdc2, 0, 0) ;copy buffer to screen
UpdateLayeredWindow(hwnd7, hdc, 0, 0, Width, Height) ; now draw on screen
return
#IfWinActive, ScreenClipperWindow ahk_class AutoHotkeyGUI
wheelup::
wheeldown::
if (tdrawshape) {
(!nextcolor)&&nextcolor:=1
++nextcolor
(nextcolor=5)&&nextcolor:=1
if (nextcolor=1) {
pPen := Gdip_CreatePen("0xFFFF0000" , 5)
pBrush := Gdip_BrushCreateSolid("0xFFFF0000")
tooltip Red
sleep, 400
}
else if (nextcolor=2) {
pPen := Gdip_CreatePen("0xFF008000" , 5)
pBrush := Gdip_BrushCreateSolid("0xFF008000")
tooltip Green
sleep, 400
}
else if (nextcolor=3) {
pPen := Gdip_CreatePen("0xFF0000FF" , 5)
pBrush := Gdip_BrushCreateSolid("0xFF0000FF")
tooltip Blue
sleep, 400
}
else if (nextcolor=4) {
pPen := Gdip_CreatePen("0xFF111111" , 5)
pBrush := Gdip_BrushCreateSolid("0xFF111111")
tooltip Black
sleep, 400
}
Gdip_SetStartCap(pPen, 2)
Gdip_SetEndCap(pPen, 2)
tooltip
}
return
;arbort current drawing and clear the screen
^p::
;imageput.gdiplusstartup()
if !tdrawshape
return
Gdip_GraphicsClear(G)
BitBlt(hdc2, 0, 0, Width, Height, hdc, 0, 0)
; BitBlt(hdc3, 0, 0, Width, Height, hdc, 0, 0)
UpdateLayeredWindow(hwnd7, hdc, 0, 0, Width, Height)
SelectObject(hdc, obm)
DeleteObject(hbm)
DeleteDC(hdc)
Gdip_DeleteGraphics(G)
SelectObject(hdc2, obm2)
DeleteObject(hbm2)
DeleteDC(hdc2)
Gdip_DeleteGraphics(G2)
Gdip_DisposeImage(pBitmap3)
imageput.gdiplusShutdown()
Gui, gdraw: Hide
tdrawshape:=false
return
#IfWinActive
SM_FixLines(){
global
WinGet, Hwnd, ID, A
MaxGuis := SCW_Reg("MaxGuis"), i := SCW_Reg("StartAfter")
Loop % MaxGuis {
if (SCW_Reg("G" ++i "#HWND") = WinExist()) {
currentgui := i
break
}
}
if !(currentgui) {
msgbox, curent gui not found 2
return
}
WinGetPos , OutX, OutY, OutWidth, OutHeight, A
OutX:=OutX+3, OutY:=OutY+3, OutWidth:=OutWidth-6, OutHeight:=OutHeight-6
Area := OutX "|" OutY "|" OutWidth "|" OutHeight
StringSplit, v, Area, |
if (v3 < 10 and v4 < 10) ; too small area
return
pBitmap := Gdip_BitmapFromScreen(Area)
SCW_CreateLayeredWinMod(currentgui,pBitmap,v1,v2, SCW_Reg("DrawCloseButton"))
Gdip_GraphicsClear(G)
BitBlt(hdc2, 0, 0, Width, Height, hdc, 0, 0)
BitBlt(hdc3, 0, 0, Width, Height, hdc, 0, 0)
UpdateLayeredWindow(hwnd7, hdc, 0, 0, Width, Height)
imageput.gdiplusShutdown()
}
return
; draw arrow function converted to ahk by speedmaster
; https://stackoverflow.com/questions/26804679/how-can-i-draw-arrows-on-a-canvas-with-mouse
gdip_DrawArrow(Graphic,pen,EndPosX,EndPosY,StartPosX,StartPosY,headLength,degreeA:=205, double:=false) {
Static PI := 4 * ATan(1)
degreeB:=360-degreeA
dx:=EndPosX-StartPosX
dy:=EndPosY-StartPosY
angle_atan2:=atan(dy/dx)+4*atan((dx<0)*((dy>0)-(dy<0)))
(headLength)?headLength:headLength:=50
degreesInRadiansA:=degreeA*PI/180
degreesInRadiansB:=degreeB*PI/180
RadXA:=round(EndPosX+headLength*cos(angle_atan2+degreesInRadiansA))
RadYA:=round(EndPosY+headLength*sin(angle_atan2+degreesInRadiansA))
RadXB:=round(EndPosX+headLength*cos(angle_atan2+degreesInRadiansB))
RadYB:=round(EndPosY+headLength*sin(angle_atan2+degreesInRadiansB))
Gdip_DrawLine(Graphic, Pen, EndPosX, EndPosY, RadXA, RadYA) ; arrow head side left
Gdip_DrawLine(Graphic, Pen, EndPosX, EndPosY, RadXB, RadYB) ; arrow head side right
if (double) {
RadXA2:=round(StartPosX+headLength*-cos(angle_atan2+degreesInRadiansA))
RadYA2:=round(StartPosY+headLength*-sin(angle_atan2+degreesInRadiansA))
RadXB2:=round(StartPosX+headLength*-cos(angle_atan2+degreesInRadiansB))
RadYB2:=round(StartPosY+headLength*-sin(angle_atan2+degreesInRadiansB))
Gdip_DrawLine(Graphic, Pen, StartPosX, StartPosY, RadXA2, RadYA2) ; arrow head side left
Gdip_DrawLine(Graphic, Pen, StartPosX, StartPosY, RadXB2, RadYB2) ; arrow head side right
}
Gdip_DrawLine(Graphic, Pen, StartPosX, StartPosY, EndPosX, EndPosY) ; line
}
return