Need help creating a timer with GUI Topic is solved

Ask gaming related questions (AHK v1.1 and older)
acnl
Posts: 95
Joined: 25 Nov 2017, 09:04

Need help creating a timer with GUI

Post by acnl » 28 May 2023, 09:11

Would it be possible to create an 18 second timer that shows a very small green circle to the right of my mouse cursor during the first 12 seconds and then turns orange in the last 5 seconds, and turns red when it reaches 18? I know ahk can do this but is it possible to have the circle stay alongside the mouse cursor?

I would like alt+f to start the timer and reset the timer whenever it is pressed. If you can create an ahk like this, I would greatly appreciate it! Thanks!

Rohwedder
Posts: 7627
Joined: 04 Jun 2014, 08:33
Location: Germany

Re: Need help creating a timer with GUI

Post by Rohwedder » 28 May 2023, 11:06

Hallo,
(12 + 5 = 18 ?) try:

Code: Select all

SetWinDelay, 0
SetBatchLines, -1
!f::SetTimer, Green, -10
Green:
Diameter := 15, Thickness := 2, Right := 10 ;Offset to the right
SetTimer, FFA500, -12000 ;Orange
SetTimer, Red, -18000
Red:
FFA500: ;Orange
WinClose, ahk_id %hCircle%
hCircle := MakeCircle(A_ThisLabel, Diameter, Thickness)
Hook := new WindowsHook(WH_MOUSE_LL := 14, "LowLevelMouseProc", hCircle)
CoordMode, Mouse
MouseGetPos, x, y
WinMove, ahk_id %hCircle% ,, Right + x - offset:=Diameter//2, y - offset
Return 
LowLevelMouseProc(nCode, wParam, lParam)
{ ;teadrinker
    global offset, Right
    static WM_MOUSEMOVE := 0x200
    if (wParam = WM_MOUSEMOVE)
    {
        mouse_x := NumGet(lParam + 0, "Int") + Right
        mouse_y := NumGet(lParam + 4, "Int")
        WinMove, ahk_id %A_EventInfo% ,, mouse_x - offset, mouse_y - offset
    }
    Return DllCall("CallNextHookEx", "Ptr", 0, "Int", nCode, "UInt", wParam, "Ptr", lParam)
}
class WindowsHook
{ ;teadrinker
    __New(type, callback, eventInfo := "", isGlobal := true)
    {
        this.pCallback := RegisterCallback(callback, "Fast", 3, eventInfo)
        this.hHook := DllCall("SetWindowsHookEx", "Int", type, "Ptr", this.pCallback
        , "Ptr", !isGlobal ? 0 : DllCall("GetModuleHandle", "UInt", 0, "Ptr")
        , "UInt", isGlobal ? 0 : DllCall("GetCurrentThreadId"), "Ptr")
    }
    __Delete()
    {
        DllCall("UnhookWindowsHookEx", "Ptr", this.hHook)
        DllCall("GlobalFree", "Ptr", this.pCallback, "Ptr")
    }
}
MakeCircle(color, Diameter := 100, thickness := 10, transparency := 255)
{ ; https://autohotkey.com/board/topic/7377-create-a-transparent-circle-in-window-w-winset-region/
    Gui New, +E0x20 +AlwaysOnTop +HwndhCircle +ToolWindow -Caption
    outer := DllCall("CreateEllipticRgn", "Int", 0, "Int", 0, "Int", Diameter, "Int", Diameter)
    inner := DllCall("CreateEllipticRgn", "Int", thickness, "Int", thickness, "Int"
    , Diameter - thickness, "Int", Diameter - thickness)
    DllCall("CombineRgn", "UInt", outer, "UInt", outer, "UInt", inner, "Int", 3) ; RGN_XOR = 3
    DllCall("SetWindowRgn", "UInt", hCircle, "UInt", outer, "UInt", true)
    Gui Color,% color
    Gui Show, xCenter yCenter w%Diameter% h%Diameter% NoActivate
    WinSet Transparent,% transparency, ahk_id %Circle%
    Return, hCircle
}

acnl
Posts: 95
Joined: 25 Nov 2017, 09:04

