Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Drawing a circle on the Screen.


  • Please log in to reply
13 replies to this topic
jpjazzy
  • Members
  • 800 posts
  • Last active: Dec 17 2014 07:22 AM
  • Joined: 16 Feb 2010
First of all what I want is a circle to be drawn visually using a boarder on the screen like a sample script I will show you of a square. (Thanks to "Print" for his SS script which draws the square boarder and I just edited out the GUI function and replaced it with a mouse movement.)

Ok, so I don't even know where to begin on this project really... Not near experienced enough to dip into trying this myself. What I would like is to make the first place you click after hitting the trigger the center for the circle and then when you drag the circle, have it be resized based on the distance from that center point without showing the line representing the radius.

For a circle I wrote this and it works:

;Circle Symbol
!c::
;Input my radius
InputBox, Radius, Radius, Input Radius
;Draw my circle
MouseGetPos, StartX, StartY
MouseMove, 0, %Radius%, 0, R
MouseClick, Left, , , , 0, D
Loop 64
{
   xVar := Radius*Sin(A_Index/10)
   yVar := Radius*Cos(A_Index/10)
   DrawX := StartX+xVar
   DrawY := StartY+yVar
   MouseMove, %DrawX%, %DrawY%, 
   
}   
MouseClick, Left, , , , 0, U

Return

However you don't see the circle before its drawn... you have to just have to guess the size of the radius based in pixels on the screen.

Now I want a way to draw a shape using the same techniques as this script preferably:

!d::
gosub, BeginDraw
return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Special thanks to Print for the Square Shape draw.;;;;;;;;;;;;;;;;;
BeginDraw:
MouseGetPos, StartX, StartY
prs = 1
Gui, 20: destroy
Gui, 21: destroy
line_c = 0x008000
frame_c = 0x000F00
frame_t = 5
Gui, 21: Color, white
Gui, 21: +Lastfound +AlwaysOnTop +toolwindow
WinSet, Transparent, 100
Gui, 21:-Caption
Gui, 21: Show, x0 y0 w%A_ScreenWidth% h%A_ScreenHeight%
Hotkey, Lbutton, dragw
Hotkey, Lbutton, on
return
dragw:
MouseGetPos, MX, MY
Gui, 20:Color, black
Gui, 20:+Lastfound +AlwaysOnTop +toolwindow
WinSet, TransColor, Black
Gui, 20:-Caption
Gui, 20: Show, x0 y0 w%A_ScreenWidth% h%A_ScreenHeight%
WinGet, hw_frame, id
hdc_frame := DllCall( "GetDC", "uint", hw_frame )
hdc_buffer := DllCall( "gdi32.dll\CreateCompatibleDC", "uint", hdc_frame )
hbm_buffer := DllCall( "gdi32.dll\CreateCompatibleBitmap", "uint", hdc_frame, "int", A_ScreenWidth, "int", A_ScreenHeight )
DllCall( "gdi32.dll\SelectObject", "uint", hdc_buffer, "uint", hbm_buffer )
h_region := DllCall( "gdi32.dll\CreateRectRgn", "int", 0, "int", 0, "int", 0, "int", 0 )
h_brush := DllCall( "gdi32.dll\CreateSolidBrush", "uint", frame_c )
Loop
{
If GetKeyState("LButton", "P")
{
MouseGetPos, MXend, MYend
If ( MXend <> MXend_old or MYend <> MYend_old)
{
w := abs(MX - MXend)
h := abs(MY - MYend)
X := Min( MX, MXend )
Y := Min( MY, MYend )
DrawFrame( X, Y, w, h, frame_t )
MXend_old = %MXend%
MYend_old = %MYend%
}
}
Else
Break
Sleep, 40
}
Gui, 21:Destroy
if (MY > MYend)
{
temp := MY
MY := MYend
MYend := temp
}
if (MX > MXend)
{
temp := MX
MX := MXend - 1
MXend := temp
}
MYend-=2
MY+=2
MXend-=2
MX+=2
Hotkey, Lbutton , Off
aa=%MX%, %MY%, %MXend%, %MYend%
CaptureScreen(aa)
GoSub, CleanUp
loop
{
IfExist, %sFile%
break
sleep 100
}
Gui, 21: destroy
Hotkey, Lbutton, off
prs = 0






;~ MsgBox  %MX% %MXend% %MY% %MYend%
{
MoveX := (MXend-MX)
MoveY := (MYend-MY)
MouseClick, Left, , , , , D
MouseMove, 0, -%MoveY%, 2, R
MouseMove, -%MoveX%, 0, 2, R
MouseMove, 0, %MoveY%, 2, R
MouseMove, %MoveX%, 0, 2, R
MouseClick, Left, , , , , U


}






