Skip to content

Instantly share code, notes, and snippets.

@Gewerd-Strauss
Last active September 3, 2022 09:43
Show Gist options
  • Save Gewerd-Strauss/d8dbfdd633410001dabeff90b8977b19 to your computer and use it in GitHub Desktop.
Save Gewerd-Strauss/d8dbfdd633410001dabeff90b8977b19 to your computer and use it in GitHub Desktop.
PING-GUI - minimal OSD showing current ping in milliseconds.
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
#SingleInstance,Force
#Persistent
;#Warn All ; Enable warnings to assist with detecting common errors.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
SetBatchLines -1
SetTitleMatchMode, 2
;;_____________________________________________________________________________________
;{#[File Overview]
Menu, Tray, Icon, C:\windows\system32\shell32.dll,19 ;Set custom Script icon
menu, Tray, Add, About, Label_AboutFile
;}______________________________________________________________________________________
;{#[Autorun Section]
OnError("LogError")
FileGetTime, ModDate,%A_ScriptFullPath%,M
FileGetTime, CrtDate,%A_ScriptFullPath%,C
SysGet, MWA, MonitorWorkArea
CrtDate:=SubStr(CrtDate,7, 2) "." SubStr(CrtDate,5,2) "." SubStr(CrtDate,1,4)
, ModDate:=SubStr(ModDate,7, 2) "." SubStr(ModDate,5,2) "." SubStr(ModDate,1,4)
, global script := { base : script
, name : regexreplace(A_ScriptName, "\.\w+")
, version : "1.6.1"
, dbgLevel : 1
, author : "Gewerd Strauss"
, authorID : "Laptop-C"
, authorlink : ""
, email : ""
, credits : ""
, creditslink : ""
, crtdate : CrtDate
, moddate : ModDate
, homepagetext : ""
, homepagelink : ""
, ghtext : ""
, ghlink : ""
, doctext : ""
, doclink : ""
, forumtext : ""
, forumlink : ""
, donateLink : ""
, resfolder : A_ScriptDir "\res"
, iconfile : A_ScriptDir "\res\sct.ico"
, rfile : ""
, vfile_raw : ""
, vfile : ""
, vfile_local : A_ScriptDir "\version.ini"
, ErrorCache : []
, config : []
, configfile : A_ScriptDir "\INI-Files\" regexreplace(A_ScriptName, "\.\w+") ".ini"
, configfolder : A_ScriptDir "\INI-Files"}
cause := error
global DefaultX:=A_ScreenWidth - 70
global DefaultY:=MWABottom-18 ; might have to be adjusted depending on resolution.
global sGUINAME:="PingGui"
, CallIndex:=0
, myString:=0
Gui, STPG: new
Gui, Margin, 0,0
Gui, +AlwaysOnTop -SysMenu +ToolWindow -caption +Border +HwndHwndSTPG
cYellow := "c" . "f0c674"
Gui, Color, 101010, 373b41,
Gui, Font, s9 cYellow, Segoe UI
OnMessage(0x201, "WM_LBUTTONDOWN")
Gui, Add, Text, x3 w60 h16 vvMyText HwndMyText gMyText, Ping: %myString%
Gui, +LastFound
Gui, Show, NoActivate X%DefaultX% Y%DefaultY% ,% sGUINAME
SetTimer, DoPing, 1000
Settimer, fmoveGUI, 500
global Hwnd:=HwndSTPG, ReloadCount:=0
OnMessage(0x0200,"WM_MouseMove")
return
;}______________________________________________________________________________________
;{#[Hotkeys Section]
;}______________________________________________________________________________________
;{#[Label Section]
RemoveToolTip:
Tooltip,
return
MyText:
SendMessage, 0xA1,2
return
Label_AboutFile:
Text := script.name " - v " script.version "`n`nby " script.Author
Result := MsgBoxEx(Text, "About "script.name, "OK", 5)
If (Result == "OK") {
} Else If (Result == "Cancel") {
}
return
;}______________________________________________________________________________________
;{#[Functions Section]
DoPing()
{
global MyText
static callindex := 0, position := 0
, sites := ["1.1.1.1", "8.8.8.8", "9.9.9.9", "64.6.64.6", "77.88.8.88", "64.6.65.6", "77.88.8.2"]
if (!Mod(callindex++, 5))
position := ++position > sites.Count() ? 1 : position
site := sites[position]
Ping2 := Ping(site)
;ToolTip % site ": " Ping2 "ms"
Menu, Tray, Tip, % "Ind:" callindex "|IP:" site
Ping2:=Ping(site,Result)
EL:=""
EL:=ErrorLevel
mystring:= "Ping: " Ping2
fmoveGUI()
GuiControl,, %MyText%, %mystring%
aErrorsKnown:={"gethostbyname failed with error 0":"RAW:gethostbyname failed with error 0`n`nTODO: check router."}
str:=(aErrorsKnown[EL]!="")?aErrorsKnown[EL]:EL
if (str!=0)
AddToolTip(MyText,"Error:" str )
Else
AddToolTip(MyText,"")
if (ReloadCount++)>1200
reload
return
}
fmoveGUI()
{
if !fullscreen()
WinMove, % "ahk_id " Hwnd ,,% DefaultX,DefaultY
Else
{
WinGetClass, cClass,A
if (cClass="WorkerW")
WinMove, % "ahk_id " Hwnd ,,% DefaultX,% DefaultY
else
WinMove, % "ahk_id " Hwnd ,,% DefaultX,% A_ScreenHeight-18
}
}
WM_MouseMove(wParam,lParam,msg,hwnd)
{
static mXo, mYo
if GetKeyState("LControl")
return
MouseGetPos, mX, mY
gui, hide
MouseGetPos, mX2,mY2
while (mX2==mX) && (mY2==mY)
MouseGetPos, mX2,mY2
Settimer, lCheckHover, -200
mXo:=mX, mYo:=mY
return
lCheckHover:
MouseGetPos, cX, cY
; m(cX,cY,mXo,mYo)
while ((cX-mXo)>300) && ((cY-mYo)>300)
sleep, 400
gui, STPG: show, NoActivate
return
}
fullscreen() {
WinGetActiveTitle, cW
if (cW="")
{
}
WinGetPos,,, w, h, A
return (w = A_ScreenWidth && h = A_ScreenHeight)
}
LogError(exception)
{ ; write error messages to file. Log-File is deleted if greater than 30 MB
FileAppend % "Error on line " exception.Line ": " exception.Message "`n", % script.name "_errorlog.txt"
return true
}
WM_LBUTTONDOWN()
{
if WinExist(sGUINAME) && GetKeyState("LControl")
reload
}
AddToolTip(_CtrlHwnd, _TipText, _Modify = 0) ;-- very easy to use function to add a tooltip to a control
{ ; AddToolTip | retrieved from AHK-Rare Repository, original by jballi: https://www.autohotkey.com/boards/viewtopic.php?t=30079
; retrieved from AHK-Rare Repository, original by jballi: https://www.autohotkey.com/boards/viewtopic.php?t=30079
/* DESCRIPTION
Adds Multi-line ToolTips to any Gui Control
AHK basic, AHK ANSI, Unicode x86/x64 compatible
Thanks Superfraggle & Art: http://www.autohotkey.com/forum/viewtopic.php?p=188241
Heavily modified by Rseding91 3/4/2014:
Version: 1.0
* Fixed 64 bit support
* Fixed multiple GUI support
* Changed the _Modify parameter
* blank/0/false: Create/update the tool tip.
* -1: Delete the tool tip.
* any other value: Update an existing tool tip - same as blank/0/false
but skips unnecessary work if the tool tip already
exists - silently fails if it doesn't exist.
* Added clean-up methods:
* AddToolTip(YourGuiHwnd, "Destroy", -1): Cleans up and erases the cached tool tip data created
for that GUI. Meant to be used in conjunction with
GUI, Destroy.
* AddToolTip(YourGuiHwnd, "Remove All", -1): Removes all tool tips from every control in the GUI.
Has the same effect as "Destroy" but first removes
every tool tip from every control. This is only used
when you want to remove every tool tip but not destroy
the entire GUI afterwords.
* NOTE: Neither of the above are required if
your script is closing.
- 'Text' and 'Picture' Controls requires a g-label to be defined.
- 'ComboBox' = Drop-Down button + Edit (Get hWnd of the 'Edit' control using "ControlGet" command).
- 'ListView' = ListView + Header (Get hWnd of the 'Header' control using "ControlGet" command).
*/
Static TTHwnds, GuiHwnds, Ptr
, LastGuiHwnd
, LastTTHwnd
, TTM_DELTOOLA := 1029
, TTM_DELTOOLW := 1075
, TTM_ADDTOOLA := 1028
, TTM_ADDTOOLW := 1074
, TTM_UPDATETIPTEXTA := 1036
, TTM_UPDATETIPTEXTW := 1081
, TTM_SETMAXTIPWIDTH := 1048
, WS_POPUP := 0x80000000
, BS_AUTOCHECKBOX = 0x3
, CW_USEDEFAULT := 0x80000000
Ptr := A_PtrSize ? "Ptr" : "UInt"
/* NOTE
This is used to remove all tool tips from a given GUI and to clean up references used
This can be used if you want to remove every tool tip but not destroy the GUI
When a GUI is destroyed all Windows tool tip related data is cleaned up.
The cached Hwnd's in this function will be removed automatically if the caching code
ever matches them to a new GUI that doesn't actually own the Hwnd's.
It's still possible that a new GUI could have the same Hwnd as a previously destroyed GUI
If such an event occurred I have no idea what would happen. Either the tool tip
To avoid that issue, do either of the following:
* Don't destroy a GUI once created
NOTE: You do not need to do the above if you're exiting the script Windows will clean up
all tool tip related data and the cached Hwnd's in this function are lost when the script
exits anyway.AtEOF
*/
If (_TipText = "Destroy" Or _TipText = "Remove All" And _Modify = -1)
{
; Check if the GuiHwnd exists in the cache list of GuiHwnds
; If it doesn't exist, no tool tips can exist for the GUI.
;
; If it does exist, find the cached TTHwnd for removal.
Loop, Parse, GuiHwnds, |
If (A_LoopField = _CtrlHwnd)
{
TTHwnd := A_Index
, TTExists := True
Loop, Parse, TTHwnds, |
If (A_Index = TTHwnd)
TTHwnd := A_LoopField
}
If (TTExists)
{
If (_TipText = "Remove All")
{
WinGet, ChildHwnds, ControlListHwnd, ahk_id %_CtrlHwnd%
Loop, Parse, ChildHwnds, `n
AddToolTip(A_LoopField, "", _Modify) ;Deletes the individual tooltip for a given control if it has one
DllCall("DestroyWindow", Ptr, TTHwnd)
}
GuiHwnd := _CtrlHwnd
; This sub removes 'GuiHwnd' and 'TTHwnd' from the cached list of Hwnds
GoSub, RemoveCachedHwnd
}
Return
}
If (!GuiHwnd := DllCall("GetParent", Ptr, _CtrlHwnd, Ptr))
Return "Invalid control Hwnd: """ _CtrlHwnd """. No parent GUI Hwnd found for control."
; If this GUI is the same one as the potential previous one
; else look through the list of previous GUIs this function
; has operated on and find the existing TTHwnd if one exists.
If (GuiHwnd = LastGuiHwnd)
TTHwnd := LastTTHwnd
Else
{
Loop, Parse, GuiHwnds, |
If (A_LoopField = GuiHwnd)
{
TTHwnd := A_Index
Loop, Parse, TTHwnds, |
If (A_Index = TTHwnd)
TTHwnd := A_LoopField
}
}
; If the TTHwnd isn't owned by the controls parent it's not the correct window handle
If (TTHwnd And GuiHwnd != DllCall("GetParent", Ptr, TTHwnd, Ptr))
{
GoSub, RemoveCachedHwnd
TTHwnd := ""
}
; Create a new tooltip window for the control's GUI - only one needs to exist per GUI.
; The TTHwnd's are cached for re-use in any subsequent calls to this function.
If (!TTHwnd)
{
TTHwnd := DllCall("CreateWindowEx"
, "UInt", 0 ;dwExStyle
, "Str", "TOOLTIPS_CLASS32" ;lpClassName
, "UInt", 0 ;lpWindowName
, "UInt", WS_POPUP | BS_AUTOCHECKBOX ;dwStyle
, "UInt", CW_USEDEFAULT ;DefaultX
, "UInt", 0 ;DefaultY
, "UInt", 0 ;nWidth
, "UInt", 0 ;nHeight
, "UInt", GuiHwnd ;hWndParent
, "UInt", 0 ;hMenu
, "UInt", 0 ;hInstance
, "UInt", 0) ;lpParam
; TTM_SETWINDOWTHEME
DllCall("uxtheme\SetWindowTheme"
, Ptr, TTHwnd
, Ptr, 0
, Ptr, 0)
; Record the TTHwnd and GuiHwnd for re-use in any subsequent calls.
TTHwnds .= (TTHwnds ? "|" : "") TTHwnd
, GuiHwnds .= (GuiHwnds ? "|" : "") GuiHwnd
}
; Record the last-used GUIHwnd and TTHwnd for re-use in any immediate future calls.
LastGuiHwnd := GuiHwnd
, LastTTHwnd := TTHwnd
/*
*TOOLINFO STRUCT*
UINT cbSize
UINT uFlags
HWND hwnd
UINT_PTR uId
RECT rect
HINSTANCE hinst
LPTSTR lpszText
#if (_WIN32_IE >= 0x0300)
LPARAM lParam;
#endif
#if (_WIN32_WINNT >= Ox0501)
void *lpReserved;
#endif
*/
, TInfoSize := 4 + 4 + ((A_PtrSize ? A_PtrSize : 4) * 2) + (4 * 4) + ((A_PtrSize ? A_PtrSize : 4) * 4)
, Offset := 0
, Varsetcapacity(TInfo, TInfoSize, 0)
, Numput(TInfoSize, TInfo, Offset, "UInt"), Offset += 4 ; cbSize
, Numput(1 | 16, TInfo, Offset, "UInt"), Offset += 4 ; uFlags
, Numput(GuiHwnd, TInfo, Offset, Ptr), Offset += A_PtrSize ? A_PtrSize : 4 ; hwnd
, Numput(_CtrlHwnd, TInfo, Offset, Ptr), Offset += A_PtrSize ? A_PtrSize : 4 ; UINT_PTR
, Offset += 16 ; RECT (not a pointer but the entire RECT)
, Offset += A_PtrSize ? A_PtrSize : 4 ; hinst
, Numput(&_TipText, TInfo, Offset, Ptr) ; lpszText
; The _Modify flag can be used to skip unnecessary removal and creation if
; the caller follows usage properly but it won't hurt if used incorrectly.
If (!_Modify Or _Modify = -1)
{
If (_Modify = -1)
{
; Removes a tool tip if it exists - silently fails if anything goes wrong.
DllCall("SendMessage"
, Ptr, TTHwnd
, "UInt", A_IsUnicode ? TTM_DELTOOLW : TTM_DELTOOLA
, Ptr, 0
, Ptr, &TInfo)
Return
}
; Adds a tool tip and assigns it to a control.
DllCall("SendMessage"
, Ptr, TTHwnd
, "UInt", A_IsUnicode ? TTM_ADDTOOLW : TTM_ADDTOOLA
, Ptr, 0
, Ptr, &TInfo)
; Sets the preferred wrap-around width for the tool tip.
DllCall("SendMessage"
, Ptr, TTHwnd
, "UInt", TTM_SETMAXTIPWIDTH
, Ptr, 0
, Ptr, A_ScreenWidth)
}
; Sets the text of a tool tip - silently fails if anything goes wrong.
DllCall("SendMessage"
, Ptr, TTHwnd
, "UInt", A_IsUnicode ? TTM_UPDATETIPTEXTW : TTM_UPDATETIPTEXTA
, Ptr, 0
, Ptr, &TInfo)
Return
RemoveCachedHwnd:
Loop, Parse, GuiHwnds, |
NewGuiHwnds .= (A_LoopField = GuiHwnd ? "" : ((NewGuiHwnds = "" ? "" : "|") A_LoopField))
Loop, Parse, TTHwnds, |
NewTTHwnds .= (A_LoopField = TTHwnd ? "" : ((NewTTHwnds = "" ? "" : "|") A_LoopField))
GuiHwnds := NewGuiHwnds
, TTHwnds := NewTTHwnds
, LastGuiHwnd := ""
, LastTTHwnd := ""
Return
}
Ping(Address, ByRef Result := "", Timeout := 1000)
{
static lastAddr := "", ipAddr := 0, hIcmp := 0
if (Address != lastAddr) {
lastAddr := Address
ipAddr := Ping_IPAddress(Address)
if (!ipAddr)
return
}
if (!hIcmp) {
hIcmp := DllCall("Iphlpapi\IcmpCreateFile")
if (!hIcmp) {
ErrorLevel := "IcmpCreateFile() failed to open a port!"
return
}
}
replySize := VarSetCapacity(replyBuffer, 40, 0)
replies := DllCall("Iphlpapi\IcmpSendEcho"
, "Ptr",hIcmp
, "Int",ipAddr
, "Ptr",0
, "Int",0
, "Ptr",0
, "Ptr",&replyBuffer
, "Int",replySize
, "Int",Timeout)
if (!replies) {
ErrorLevel := "IcmpSendEcho() failed with code: " A_LastError
return
}
ip := DllCall("Ws2_32\inet_ntoa", "Int",NumGet(replyBuffer, 0, "Int"))
Result := { ""
. "InAddr":Address
, "IPAddr":StrGet(ip, "CP0")
, "RTTime":NumGet(replyBuffer, 8, "UInt") }
return Result.RTTime
}
Ping_IPAddress(Address)
{
static size := 434 + (A_PtrSize - 2) + A_PtrSize
, _ := DllCall("LoadLibrary", "Str","Iphlpapi.dll")
VarSetCapacity(WSADATA, size, 0)
err := DllCall("Ws2_32\WSAStartup", "Int",0x0202, "Ptr",&WSADATA)
if (err) {
ErrorLevel := "WSAStartup() failed with code: " err
return
}
if (RegExMatch(Address, "\w")) {
HOSTENT := DllCall("Ws2_32\gethostbyname", "AStr",Address)
if (!HOSTENT) {
err := DllCall("Ws2_32\WSAGetLastError", "Int")
DllCall("Ws2_32\WSACleanup")
ErrorLevel := "gethostbyname() failed with code: " err
return
}
offset := (2 * A_PtrSize) + 4 + (A_PtrSize - 4)
addrList := NumGet(HOSTENT + 0, offset, "Ptr")
pIpAddr := NumGet(addrList + 0, 0, "Ptr")
pIpAddr := NumGet(pIpAddr + 0, 0, "Int")
Address := DllCall("Ws2_32\inet_ntoa", "Int",pIpAddr)
Address := StrGet(Address, "CP0")
}
ipAddr := DllCall("Ws2_32\inet_addr", "AStr",Address)
DllCall("Ws2_32\WSACleanup")
if (ipAddr = 0xFFFFFFFF) {
ErrorLevel := "inet_addr() failed for address: " Address
return
}
return ipAddr
}
MsgBoxEx(Text, Title := "", Buttons := "", Icon := "", ByRef CheckText := "", Styles := "", Owner := "", Timeout := "", FontOptions := "", FontName := "", BGColor := "", Callback := "") {
Static hWnd, y2, p, px, pw, c, cw, cy, ch, f, o, gL, hBtn, lb, DHW, ww, Off, k, v, RetVal
Static Sound := {2: "*48", 4: "*16", 5: "*64"}
Gui New, hWndhWnd LabelMsgBoxEx -0xA0000
Gui % (Owner) ? "+Owner" . Owner : ""
Gui Font
Gui Font, % (FontOptions) ? FontOptions : "s9", % (FontName) ? FontName : "Segoe UI"
Gui Color, % (BGColor) ? BGColor : "White"
Gui Margin, 10, 12
If (IsObject(Icon)) {
Gui Add, Picture, % "x20 y24 w32 h32 Icon" . Icon[1], % (Icon[2] != "") ? Icon[2] : "shell32.dll"
} Else If (Icon + 0) {
Gui Add, Picture, x20 y24 Icon%Icon% w32 h32, user32.dll
SoundPlay % Sound[Icon]
}
Gui Add, Link, % "x" . (Icon ? 65 : 20) . " y" . (InStr(Text, "`n") ? 24 : 32) . " vc", %Text%
GuicontrolGet c, Pos
GuiControl Move, c, % "w" . (cw + 30)
y2 := (cy + ch < 52) ? 90 : cy + ch + 34
Gui Add, Text, vf -Background ; Footer
Gui Font
Gui Font, s9, Segoe UI
px := 42
If (CheckText != "") {
CheckText := StrReplace(CheckText, "*",, ErrorLevel)
Gui Add, CheckBox, vCheckText x12 y%y2% h26 -Wrap -Background AltSubmit Checked%ErrorLevel%, %CheckText%
GuicontrolGet p, Pos, CheckText
px := px + pw + 10
}
o := {}
Loop Parse, Buttons, |, *
{
gL := (Callback != "" && InStr(A_LoopField, "...")) ? Callback : "MsgBoxExBUTTON"
Gui Add, Button, hWndhBtn g%gL% x%px% w90 y%y2% h26 -Wrap, %A_Loopfield%
lb := hBtn
o[hBtn] := px
px += 98
}
GuiControl +Default, % (RegExMatch(Buttons, "([^\*\|]*)\*", Match)) ? Match1 : StrSplit(Buttons, "|")[1]
Gui Show, Autosize Center Hide, %Title%
DHW := A_DetectHiddenWindows
DetectHiddenWindows On
WinGetPos,,, ww,, ahk_id %hWnd%
GuiControlGet p, Pos, %lb% ; Last button
Off := ww - (((px + pw + 14) * A_ScreenDPI) // 96)
For k, v in o {
GuiControl Move, %k%, % "x" . (v + Off)
}
Guicontrol MoveDraw, f, % "x-1 y" . (y2 - 10) . " w" . ww . " h" . 48
Gui Show
Gui +SysMenu %Styles%
DetectHiddenWindows %DHW%
If (Timeout) {
SetTimer MsgBoxExTIMEOUT, % Round(Timeout) * 1000
}
If (Owner) {
WinSet Disable,, ahk_id %Owner%
}
GuiControl Focus, f
Gui Font
WinWaitClose ahk_id %hWnd%
Return RetVal
MsgBoxExESCAPE:
MsgBoxExCLOSE:
MsgBoxExTIMEOUT:
MsgBoxExBUTTON:
SetTimer MsgBoxExTIMEOUT, Delete
If (A_ThisLabel == "MsgBoxExBUTTON") {
RetVal := StrReplace(A_GuiControl, "&")
} Else {
RetVal := (A_ThisLabel == "MsgBoxExTIMEOUT") ? "Timeout" : "Cancel"
}
If (Owner) {
WinSet Enable,, ahk_id %Owner%
}
Gui Submit
Gui %hWnd%: Destroy
Return
}
;}_____________________________________________________________________________________
;{#[Include Section]
;}_____________________________________________________________________________________
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment