Here is another example that uses a custom gui class for scaling.
.
Code: Select all
#SingleInstance, Force
SetBatchLines, -1
MyText =
(
F2 -> Removes the Menu bar of the GUI
F3 -> Bring back the Menu bar of the GUI
F4 -> Makes the GUI window not resizable
F5 -> Makes the GUI window resizable
)
Gui1 := New Gui( "+AlwaysOnTop +E0x02000000 +E0x00080000" )
Gui1.Margin( 10 , 10 )
Gui1.SetFont( Size := 9 , color := "Black" , Options := "" , Type := "Arial" )
Gui1.Add( "Text" , "xm ym" , "Info:" , "InfoTextControl" )
Gui1.Add( "Edit" , "xm y+m w250 h150" , MyText )
Gui1.Set( Gui1.Controls.InfoTextControl.Hwnd ,, "Focus" )
Gui1.Options( "-Caption" )
DetectHiddenWindows, On
Gui1.Show( "Hide AutoSize" )
Gui1.CaptionLessSize := Gui1.WindowPosition()
Gui1.Options( "-E0x02000000 -E0x00080000 +Caption" )
Gui1.Show( "AutoSize" )
Gui1.Options( "+E0x02000000 +E0x00080000" )
Gui1.CaptionedSize := Gui1.WindowPosition()
Gui1.OriginalSize := { W: Gui1.CaptionLessSize.W , H: Gui1.CaptionLessSize.H }
Gui1.TriggerRadius := 10
Gui1.ResizeMode := 1
Gui1.CaptionMode := 1
OnMessage( 0x201 , func( "ClickEvent" ).bind( Gui1 ) )
return
;|<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>|
GuiClose:
GuiContextMenu:
*ESC::ExitApp
;|<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>|
F2:: ;{
Gui1.Options( "-Caption" )
Gui1.Show( "AutoSize" )
return
;}
;|<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>|
F3:: ;{
Gui1.Options( "-E0x02000000 -E0x00080000 +Caption" )
Gui1.Options( "+E0x02000000 +E0x00080000" )
Gui1.Show( "AutoSize" )
return
;}
;|<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>|
F4:: ;{
Gui1.ResizeMode := false
return
;}
;|<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>|
F5:: ;{
Gui1.ResizeMode := True
return
;}
;|<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>|
ClickEvent( Gui1 ){
SetControlDelay, -1
CoordMode, Mouse, Window
MouseGetPos, x , y , win
if( win != Gui1.Hwnd )
return
MouseVector := New Vector( x , y )
pos := Gui1.WindowPosition()
triggerVector := New Vector( pos.W , pos.H )
if( Gui1.ResizeMode && MouseVector.Dist( triggerVector ) <= Gui1.TriggerRadius ){
While( GetKeyState( "LButton" , "P" ) ){
CoordMode, Mouse, Screen
MouseGetPos, x , y
pos := Gui1.WindowPosition()
scale := ( x - pos.X ) / Gui1.OriginalSize.W
if( scale < 1 )
scale := 1
Gui1.ScaleAllControls( scale )
Gui1.Margin( 10 * scale , 10 * scale )
Gui1.Show( "AutoSize" )
Gui1.Options( "+LastFound" )
WinSet, Redraw
sleep, 60
}
Gui1.Show( "Hide" )
Gui1.Show( "AutoSize" )
}
}
;|<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>|
;|<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>|
class Gui {
static Index := 0 , Windows := [] , Handles := []
;Written By: Hellbent
;Date: Sept 9th, 2021
;Last Edit: Oct 16th 2023
;Class to create Easy Scale windows
__New( Options := "+AlwaysOnTop" , Title := "" ){
local hwnd
;********************
Gui, New, % Options " +Hwndhwnd" , % Title
This.Hwnd := hwnd
;********************
This.Controls := {}
This.ControlArray := []
This.Handles := []
;********************
This.FontType := "Arial"
This.FontSize := 10
This.FontColor := "Black"
This.FontOptions := ""
This.Font()
;********************
This.Color := "F0F0F0"
This.ControlColor := "FFFFFF"
This.SetColors()
;********************
Gui.Handles[ This.Hwnd ] := Gui.Windows[ ++Gui.Index ] := This
This.Show( "Hide w1 h1 " )
}
Show( Options := "" , Title := "" ){
Gui, % This.Hwnd ":Show" , % Options , % Title
}
Hide( Name := 1 ){
Gui, % Name ":Hide"
}
Enable(){
Gui, % This.Hwnd ":-Disabled"
}
Disable(){
Gui, % This.Hwnd ":+Disabled"
}
Destroy( Name := 1 ){
Try
Gui, % This.Hwnd ":Destroy"
}
__Delete(){
Try
Gui, % This.Hwnd ":Destroy"
}
Get( Control , SubCommand := "" ){
local output
GuiControlGet, output, % This.Hwnd ":" SubCommand , % Control
return output
}
Set( Control , Value := "" , SubCommand := "" ){
GuiControl, % This.Hwnd ":" SubCommand , % Control , % Value
}
Margin( x := 10 , y := 10 ){
Gui, % This.Hwnd ":Margin", % x , % y
}
SetColors( Color1 := "" , Color2 := "" ){
if( Color1 != "" )
This.Color := Color1
if( Color2 != "" )
This.ControlColor := Color2
Gui, % This.Hwnd ":Color", % This.Color , % This.ControlColor
}
WindowPosition(){
local x , y , w , h
WinGetPos, x , y , w , h , % "ahk_id " This.Hwnd
return { X: x , Y: y , W: w , H: h }
}
ControlPosition( Hwnd ){
local pos , posX , posY , PosW , PosH
GuiControlGet, pos , % This.Hwnd ":pos", % Hwnd
if( This.Handles[ hwnd ].Index ){
This.Handles[ hwnd ].Position := { X: posX , Y: posY , W: posW , H: posH }
return
}else{
return { X: posX , Y: posY , W: posW , H: posH }
}
}
Add( Type := "Button" , Options := "" , Display := "" , ControlName := "" , ScaleMode := "" , rows := "" ){ ;scaleMode 1: scale via font size. 2= scale via controls size
static ScaleModeList := { "Text": 1 , "Edit": 1 , "Button": 1 , "DDL": 2 , "DropDownList": 2 , "ListBox": 1 , "CheckBox": 1 }
local hwnd
Gui, % This.Hwnd ":Add", % Type, % Options " hwndhwnd " , % Display
if( ControlName != "" ){
This.Controls[ ControlName ] := {}
This.Controls[ ControlName ].Name := ControlName
This.Controls[ ControlName ].Hwnd := hwnd
This.Controls[ ControlName ].Type := type
This.Handles[ hwnd ] := This.Controls[ ControlName ]
This.ControlArray.Push( This.Controls[ ControlName ] )
}else{
This.Controls[ hwnd ] := {}
This.Controls[ hwnd ].Name := hwnd
This.Controls[ hwnd ].Type := Type
This.Controls[ hwnd ].Hwnd := hwnd
This.Handles[ hwnd ] := This.Controls[ hwnd ]
This.ControlArray.Push( This.Controls[ hwnd ] )
}
if( ScaleMode != "" )
This.Handles[ hwnd ].ScaleMode := ScaleMode
else
This.Handles[ hwnd ].ScaleMode := ScaleModeList[ type ]
if( This.Handles[ hwnd ].ScaleMode = "" )
This.Handles[ hwnd ].ScaleMode := 1
This.Handles[ hwnd ].Index := This.ControlArray.Length()
This.ControlPosition( Hwnd )
This.Handles[ hwnd ].Font := { Type: This.FontType , Size: This.FontSize , Color: This.FontColor , Options: This.FontOptions }
if( rows != "" )
This.Handles[ hwnd ].Rows := rows
}
SetFont( Size := "" , color := "" , Options := "" , Type := "" ){
if( Size != "" )
This.FontSize := Size
if( color != "" )
This.FontColor := Color
if( Options != "" )
This.FontOptions := Options
if( Type != "" )
This.FontType := Type
Gui, % This.Hwnd ":Font", % "norm s" ( This.FontSize * A_ScreenDPI / 96 ) " c" This.FontColor " " This.FontOptions , % This.FontType
}
Options( Options ){
Gui, % This.Hwnd ":" Options
}
Bind( Control , Method , BoundObject := "" ){
local fn
if( BoundObject = "Label" )
fn := Method
else if( BoundObject != "" )
fn := Func( Method ).Bind( This , Control , BoundObject )
else
fn := Func( Method ).Bind( This , Control )
GuiControl, % This.Hwnd ":+g", % Control, % fn
}
ScaleControl( ControlHwnd , scalefactor , mode := 1 ){
if( mode = 1 ){
cc := This.Handles[ ControlHwnd ].Position
x := cc.X * scaleFactor
y := cc.Y * scaleFactor
w := cc.W * scaleFactor
h := cc.H * scaleFactor
This.SetControlFont( controlhwnd , , , , , scalefactor )
This.Set( ControlHwnd , "X" x " y" y " w " w " h" h , "MoveDraw" )
}else if( mode = 2 ){
cc := This.Handles[ ControlHwnd ].Position
x := cc.X * scaleFactor
y := cc.Y * scaleFactor
w := cc.W * scaleFactor
h := ( 16 * This.Handles[ ControlHwnd ].Rows ) * scaleFactor
This.SetControlFont( controlhwnd , , , , , scalefactor )
This.Set( ControlHwnd , "X" x " y" y " w " w " h" h , "MoveDraw" )
}
}
SetControlFont( controlhwnd , Size := "" , color := "" , Options := "" , Type := "" , Scale := 1 ){
cc := This.Handles[ controlhwnd ].Font
if( Size != "" ){
cc.Size := Size
Size /= A_ScreenDPI / 96
Size *= Scale
}else{
Size := ( cc.Size / ( A_ScreenDPI / 96 ) ) * Scale
}
if( color != "" )
cc.Color := Color
else
Color := cc.Color
if( Options != "" )
cc.Options := Options
else
Options := cc.Options
if( Type != "" )
cc.Type := Type
else
Type := cc.Type
Gui, % This.Hwnd ":Font" , % " norm s" size " c" color " " options , % Type
This.Set( controlhwnd ,, "Font" )
}
ScaleAllControls( scale := 1 ){
for k, v in This.ControlArray {
cc := This.ControlArray[ k ]
This.ScaleControl( cc.Hwnd , Scale , mode := cc.ScaleMode )
}
}
}
;************
;Vector Class
;**************************************************************************************************************************************************************************
;00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000
;00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000
;00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000
;**************************************************************************************************************************************************************************
Class Vector {
;Written By: HB
;Date: Sept 23rd, 2022
;Last Edit: Sept 24th, 2022
;Purpose: Vector math class
;Credit: Rohwedder
;Resources:
;Line intercept concepts and code: https://www.autohotkey.com/boards/viewtopic.php?f=76&t=37175
;Create an Arrow: https://www.autohotkey.com/boards/viewtopic.php?f=76&t=92039&p=479129#p478944
;Getting an angle: https://www.autohotkey.com/boards/viewtopic.php?f=76&t=108760&p=483661#p483678
;Setting an Angle: https://www.autohotkey.com/boards/viewtopic.php?f=76&t=108760&p=483786#p483811
;
static RadToDeg := 45 / ATan( 1 )
, DegToRad := ATan( 1 ) / 45
__New( x := 0 , y := 0 , rotate := 0 ){
if( IsObject( x ) ){
if( rotate = 3 ){
This.X := x.X * -1
,This.Y := x.Y * -1
}else if( rotate = 2 ){
This.X := x.Y
,This.Y := x.X * -1
}else if( rotate = 1 ){
This.X := x.Y * -1
,This.Y := x.X
}else{
This.X := x.X
,This.Y := x.Y
}
}else{
if( rotate = 3 ){
This.X := X * -1
,This.Y := Y * -1
}else if( rotate = 2 ){
This.X := Y
,This.Y := X * -1
}else if( rotate = 1 ){
This.X := Y * -1
,This.Y := X
}else{
This.X := X
,This.Y := Y
}
}
}
Add( x , y := "" ){
if( IsObject( x ) ){
This.X += x.X
,This.Y += x.Y
}else if( y = "" ){
This.X += x
,This.Y += x
}else{
This.X += x
,This.Y += y
}
}
Sub( x , y := "" ){
if( IsObject( x ) ){
This.X -= x.X
,This.Y -= x.Y
}else if( y = "" ){
This.X -= X
,This.Y -= X
}else{
This.X -= X
,This.Y -= Y
}
}
Div( x , y := "" ){
if( IsObject( x ) ){
This.X /= x.X
,This.Y /= x.Y
}else if( x && y = "" ){
This.X /= x
,This.Y /= x
}else{
This.X /= X
,This.Y /= Y
}
}
Mult( x , y := "" ){
if( IsObject( x ) ){
This.X *= x.X
,This.Y *= x.Y
}else if( x && y = "" ){
This.X *= x
,This.Y *= x
}else{
This.X *= X
,This.Y *= Y
}
}
Dist( x , y := "" ){
if( IsObject( x ) )
return Sqrt( ( ( This.X - x.X ) **2 ) + ( ( This.Y - x.Y ) **2 ) )
else
return Sqrt( ( ( This.X - X ) **2 ) + ( ( This.Y - Y ) **2 ) )
}
GetMag(){
return Sqrt( This.X * This.X + This.Y * This.Y )
}
SetMag( magnitude ){
local m := This.GetMag()
This.X := This.X * magnitude / m
,This.Y := This.Y * magnitude / m
}
MagSq(){
return This.GetMag()**2
}
Dot( x , y := "" ){
if( IsObject( x ) )
return ( This.X * x.X ) + ( This.Y * x.Y )
else
return ( This.X * X ) + ( This.Y * Y )
}
Cross( x , y := "" ){
if( IsObject( x ) )
return This.X * x.Y - This.Y * x.X
else
return This.X * Y - This.Y * X
}
Norm(){
local m := This.GetMag()
This.X /= m
This.Y /= m
}
GetAngle(){
local angle
( ( angle := Vector.RadToDeg * DllCall( "msvcrt\atan2" , "Double" , This.Y , "Double" , This.X , "CDECL Double" ) ) < 0 ) ? ( angle += 360 )
return angle
}
SetAngle( newAngle := 0 , NewVector := 0 ){
local Angle := This.GetAngle()
, ChangeAngle := newAngle - Angle
, Co := Cos( Vector.DegToRad * ChangeAngle )
, Si := Sin( Vector.DegToRad * ChangeAngle )
, X := This.X
, Y := This.Y
, X2 := X * Co - Y * Si
, Y2 := X * Si + Y * Co
if( !NewVector )
This.X := X2 , This.Y := Y2
else
return New Vector( X2 , Y2 )
}
RotateAngle( rotationAmount := 90 , NewVector := 0 ){
local Co := Cos( Vector.DegToRad * rotationAmount )
, Si := Sin( Vector.DegToRad * rotationAmount )
, X := This.X
, Y := This.Y
, X2 := X * Co - Y * Si
, Y2 := X * Si + Y * Co
if( !NewVector )
This.X := X2 , This.Y := Y2
else
return New Vector( X2 , Y2 )
}
;********************************************
;class methods
TestLineInterceptPoint( interceptPoint , Line1 , Line2 ){ ; Line = { Start: { X: , Y: } , End: { X: , Y: } } , interceptPoint = { X: , Y: }
local
for k , v in [ "X" , "Y" ]
M%v%_Min := min( Line1.Start[ v ] , Line1.End[ v ] )
,M%v%_Max := max( Line1.Start[ v ] , Line1.End[ v ] )
,L%v%_Min := min( Line2.Start[ v ] , Line2.End[ v ] )
,L%v%_Max := max( Line2.Start[ v ] , Line2.End[ v ] )
if( !( interceptPoint.X < Mx_Min || interceptPoint.X > Mx_Max || interceptPoint.X < Lx_Min || interceptPoint.X > Lx_Max ) && !( interceptPoint.Y < My_Min || interceptPoint.Y > My_Max || interceptPoint.Y < Ly_Min || interceptPoint.Y > Ly_Max ) )
return 1
return 0
}
GetLineInterceptPoint( Line1 , Line2 ){ ; Line = { Start: { X: , Y: } , End: { X: , Y: } }
local A1 := Line1.End.Y - Line1.Start.Y
,B1 := Line1.Start.X - Line1.End.X
,C1 := A1 * Line1.Start.X + B1 * Line1.Start.Y
,A2 := Line2.End.Y - Line2.Start.Y
,B2 := Line2.Start.X - Line2.End.X
,C2 := A2 * Line2.Start.X + B2 * Line2.Start.Y
,Denominator := A1 * B2 - A2 * B1
return New Vector( { X: ( ( B2 * C1 - B1 * C2 ) / Denominator ) , Y: ( ( A1 * C2 - A2 * C1 ) / Denominator ) } )
}
;********************************************
}
;**************************************************************************************************************************************************************************
;00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000
;00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000
;00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000
;**************************************************************************************************************************************************************************