handle_exit:
GoSub, CleanUp
Return
CleanUp:
DeleteObject( h_brush )
DeleteObject( h_region )
DeleteObject( hbm_buffer )
DeleteDC( hdc_frame )
DeleteDC( hdc_buffer )
Gui, 20:Destroy
prs = 0
Return
DrawFrame( p_x, p_y, p_w, p_h, p_t )
{
global hdc_frame, hdc_buffer, h_region, h_brush
static buffer_state, old_x, old_y, old_w, old_h
SRCCOPY = 0x00CC0020
if ( buffer_state = "full")
DllCall( "gdi32.dll\BitBlt", "uint", hdc_frame, "int", old_x, "int", old_y, "int", old_w, "int", old_h, "uint", hdc_buffer, "int", 0, "int", 0, "uint", SRCCOPY )
else
buffer_state = full
old_x := p_x, old_y := p_y, old_w := p_w, old_h := p_h
DllCall( "gdi32.dll\BitBlt", "uint", hdc_buffer, "int", 0, "int", 0, "int", p_w, "int", p_h, "uint", hdc_frame, "int", p_x, "int", p_y , "uint", SRCCOPY )
DllCall( "gdi32.dll\SetRectRgn" , "uint", h_region , "int", p_x , "int", p_y , "int", p_x+p_w , "int", p_y+p_h )
DllCall( "gdi32.dll\FrameRgn" , "uint", hdc_frame , "uint", h_region , "uint", h_brush , "int", p_t , "int", p_t )
}
DeleteDC( p_dc )
{
DllCall( "gdi32.dll\DeleteDC", "uint", p_dc )
}
DeleteObject( p_object )
{
DllCall( "gdi32.dll\DeleteObject", "uint", p_object )
}
Min( value1, value2 )
{
If ( value1 < value2 )
return value1
Else
return value2
}
CaptureScreen(aRect = 0)
{
global sFile
sFile = %A_temp%\S%A_tickcount%.jpg


nQuality = 95
If !aRect
{
SysGet, Mon, Monitor, 1
nL := MonLeft
nT := MonTop
nW := MonRight - MonLeft
nH := MonBottom - MonTop
}
Else If aRect = 1
WinGetPos, nL, nT, nW, nH, A
Else If aRect = 2
{
WinGet, hWnd, ID, A
VarSetCapacity(rt, 16, 0)
DllCall("GetClientRect" , "Uint", hWnd, "Uint", &rt)
DllCall("ClientToScreen", "Uint", hWnd, "Uint", &rt)
nL := NumGet(rt, 0, "int")
nT := NumGet(rt, 4, "int")
nW := NumGet(rt, 8)
nH := NumGet(rt,12)
}
Else
{
StringSplit, rt, aRect, `,, %A_Space%%A_Tab%
nL := rt1
nT := rt2
nW := rt3 - rt1
nH := rt4 - rt2
znW := rt5
znH := rt6
}
mDC := DllCall("CreateCompatibleDC", "Uint", 0)
hBM := CreateDIBSection(mDC, nW, nH)
oBM := DllCall("SelectObject", "Uint", mDC, "Uint", hBM)
hDC := DllCall("GetDC", "Uint", 0)
DllCall("BitBlt", "Uint", mDC, "int", 0, "int", 0, "int", nW, "int", nH, "Uint", hDC, "int", nL, "int", nT, "Uint", 0x40000000 | 0x00CC0020)
DllCall("ReleaseDC", "Uint", 0, "Uint", hDC)
If bCursor
CaptureCursor(mDC, nL, nT)
DllCall("SelectObject", "Uint", mDC, "Uint", oBM)
DllCall("DeleteDC", "Uint", mDC)
If znW && znH
hBM := Zoomer(hBM, nW, nH, znW, znH)
If sFile = 0
SetClipboardData(hBM)
Else Convert(hBM, sFile, nQuality), DllCall("DeleteObject", "Uint", hBM)
}
CaptureCursor(hDC, nL, nT)
{
VarSetCapacity(mi, 20, 0)
mi := Chr(20)
DllCall("GetCursorInfo", "Uint", &mi)
bShow := NumGet(mi, 4)
hCursor := NumGet(mi, 8)
xCursor := NumGet(mi,12)
yCursor := NumGet(mi,16)
VarSetCapacity(ni, 20, 0)
DllCall("GetIconInfo", "Uint", hCursor, "Uint", &ni)
xHotspot := NumGet(ni, 4)
yHotspot := NumGet(ni, 8)
hBMMask := NumGet(ni,12)
hBMColor := NumGet(ni,16)
If bShow
DllCall("DrawIcon", "Uint", hDC, "int", xCursor - xHotspot - nL, "int", yCursor - yHotspot - nT, "Uint", hCursor)
If hBMMask
DllCall("DeleteObject", "Uint", hBMMask)
If hBMColor
DllCall("DeleteObject", "Uint", hBMColor)
}
Zoomer(hBM, nW, nH, znW, znH)
{
mDC1 := DllCall("CreateCompatibleDC", "Uint", 0)
mDC2 := DllCall("CreateCompatibleDC", "Uint", 0)
zhBM := CreateDIBSection(mDC2, znW, znH)
oBM1 := DllCall("SelectObject", "Uint", mDC1, "Uint", hBM)
oBM2 := DllCall("SelectObject", "Uint", mDC2, "Uint", zhBM)
DllCall("SetStretchBltMode", "Uint", mDC2, "int", 4)
DllCall("StretchBlt", "Uint", mDC2, "int", 0, "int", 0, "int", znW, "int", znH, "Uint", mDC1, "int", 0, "int", 0, "int", nW, "int", nH, "Uint", 0x00CC0020)
DllCall("SelectObject", "Uint", mDC1, "Uint", oBM1)
DllCall("SelectObject", "Uint", mDC2, "Uint", oBM2)
DllCall("DeleteDC", "Uint", mDC1)
DllCall("DeleteDC", "Uint", mDC2)
DllCall("DeleteObject", "Uint", hBM)
Return zhBM
}
Convert(sFileFr = "", sFileTo = "", nQuality = "")
{
If sFileTo =
sFileTo := A_ScriptDir . "\screen.bmp"
SplitPath, sFileTo, , sDirTo, sExtTo, sNameTo
If Not hGdiPlus := DllCall("LoadLibrary", "str", "gdiplus.dll")
Return sFileFr+0 ? SaveHBITMAPToFile(sFileFr, sDirTo . "\" . sNameTo . ".bmp") : ""
VarSetCapacity(si, 16, 0), si := Chr(1)
DllCall("gdiplus\GdiplusStartup", "UintP", pToken, "Uint", &si, "Uint", 0)
If !sFileFr
{
DllCall("OpenClipboard", "Uint", 0)
If DllCall("IsClipboardFormatAvailable", "Uint", 2) && (hBM:=DllCall("GetClipboardData", "Uint", 2))
DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "Uint", hBM, "Uint", 0, "UintP", pImage)
DllCall("CloseClipboard")
}
Else If sFileFr Is Integer
DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "Uint", sFileFr, "Uint", 0, "UintP", pImage)
Else DllCall("gdiplus\GdipLoadImageFromFile", "Uint", Unicode4Ansi(wFileFr,sFileFr), "UintP", pImage)
DllCall("gdiplus\GdipGetImageEncodersSize", "UintP", nCount, "UintP", nSize)
VarSetCapacity(ci,nSize,0)
DllCall("gdiplus\GdipGetImageEncoders", "Uint", nCount, "Uint", nSize, "Uint", &ci)
Loop, % nCount
If InStr(Ansi4Unicode(NumGet(ci,76*(A_Index-1)+44)), "." . sExtTo)
{
pCodec := &ci+76*(A_Index-1)
Break
}
If InStr(".JPG.JPEG.JPE.JFIF", "." . sExtTo) && nQuality<>"" && pImage && pCodec
{
DllCall("gdiplus\GdipGetEncoderParameterListSize", "Uint", pImage, "Uint", pCodec, "UintP", nSize)
VarSetCapacity(pi,nSize,0)
DllCall("gdiplus\GdipGetEncoderParameterList", "Uint", pImage, "Uint", pCodec, "Uint", nSize, "Uint", &pi)
Loop, % NumGet(pi)
If NumGet(pi,28*(A_Index-1)+20)=1 && NumGet(pi,28*(A_Index-1)+24)=6
{
pParam := &pi+28*(A_Index-1)
NumPut(nQuality,NumGet(NumPut(4,NumPut(1,pParam+0)+20)))
Break
}
}
If pImage
pCodec ? DllCall("gdiplus\GdipSaveImageToFile", "Uint", pImage, "Uint", Unicode4Ansi(wFileTo,sFileTo), "Uint", pCodec, "Uint", pParam) : DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", "Uint", pImage, "UintP", hBitmap, "Uint", 0) . SetClipboardData(hBitmap), DllCall("gdiplus\GdipDisposeImage", "Uint", pImage)
DllCall("gdiplus\GdiplusShutdown" , "Uint", pToken)
DllCall("FreeLibrary", "Uint", hGdiPlus)
}
CreateDIBSection(hDC, nW, nH, bpp = 32, ByRef pBits = "")
{
NumPut(VarSetCapacity(bi, 40, 0), bi)
NumPut(nW, bi, 4)
NumPut(nH, bi, 8)
NumPut(bpp, NumPut(1, bi, 12, "UShort"), 0, "Ushort")
NumPut(0, bi,16)
Return DllCall("gdi32\CreateDIBSection", "Uint", hDC, "Uint", &bi, "Uint", 0, "UintP", pBits, "Uint", 0, "Uint", 0)
}
SaveHBITMAPToFile(hBitmap, sFile)
{
DllCall("GetObject", "Uint", hBitmap, "int", VarSetCapacity(oi,84,0), "Uint", &oi)
hFile:= DllCall("CreateFile", "Uint", &sFile, "Uint", 0x40000000, "Uint", 0, "Uint", 0, "Uint", 2, "Uint", 0, "Uint", 0)
DllCall("WriteFile", "Uint", hFile, "int64P", 0x4D42|14+40+NumGet(oi,44)<<16, "Uint", 6, "UintP", 0, "Uint", 0)
DllCall("WriteFile", "Uint", hFile, "int64P", 54<<32, "Uint", 8, "UintP", 0, "Uint", 0)
DllCall("WriteFile", "Uint", hFile, "Uint", &oi+24, "Uint", 40, "UintP", 0, "Uint", 0)
DllCall("WriteFile", "Uint", hFile, "Uint", NumGet(oi,20), "Uint", NumGet(oi,44), "UintP", 0, "Uint", 0)
DllCall("CloseHandle", "Uint", hFile)
}
SetClipboardData(hBitmap)
{
DllCall("GetObject", "Uint", hBitmap, "int", VarSetCapacity(oi,84,0), "Uint", &oi)
hDIB := DllCall("GlobalAlloc", "Uint", 2, "Uint", 40+NumGet(oi,44))
pDIB := DllCall("GlobalLock", "Uint", hDIB)
DllCall("RtlMoveMemory", "Uint", pDIB, "Uint", &oi+24, "Uint", 40)
DllCall("RtlMoveMemory", "Uint", pDIB+40, "Uint", NumGet(oi,20), "Uint", NumGet(oi,44))
DllCall("GlobalUnlock", "Uint", hDIB)
DllCall("DeleteObject", "Uint", hBitmap)
DllCall("OpenClipboard", "Uint", 0)
DllCall("EmptyClipboard")
DllCall("SetClipboardData", "Uint", 8, "Uint", hDIB)
DllCall("CloseClipboard")
}
Unicode4Ansi(ByRef wString, sString)
{
nSize := DllCall("MultiByteToWideChar", "Uint", 0, "Uint", 0, "Uint", &sString, "int", -1, "Uint", 0, "int", 0)
VarSetCapacity(wString, nSize * 2)
DllCall("MultiByteToWideChar", "Uint", 0, "Uint", 0, "Uint", &sString, "int", -1, "Uint", &wString, "int", nSize)
Return &wString
}
Ansi4Unicode(pString)
{
nSize := DllCall("WideCharToMultiByte", "Uint", 0, "Uint", 0, "Uint", pString, "int", -1, "Uint", 0, "int", 0, "Uint", 0, "Uint", 0)
VarSetCapacity(sString, nSize)
DllCall("WideCharToMultiByte", "Uint", 0, "Uint", 0, "Uint", pString, "int", -1, "str", sString, "int", nSize, "Uint", 0, "Uint", 0)
Return sString
}
return

Reading through that, I realize I am way over my head which is why I turn to you guys for help and hopefully someone will have time to help me out. Thanks for any help in advance!

Leef_me
  • Moderators
  • 8510 posts
  • Last active: Sep 10 2015 05:50 AM
  • Joined: 08 Apr 2009
Whoa :shock:
Have you taken a look at:

GDI+ standard library 1.30 by tic: <!-- m -->http://www.autohotke... ... highlight=<!-- m -->

MasterFocus
  • Moderators
  • 4323 posts
  • Last active: Jan 28 2016 01:38 AM
  • Joined: 08 Apr 2009
This script by VxE may be helpful.

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Antonio França -- git.io -- github.com -- ahk4.net -- sites.google.com -- ahkscript.org

Member of the AHK community since 08/Apr/2009. Moderator since mid-2012.


jpjazzy
  • Members
  • 800 posts
  • Last active: Dec 17 2014 07:22 AM
  • Joined: 16 Feb 2010

Whoa :shock:
Have you taken a look at:

GDI+ standard library 1.30 by tic: <!-- m -->http://www.autohotke... ... highlight=<!-- m -->


Oh no I didn't see that. Thanks. Ill take a look at it see if I can attempt to understand gdi... never done it before so I was a bit scared to try. :lol:

Master, thanks but I think my circular script works fine, same principal as his only I made mine worth with inputting a radius which I think will work better when I throw in a gdi. Thanks for the link though.

jpjazzy
  • Members
  • 800 posts
  • Last active: Dec 17 2014 07:22 AM
  • Joined: 16 Feb 2010
EDIT: Nevermind, I figured it out....

Ok I have a question. I am trying to alter this Gdi slightly to fit my needs with the circle. When I change Width and Height to 1680 and 1050 it works (That is my screen resolution), draws the shapes but if I change it to A_ScreenWidth and A_ScreenHeight the gdi doesn't display?

hd :=1

; gdi+ ahk tutorial 2 written by tic (Tariq Porter)
; Requires Gdip.ahk either in your Lib folder as standard library or using #Include
;
; Tutorial to draw a single ellipse and rectangle to the screen, but just the outlines of these shapes

#SingleInstance, Force
#NoEnv
SetBatchLines, -1

; Uncomment if Gdip.ahk is not in your standard library
#Include, Gdip.ahk

; Start gdi+
If !pToken := Gdip_Startup()
{
	MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
	ExitApp
}
OnExit, Exit

; Set the width and height we want as our drawing area, to draw everything in. This will be the dimensions of our bitmap
Width := 1680, Height := 1050

; Create a layered window (+E0x80000 : must be used for UpdateLayeredWindow to work!) that is always on top (+AlwaysOnTop), has no taskbar entry or caption
Gui, 1: -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs

; Show the window
Gui, 1: Show, NA

; Get a handle to this window we have created in order to update it later
hwnd1 := WinExist()

; Create a gdi bitmap with width and height of what we are going to draw into it. This is the entire drawing area for everything
hbm := CreateDIBSection(Width, Height)

; Get a device context compatible with the screen
hdc := CreateCompatibleDC()

; Select the bitmap into the device context
obm := SelectObject(hdc, hbm)

; Get a pointer to the graphics of the bitmap, for use with drawing functions
G := Gdip_GraphicsFromHDC(hdc)

; Set the smoothing mode to antialias = 4 to make shapes appear smother (only used for vector drawing and filling)
Gdip_SetSmoothingMode(G, 4)

; Create a fully opaque red pen (ARGB = Transparency, red, green, blue) of width 3 (the thickness the pen will draw at) to draw a circle
pPen := Gdip_CreatePen(0xffff0000, 3)

; Draw an ellipse into the graphics of the bitmap (this being only the outline of the shape) using the pen created
; This pen has a width of 3, and is drawing from coordinates (100,50) an ellipse of 200x300
Gdip_DrawEllipse(G, pPen, 100, 50, 200, 300)

; Delete the pen as it is no longer needed and wastes memory
Gdip_DeletePen(pPen)

; Create a slightly transparent (66) blue pen (ARGB = Transparency, red, green, blue) to draw a rectangle
; This pen is wider than the last one, with a thickness of 10
pPen := Gdip_CreatePen(0x660000ff, 10)

; Draw a rectangle onto the graphics of the bitmap using the pen just created
; Draws the rectangle from coordinates (250,80) a rectangle of 300x200 and outline width of 10 (specified when creating the pen)
Gdip_DrawRectangle(G, pPen, 250, 80, 300, 200)

; Delete the brush as it is no longer needed and wastes memory
Gdip_DeletePen(pPen)

; Update the specified window we have created (hwnd1) with a handle to our bitmap (hdc), specifying the x,y,w,h we want it positioned on our screen
; So this will position our gui at (0,0) with the Width and Height specified earlier
UpdateLayeredWindow(hwnd1, hdc, 0, 0, Width, Height)


; Select the object back into the hdc
SelectObject(hdc, obm)

; Now the bitmap may be deleted
DeleteObject(hbm)

; Also the device context related to the bitmap may be deleted
DeleteDC(hdc)

; The graphics may now be deleted
Gdip_DeleteGraphics(G)
Return

;#######################################################################
F2::
If (hd = 1)
{
Gui, 1: Hide
hd := 2
Return
}
Else If (hd = 2)
{
Gui, 1: Show
hd := 1
Return
}

Exit:
; gdi+ may now be shutdown on exiting the program
Gdip_Shutdown(pToken)
ExitApp
Return

F3::Reload


jpjazzy
  • Members
  • 800 posts
  • Last active: Dec 17 2014 07:22 AM
  • Joined: 16 Feb 2010
Ok, so I got what I wanted half way but there are some obvious bugs I can't seem work out since I am a gdi newb. :lol:

Here is what I got:

; Requires Gdip.ahk either in your Lib folder as standard library or using #Include
#InstallMouseHook
#SingleInstance, Force
#NoEnv
SetBatchLines, -1

; Uncomment if Gdip.ahk is not in your standard library
#Include, Gdip.ahk



!c::

; Start gdi+
If !pToken := Gdip_Startup()
{
	MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
	ExitApp
}
OnExit, Exit

;Gui to be the background
Gui, 21: Color, white
Gui, 21:-Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs
WinSet, Transparent, 100
Gui, 21: Show, x0 y0 w%A_ScreenWidth% h%A_ScreenHeight%
Hotkey, LButton, Drag
Return



Drag:
; Create a layered window (+E0x80000 : must be used for UpdateLayeredWindow to work!) that is always on top (+AlwaysOnTop), has no taskbar entry or caption
Gui, 1: -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs

; Show the window
Gui, 1: Show, NA

; Set the width and height we want as our drawing area, to draw everything in. This will be the dimensions of our bitmap
Width := A_ScreenWidth
Height := A_ScreenHeight

MouseGetPos, MX, MY

Loop
{
MouseGetPos, NewMX, NewMY

Radius := (MX-NewMX)
Diameter := (Radius*2)
StartX := (MX-Radius)
StartY := (MY-Radius)

; Get a handle to this window we have created in order to update it later
hwnd1 := WinExist()

; Create a gdi bitmap with width and height of what we are going to draw into it. This is the entire drawing area for everything
hbm := CreateDIBSection(Width, Height)

; Get a device context compatible with the screen
hdc := CreateCompatibleDC()

; Select the bitmap into the device context
obm := SelectObject(hdc, hbm)

; Get a pointer to the graphics of the bitmap, for use with drawing functions
G := Gdip_GraphicsFromHDC(hdc)

; Set the smoothing mode to antialias = 4 to make shapes appear smother (only used for vector drawing and filling)
Gdip_SetSmoothingMode(G, 4)

; Create a fully opaque red pen (ARGB = Transparency, red, green, blue) of width 3 (the thickness the pen will draw at) to draw a circle
pPen := Gdip_CreatePen(0x55ff0000, 3)

; Draw an ellipse into the graphics of the bitmap (this being only the outline of the shape) using the pen created
Gdip_DrawEllipse(G, pPen, StartX, StartY, Diameter, Diameter)


; Delete the pen as it is no longer needed and wastes memory
Gdip_DeletePen(pPen)

; Create a slightly transparent (66) blue pen (ARGB = Transparency, red, green, blue) to draw a rectangle
; This pen is wider than the last one, with a thickness of 10
pPen := Gdip_CreatePen(0x660000ff, 10)

; Update the specified window we have created (hwnd1) with a handle to our bitmap (hdc), specifying the x,y,w,h we want it positioned on our screen
; So this will position our gui at (0,0) with the Width and Height specified earlier
UpdateLayeredWindow(hwnd1, hdc, 0, 0, Width, Height)


; Select the object back into the hdc
SelectObject(hdc, obm)

; Now the bitmap may be deleted
DeleteObject(hbm)

; Also the device context related to the bitmap may be deleted
DeleteDC(hdc)

; The graphics may now be deleted
Gdip_DeleteGraphics(G)
Hotkey, LButton Up, Exit

}


Return

;#######################################################################


Exit:
; gdi+ may now be shutdown on exiting the program
Gdip_Shutdown(pToken)
Return

F3::Reload

It does what I want the first Alt+C but then after that there is problems....

Problems:
1.) When hitting Alt+C again origin of the circle doesn't seem to change...
2.) Getting the script to reload or exit was a major pain... must use task manager to exit AHK.
3.)Input from the mouse seems to be blocked after you hit alt C

Can you guys help me with these pretty please with a cherry on top? :(

  • Guests
  • Last active:
  • Joined: --
Oh, and also another problem was the input from the mouse seems to be blocked after you hit alt C which I don't understand either... :? Ill add that to my last post later tonight.

jpjazzy
  • Members
  • 800 posts
  • Last active: Dec 17 2014 07:22 AM
  • Joined: 16 Feb 2010
Ok Jaco said no new topic so, here it is again. "I still need help".

Going back and looking at my script I think the problem isn't that the origin doesn't change. Also I think if I just figure out why the mouse input from my left button is being blocked after Drawing one circle then the other problems would be fixed because the reason it is not drawing the next circle I can see now is how can it if the left mouse button isn't working. I'm sure this would also fix the exit problem I am having.... :?

jpjazzy
  • Members
  • 800 posts
  • Last active: Dec 17 2014 07:22 AM
  • Joined: 16 Feb 2010
Another day, another try.

I was playing with the code last night and after looking at it again is it possible that the hwnd1 in the update layered window is what is blocking my input? If that is the case, how can I delete a layered bitmap window that's being displayed?

jpjazzy
  • Members
  • 800 posts
  • Last active: Dec 17 2014 07:22 AM
  • Joined: 16 Feb 2010
:?

  • Guests
  • Last active:
  • Joined: --

2.) Getting the script to reload or exit was a major pain... must use task manager to exit AHK.

OnExit, Exit
;//...
Exit:
;//gdi+ may now be shutdown on exiting the program
Gdip_Shutdown(pToken)
;//Return
ExitApp
...need to change Return to ExitApp in the OnExit routine or else it cancels the exit...(making it a bitch to close!)...

No promises, but at least now I'm looking at this topic & I also semi-want this script, so I may actually run/test & post new code in a few days...

  • Guests
  • Last active:
  • Joined: --

...& post new code in a few days...

...or just an hour, whichever comes 1st...

#SingleInstance force
#NoEnv
;//#InstallMouseHook		;// works without, so why?
OnExit, OnExit
SetBatchLines, -1
WS_EX_LAYERED:=0x00080000
WS_EX_NOACTIVATE:=0x08000000
Hotkey, LButton, Off

#Include Gdip.ahk

LButton::Gosub, Drag

!c::
if (!CircleActive) {
	;//Start gdi+
	if (!pToken:=Gdip_Startup()) {
		msgbox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
		ExitApp
	}

	;//Gui to be the background
	Gui, 21:Default		;// set default, don't put number everywhere!
	Gui, +LastFound -Caption +AlwaysOnTop +E%WS_EX_LAYERED% +E%WS_EX_NOACTIVATE%
	Gui, Color, White
	Gui, Show, Hide
	WinSet, Transparent, 119
	WinMove, , , 0, 0, A_ScreenWidth, A_ScreenHeight
	Gui, Show, NA
	Hotkey, LButton, On
	CircleActive=1
} else {
	Hotkey, LButton, Off
	Gui, 21:Destroy
	Gui, Destroy
	CircleActive=
}
return

Drag:
;//Create a layered window (+E0x80000 : must be used for UpdateLayeredWindow to work!) that is always on top (+AlwaysOnTop), has no taskbar entry or caption
Gui, +LastFound -Caption +AlwaysOnTop +E%WS_EX_LAYERED% +E%WS_EX_NOACTIVATE%
;//Gui, -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs

;//Show the window
Gui, Show, NA

;//Set the width and height we want as our drawing area, to draw everything in. This will be the dimensions of our bitmap
Width:=A_ScreenWidth
Height:=A_ScreenHeight

MouseGetPos, MX, MY

Loop {
	MouseGetPos, NewMX, NewMY

	Radius:=(MX-NewMX)
	Diameter:=(Radius*2)
	StartX:=(MX-Radius)
	StartY:=(MY-Radius)

	;//Get a handle to this window we have created in order to update it later
	hwnd1:=WinExist()

	;//Create a gdi bitmap with width and height of what we are going to draw into it. This is the entire drawing area for everything
	hbm:=CreateDIBSection(Width, Height)

	;//Get a device context compatible with the screen
	hdc:=CreateCompatibleDC()

	;//Select the bitmap into the device context
	obm:=SelectObject(hdc, hbm)

	;//Get a pointer to the graphics of the bitmap, for use with drawing functions
	G:=Gdip_GraphicsFromHDC(hdc)

	;//Set the smoothing mode to antialias = 4 to make shapes appear smother (only used for vector drawing and filling)
	Gdip_SetSmoothingMode(G, 4)

	;//Create a fully opaque red pen (ARGB = Transparency, red, green, blue) of width 3 (the thickness the pen will draw at) to draw a circle
	pPen:=Gdip_CreatePen(0x55ff0000, 3)

	;//Draw an ellipse into the graphics of the bitmap (this being only the outline of the shape) using the pen created
	Gdip_DrawEllipse(G, pPen, StartX, StartY, Diameter, Diameter)

	;//Delete the pen as it is no longer needed and wastes memory
	Gdip_DeletePen(pPen)

	;//Create a slightly transparent (66) blue pen (ARGB = Transparency, red, green, blue) to draw a rectangle
	;//This pen is wider than the last one, with a thickness of 10
	pPen:=Gdip_CreatePen(0x660000ff, 10)

	;//Update the specified window we have created (hwnd1) with a handle to our bitmap (hdc), specifying the x,y,w,h we want it positioned on our screen
	;//So this will position our gui at (0,0) with the Width and Height specified earlier
	UpdateLayeredWindow(hwnd1, hdc, 0, 0, Width, Height)

	;//Select the object back into the hdc
	SelectObject(hdc, obm)

	;//Now the bitmap may be deleted
	DeleteObject(hbm)

	;//Also the device context related to the bitmap may be deleted
	DeleteDC(hdc)

	;//The graphics may now be deleted
	Gdip_DeleteGraphics(G)
	;//Hotkey, LButton Up, Exit
	if (!GetKeyState("LButton", "P")) {
		return
	}
}
return

;//#######################################################################

OnExit:
;//gdi+ may now be shutdown on exiting the program
Gdip_Shutdown(pToken)
ExitApp

F10::Reload
F12::ExitApp
...that is much freaking better code...

tic
  • Members
  • 1934 posts
  • Last active: May 30 2018 08:13 PM
  • Joined: 22 Apr 2007
Hi.....I will write this code, but I strongly advise you first work your way through all the tutorials. You may find that you learn some things that will help with this. I should write a note that you shouldnt start gdi+ or create your gui in a subroutine...do that at the top of the script

jpjazzy
  • Members
  • 800 posts
  • Last active: Dec 17 2014 07:22 AM
  • Joined: 16 Feb 2010
OMG I THINK I LOVE YOU WHOEVER YOU ARE GUEST :shock:

I edited the code just a bit cuz I actually wanted it exit the GUIs upon lifting the L button. Thank you so much and thank you Tic for trying! I made a few changes, so since you helped me, if anyone wants the script, here:

#SingleInstance force
#NoEnv
OnExit, OnExit
SetBatchLines, -1
WS_EX_LAYERED:=0x00080000
WS_EX_NOACTIVATE:=0x08000000
Hotkey, LButton, Off

#Include Gdip.ahk

LButton::Gosub, Drag

!c::
if (!CircleActive) {
   ;//Start gdi+
   if (!pToken:=Gdip_Startup()) {
      msgbox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
      ExitApp
   }

   ;//Gui to be the background
   Gui, 21:Default      ;// "set default, don't put number everywhere!" Sorry. Copy and paste. ;) 
   Gui, +LastFound -Caption +AlwaysOnTop +E%WS_EX_LAYERED% +E%WS_EX_NOACTIVATE%
   Gui, Color, White
   Gui, Show, Hide
   WinSet, Transparent, 100
   WinMove, , , 0, 0, A_ScreenWidth, A_ScreenHeight
   Gui, Show, NA
   Hotkey, LButton, On
   CircleActive=1
}  ;else {
;~    Hotkey, LButton, Off
;~    Gui, 21:Destroy   ;;; This isn't needed if we are exiting the circle on the LButton lift.
;~    Gui, Destroy
;~    CircleActive=
;~ }
return

Drag:
;//Create a layered window (+E0x80000 : must be used for UpdateLayeredWindow to work!) that is always on top (+AlwaysOnTop), has no taskbar entry or caption
Gui, +LastFound -Caption +AlwaysOnTop +E%WS_EX_LAYERED% +E%WS_EX_NOACTIVATE%
;//Gui, -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs

;//Show the window
Gui, Show, NA

;//Set the width and height we want as our drawing area, to draw everything in. This will be the dimensions of our bitmap
Width:=A_ScreenWidth
Height:=A_ScreenHeight

MouseGetPos, MX, MY

Loop {
   MouseGetPos, NewMX, NewMY

   Radius:=(MX-NewMX)
   Diameter:=(Radius*2)
   StartX:=(MX-Radius)
   StartY:=(MY-Radius)

   ;//Get a handle to this window we have created in order to update it later
   hwnd1:=WinExist()

   ;//Create a gdi bitmap with width and height of what we are going to draw into it. This is the entire drawing area for everything
   hbm:=CreateDIBSection(Width, Height)

   ;//Get a device context compatible with the screen
   hdc:=CreateCompatibleDC()

   ;//Select the bitmap into the device context
   obm:=SelectObject(hdc, hbm)

   ;//Get a pointer to the graphics of the bitmap, for use with drawing functions
   G:=Gdip_GraphicsFromHDC(hdc)

   ;//Set the smoothing mode to antialias = 4 to make shapes appear smother (only used for vector drawing and filling)
   Gdip_SetSmoothingMode(G, 4)

   ;//Create a fully opaque red pen (ARGB = Transparency, red, green, blue) of width 3 (the thickness the pen will draw at) to draw a circle
   pPen:=Gdip_CreatePen(0x55ff0000, 3)

   ;//Draw an ellipse into the graphics of the bitmap (this being only the outline of the shape) using the pen created
   Gdip_DrawEllipse(G, pPen, StartX, StartY, Diameter, Diameter)

   ;//Delete the pen as it is no longer needed and wastes memory
   Gdip_DeletePen(pPen)

   ;//Create a slightly transparent (66) blue pen (ARGB = Transparency, red, green, blue) to draw a rectangle
   ;//This pen is wider than the last one, with a thickness of 10
   pPen:=Gdip_CreatePen(0x660000ff, 10)

   ;//Update the specified window we have created (hwnd1) with a handle to our bitmap (hdc), specifying the x,y,w,h we want it positioned on our screen
   ;//So this will position our gui at (0,0) with the Width and Height specified earlier
   UpdateLayeredWindow(hwnd1, hdc, 0, 0, Width, Height)

   ;//Select the object back into the hdc
   SelectObject(hdc, obm)

   ;//Now the bitmap may be deleted
   DeleteObject(hbm)

   ;//Also the device context related to the bitmap may be deleted
   DeleteDC(hdc)

   ;//The graphics may now be deleted
   Gdip_DeleteGraphics(G)
   ;//Hotkey, LButton Up, Exit
   if (GetKeyState("LButton", "P") = 0) ;If left button is not pushed (Lifted up) then break
   {
      Break
   }
}
Hotkey, LButton, Off
   Gui, 21:Destroy ;else statement "circle turning off" stuff goes after the L button lift.
   Gui, Destroy
   CircleActive=
return

;//#######################################################################

OnExit:
;//gdi+ may now be shutdown on exiting the program
Gdip_Shutdown(pToken)
ExitApp

F10::Reload
F12::ExitApp