Re: Need help creating a timer with GUI

Post by acnl » 28 May 2023, 11:18

@Rohwedder

Wow, this works brilliantly! I just found one slight issue. a cute issue. When I turn the script on and off (suspend and then resume), it leaves an imprint of the circle in the last position my cursor was at before I suspended. it leaves a bunch of circles everywhere =)

Do you know of a way to make sure it doesn't do this? thank you!

Rohwedder
Posts: 7627
Joined: 04 Jun 2014, 08:33
Location: Germany

Re: Need help creating a timer with GUI

Post by Rohwedder » 28 May 2023, 11:26

This destroys the circle gui:

Code: Select all

WinClose, ahk_id %hCircle%

acnl
Posts: 95
Joined: 25 Nov 2017, 09:04

Re: Need help creating a timer with GUI

Post by acnl » 28 May 2023, 11:56

@Rohwedder

https://imgur.com/a/t9ffsYG

this is what I mean. WinClose, ahk_id %hCircle%

should I put this somewhere else so that it doesn't leave these marks when I suspend and then resume the ahk?

Rohwedder, can I also make one last request? instead of a circle that is empty, can it be a filled circle as well? This would make it easier for me to see.

Rohwedder
Posts: 7627
Joined: 04 Jun 2014, 08:33
Location: Germany

Re: Need help creating a timer with GUI

Post by Rohwedder » 28 May 2023, 13:00

Try:

Code: Select all

SetWinDelay, 0
SetBatchLines, -1
!f::SetTimer, Green, -10
*Pause:: ;Key Pause toggles script
Suspend ;Suspend Hotkeys
IF %A_IsSuspended%
{
	For all, Timer in ["Green","Red","FFA500"]
		SetTimer,% Timer, off
	WinClose, ahk_id %hCircle% ;destroys the circle gui
}
Pause,, 1 ;Pause Script
Return
Green:
Diameter := 15, Right := 10 ;Offset to the right
SetTimer, FFA500, -12000 ;Orange
SetTimer, Red, -18000
Red:
FFA500: ;Orange
hCircle := MakeCircle(A_ThisLabel, Diameter)
Hook := new WindowsHook(WH_MOUSE_LL := 14, "LowLevelMouseProc", hCircle)
CoordMode, Mouse
MouseGetPos, x, y
WinMove, ahk_id %hCircle% ,, Right + x - offset:=Diameter//2, y - offset
Return 
LowLevelMouseProc(nCode, wParam, lParam)
{ ;teadrinker
    global offset, Right
    static WM_MOUSEMOVE := 0x200
    if (wParam = WM_MOUSEMOVE)
    {
        mouse_x := NumGet(lParam + 0, "Int") + Right
        mouse_y := NumGet(lParam + 4, "Int")
        WinMove, ahk_id %A_EventInfo% ,, mouse_x - offset, mouse_y - offset
    }
    Return DllCall("CallNextHookEx", "Ptr", 0, "Int", nCode, "UInt", wParam, "Ptr", lParam)
}
class WindowsHook
{ ;teadrinker
    __New(type, callback, eventInfo := "", isGlobal := true)
    {
        this.pCallback := RegisterCallback(callback, "Fast", 3, eventInfo)
        this.hHook := DllCall("SetWindowsHookEx", "Int", type, "Ptr", this.pCallback
        , "Ptr", !isGlobal ? 0 : DllCall("GetModuleHandle", "UInt", 0, "Ptr")
        , "UInt", isGlobal ? 0 : DllCall("GetCurrentThreadId"), "Ptr")
    }
    __Delete()
    {
        DllCall("UnhookWindowsHookEx", "Ptr", this.hHook)
        DllCall("GlobalFree", "Ptr", this.pCallback, "Ptr")
    }
}
MakeCircle(color, Diameter := 100, transparency := 255)
{
    Gui +AlwaysOnTop +HwndhCircle +ToolWindow -Caption +LastFound
    Gui Color,% color
    Gui Show, xCenter yCenter w%Diameter% h%Diameter% NoActivate
	WinSet, Region, 0-0 w%Diameter% h%Diameter% E 
    WinSet Transparent,% transparency
    Return, hCircle
}

acnl
Posts: 95
Joined: 25 Nov 2017, 09:04

Re: Need help creating a timer with GUI

Post by acnl » 28 May 2023, 19:33

@Rohwedder

Sir, this works wonderfully! Ummm I am very very sorry to ask but would it be possible to create a triangle like this instead of a circle?

https://imgur.com/a/atM36gv

I actually like how you made the first circle so that I can control the thickness, this triangle also does not need to be filled. Can you create a triangle in your script instead of a circle? thank you~

Rohwedder
Posts: 7627
Joined: 04 Jun 2014, 08:33
Location: Germany

Re: Need help creating a timer with GUI

Post by Rohwedder » 29 May 2023, 01:53

An unfilled triangle, like all polygons, can be made with Region.
https://www.autohotkey.com/docs/v1/lib/WinSet.htm#Region
Here at the example of a Hexagon:

Code: Select all

; nested Polygons
Radii := [200,180] ; polygon radii from the outside in
Angles := [0,60,120,180,240,300,0] ; Hexagon
; Angle of the polygon corners in degrees, starting and ending with the first corner
Region := "", Deg2Rad := Atan(1)/45
For each, Radius in Radii	
	For each, Angle in Angles
		Region .= Round(Radii.1+Radius*Cos(Angle*=Deg2Rad))
		. "-" Round(Radii.1+Radius*Sin(Angle)) " "
Gui, -DPIScale +ToolWindow +LastFound -Caption -SysMenu +AlwaysOnTop
Gui, Color, Red
WinSet, Region,% Region
Gui, Show,% "w" 2*Radii.1 "h" 2*Radii.1

acnl
Posts: 95
Joined: 25 Nov 2017, 09:04

Re: Need help creating a timer with GUI

Post by acnl » 29 May 2023, 02:59

@Rohwedder

Haha I tried it with the hexagon example you gave me but I failed completely. I changed the angles to 32, 76, 76, 32 but it didn't make the isosceles triangle. Could you please add it to the script you made me when you have time? I'm completely lost here. I am so sorry to bother you Mr. Rohwedder.

Code: Select all

SetWinDelay, 0
SetBatchLines, -1
!f::SetTimer, Green, -10
*Pause:: ;Key Pause toggles script
Suspend ;Suspend Hotkeys
IF %A_IsSuspended%
{
	For all, Timer in ["Green","Red","FFA500"]
		SetTimer,% Timer, off
	WinClose, ahk_id %hCircle% ;destroys the circle gui
}
Pause,, 1 ;Pause Script
Return
Green:
Diameter := 15, Right := 10 ;Offset to the right
SetTimer, FFA500, -12000 ;Orange
SetTimer, Red, -18000
Red:
FFA500: ;Orange
hCircle := MakeCircle(A_ThisLabel, Diameter)
Hook := new WindowsHook(WH_MOUSE_LL := 14, "LowLevelMouseProc", hCircle)
CoordMode, Mouse
MouseGetPos, x, y
WinMove, ahk_id %hCircle% ,, Right + x - offset:=Diameter//2, y - offset
Return 
LowLevelMouseProc(nCode, wParam, lParam)
{ ;teadrinker
    global offset, Right
    static WM_MOUSEMOVE := 0x200
    if (wParam = WM_MOUSEMOVE)
    {
        mouse_x := NumGet(lParam + 0, "Int") + Right
        mouse_y := NumGet(lParam + 4, "Int")
        WinMove, ahk_id %A_EventInfo% ,, mouse_x - offset, mouse_y - offset
    }
    Return DllCall("CallNextHookEx", "Ptr", 0, "Int", nCode, "UInt", wParam, "Ptr", lParam)
}
class WindowsHook
{ ;teadrinker
    __New(type, callback, eventInfo := "", isGlobal := true)
    {
        this.pCallback := RegisterCallback(callback, "Fast", 3, eventInfo)
        this.hHook := DllCall("SetWindowsHookEx", "Int", type, "Ptr", this.pCallback
        , "Ptr", !isGlobal ? 0 : DllCall("GetModuleHandle", "UInt", 0, "Ptr")
        , "UInt", isGlobal ? 0 : DllCall("GetCurrentThreadId"), "Ptr")
    }
    __Delete()
    {
        DllCall("UnhookWindowsHookEx", "Ptr", this.hHook)
        DllCall("GlobalFree", "Ptr", this.pCallback, "Ptr")
    }
}
MakeCircle(color, Diameter := 100, transparency := 255)
{
    Gui +AlwaysOnTop +HwndhCircle +ToolWindow -Caption +LastFound
    Gui Color,% color
    Gui Show, xCenter yCenter w%Diameter% h%Diameter% NoActivate
	WinSet, Region, 0-0 w%Diameter% h%Diameter% E 
    WinSet Transparent,% transparency
    Return, hCircle
}

Rohwedder
Posts: 7627
Joined: 04 Jun 2014, 08:33
Location: Germany

Re: Need help creating a timer with GUI  Topic is solved

Post by Rohwedder » 29 May 2023, 03:24

Try:

Code: Select all

; nested Polygons
Radii := [20,10] ; polygon radii from the outside in
Angles := [40,180,320,40] ; isosceles triangle
; Angle of the polygon corners in degrees, starting and ending with the first corner
Region := "", Deg2Rad := Atan(1)/45
For each, Radius in Radii	
	For each, Angle in Angles
		Region .= Round(Radii.1+Radius*Cos(Angle*=Deg2Rad)+(Radii.1-Radius)/4)
		. "-" Round(Radii.1+Radius*Sin(Angle)) " "
Gui, -DPIScale +ToolWindow +LastFound -Caption -SysMenu +AlwaysOnTop
Gui, Color, Red
WinSet, Region,% Region
Gui, Show,% "w" 2*Radii.1 "h" 2*Radii.1
You can simply feed the region command with numbers. I.e. without trigonometry.

acnl
Posts: 95
Joined: 25 Nov 2017, 09:04

Re: Need help creating a timer with GUI

Post by acnl » 29 May 2023, 07:37

@Rohwedder

Much appreciated! it works great!!!

acnl
Posts: 95
Joined: 25 Nov 2017, 09:04

Re: Need help creating a timer with GUI

Post by acnl » 30 May 2023, 03:18

@Rohwedder

For one of the scripts you made me, can you teach me how to lower the circle so that I can adjust how high or low the position is? I tried messing with the WinMove, ahk_id %hCircle% ,, Right + x - offset:=Diameter//2, y - offset but it didn't do anything.

Thank you kindly~

Code: Select all

SetWinDelay, 0
SetBatchLines, -1
+f::SetTimer, Blue, -10
*Pause:: ;Key Pause toggles script
Suspend ;Suspend Hotkeys
IF %A_IsSuspended%
{
	For all, Timer in ["Blue","Red","White"]
		SetTimer,% Timer, off
	WinClose, ahk_id %hCircle% ;destroys the circle gui
}
Pause,, 1 ;Pause Script
Return
Blue:
Diameter := 15, Right := 50 ;Offset to the right
SetTimer, White, -14000 ;Orange
SetTimer, Red, -20000
Red:
White: ;Orange
hCircle := MakeCircle(A_ThisLabel, Diameter)
Hook := new WindowsHook(WH_MOUSE_LL := 14, "LowLevelMouseProc", hCircle)
CoordMode, Mouse
MouseGetPos, x, y
WinMove, ahk_id %hCircle% ,, Right + x - offset:=Diameter//2, y - offset
Return 
LowLevelMouseProc(nCode, wParam, lParam)
{ ;teadrinker
    global offset, Right
    static WM_MOUSEMOVE := 0x200
    if (wParam = WM_MOUSEMOVE)
    {
        mouse_x := NumGet(lParam + 0, "Int") + Right
        mouse_y := NumGet(lParam + 4, "Int") 
        WinMove, ahk_id %A_EventInfo% ,, mouse_x - offset, mouse_y - offset
    }
    Return DllCall("CallNextHookEx", "Ptr", 0, "Int", nCode, "UInt", wParam, "Ptr", lParam)
}
class WindowsHook
{ ;teadrinker
    __New(type, callback, eventInfo := "", isGlobal := true)
    {
        this.pCallback := RegisterCallback(callback, "Fast", 3, eventInfo)
        this.hHook := DllCall("SetWindowsHookEx", "Int", type, "Ptr", this.pCallback
        , "Ptr", !isGlobal ? 0 : DllCall("GetModuleHandle", "UInt", 0, "Ptr")
        , "UInt", isGlobal ? 0 : DllCall("GetCurrentThreadId"), "Ptr")
    }
    __Delete()
    {
        DllCall("UnhookWindowsHookEx", "Ptr", this.hHook)
        DllCall("GlobalFree", "Ptr", this.pCallback, "Ptr")
    }
}
MakeCircle(color, Diameter := 100, transparency := 255)
{
    Gui +AlwaysOnTop +HwndhCircle +ToolWindow -Caption +LastFound
    Gui Color,% color
    Gui Show, xCenter yCenter w%Diameter% h%Diameter% NoActivate
	WinSet, Region, 0-0 w%Diameter% h%Diameter% E 
    WinSet Transparent,% transparency
    Return, hCircle
}

Rohwedder
Posts: 7627
Joined: 04 Jun 2014, 08:33
Location: Germany

Re: Need help creating a timer with GUI

Post by Rohwedder » 30 May 2023, 03:34

Try:

Code: Select all

SetWinDelay, 0
SetBatchLines, -1
+f::SetTimer, Blue, -10
*Pause:: ;Key Pause toggles script
Suspend ;Suspend Hotkeys
IF %A_IsSuspended%
{
	For all, Timer in ["Blue","Red","White"]
		SetTimer,% Timer, off
	WinClose, ahk_id %hCircle% ;destroys the circle gui
}
Pause,, 1 ;Pause Script
Return
Blue:
Diameter := 15, Right := 50, Down := 10 ;Offset to the right and down
SetTimer, White, -14000
SetTimer, Red, -20000
Red:
White:
hCircle := MakeCircle(A_ThisLabel, Diameter)
Hook := new WindowsHook(WH_MOUSE_LL := 14, "LowLevelMouseProc", hCircle)
CoordMode, Mouse
MouseGetPos, x, y
WinMove, ahk_id %hCircle% ,, Right + x - offset:=Diameter//2, Down + y - offset
Return 
LowLevelMouseProc(nCode, wParam, lParam)
{ ;teadrinker
    global offset, Right, Down
    static WM_MOUSEMOVE := 0x200
    if (wParam = WM_MOUSEMOVE)
    {
        mouse_x := NumGet(lParam + 0, "Int") + Right
        mouse_y := NumGet(lParam + 4, "Int") + Down 
        WinMove, ahk_id %A_EventInfo% ,, mouse_x - offset, mouse_y - offset
    }
    Return DllCall("CallNextHookEx", "Ptr", 0, "Int", nCode, "UInt", wParam, "Ptr", lParam)
}
class WindowsHook
{ ;teadrinker
    __New(type, callback, eventInfo := "", isGlobal := true)
    {
        this.pCallback := RegisterCallback(callback, "Fast", 3, eventInfo)
        this.hHook := DllCall("SetWindowsHookEx", "Int", type, "Ptr", this.pCallback
        , "Ptr", !isGlobal ? 0 : DllCall("GetModuleHandle", "UInt", 0, "Ptr")
        , "UInt", isGlobal ? 0 : DllCall("GetCurrentThreadId"), "Ptr")
    }
    __Delete()
    {
        DllCall("UnhookWindowsHookEx", "Ptr", this.hHook)
        DllCall("GlobalFree", "Ptr", this.pCallback, "Ptr")
    }
}
MakeCircle(color, Diameter := 100, transparency := 255)
{
    Gui +AlwaysOnTop +HwndhCircle +ToolWindow -Caption +LastFound
    Gui Color,% color
    Gui Show, xCenter yCenter w%Diameter% h%Diameter% NoActivate
	WinSet, Region, 0-0 w%Diameter% h%Diameter% E 
    WinSet Transparent,% transparency
    Return, hCircle
}

Post Reply

Return to “Gaming Help (v1)”