Examples of Non-Standard GUIs (ActiveX, GDI, etc.)

Post your working scripts, libraries and tools for AHK v1.1 and older
User avatar
Hellbent
Posts: 2102
Joined: 23 Sep 2017, 13:34

Re: Examples of Non-Standard GUIs (ActiveX, GDI, etc.)

Post by Hellbent » 29 Nov 2021, 17:56

@lblb Thank you very much.

To be honest, I'm not all that well versed in GDIP.
I have never bothered to even try to look at the C++ stuff since I wouldn't know where to start in determining what I should do with it.
I only play around with the stuff that is translated into AHK through the GDIP lib for ahk and there are still many functions in it that I have no idea what they are for and others that I know what they do (more or less) but I haven't bothered to start using them yet.

With that said, here are a few tips from one newb to another.

Often my goal is to draw something on a window or on the screen, well there are a number of ways to draw to a window. So learning as many methods of getting a image onto the screen gives you more options when starting a project.

Typically you use images in two forms. One is the hBitmap and the other is the pBitmap. Learn how to switch between both and how to do cleanup for both. Knowing which to use is provided on a case by case basis and you can just follow along without really having to understand what the difference is.

*analogy breaks down with this next part.
Typically you draw to something called graphics. often you will do this in a sort of cycle.
First you clear the graphics (if something had already been added), next you draw what you want to the graphics, and lastly you update the control / window with the graphics.
This draw cycle can be used in a draw loop where changes in the display can be made over time.

Lastly, I mostly use gdip to draw shapes, so knowing the different shapes that are available and the different types of brushes
is critical to getting anything done. I started out with just trying to make a gui using as many brushes and shapes as I could and seeing what changing some of the different values did. Funny enough, I learnt much of the drawing aspects of gdip only after I made my bitmap maker, which is kind of crazy tbh.

I wish I could offer more, but until someone makes a video series on the subject, I sort of just make stuff up as I go along and pick up little bits and pieces here and there.

User avatar
Hellbent
Posts: 2102
Joined: 23 Sep 2017, 13:34

Re: Examples of Non-Standard GUIs (ActiveX, GDI, etc.)

Post by Hellbent » 30 Nov 2021, 11:21

This shows a bit of the limited development I have done at creating a edit control for a layered window.

I haven't done much work on it yet but it is showing promise. Here is the related thread.
viewtopic.php?f=76&t=92270
If anyone has ever done any work on a edit control like this before or if you think you have something to add, please do.


I just used a bit of duct tape to add the edit control in.
Temp (1).gif
Temp (1).gif (233.92 KiB) Viewed 4963 times

lblb
Posts: 190
Joined: 30 Sep 2013, 11:31

Re: Examples of Non-Standard GUIs (ActiveX, GDI, etc.)

Post by lblb » 06 Dec 2021, 02:18

@Hellbent

What a great reply! Thanks for taking the time to write this, this information is very helpful.

fmildemberger
Posts: 29
Joined: 22 Jan 2014, 10:31

Re: Examples of Non-Standard GUIs (ActiveX, GDI, etc.)

Post by fmildemberger » 15 Dec 2021, 12:07

My God, it's excellent!

User avatar
Hellbent
Posts: 2102
Joined: 23 Sep 2017, 13:34

Re: Examples of Non-Standard GUIs (ActiveX, GDI, etc.)

Post by Hellbent » 05 Feb 2022, 12:31

GDI+
Scalable Arrow Button Set. ( early draft , Windows 8+ )

.
Animation.gif
Animation.gif (441.43 KiB) Viewed 4588 times
.

Code: Select all

;****************************************************************************************************************************************************************************
#Include <My Altered GDIP lib>
#Include <PopUpWindow_V2> 
;****************************************************************************************************************************************************************************
#SingleInstance, Force
SetBatchlines, -1
CoordMode, Mouse, Screen
#NoEnv
GDIP_STARTUP()

Gui1 := New PopUpWindow( { AutoShow: 1 , X: 0 , Y: 0 , W: 300 , H: 200 , Options: " -DPIScale +AlwaysOnTop " } )
Gui1.PaintBackground( color := "0x66FF0000" , 1 )  

Gui, % "1:+AlwaysOnTop +Owner" Gui1.Hwnd
Gui, 1:Color, 22262a
Gui, 1:Show, w600 h500

Bob := New PositionButtons( { Scale: 3 , Parent: 1 , X: 0 , Y: 0 , Bind: [ Func("MoveUp").Bind( Gui1 ) , Func("MoveDown").Bind( Gui1 ) , Func("MoveLeft").Bind( Gui1 ) , Func("MoveRight").Bind( Gui1 ) ] } )
Bob2 := New PositionButtons( { Parent: 1 , X: 20 , Y: 300 , Bind: [ Func("MoveUp").Bind( Gui1 ) , Func("MoveDown").Bind( Gui1 ) , Func("MoveLeft").Bind( Gui1 ) , Func("MoveRight").Bind( Gui1 ) ] } )
Bob3 := New PositionButtons( { Scale: 0.5 , Parent: 1 , X: 20 , Y: 850 , Bind: [ Func("MoveUp").Bind( Gui1 ) , Func("MoveDown").Bind( Gui1 ) , Func("MoveLeft").Bind( Gui1 ) , Func("MoveRight").Bind( Gui1 ) ] } )

return
GuiClose:
GuiContextMenu:
*ESC::ExitApp

RAlt::PopUpWindow.Helper()
	
MoveLeft( obj ){
	( GetKeyState( "ctrl" ) ) ? ( obj.X -= 100 ) : ( GetKeyState( "Shift" ) ) ? ( obj.X -= 10 ) : ( obj.X -= 1 )
	obj.UpdateSettings()
	obj.ShowWindow()
}
MoveRight( obj ){
	( GetKeyState( "ctrl" ) ) ? ( obj.X += 100 ) : ( GetKeyState( "Shift" ) ) ? ( obj.X += 10 ) : ( obj.X += 1 )
	obj.UpdateSettings()
	obj.ShowWindow()
}
MoveUp( obj ){
	( GetKeyState( "ctrl" ) ) ? ( obj.Y -= 100 ) : ( GetKeyState( "Shift" ) ) ? ( obj.Y -= 10 ) : ( obj.Y -= 1 )
	obj.UpdateSettings()
	obj.ShowWindow()
}
MoveDown( obj ){
	( GetKeyState( "ctrl" ) ) ? ( obj.Y += 100 ) : ( GetKeyState( "Shift" ) ) ? ( obj.Y += 10 ) : ( obj.Y += 1 )
	obj.UpdateSettings()
	obj.ShowWindow()
}

;**************************************************************************************************************************************************************************************************************
;**************************************************************************************************************************************************************************************************************
;**************************************************************************************************************************************************************************************************************
;**************************************************************************************************************************************************************************************************************
;Written By: Hellbent
;Date: Jan 22nd, 2022
class PositionButtons	{
	__New( obj := "" ){
		This._SetDefaults()
		This._UpdateDefaults( obj )
		This._CreateWindow()
		This._GraphicsSetup()
		This._AddControls()
		This._BindControls()
		This.ShowControl()
		This.UpdateControl()
		This._SetHoverTimer()
	}
	_SetDefaults(){
		This.Smoothing := 2
		This.InterpolationMode := 7
		This.hbm := ""
		This.Hwnd := ""
		This.hdc := ""
		This.obm := ""
		This.G := ""
		This.WindowOptions := " +LastFound +E0x80000 hwndhwnd -Caption "
		This.Scale := 1
		This.Width := 204 
		This.Height := 109 
		This.X := 10 
		This.Y := 10 
		This.Controls := []
		This.Handles := []
		This.Controls[ 1 ] := { X: 63 * This.Scale , Y: 15 * This.Scale , W: 78 * This.Scale , H: 40 * This.Scale }
		This.Controls[ 2 ] := { X: 63 * This.Scale , Y: 56 * This.Scale , W: 78 * This.Scale , H: 40 * This.Scale }
		This.Controls[ 3 ] := { X: 20 * This.Scale , Y: 28 * This.Scale , W: 40 * This.Scale , H: 56 * This.Scale }
		This.Controls[ 4 ] := { X: 148 * This.Scale , Y: 28 * This.Scale , W: 40 * This.Scale , H: 56 * This.Scale }
		This.Bind := []
		This.XOffset := 38
		This.YOffset := 18
		This.ButtonTopHighlightColor := "0xFF3399FF"
		This.ButtonBottomHighlightColor := "0x66336699"
		This.HoverTimer := This._MouseHover.Bind( This )
		
	}
	_UpdateDefaults( obj := "" ){
		local k , v , index := 0
		for k, v in obj	{
			if( IsObject( obj[ k ] ) ){
				for i, j in obj[ k ]	{
					This[ k , i ] := obj[ k , i ]
				}
			}else{
				This[ k ] := obj[ k ] 
			}
		}
	
		This._Scale()
	}
	_Scale(){
		This.Width := 204 * This.Scale
		This.Height := 109 * This.Scale
		This.X *= This.Scale
		This.Y *= This.Scale
		This.Controls[ 1 ] := { X: 63 * This.Scale , Y: 15 * This.Scale , W: 78 * This.Scale , H: 40 * This.Scale }
		This.Controls[ 2 ] := { X: 63 * This.Scale , Y: 56 * This.Scale , W: 78 * This.Scale , H: 40 * This.Scale }
		This.Controls[ 3 ] := { X: 20 * This.Scale , Y: 28 * This.Scale , W: 40 * This.Scale , H: 56 * This.Scale }
		This.Controls[ 4 ] := { X: 148 * This.Scale , Y: 28 * This.Scale , W: 40 * This.Scale , H: 56 * This.Scale }
	}
	_SetHoverTimer( state := "" ){
		local HoverTimer := This.HoverTimer
		SetTimer, % HoverTimer , % ( state = "" ) ? ( 60 ) : ( State )
	}
	_MouseHover(){
		static index := 0
		MouseGetPos,,,, ctrl, 2
		if( This.Handles[ ctrl ] && !This.Active ){
			This.Active := This.Handles[ ctrl ]
			This.UpdateControl()
		}else if( This.Active && This.Handles[ ctrl ] != This.Active && !This.Active := "" ){
			This.UpdateControl()
		}
	}
	_OnClick(){
		This._SetHoverTimer( "Off" )
		This.Pressed := This.Handles[ This._GetControlHwnd() ]
		This.Active := ""
		This.UpdateControl()
		While( GetKeyState( "LButton" ) )
			sleep, 60
		if( This.Pressed != This.Handles[ This._GetControlHwnd() ] ){
			This.Pressed := ""
			This.Active := This.Handles[ This._GetControlHwnd() ]
			This.UpdateControl()
			This._SetHoverTimer()
		}else{
			This.Pressed := ""
			This.Active := This.Handles[ This._GetControlHwnd() ]
			This.UpdateControl()
			if( This.Bind[ This.Active ] ){
				try{
					This.Bind[ This.Active ].Call()
					This._SetHoverTimer()
					return
				}
				try{
					This._SetHoverTimer()
					gosub, % This.Bind[ This.Active ]
					return
				}
			}
		}
	}
	_GetControlHwnd(){
		local ctrl
		MouseGetPos,,,, ctrl, 2
		return ctrl
	}
	_CreateWindow(){
		local hwnd
		Gui , New, % This.WindowOptions " +Parent" This.Parent 
		This.Hwnd := hwnd
	}
	_GraphicsSetup(){
		This.hbm := CreateDIBSection( This.Width , This.Height )
		This.hdc := CreateCompatibleDC()
		This.obm := SelectObject( This.hdc , This.hbm )
		This.G := Gdip_GraphicsFromHDC( This.hdc )
		Gdip_SetSmoothingMode( This.G , This.Smoothing )
		Gdip_SetInterpolationMode( This.G , This.InterpolationMode )
	}
	_AddControls(){
		local hwnd
		loop, 4	{
			Gui, % This.Hwnd ":Add", Text, % "x" This.Controls[ A_Index ].X " y" This.Controls[ A_Index ].Y " w" This.Controls[ A_Index ].W " h" This.Controls[ A_Index ].H " hwndhwnd"
			This.Controls[ A_Index ].Hwnd := hwnd
			This.Handles[ hwnd ] := A_Index
		}
	}
	_BindControls(){
		local bd := This._OnClick.Bind( This )
		Loop, 4	
			GuiControl, % This.Hwnd ":+G" , % This.Controls[ A_Index ].Hwnd , % bd
	}
	ShowControl(){
		Gui, % This.Hwnd ":Show",
	}
	_ClearWindow(){
		Gdip_GraphicsClear( This.G )
	}
	_UpdateWindow(){
		UpdateLayeredWindow( This.hwnd , This.hdc , This.X , This.Y , This.Width , This.Height )
	}
	UpdateControl(){
		This._ClearWindow()
		This.DrawControlBitmap()
		This._UpdateWindow()
	}
	DrawControlBitmap(){
		;background left 
		Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_FillEllipse( This.G , Brush , ( 40 - This.XOffset ) * This.Scale , ( 20 - This.YOffset ) * This.Scale , 200 * This.Scale , 105 * This.Scale ) , Gdip_DeleteBrush( Brush )
		;inner circle
		Brush := Gdip_CreateLineBrushFromRect( ( 40 - This.XOffset ) * This.Scale , ( 25 - This.YOffset ) * This.Scale , 190 * This.Scale , 79 * This.Scale , "0xFF72767a" , "0xFF000000" , 1 , 1 ) , Gdip_FillEllipse( This.G , Brush , ( 45 - This.XOffset ) * This.Scale , ( 26 - This.YOffset ) * This.Scale , 190 * This.Scale , 94 * This.Scale ) , Gdip_DeleteBrush( Brush )
		;***************************************************************************************************************************
		;***************************************************************************************************************************
		;Button 1
		if( This.Pressed = 1 )
			Brush := Gdip_CreateLineBrushFromRect( ( 102 - This.XOffset ) * This.Scale , ( 34 - This.YOffset ) * This.Scale , 77 * This.Scale , 33 * This.Scale , "0xFF12161a" , "0xFF22262a" , 1 , 1 ) , Gdip_FillRoundedRectangle( This.G , Brush , ( 103 - This.XOffset ) * This.Scale , ( 35 - This.YOffset ) * This.Scale , 74 * This.Scale , 36 * This.Scale , 5 * This.Scale ) , Gdip_DeleteBrush( Brush )
		else	
			Brush := Gdip_CreateLineBrushFromRect( ( 102 - This.XOffset ) * This.Scale , ( 34 - This.YOffset ) * This.Scale , 77 * This.Scale , 33 * This.Scale , "0xFF32363a" , "0xFF22262a" , 1 , 1 ) , Gdip_FillRoundedRectangle( This.G , Brush , ( 103 - This.XOffset ) * This.Scale , ( 35 - This.YOffset ) * This.Scale , 74 * This.Scale , 36 * This.Scale , 5 * This.Scale ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_CreateLineBrushFromRect( ( 103 - This.XOffset ) * This.Scale , ( 33 - This.YOffset ) * This.Scale , 77 * This.Scale , 36 * This.Scale , "0xFF3F4752" , "0xFF1C2024" , 1 , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 1 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawRoundedRectangle( This.G , Pen , ( 103 - This.XOffset ) * This.Scale , ( 35 - This.YOffset ) * This.Scale , 74 * This.Scale , 36 * This.Scale , 5 * This.Scale ) , Gdip_DeletePen( Pen )

		if( This.Pressed = 1 ){
			Brush := Gdip_BrushCreateSolid( "0xAA3399FF" ) , Gdip_FillRectangle( This.G , Brush , ( 106 - This.XOffset ) * This.Scale , ( 38 - This.YOffset ) * This.Scale , 68 * This.Scale , 15 * This.Scale ) , Gdip_DeleteBrush( Brush )
			Brush := Gdip_BrushCreateSolid( "0x99336699" ) , Gdip_FillRectangle( This.G , Brush , ( 106 - This.XOffset ) * This.Scale , ( 53 - This.YOffset ) * This.Scale , 68 * This.Scale , 15 * This.Scale ) , Gdip_DeleteBrush( Brush )
		}else if( This.Active = 1 ){
			Brush := Gdip_BrushCreateSolid( "0x993399FF" ) , Gdip_FillRectangle( This.G , Brush , ( 106 - This.XOffset ) * This.Scale , ( 38 - This.YOffset ) * This.Scale , 68 * This.Scale , 15 * This.Scale ) , Gdip_DeleteBrush( Brush )
			Brush := Gdip_BrushCreateSolid( "0x66336699" ) , Gdip_FillRectangle( This.G , Brush , ( 106 - This.XOffset ) * This.Scale , ( 53 - This.YOffset ) * This.Scale , 68 * This.Scale , 15 * This.Scale ) , Gdip_DeleteBrush( Brush )
		}else{
			Brush := Gdip_BrushCreateSolid( "0x66F0F0F0" ) , Gdip_FillRectangle( This.G , Brush , ( 106 - This.XOffset ) * This.Scale , ( 38 - This.YOffset ) * This.Scale , 68 * This.Scale , 15 * This.Scale ) , Gdip_DeleteBrush( Brush )
			Brush := Gdip_BrushCreateSolid( "0x66000000" ) , Gdip_FillRectangle( This.G , Brush , ( 106 - This.XOffset ) * This.Scale , ( 53 - This.YOffset ) * This.Scale , 68 * This.Scale , 15 * This.Scale ) , Gdip_DeleteBrush( Brush )
		}
		if( This.Pressed = 1 )
			Brush := Gdip_BrushCreateSolid( "0xFFF0F0F0" ) , Gdip_TextToGraphics( This.G , "5" , "s" 22 * This.Scale " Center vCenter  c" Brush " x" ( 104 - This.XOffset ) * This.Scale " y" ( 37 - This.YOffset ) * This.Scale , "Webdings" , 74 * This.Scale , 36 * This.Scale ) , Gdip_DeleteBrush( Brush )
		else	
			Brush := Gdip_BrushCreateSolid( "0xFFF0F0F0" ) , Gdip_TextToGraphics( This.G , "5" , "s" 22 * This.Scale " Center vCenter  c" Brush " x" ( 104 - This.XOffset ) * This.Scale " y" ( 36 - This.YOffset ) * This.Scale , "Webdings" , 74 * This.Scale , 36 * This.Scale ) , Gdip_DeleteBrush( Brush )
		;***************************************************************************************************************************
		;***************************************************************************************************************************
		;Button 2
		
		
		
		if( This.Pressed = 2 ){
			Brush := Gdip_CreateLineBrushFromRect( ( 107 - This.XOffset ) * This.Scale , ( 78 - This.YOffset ) * This.Scale , 70 * This.Scale , 36 * This.Scale , "0xFF12161a" , "0xFF22262a" , 1 , 1 ) , Gdip_FillRoundedRectangle( This.G , Brush , ( 103 - This.XOffset ) * This.Scale , ( 76 - This.YOffset ) * This.Scale , 74 * This.Scale , 36 * This.Scale , 5 * This.Scale ) , Gdip_DeleteBrush( Brush )
			Brush := Gdip_CreateLineBrushFromRect( ( 103 - This.XOffset ) * This.Scale , ( 79 - This.YOffset ) * This.Scale , 74 * This.Scale , 35 * This.Scale , "0xFF02050a" , "0xFF22262a" , 1 , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 1 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawRoundedRectangle( This.G , Pen , ( 103 - This.XOffset ) * This.Scale , ( 76 - This.YOffset ) * This.Scale , 74 * This.Scale , 36 * This.Scale , 5 * This.Scale ) , Gdip_DeletePen( Pen )
		}else{
			Brush := Gdip_CreateLineBrushFromRect( ( 107 - This.XOffset ) * This.Scale , ( 78 - This.YOffset ) * This.Scale , 70 * This.Scale , 36 * This.Scale , "0xFF32363a" , "0xFF22262a" , 1 , 1 ) , Gdip_FillRoundedRectangle( This.G , Brush , ( 103 - This.XOffset ) * This.Scale , ( 76 - This.YOffset ) * This.Scale , 74 * This.Scale , 36 * This.Scale , 5 * This.Scale ) , Gdip_DeleteBrush( Brush )
			Brush := Gdip_CreateLineBrushFromRect( ( 103 - This.XOffset ) * This.Scale , ( 79 - This.YOffset ) * This.Scale , 74 * This.Scale , 35 * This.Scale , "0xFF3F4752" , "0xFF1C2024" , 1 , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 1 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawRoundedRectangle( This.G , Pen , ( 103 - This.XOffset ) * This.Scale , ( 76 - This.YOffset ) * This.Scale , 74 * This.Scale , 36 * This.Scale , 5 * This.Scale ) , Gdip_DeletePen( Pen )
		}
		if( This.Pressed = 2 ){
			Brush := Gdip_BrushCreateSolid( "0xAA3399FF" ) , Gdip_FillRectangle( This.G , Brush , ( 106 - This.XOffset ) * This.Scale , ( 79 - This.YOffset ) * This.Scale , 68 * This.Scale , 15 * This.Scale ) , Gdip_DeleteBrush( Brush )
			Brush := Gdip_BrushCreateSolid( "0x99336699" ) , Gdip_FillRectangle( This.G , Brush , ( 106 - This.XOffset ) * This.Scale , ( 94 - This.YOffset ) * This.Scale , 68 * This.Scale , 15 * This.Scale ) , Gdip_DeleteBrush( Brush )
		}else if( This.Active = 2 ){
			Brush := Gdip_BrushCreateSolid( "0x993399FF" ) , Gdip_FillRectangle( This.G , Brush , ( 106 - This.XOffset ) * This.Scale , ( 79 - This.YOffset ) * This.Scale , 68 * This.Scale , 15 * This.Scale ) , Gdip_DeleteBrush( Brush )
			Brush := Gdip_BrushCreateSolid( "0x66336699" ) , Gdip_FillRectangle( This.G , Brush , ( 106 - This.XOffset ) * This.Scale , ( 94 - This.YOffset ) * This.Scale , 68 * This.Scale , 15 * This.Scale ) , Gdip_DeleteBrush( Brush )
		}else{
			Brush := Gdip_BrushCreateSolid( "0x66F0F0F0" ) , Gdip_FillRectangle( This.G , Brush , ( 106 - This.XOffset ) * This.Scale , ( 79 - This.YOffset ) * This.Scale , 68 * This.Scale , 15 * This.Scale ) , Gdip_DeleteBrush( Brush )
			Brush := Gdip_BrushCreateSolid( "0x66000000" ) , Gdip_FillRectangle( This.G , Brush , ( 106 - This.XOffset ) * This.Scale , ( 94 - This.YOffset ) * This.Scale , 68 * This.Scale , 15 * This.Scale ) , Gdip_DeleteBrush( Brush )
		}
		if( This.Pressed = 2 )
			Brush := Gdip_BrushCreateSolid( "0xFFF0F0F0" ) , Gdip_TextToGraphics( This.G , "6" , "s" 22 * This.Scale " Center vCenter  c" Brush " x" ( 104 - This.XOffset ) * This.Scale " y" ( 77 - This.YOffset ) * This.Scale , "Webdings" , 74 * This.Scale , 36 * This.Scale ) , Gdip_DeleteBrush( Brush )
		else
			Brush := Gdip_BrushCreateSolid( "0xFFF0F0F0" ) , Gdip_TextToGraphics( This.G , "6" , "s" 22 * This.Scale " Center vCenter  c" Brush " x" ( 104 - This.XOffset ) * This.Scale " y" ( 76 - This.YOffset ) * This.Scale , "Webdings" , 74 * This.Scale , 36 * This.Scale ) , Gdip_DeleteBrush( Brush )
		;***************************************************************************************************************************
		;***************************************************************************************************************************
		;Button 3
		if( This.Pressed = 3 ){
			Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_FillPie( This.G , Brush , ( 49 - This.XOffset ) * This.Scale , ( 39 - This.YOffset ) * This.Scale , 95 * This.Scale , 70 * This.Scale , 90 , 180 ) , Gdip_DeleteBrush( Brush )
			Brush := Gdip_CreateLineBrushFromRect( ( 51 - This.XOffset ) * This.Scale , ( 44 - This.YOffset ) * This.Scale , 44 * This.Scale , 65 * This.Scale , "0xFF12161a" , "0xFF22262a" , 1 , 1 ) , Gdip_FillPie( This.G , Brush , ( 51 - This.XOffset ) * This.Scale , ( 41 - This.YOffset ) * This.Scale , 89 * This.Scale , 66 * This.Scale , 90 , 180 ) , Gdip_DeleteBrush( Brush )
		}else{
			Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_FillPie( This.G , Brush , ( 49 - This.XOffset ) * This.Scale , ( 39 - This.YOffset ) * This.Scale , 95 * This.Scale , 70 * This.Scale , 90 , 180 ) , Gdip_DeleteBrush( Brush )
			Brush := Gdip_CreateLineBrushFromRect( ( 51 - This.XOffset ) * This.Scale , ( 44 - This.YOffset ) * This.Scale , 44 * This.Scale , 65 * This.Scale , "0xFF32363a" , "0xFF22262a" , 1 , 1 ) , Gdip_FillPie( This.G , Brush , ( 51 - This.XOffset ) * This.Scale , ( 41 - This.YOffset ) * This.Scale , 89 * This.Scale , 66 * This.Scale , 90 , 180 ) , Gdip_DeleteBrush( Brush )
		}
		if( This.Pressed = 3 )
			Brush := Gdip_BrushCreateSolid( "0xAA3399FF" ) , Gdip_FillPie( This.G , Brush , ( 53 - This.XOffset ) * This.Scale , ( 44 - This.YOffset ) * This.Scale , 81 * This.Scale , 59 * This.Scale , 180 , 90 ) , Gdip_DeleteBrush( Brush )
		else if( This.Active = 3 )
			Brush := Gdip_BrushCreateSolid( "0x993399FF" ) , Gdip_FillPie( This.G , Brush , ( 53 - This.XOffset ) * This.Scale , ( 44 - This.YOffset ) * This.Scale , 81 * This.Scale , 59 * This.Scale , 180 , 90 ) , Gdip_DeleteBrush( Brush )
		else 
			Brush := Gdip_BrushCreateSolid( "0x66F0F0F0" ) , Gdip_FillPie( This.G , Brush , ( 53 - This.XOffset ) * This.Scale , ( 44 - This.YOffset ) * This.Scale , 81 * This.Scale , 59 * This.Scale , 180 , 90 ) , Gdip_DeleteBrush( Brush )
		if( This.Pressed = 3 )
			Brush := Gdip_BrushCreateSolid( "0x99336699" ) , Gdip_FillPie( This.G , Brush , ( 53 - This.XOffset ) * This.Scale , ( 44 - This.YOffset ) * This.Scale , 81 * This.Scale , 59 * This.Scale , 90 , 90 ) , Gdip_DeleteBrush( Brush )
		else if( This.Active = 3 )
			Brush := Gdip_BrushCreateSolid( "0x66336699" ) , Gdip_FillPie( This.G , Brush , ( 53 - This.XOffset ) * This.Scale , ( 44 - This.YOffset ) * This.Scale , 81 * This.Scale , 59 * This.Scale , 90 , 90 ) , Gdip_DeleteBrush( Brush )
		else
			Brush := Gdip_BrushCreateSolid( "0x66000000" ) , Gdip_FillPie( This.G , Brush , ( 53 - This.XOffset ) * This.Scale , ( 44 - This.YOffset ) * This.Scale , 81 * This.Scale , 59 * This.Scale , 90 , 90 ) , Gdip_DeleteBrush( Brush )
		if( This.Pressed = 3 )
			Brush := Gdip_BrushCreateSolid( "0xFFF0F0F0" ) , Gdip_TextToGraphics( This.G , "3" , "s" 22 * This.Scale " Center vCenter  c" Brush " x" ( 49 - This.XOffset ) * This.Scale " y" ( 40 - This.YOffset ) * This.Scale , "Webdings" , 55 * This.Scale , 70 * This.Scale ) , Gdip_DeleteBrush( Brush )
		else	
			Brush := Gdip_BrushCreateSolid( "0xFFF0F0F0" ) , Gdip_TextToGraphics( This.G , "3" , "s" 22 * This.Scale " Center vCenter  c" Brush " x" ( 49 - This.XOffset ) * This.Scale " y" ( 39 - This.YOffset ) * This.Scale , "Webdings" , 55 * This.Scale , 70 * This.Scale ) , Gdip_DeleteBrush( Brush )
		;***************************************************************************************************************************
		;***************************************************************************************************************************
		;Button 4
		if( This.Pressed = 4 ){
			Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_FillPie( This.G , Brush , ( 136 - This.XOffset ) * This.Scale , ( 39 - This.YOffset ) * This.Scale , 95 * This.Scale , 70 * This.Scale , 90 , -180 ) , Gdip_DeleteBrush( Brush )
			Brush := Gdip_CreateLineBrushFromRect( ( 51 - This.XOffset ) * This.Scale , ( 44 - This.YOffset ) * This.Scale , 44 * This.Scale , 65 * This.Scale , "0xFF12161a" , "0xFF22262a" , 1 , 1 ) , Gdip_FillPie( This.G , Brush , ( 140 - This.XOffset ) * This.Scale , ( 41 - This.YOffset ) * This.Scale , 89 * This.Scale , 66 * This.Scale , 90 , -180 ) , Gdip_DeleteBrush( Brush )
		}else{
			Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_FillPie( This.G , Brush , ( 136 - This.XOffset ) * This.Scale , ( 39 - This.YOffset ) * This.Scale , 95 * This.Scale , 70 * This.Scale , 90 , -180 ) , Gdip_DeleteBrush( Brush )
			Brush := Gdip_CreateLineBrushFromRect( ( 51 - This.XOffset ) * This.Scale , ( 44 - This.YOffset ) * This.Scale , 44 * This.Scale , 65 * This.Scale , "0xFF32363a" , "0xFF22262a" , 1 , 1 ) , Gdip_FillPie( This.G , Brush , ( 140 - This.XOffset ) * This.Scale , ( 41 - This.YOffset ) * This.Scale , 89 * This.Scale , 66 * This.Scale , 90 , -180 ) , Gdip_DeleteBrush( Brush )
		}
		if( This.Pressed = 4 ){
			Brush := Gdip_BrushCreateSolid( "0xAA3399FF" ) , Gdip_FillPie( This.G , Brush , ( 146 - This.XOffset ) * This.Scale , ( 44 - This.YOffset ) * This.Scale , 81 * This.Scale , 59 * This.Scale , -90 , 90 ) , Gdip_DeleteBrush( Brush )
			Brush := Gdip_BrushCreateSolid( "0x99336699" ) , Gdip_FillPie( This.G , Brush , ( 146 - This.XOffset ) * This.Scale , ( 44 - This.YOffset ) * This.Scale , 81 * This.Scale , 59 * This.Scale , 90 , -90 ) , Gdip_DeleteBrush( Brush )
		}else if( This.Active = 4 ){
			Brush := Gdip_BrushCreateSolid( "0x993399FF" ) , Gdip_FillPie( This.G , Brush , ( 146 - This.XOffset ) * This.Scale , ( 44 - This.YOffset ) * This.Scale , 81 * This.Scale , 59 * This.Scale , -90 , 90 ) , Gdip_DeleteBrush( Brush )
			Brush := Gdip_BrushCreateSolid( "0x66336699" ) , Gdip_FillPie( This.G , Brush , ( 146 - This.XOffset ) * This.Scale , ( 44 - This.YOffset ) * This.Scale , 81 * This.Scale , 59 * This.Scale , 90 , -90 ) , Gdip_DeleteBrush( Brush )
		}else{
			Brush := Gdip_BrushCreateSolid( "0x66F0F0F0" ) , Gdip_FillPie( This.G , Brush , ( 146 - This.XOffset ) * This.Scale , ( 44 - This.YOffset ) * This.Scale , 81 * This.Scale , 59 * This.Scale , -90 , 90 ) , Gdip_DeleteBrush( Brush )
			Brush := Gdip_BrushCreateSolid( "0x66000000" ) , Gdip_FillPie( This.G , Brush , ( 146 - This.XOffset ) * This.Scale , ( 46 - This.YOffset ) * This.Scale , 81 * This.Scale , 59 * This.Scale , 90 , -90 ) , Gdip_DeleteBrush( Brush )
		}
		if( This.Pressed = 4 )
			Brush := Gdip_BrushCreateSolid( "0xFFF0F0F0" ) , Gdip_TextToGraphics( This.G , "4" , "s" 22 * This.Scale " Center vCenter  c" Brush " x" ( 179 - This.XOffset ) * This.Scale " y" ( 40 - This.YOffset ) * This.Scale , "Webdings" , 55 * This.Scale , 70 * This.Scale ) , Gdip_DeleteBrush( Brush )
		else
			Brush := Gdip_BrushCreateSolid( "0xFFF0F0F0" ) , Gdip_TextToGraphics( This.G , "4" , "s" 22 * This.Scale " Center vCenter  c" Brush " x" ( 179 - This.XOffset ) * This.Scale " y" ( 39 - This.YOffset ) * This.Scale , "Webdings" , 55 * This.Scale , 70 * This.Scale ) , Gdip_DeleteBrush( Brush )
		;inner circle  
		;***************************************************************************************************************************
		;***************************************************************************************************************************
		;~ Brush := Gdip_BrushCreateSolid( "0x2266AAFF" ) , Gdip_FillEllipse( This.G , Brush , ( 45 - This.XOffset ) * This.Scale , ( 26 - This.YOffset ) * This.Scale , 190 * This.Scale , 94 * This.Scale ) , Gdip_DeleteBrush( Brush )
	}
}
;**************************************************************************************************************************************************************************************************************
;**************************************************************************************************************************************************************************************************************
;**************************************************************************************************************************************************************************************************************
;**************************************************************************************************************************************************************************************************************

burque505
Posts: 1731
Joined: 22 Jan 2017, 19:37

Re: Examples of Non-Standard GUIs (ActiveX, GDI, etc.)

Post by burque505 » 05 Feb 2022, 12:57

@Hellbent, that is really, really slick. Thank you! :bravo:
Regards,
burque505

User avatar
Hellbent
Posts: 2102
Joined: 23 Sep 2017, 13:34

Re: Examples of Non-Standard GUIs (ActiveX, GDI, etc.)

Post by Hellbent » 05 Feb 2022, 13:25

Thanks @burque505. Hope you are doing well.


Here's another one.

Scalable custom DropDownList controls.

version 1.
Animation.gif
Animation.gif (382.93 KiB) Viewed 4559 times
version 2.
Animation.gif
Animation.gif (400.11 KiB) Viewed 4559 times

User avatar
emrekarahan0001
Posts: 25
Joined: 18 Jan 2021, 14:19

Re: Examples of Non-Standard GUIs (ActiveX, GDI, etc.)

Post by emrekarahan0001 » 06 Feb 2022, 17:27

Maybe it will be of use to someone. 8-)

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; 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.
FileCreateDir, C:\SMenu\PicTure
Sleep, 1000

F0 = https://imgur.com/laCqoqu.png
SMenu = C:\SMenu\PicTure\SMenu-Main.png
ifnotexist,%SMenu%
   urldownloadtofile,%f0%,%SMenu%

Chrome0 = https://imgur.com/jLU9hhk.png
Chrome1 = C:\SMenu\PicTure\SMenu-Chrome.png
ifnotexist,%Chrome1%
   urldownloadtofile,%Chrome0%,%Chrome1%

Github0 = https://imgur.com/QBniAt9.png
Github1 = C:\SMenu\PicTure\SMenu_Github.png
ifnotexist,%Github1%
   urldownloadtofile,%Github0%,%Github1%

YouTube0 = https://imgur.com/hIDWJYL.png
YouTube1 = C:\SMenu\PicTure\SMenu_YouTube.png
ifnotexist,%YouTube1%
   urldownloadtofile,%YouTube0%,%YouTube1%

Translate0 = https://imgur.com/iokWEv7.png
Translate1 = C:\SMenu\PicTure\SMenu_Translate.png
ifnotexist,%Translate1%
   urldownloadtofile,%Translate0%,%Translate1%

Voice0 = https://imgur.com/Jr0u0Rc.png
Voice1 = C:\SMenu\PicTure\SMenu_Voice.png
ifnotexist,%Voice1%
   urldownloadtofile,%Voice0%,%Voice1%

CodeRunner0 = https://imgur.com/NtmDDig.png
CodeRunner1 = C:\SMenu\PicTure\SMenu_CodeRunner.png
ifnotexist,%CodeRunner1%
   urldownloadtofile,%CodeRunner0%,%CodeRunner1%

NotePad0 = https://imgur.com/j4NVV8p.png
NotePad1 = C:\SMenu\PicTure\SMenu_NotePad.png
ifnotexist,%NotePad1%
   urldownloadtofile,%NotePad0%,%NotePad1%

DownLoad0 = https://imgur.com/KbLhKC3.png
DownLoad1 = C:\SMenu\PicTure\SMenu_DownLoad.png
ifnotexist,%DownLoad1%
   urldownloadtofile,%DownLoad0%,%DownLoad1%

Twitter0 = https://imgur.com/9EoCCZv.png
Twitter1 = C:\SMenu\PicTure\SMenu_Twitter.png
ifnotexist,%Twitter1%
   urldownloadtofile,%Twitter0%,%Twitter1%

WhatsApp0 = https://imgur.com/EsOFoZf.png
WhatsApp1 = C:\SMenu\PicTure\SMenu_WhatsApp.png
ifnotexist,%WhatsApp1%
   urldownloadtofile,%WhatsApp0%,%WhatsApp1%

Others0 = https://imgur.com/KDLzxNr.png
Others1 = C:\SMenu\PicTure\SMenu_Others.png
ifnotexist,%Others1%
   urldownloadtofile,%Others0%,%Others1%

Gui, -Caption +Owner +AlwaysOnTop
Gui, Add , Picture, x0 y0 w50 h550, %SMenu%
Gui, Add , Picture, x0 y0 w50 h50 vSMenu1 gSMenu1, %Chrome1%
Gui, Add , Picture, x0 y50 w50 h50 vSMenu2 gSMenu2, %Github1%
Gui, Add , Picture, x0 y100 w50 h50 vSMenu3 gSMenu3, %YouTube1%
Gui, Add , Picture, x0 y150 w50 h50 vSMenu4 gSMenu4, %Translate1%
Gui, Add , Picture, x0 y200 w50 h50 vSMenu5 gSMenu5, %Voice1%
Gui, Add , Picture, x0 y250 w50 h50 vSMenu6 gSMenu6, %CodeRunner1%
Gui, Add , Picture, x0 y300 w50 h50 vSMenu7 gSMenu7, %NotePad1%
Gui, Add , Picture, x0 y350 w50 h50 vSMenu8 gSMenu8, %DownLoad1%
Gui, Add , Picture, x0 y400 w50 h50 vSMenu9 gSMenu9, %Twitter1%
Gui, Add , Picture, x0 y450 w50 h50 vSMenu10 gSMenu10, %WhatsApp1%
Gui, Add , Picture, x0 y500 w50 h50 vSMenu11 gSMenu11, %Others1%
Gui, Show, x0 y60 w50 h550, SMenu
Return

SMenu1:
GuiControl, Hide, SMenu1
Sleep, 250
GuiControl, Show, SMenu1
Return

SMenu2:
GuiControl, Hide, SMenu2
Sleep, 250
GuiControl, Show, SMenu2
Return

SMenu3:
GuiControl, Hide, SMenu3
Sleep, 250
GuiControl, Show, SMenu3
Return

SMenu4:
GuiControl, Hide, SMenu4
Sleep, 250
GuiControl, Show, SMenu4
Return

SMenu5:
GuiControl, Hide, SMenu5
Sleep, 250
GuiControl, Show, SMenu5
Return

SMenu6:
GuiControl, Hide, SMenu6
Sleep, 250
GuiControl, Show, SMenu6
Return

SMenu7:
GuiControl, Hide, SMenu7
Sleep, 250
GuiControl, Show, SMenu7
Sleep, 250
Run, NotePad.exe
Sleep, 250
Return

SMenu8:
GuiControl, Hide, SMenu8
Sleep, 250
GuiControl, Show, SMenu8
Return

SMenu9:
GuiControl, Hide, SMenu9
Sleep, 250
GuiControl, Show, SMenu9
Return

SMenu10:
GuiControl, Hide, SMenu10
Sleep, 250
GuiControl, Show, SMenu10
Return

SMenu11:
GuiControl, Hide, SMenu11
Sleep, 250
GuiControl, Show, SMenu11
Return

SMenu12:
GuiControl, Hide, SMenu12
Sleep, 250
GuiControl, Show, SMenu12
Return

ESC:
ExitApp
Return

malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: Examples of Non-Standard GUIs (ActiveX, GDI, etc.)

Post by malcev » 09 Feb 2022, 02:35

@Hellbent Can You show Your code for Scalable custom DropDownList controls?

User avatar
Hellbent
Posts: 2102
Joined: 23 Sep 2017, 13:34

Re: Examples of Non-Standard GUIs (ActiveX, GDI, etc.)

Post by Hellbent » 09 Feb 2022, 12:24

malcev wrote:
09 Feb 2022, 02:35
@Hellbent Can You show Your code for Scalable custom DropDownList controls?
Sure.
It is still an early draft, but I have it just about ready for a project I need it for.
The only major thing I need to tweak is the slider button sizing and scrolling method.

Here is the current method for sizing the slider / scrollbar.
This works fine for a list of under 200 items but I need figure out how I want to deal with cases where I have less than 1px per item.
I can just turn off the auto sizing if the list is too long and just do what I would normally do with a slider, not sure yet either way.

Code: Select all

	if( This.Rows < 8 )
			This.Rows := 8
		This.PanelTextHeight := Floor( This._GetTextSize() )
		This.PanelHeight := This.PanelTextHeight + 2 * This.PanelTextPading
		This.BodyHeight := This.BodyMargin * 2 + ( This.PanelHeight * This.Rows ) + ( This.BodyMargin * ( This.Rows - 1 ) ) + This.PanelStartingPositionY
		This.ThumbMinY := This.PanelStartingPositionY + 2
		This.ThumbRange := This.BodyHeight - This.ThumbMinY - 6 - 2
		This.Interval := Floor( ( This.ThumbRange * This.ScaleFactor) / This.List.Length() )
		This.TotalInterval := This.Interval * This.List.Length()
		This.ThumbHeight := This.ThumbRange - This.TotalInterval
		While( This.Interval > 1 ){
			This.Interval -= 1
			This.TotalInterval := This.Interval * This.List.Length()
			This.ThumbHeight := This.ThumbRange - This.TotalInterval
		}
		This.Thumb := { X: ( This.W - 32 ) , Y: This.ThumbMinY , W: 26 , H: This.ThumbHeight }
		This._MoveThumbControl()
		This.Panels := []
		This.PanelHandles := []
		temp := This.PanelStartingPositionY - 2
		Loop, % This.Rows	{
			This.Panels[ A_Index ] := { X: 4 , Y: temp , W: ( This.W - 34 - 6 ) , H: This.PanelHeight , Hwnd: "" }
			temp += This.PanelHeight + This.BodyMargin
		}
It doesn't currently watch your monitor size ( I don't need it to in my current project ) so it doesn't put the list on top when at the bottom of the screen. I likely won't add that in until the next time I do a rewrite of the class, and that likely won't happen until I have had a chance to use the DDL in a project or two and see what I like and don't like.

It also doesn't have a internal method to set focus using the tab key, I leave that on the user side. (create a list of the controls to focus and cycle through them)

Here is my test code. You can change the scalefactor up near the top.

This current version is adapted to use layered windows for both the header and body ( requires windows 8+ ), it can fairly easily be adapted so that the header can just use a static gui control instead. I needed this to work in a layered window so it is adapted to support them.
Spoiler

Code: Select all

;****************************************************************************************************************************************************************************
#Include <My Altered GDIP lib> ;gdip.ahk
;~ #Include <PopUpWindow_V2> ; At the bottom of the script
;****************************************************************************************************************************************************************************
#SingleInstance, Force
SetBatchlines, -1
;~ SetMouseDelay, 1
;~ CoordMode, Mouse, Screen
#NoEnv
GDIP_STARTUP()


FontList := []
testList := GetFontNames( 1 )
ddlList := ""
for k, v in testList	{
	if( inStr( k , "@" ) ){
		FontList.Push( SubStr( k , 2 ) )
		ddlList .= SubStr( k , 2 ) "|"
	}else{
		FontList.Push( k )
		ddlList .= k "|"
	}
}

fontsize := []
Loop, 30
	FontSize.Push( A_Index + 7 )

Width := 950
Height := 300
ScaleFactor := A_ScreenDPI / 96


Gui, 1:New, +AlwaysOnTop HwndGuiHwnd
Gui, 1:Color, 22262a
Gui, 1:Add, Edit, % "xm y" ( height - 120 ) * ScaleFactor " w" ( Width - 20 ) * ScaleFactor " h70 hwndEdit1Hwnd", Sample Text
Gui, 1:Font, s12
Gui, 1:Add, DDL, % "xm y+10 w"  Width - 20 " choose1 r10 " , % ddlList

Gui, 1:Show, % "w" Width * ScaleFactor " h" height * ScaleFactor


bob := New DropDownListv1( {  EditHwnd: Edit1Hwnd , Bind: "TestFunction" , ScaleFactor: ScaleFactor , W: 400 , FontSize: 12 , Font: "Comic Sans MS" , Parent: GuiHwnd , List: FontList } )
;~ bob := New DropDownListv1( {  EditHwnd: Edit1Hwnd , Bind: "TestFunction" , ScaleFactor: ScaleFactor , W: 400 , FontSize: 12 , Font: "Comic Sans MS" , Parent: GuiHwnd , List: [1,2,3,4] } )
FontSize := New DropDownListv1( { Y: 50 , EditHwnd: Edit1Hwnd , Bind: "ChangeFontSize" , ScaleFactor: ScaleFactor , W: 120 , FontSize: 24 , Font: "Comic Sans MS" , Parent: GuiHwnd , List: FontSize } )



return
GuiClose:
GuiContextMenu:
*ESC::ExitApp

RALT::PopUpWindow.Helper()


	
TestFunction( obj ){
	
	
	Gui, 1:Font, , % obj.List[ obj.Selected ]
	GuiControl, 1:Font, % obj.EditHwnd 
	;~ Clipboard := obj.List[ obj.Selected ]
	
}

ChangeFontSize( obj ){
	
	Gui, 1:Font, % "s" obj.List[ obj.Selected ]
	GuiControl, 1:Font, % obj.EditHwnd 
}

;********************************************************
GetFontNames(charset){ ;https://www.autohotkey.com/boards/viewtopic.php?t=12416#p386353
   hDC := DllCall("GetDC", "UInt", 0, "Ptr")
   VarSetCapacity(LOGFONT, 92, 0)
   NumPut(charset, &LOGFONT + 23, "UChar")
   DllCall("EnumFontFamiliesEx", "Ptr", hDC, "Ptr", 0 , "Ptr", RegisterCallback("EnumFontFamExProc", "F", 4) , "Ptr", pFonts := Object(Fonts := {}), "UInt", 0)
   ObjRelease(pFonts), DllCall("ReleaseDC", "Ptr", 0, "Ptr", hDC)
   Return Fonts
}
EnumFontFamExProc(lpelfe, lpntme, FontType, lParam){
   font := StrGet(lpelfe + 28)
   Object(lParam)[font] := ""
   Return true
}

;******************************************************************************************************************************************************************************************************************
;******************************************************************************************************************************************************************************************************************
;******************************************************************************************************************************************************************************************************************
;******************************************************************************************************************************************************************************************************************
class DropDownListv1	{
	__New( obj := "" ){
		This._SetDefaults()
		This._UpdateDefaults( obj )
		This._CreateWindows()
		This._CreateControls()
		This._DrawHeader()
		This._SetTimer( This.HoverTimer , 100 )
	}
	_SetDefaults(){
		This.Parent := ""
		This.ScaleFactor := 1
		This.X := 10
		This.Y := 10
		This.W := 300
		This.HeaderMargin := 5
		This.Font := "Arial"
		This.FontSize := 12
		This.FontColor := "0xFF000000"
		This.FontOptions := "Center vCenter NoWrap  "
		This.H := Floor( This._GetTextSize() + 2 * This.HeaderMargin )
		This.PanelStartingPositionY := 9
		This.Selected := 1
		This.StartingPosition := 1
		This.MainColor := "0xFFFFFFFF"
		This.ArrowColor := "0xFF000000"
		This.Rows := 10
		This.BodyMargin := 3
		This.PanelTextPading := 1
		This.PanelTextHeight := Floor( This._GetTextSize() )
		This.PanelHeight := This.PanelTextHeight + 2 * This.PanelTextPading
		This.BodyHeight := This.BodyMargin * 2 + ( This.PanelHeight * This.Rows ) + ( This.BodyMargin * ( This.Rows - 1 ) ) + This.PanelStartingPositionY
		This.ThumbMinY := This.PanelStartingPositionY + 2
		This.ThumbRange := This.BodyHeight - This.ThumbMinY - 6 
		This.ThumbY := This.ThumbMinY
		This.Interval := Floor( This.ThumbRange / This.List.Length() )
		This.PanelColor1 := "0xFFCFCFCF"
		This.PanelColor2 := "0xFFEFEFEF"
		This.HighLightPanelColor := "0x3300AAFF"
		This.SelectedPanelColor := "0x990099FF"
		This.SelectedFontColor := This.FontColor
		This.HighlightFontColor := This.FontColor
		This.HeaderFontColor := This.FontColor
		This.SliderTrackColor := "0xFFDCDCDC"
		This.SliderButtonColor := "0xFFFFFFFF"
		This.SliderRidgeColor := "0x33333333"
		This.BorderColor := "0X33000000"
		This.Hovered := ""
		This.PanelControls := []
		This.Active := 0
		This.CallBind := This._CallBind.Bind( This )
		This.HoverTimer := This._Hover.Bind( This )
		This.FocusColor := "0x990099FF"
		This.Focused := 0
	}
	_UpdateDefaults( obj := "" ){
		for k, v in obj
			This[ k ] := obj[ k ] 
		This.H := Floor( This._GetTextSize() + 2 * This.HeaderMargin )
		This.Roundness := This.H / 5
		if( obj.Bind )
			This.Bind := func( obj.Bind ).Bind( This )
		if( This.Rows < 8 )
			This.Rows := 8
		This.PanelTextHeight := Floor( This._GetTextSize() )
		This.PanelHeight := This.PanelTextHeight + 2 * This.PanelTextPading
		This.BodyHeight := This.BodyMargin * 2 + ( This.PanelHeight * This.Rows ) + ( This.BodyMargin * ( This.Rows - 1 ) ) + This.PanelStartingPositionY
		This.ThumbMinY := This.PanelStartingPositionY + 2
		This.ThumbRange := This.BodyHeight - This.ThumbMinY - 6 - 2
		This.Interval := Floor( ( This.ThumbRange * This.ScaleFactor) / This.List.Length() )
		This.TotalInterval := This.Interval * This.List.Length()
		This.ThumbHeight := This.ThumbRange - This.TotalInterval
		While( This.Interval > 1 ){
			This.Interval -= 1
			This.TotalInterval := This.Interval * This.List.Length()
			This.ThumbHeight := This.ThumbRange - This.TotalInterval
		}
		This.Thumb := { X: ( This.W - 32 ) , Y: This.ThumbMinY , W: 26 , H: This.ThumbHeight }
		This._MoveThumbControl()
		This.Panels := []
		This.PanelHandles := []
		temp := This.PanelStartingPositionY - 2
		Loop, % This.Rows	{
			This.Panels[ A_Index ] := { X: 4 , Y: temp , W: ( This.W - 34 - 6 ) , H: This.PanelHeight , Hwnd: "" }
			temp += This.PanelHeight + This.BodyMargin
		}
		This.ToggleButton := { X: 2 , Y: 2 , W: ( This.W - 4 ) , H: ( This.H - 4 ) , Hwnd: "" }
		This.WheelActive := 0
		This.FT := 0
		OnMessage( 0x020A , This._WheelChange.Bind( This ) )
		OnMessage( 0x201 , This._WatchFocus.Bind( This ) )
		OnMessage( 0x100 , This._WatchKeyPress.Bind( This ) )
		if( !obj.HasKey( "HeaderFontColor" ) )
			This.HeaderFontColor := This.FontColor
		if( !obj.HasKey( "HighlightFontColor" ) )
			This.HighlightFontColor := This.FontColor
	}
	_CreateWindows(){
		This.Gui1 :=  New PopUpWindow( { AutoShow: 1 , X: This.X * This.ScaleFactor , Y: This.Y * This.ScaleFactor , W: This.W * This.ScaleFactor , H: This.H * This.ScaleFactor , Options: " -DPIScale +AlwaysOnTop +Parent" This.Parent } )
		This.Gui2 :=  New PopUpWindow( { AutoShow: 1 , X: This.X * This.ScaleFactor , Y: This.Y * This.ScaleFactor , W: This.W * This.ScaleFactor , H: This.BodyHeight * This.ScaleFactor , Options: " -DPIScale +AlwaysOnTop +Owner" This.Gui1.Hwnd } )
	}
	_CreateControls(){
		Gui, % This.Gui2.Hwnd ":Add", Text, % "x" ( This.W - 34 ) * This.ScaleFactor " y" This.ThumbY * This.ScaleFactor " w" 30 * This.ScaleFactor " h" This.ThumbHeight * This.ScaleFactor " hwndhwnd" 
		This.ThumbHwnd := hwnd
		bd := This._AdjustSlider.Bind( This )
		GuiControl, % This.Gui2.Hwnd ":+G", % hwnd, % bd 
		Loop, % This.Rows	{
			Gui, % This.Gui2.Hwnd ":Add", Text, % "x" This.Panels[ A_Index ].X * This.ScaleFactor " y" This.Panels[ A_Index ].Y * This.ScaleFactor " w" This.Panels[ A_Index ].W * This.ScaleFactor " h" This.Panels[ A_Index ].H * This.ScaleFactor " hwndhwnd"
			This.Panels[ A_Index ].Hwnd := hwnd
			This.PanelHandles[ hwnd ] := A_Index
			bd := This._SelectPanel.Bind( This )
			GuiControl, % This.Gui2.Hwnd ":+G" , % hwnd , % bd
		}
		Gui, % This.Gui1.Hwnd ":Add", Text, % "x" This.ToggleButton.X * This.ScaleFactor " y" This.ToggleButton.Y * This.ScaleFactor " w" This.ToggleButton.W * This.ScaleFactor " h" This.ToggleButton.H * This.ScaleFactor " hwndhwnd"
		This.ToggleButton.Hwnd := hwnd
		This.HKBind := This._LButtonHK.Bind( This )
		bd := This._ToggleBody.Bind( This )
		GuiControl, % This.Gui1.Hwnd ":+G" , % hwnd , % bd
	}
	_MoveThumbControl(){
		GuiControl, % This.Gui2.Hwnd ":Move" , % This.ThumbHwnd , % "y" This.Thumb.Y * This.ScaleFactor " h" This.ThumbHeight * This.ScaleFactor
	}
	_Hover(){
		MouseGetPos,,, win , ctrl , 2 
		if( win = This.Gui2.Hwnd ){
			if( !This.Hovered && This.PanelHandles[ ctrl ] ){
				This.Hovered := ctrl
				This._DrawBody()
			}
		}
		if( This.Hovered && ctrl != This.Hovered ){
			This.Hovered := ""
			if( This.Active )
				This._DrawBody()
		}
	}
	_WheelChange( input ){
		local ctrl , Dir , win 
		if( This.WheelActive )
			return
		if( This.ft := !This.ft )
			return
		This.WheelActive := 1
		Dir := ( (input >> 16 ) > 0x7FFF ) || ( ( input < 0 ) ? ( 1 ) : ( 0 ) )
		MouseGetPos,,, win, ctrl, 2
		if( !Dir &&  ctrl = This.ToggleButton.Hwnd ){
			( --This.Selected < 1 ) ? ( This.Selected := 1 )
			This.StartingPosition := This.Selected
		}else if( Dir &&  ctrl = This.ToggleButton.Hwnd ){
			( ++This.Selected > This.List.Length() ) ? ( This.Selected := This.List.Length() )
			This.StartingPosition := This.Selected
		}else if( !Dir && win = This.Gui2.Hwnd ){
			( --This.StartingPosition < 1 ) ? ( This.StartingPosition := 1 )
		}else if( Dir && win = This.Gui2.Hwnd ){
			( ++This.StartingPosition > This.List.Length() ) ? ( This.StartingPosition := This.List.Length() )
		}
		This.Thumb.Y := This.ThumbMinY + This.StartingPosition
		This._MoveThumbControl()
		This._DrawHeader()
		if( This.Active )
			This._DrawBody()
		if( ctrl = This.ToggleButton.Hwnd )
			This._SetTimer( This.CallBind , -30 )
		This.WheelActive := 0
	}
	_WatchKeyPress( key ){
		if( key = 9 && This.Focused )
			This.SetFocus( 0 )
	}
	_WatchFocus(){
		MouseGetPos,,, win, ctrl, 2
		if( This.Focused && ctrl != This.ToggleButton.Hwnd && win != This.Gui2.Hwnd && ctrl )
			This.SetFocus( 0 )
		else if( !This.Focused && ( ctrl = This.ToggleButton.Hwnd || win = This.Gui2.Hwnd ) )
			This.SetFocus( 1 )
	}
	SetFocus( value , option := 1 ){
		if( This.Focused := value )
			GuiControl, % This.Gui1.Hwnd ":Focus" , % This.ToggleButton.Hwnd
		This._DrawHeader()
	}
	_SetTimer( Timer , Amount := 30 ){
		SetTimer, % Timer, % Amount
	}
	_CallBind(){
		Try
			This.Bind.Call()
	}
	_SelectPanel(){
		MouseGetPos,,,, ctrl, 2
		if( This.List[ This.PanelHandles[ ctrl ] + This.StartingPosition - 1 ] != "" ){
			This.Output := This.List[ This.PanelHandles[ ctrl ] + This.StartingPosition - 1 ]
			This.Selected := This.PanelHandles[ ctrl ] + This.StartingPosition - 1
			This._DrawBody()
			bd := This.HKBind 
			HotKey, ~LButton, % bd , Off
			This.Active := 0
			This.Gui2.ClearWindow( 1 )
			This._DrawHeader()
			This._SetTimer( This.CallBind , -30 )
		}
	}
	_ToggleBody(){
		if( This.Active := !This.Active ){
			WinGetPos, x, y,,, % "ahk_Id " This.Gui1.Hwnd
			This.Gui2.UpdateSettings( { X: x , Y: y + ( This.Gui1.H  ) } )
			This.StartingPosition := This.Selected 
			This.Focused := 1
			This._DrawBody()
			bd := This.HKBind
			Hotkey, ~LButton , % bd , On
		}else{
			This.Gui2.ClearWindow( 1 )
			bd := This.HKBind 
			HotKey, ~LButton, % bd , Off
		}
		This._DrawHeader()
	}
	_LButtonHK(){
		MouseGetPos,,, win, ctrl, 2
		if( win != This.Gui2.Hwnd && ctrl != This.ToggleButton.Hwnd ){
			bd := This.HKBind 
			HotKey, ~LButton, % bd , Off
			This.Active := 0
			This.Gui2.ClearWindow( 1 )
			This._DrawHeader()
		}
	}
	_AdjustSlider(){
		local ly
		CoordMode, Mouse, Client
		While( GetKeyState( "LButton" ) ){
			MouseGetPos,, y
			if( ly != y ){
				ly := y
				y /= This.ScaleFactor
				if( ( y - This.ThumbHeight / 2 ) <  This.ThumbMinY ){
					This.Thumb.Y := This.ThumbMinY 
					This.StartingPosition := 1
				}else if( ( y + This.ThumbHeight / 2 ) > ( This.ThumbMinY + This.ThumbRange ) ){
					This.Thumb.Y := This.ThumbMinY + This.ThumbRange - This.ThumbHeight
					This.StartingPosition := This.List.Length()
				}else{
					This.Thumb.Y := y - This.ThumbHeight / 2
					This.StartingPosition := floor( This.Thumb.Y - This.ThumbMinY )
				}
				This._MoveThumbControl()
				This._DrawBody()
			}
			sleep, 10
		}
	}
	_DrawHeader(){
		local brush , pen 
		This.Gui1.ClearWindow()
		Brush := Gdip_CreateLineBrushFromRect( 1 * This.ScaleFactor , 1 * This.ScaleFactor , ( This.W - 2 ) * This.ScaleFactor , ( This.H - 2 ) * This.ScaleFactor , This.MainColor , ( This.MainColor2 != "" ) ? ( This.MainColor2 ) : ( This.MainColor ) , 1 , 1 ) 
		, Gdip_FillRoundedRectangle( This.Gui1.G , Brush , 2 * This.ScaleFactor , 2 * This.ScaleFactor , ( This.W - 4 ) * This.ScaleFactor , ( This.H - 4 ) * This.ScaleFactor , This.Roundness * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_CreateLineBrush( 1 * This.ScaleFactor , 1 * This.ScaleFactor , ( This.W / 2 ) * This.ScaleFactor , ( This.H - 2 ) * This.ScaleFactor , "0xaaaaaaaa" , "0xFF000000" , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 1 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawRoundedRectangle( This.Gui1.G , Pen , 2 * This.ScaleFactor , 2 * This.ScaleFactor , ( This.W - 4 ) * This.ScaleFactor , ( This.H - 4 ) * This.ScaleFactor , This.Roundness * This.ScaleFactor ) , Gdip_DeletePen( Pen )
		if( This.Focused ){
			Brush := Gdip_BrushCreateSolid( This.FocusColor )
			, Pen := Gdip_CreatePenFromBrush( Brush , 1 ) , Gdip_DeleteBrush( Brush ) 
			, Gdip_DrawRoundedRectangle( This.Gui1.G , Pen , 4 * This.ScaleFactor , 4 * This.ScaleFactor , ( This.W - 8 ) * This.ScaleFactor , ( This.H - 8 ) * This.ScaleFactor , This.Roundness * This.ScaleFactor ) 
			, Gdip_DeletePen( Pen )
		}
		Brush := Gdip_BrushCreateSolid( This.HeaderFontColor ) , Gdip_TextToGraphics( This.Gui1.G , This.List[ This.Selected ] , "s" This.FontSize * This.ScaleFactor " " This.FontOptions " NoWrap c" Brush " x" 5 * This.ScaleFactor " y" 2 * This.ScaleFactor  , This.Font , ( This.W - ( This.W / 4 ) ) * This.ScaleFactor , This.H * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( This.ArrowColor ) , Gdip_TextToGraphics( This.Gui1.G , ( !This.Active ) ? ( 6 ) : ( 5 ) , "s" ( s := 16 ) * This.ScaleFactor " " This.FontOptions " c" Brush " x" ( This.W - 30 ) * This.ScaleFactor " y" 1 * This.ScaleFactor  , "WebDings" , 30 * This.ScaleFactor , This.H * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
		This.Gui1.UpdateWindow()
	}
	_DrawBody(){
		local temp , brush , pen , tog 
		This.Gui2.ClearWindow()
		Brush := Gdip_BrushCreateSolid( This.MainColor ) , Gdip_FillRoundedRectangle( This.Gui2.G, Brush , 2 * This.ScaleFactor , 7 * This.ScaleFactor , ( This.W - 4 ) * This.ScaleFactor , ( This.BodyHeight - 4 - 7 ) * This.ScaleFactor , 5 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( This.BorderColor ) , Pen := Gdip_CreatePenFromBrush( Brush , 1 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawRoundedRectangle( This.Gui2.G , Pen , 2 * This.ScaleFactor , 7 * This.ScaleFactor , ( This.W - 4 ) * This.ScaleFactor , ( This.BodyHeight - 4 - 7 ) * This.ScaleFactor , This.Roundness * This.ScaleFactor ) , Gdip_DeletePen( Pen )
		Brush := Gdip_BrushCreateSolid( This.MainColor ) , Gdip_FillPolygon( This.Gui2.G, Brush , ( This.W / 2 ) * This.ScaleFactor "," 0 * This.ScaleFactor "|" ( This.W - ( This.W / 5 ) ) * This.ScaleFactor "," 100 * This.ScaleFactor "|" ( This.W / 5 ) * This.ScaleFactor "," 100 * This.ScaleFactor "|" ) , Gdip_DeleteBrush( Brush )
		temp := This.PanelStartingPositionY
		Loop, % This.Rows	{
			tog := !tog
			if( ( A_Index + This.StartingPosition - 1 ) = This.Selected ){
				Brush := Gdip_BrushCreateSolid( This.SelectedPanelColor ) , Gdip_FillRoundedRectangle( This.Gui2.G, Brush , 4 * This.ScaleFactor , temp * This.ScaleFactor , ( This.W - 34 - 6 ) * This.ScaleFactor , This.PanelHeight * This.ScaleFactor , 5 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
				Brush := Gdip_BrushCreateSolid( This.SelectedFontColor ) , Gdip_TextToGraphics( This.Gui2.G, This.List[ A_Index + This.StartingPosition - 1 ] , "s" This.FontSize * This.ScaleFactor " NoWrap vCenter  c" Brush " x" 4 * This.ScaleFactor " y" ( temp + 1 ) * This.ScaleFactor  , "Segoe ui" , ( This.W - 34 - 6 ) * This.ScaleFactor , This.PanelHeight * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
			}else if( A_Index = This.PanelHandles[ This.Hovered ] ){
				Brush := Gdip_BrushCreateSolid( This.HighLightPanelColor ) , Gdip_FillRoundedRectangle( This.Gui2.G, Brush , 4 * This.ScaleFactor , temp * This.ScaleFactor , ( This.W - 34 - 6 ) * This.ScaleFactor , This.PanelHeight * This.ScaleFactor , 5 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
				Brush := Gdip_BrushCreateSolid( This.HighlightFontColor ) , Gdip_TextToGraphics( This.Gui2.G, This.List[ A_Index + This.StartingPosition - 1 ] , "s" This.FontSize * This.ScaleFactor " NoWrap vCenter  c" Brush " x" 4 * This.ScaleFactor " y" ( temp + 1 ) * This.ScaleFactor  , "Segoe ui" , ( This.W - 34 - 6 ) * This.ScaleFactor , This.PanelHeight * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
			}else{
				Brush := Gdip_BrushCreateSolid( ( !tog ) ? ( This.PanelColor1 ) : ( This.PanelColor2 ) ) , Gdip_FillRoundedRectangle( This.Gui2.G, Brush , 4 * This.ScaleFactor , temp * This.ScaleFactor , ( This.W - 34 - 6 ) * This.ScaleFactor , This.PanelHeight * This.ScaleFactor , 5 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
				Brush := Gdip_BrushCreateSolid( This.FontColor ) , Gdip_TextToGraphics( This.Gui2.G, This.List[ A_Index + This.StartingPosition - 1 ] , "s" This.FontSize * This.ScaleFactor " NoWrap vCenter  c" Brush " x" 4 * This.ScaleFactor " y" ( temp + 1 ) * This.ScaleFactor  , "Segoe ui" , ( This.W - 34 - 6 ) * This.ScaleFactor , This.PanelHeight * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
			}
			temp += This.PanelHeight + This.BodyMargin
		}
		Brush := Gdip_BrushCreateSolid( This.SliderTrackColor ) , Gdip_FillRoundedRectangle( This.Gui2.G, Brush , ( This.W - 34 ) * This.ScaleFactor , 9 * This.ScaleFactor , 30 * This.ScaleFactor , ( This.BodyHeight - 15 ) * This.ScaleFactor , 5 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( This.SliderButtonColor ) , Gdip_FillRoundedRectangle( This.Gui2.G, Brush , ( This.W - 32 ) * This.ScaleFactor , This.Thumb.Y * This.ScaleFactor , 26 * This.ScaleFactor , This.ThumbHeight * This.ScaleFactor , 5 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( This.SliderRidgeColor ) , Gdip_FillRectangle( This.Gui2.G , Brush , ( This.Thumb.X + 3 ) * This.ScaleFactor , ( This.Thumb.Y + ( This.ThumbHeight / 2 ) - 5 ) * This.ScaleFactor , ( This.Thumb.W - 6 ) * This.ScaleFactor , 3 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( This.SliderRidgeColor ) , Gdip_FillRectangle( This.Gui2.G , Brush , ( This.Thumb.X + 3 ) * This.ScaleFactor , ( This.Thumb.Y + ( This.ThumbHeight / 2 ) + 5 ) * This.ScaleFactor , ( This.Thumb.W - 6 ) * This.ScaleFactor , 3 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( This.SliderRidgeColor ) , Gdip_FillRectangle( This.Gui2.G , Brush , ( This.Thumb.X + 3 ) * This.ScaleFactor , ( This.Thumb.Y + ( This.ThumbHeight / 2 ) ) * This.ScaleFactor , ( This.Thumb.W - 6 ) * This.ScaleFactor , 3 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
		This.Gui2.UpdateWindow()
	}
	_GetTextSize( index := 4 ){
		local pBitmap, G, Brush, temparr
		pBitmap := Gdip_CreateBitmap( 10 , 10 ) , G := Gdip_GraphicsFromImage( pBitmap ), Gdip_SetSmoothingMode( G , 2 )
		Brush := Gdip_BrushCreateSolid( "0xFF000000")
		temparr := StrSplit( Gdip_TextToGraphics( G , ( This.Text ) ? ( This.Text ) : ( "Test String" ), " s" This.Fontsize " c" Brush " " This.FontOptions " x" 0 " y" 0 , This.Font , 10000, 10000  ),"|","|"  ) , Gdip_DeleteBrush( Brush )
		Gdip_DeleteGraphics( G ) , Gdip_DisposeImage( pBitmap )
		return temparr[ index ]
	}
	Delete(){
		This.Gui2.DeleteWindow()
		This.Gui1.DeleteWindow()
	}
}

;####################################################################################################################################################################################
;####################################################################################################################################################################################
;####################################################################################################################################################################################
;####################################################################################################################################################################################
class PopUpWindow	{
;PopUpWindow v2.2
;Date Written: Oct 28th, 2021
;Last Edit: Feb 7th, 2022 :Changed the trigger method.
;Written By: Hellbent aka CivReborn
;SpcThanks: teadrinker , malcev 
	static Index := 0 , Windows := [] , Handles := [] , EditHwnd , HelperHwnd
	__New( obj := "" ){
		This._SetDefaults()
		This.UpdateSettings( obj )
		This._CreateWindow()
		This._CreateWindowGraphics()
		if( This.AutoShow )
			This.ShowWindow( This.Title )
	}
	_SetDefaults(){
		This.X := 10
		This.Y := 10
		This.W := 10
		This.H := 10
		This.Smoothing := 2
		This.Options := " -DPIScale +AlwaysOnTop "
		This.AutoShow := 0
		This.GdipStartUp := 0
		This.Title := ""
		
		This.Controls := []
		This.Handles := []
		This.Index := 0 
	}
	AddTrigger( obj ){
		local k , v , cc , bd
		
		This.Controls[ ++This.Index ] := { 	X:		10
										,	Y:		10
										,	W:		10
										,	H:		10	}
		for k, v in obj
			This.Controls[ This.Index ][ k ] := obj[ k ] 
		cc := This.Controls[ This.Index ]
		Gui, % This.Hwnd ":Add", Text, % "x" cc.X " y" cc.Y " w" cc.W " h" cc.H " hwndhwnd"
		This.Handles[ hwnd ] := This.Index
		This.Controls[ This.Index ].Hwnd := hwnd
		
		if( IsObject( cc.Label ) ){
			bd := cc.Label
			GuiControl, % This.Hwnd ":+G" , % hwnd , % bd
		}else{
			bd := This._TriggerCall.Bind( This )
			GuiControl, % This.Hwnd ":+G" , % hwnd , % bd
		}
		return hwnd
		
	}
	_TriggerCall(){
		MouseGetPos,,,, ctrl, 2
		Try
			;~ SetTimer, % This.Controls[ This.Handles[ ctrl ] ].Label, -0
			gosub, % This.Controls[ This.Handles[ ctrl ] ].Label
		
				
	}
	DrawTriggers( color := "0xFFFF0000" , AutoUpdate := 0 ){
		local brush , cc 
		Brush := Gdip_BrushCreateSolid( color ) 
		Gdip_SetSmoothingMode( This.G , 3 )
		loop, % This.Controls.Length()	{
			cc := This.Controls[ A_Index ]
			Gdip_FillRectangle( This.G , Brush , cc.x , cc.y , cc.w , cc.h )
		
		}
		Gdip_DeleteBrush( Brush )
		Gdip_SetSmoothingMode( This.G , This.Smoothing )
		if( AutoUpdate )
			This.UpdateWindow()
	}
	UpdateSettings( obj := "" , UpdateGraphics := 0 ){
		local k , v
		if( IsObject( obj ) )
			for k, v in obj
				This[ k ] := obj[ k ]
		( This.X = "Center" ) ? ( This.X := ( A_ScreenWidth - This.W ) / 2 ) 	
		( This.Y = "Center" ) ? ( This.Y := ( A_ScreenHeight - This.H ) / 2 ) 	
		if( UpdateGraphics ){
			This._DestroyWindowsGraphics()
			This._CreateWindowGraphics()
		}
	}
	_CreateWindow(){
		local hwnd
		Gui , New, % " +LastFound +E0x80000 hwndhwnd -Caption  " This.Options
		PopUpWindow.Index++
		This.Index := PopUpWindow.Index
		PopUpWindow.Windows[ PopUpWindow.Index ] := This
		This.Hwnd := hwnd
		PopUpWindow.Handles[ hwnd ] := PopUpWindow.Index
		if( This.GdipStartUp && !PopUpWindow.pToken )
			PopUpWindow.pToken := GDIP_STARTUP()
	}
	_DestroyWindowsGraphics(){
		Gdip_DeleteGraphics( This.G )
		SelectObject( This.hdc , This.obm )
		DeleteObject( This.hbm )
		DeleteDC( This.hdc )
	}
	_CreateWindowGraphics(){
		This.hbm := CreateDIBSection( This.W , This.H )
		This.hdc := CreateCompatibleDC()
		This.obm := SelectObject( This.hdc , This.hbm )
		This.G := Gdip_GraphicsFromHDC( This.hdc )
		Gdip_SetSmoothingMode( This.G , This.Smoothing )
	}
	ShowWindow( Title := "" ){
		Gui , % This.Hwnd ":Show", % "x" This.X " y" This.Y " w" This.W " h" This.H " NA", % Title
	}
	HideWindow(){
		Gui , % This.Hwnd ":Hide",
	}
	UpdateWindow(){
		UpdateLayeredWindow( This.hwnd , This.hdc , This.X , This.Y , This.W , This.H )
	}
	ClearWindow( AutoUpdate := 0 ){
		Gdip_GraphicsClear( This.G )
		if( Autoupdate )
			This.UpdateWindow()
	}
	DrawBitmap( pBitmap , obj , dispose := 1 , AutoUpdate := 0 ){
		Gdip_DrawImage( This.G , pBitmap , obj.X , obj.Y , obj.W , obj.H )
		if( dispose )
			Gdip_DisposeImage( pBitmap )
		if( Autoupdate )
			This.UpdateWindow()
	}
	PaintBackground( color := "0xFF000000" , AutoUpdate := 0 ){
		if( isObject( color ) ){
			Brush := Gdip_BrushCreateSolid( ( color.HasKey( "Color" ) ) ? ( color.Color ) : ( "0xFF000000" ) ) 
			if( color.Haskey( "Round" ) )
				Gdip_FillRoundedRectangle( This.G , Brush , color.X , color.Y , color.W , color.H , color.Round )
			else
				Gdip_FillRectangle( This.G , Brush , color.X , color.Y , color.W , color.H ) 
		}else{
			Brush := Gdip_BrushCreateSolid( color ) 
			Gdip_FillRectangle( This.G , Brush , -1 , -1 , This.W + 2 , This.H + 2 ) 
		}
		Gdip_DeleteBrush( Brush )
		if( AutoUpdate )
			This.UpdateWindow()
	}
	DeleteWindow( GDIPShutdown := 0 ){
		Gui, % This.Hwnd ":Destroy"
		SelectObject( This.hdc , This.obm )
		DeleteObject( This.hbm )
		DeleteDC( This.hdc )
		Gdip_DeleteGraphics( This.G )
		hwnd := This.Hwnd
		for k, v in PopUpWindow.Windows[ Hwnd ]
			This[k] := ""
		PopUpWindow.Windows[ Hwnd ] := ""
		if( GDIPShutdown ){
			Gdip_Shutdown( PopUpWindow.pToken )
			PopUpWindow.pToken := ""
		}
	}
	_OnClose( wParam ){
		if( wParam = 0xF060 ){	;SC_CLOSE ;[ clicking on the gui close button ]
			Try{
				Gui, % PopUpWindow.HelperHwnd ":Destroy"
				SoundBeep, 555
			}
		}
	}
	CreateCachedBitmap( pBitmap , Dispose := 0 ){
		local pCachedBitmap
		if( This.CachedBitmap )
			This.DisposeCachedbitmap()
		DllCall( "gdiplus\GdipCreateCachedBitmap" , "Ptr" , pBitmap , "Ptr" , this.G , "PtrP" , pCachedBitmap )
		This.CachedBitmap := pCachedBitmap
		if( Dispose )
			Gdip_DisposeImage( pBitmap )
	}
	DrawCachedBitmap( AutoUpdate := 0 ){
		DllCall( "gdiplus\GdipDrawCachedBitmap" , "Ptr" , this.G , "Ptr" , This.CachedBitmap , "Int" , 0 , "Int" , 0 )
		if( AutoUpdate )
			This.UpdateWindow()
	}
	DisposeCachedbitmap(){
		DllCall( "gdiplus\GdipDeleteCachedBitmap" , "Ptr" , This.CachedBitmap )
	}
	Helper(){
		local hwnd , MethodList := ["__New","UpdateSettings","ShowWindow","HideWindow","UpdateWindow","ClearWindow","DrawBitmap","PaintBackground","DeleteWindow" , "AddTrigger" , "DrawTriggers", "CreateCachedBitmap" , "DrawCachedBitmap" , "DisposeCachedbitmap" ]
		Gui, New, +AlwaysOnTop +ToolWindow +HwndHwnd
		PopUpWindow.HelperHwnd := hwnd
		Gui, Add, Edit, xm ym w250 r1 Center hwndhwnd, Gui1
		PopUpWindow.EditHwnd := hwnd
		loop, % MethodList.Length()	
			Gui, Add, Button, xm y+1 w250 r1 gPopUpWindow._HelperClip, % MethodList[ A_Index ]
		Gui, Show,,
		OnMessage( 0x112 , This._OnClose.Bind( hwnd ) )
	}
	_HelperClip(){
		local ClipList 
		
		GuiControlGet, out, % PopUpWindow.HelperHwnd ":", % PopUpWindow.EditHwnd	
		
		ClipList := 		{ 	__New: 					" := New PopUpWindow( { AutoShow: 1 , X: 0 , Y: 0 , W: A_ScreenWidth , H: A_ScreenHeight , Options: "" -DPIScale +AlwaysOnTop "" } )"
							,	UpdateSettings:			".UpdateSettings( { X: """" , Y: """" , W: """" , H: """" } , UpdateGraphics := 0 )"
							,	ShowWindow:				".ShowWindow( Title := """" )"
							,	HideWindow:				".HideWindow()"
							,	UpdateWindow:			".UpdateWindow()"
							,	ClearWindow:			".ClearWindow( AutoUpdate := 0 )"
							,	DrawBitmap:				".DrawBitmap( pBitmap := """" , { X: 0 , Y: 0 , W: " Out ".W , H: " Out ".H } , dispose := 1 , AutoUpdate := 0 )"
							,	PaintBackground:		".PaintBackground( color := ""0xFF000000"" , AutoUpdate := 0 )  "  ";{ Color: ""0xFF000000"" , X: 2 , Y: 2 , W: " Out ".W - 4 , H: " Out ".H - 4 , Round: 10 }"
							,	DeleteWindow:			".DeleteWindow( GDIPShutdown := 0 )"
							,	AddTrigger:				".AddTrigger( { X: """" , Y: """" , W: """" , H: """" , Value: """" , Label: """" } )"	
							,	DrawTriggers:			".DrawTriggers( color := ""0xFFFF0000"" , AutoUpdate := 0 )"	
							,	CreateCachedBitmap:		".CreateCachedBitmap( pBitmap , Dispose := 0 )"	
							,	DrawCachedBitmap: 		".DrawCachedBitmap( AutoUpdate := 0 )"	
							,	DisposeCachedbitmap:	".DisposeCachedbitmap()"	}
							
		clipboard := Out ClipList[ A_GuiControl ]
		
	}
}
Last edited by Hellbent on 09 Feb 2022, 17:41, edited 1 time in total.

malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: Examples of Non-Standard GUIs (ActiveX, GDI, etc.)

Post by malcev » 09 Feb 2022, 17:36

Thank You.
For me scroll does not work ok win10 1920x1080.
If i press on it, it scrolls to the end and sometimes disappears.

User avatar
Hellbent
Posts: 2102
Joined: 23 Sep 2017, 13:34

Re: Examples of Non-Standard GUIs (ActiveX, GDI, etc.)

Post by Hellbent » 09 Feb 2022, 17:41

malcev wrote:
09 Feb 2022, 17:36
Thank You.
For me scroll does not work ok win10 1920x1080.
If i press on it, it scrolls to the end and sometimes disappears.
Can you show a gif.

User avatar
Hellbent
Posts: 2102
Joined: 23 Sep 2017, 13:34

Re: Examples of Non-Standard GUIs (ActiveX, GDI, etc.)

Post by Hellbent » 09 Feb 2022, 17:47

@malcev it could have to do with the thing I mentioned about lists that are over 200 items long.
( 200 is a rough estimate of how many can fit with the current defaults, the actual amount is unknown. I have about 140 fonts and I just estimated that you could fit about 50 or so more.)

malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: Examples of Non-Standard GUIs (ActiveX, GDI, etc.)

Post by malcev » 09 Feb 2022, 18:00

Yes, exactly that was a reason.
With 200 works good.
Can You upload, please, dark version?

User avatar
Hellbent
Posts: 2102
Joined: 23 Sep 2017, 13:34

Re: Examples of Non-Standard GUIs (ActiveX, GDI, etc.)

Post by Hellbent » 09 Feb 2022, 19:17

malcev wrote:
09 Feb 2022, 18:00
Can You upload, please, dark version?
The one I gave you is intended to be customizable, I started on a tool to make customizing easier but it is far from done.

You can try playing around with the theme by changing these keys. ( and others )

Code: Select all

		This.PanelColor1 := "0xFFCFCFCF"
		This.PanelColor2 := "0xFFEFEFEF"
		This.HighLightPanelColor := "0x3300AAFF"
		This.SelectedPanelColor := "0x990099FF"
		This.SelectedFontColor := This.FontColor
		This.HighlightFontColor := This.FontColor
		This.HeaderFontColor := This.FontColor
		This.SliderTrackColor := "0xFFDCDCDC"
		This.SliderButtonColor := "0xFFFFFFFF"
		This.SliderRidgeColor := "0x33333333"
		This.BorderColor := "0X33000000"


I can give you the dark one but it is just the code I started with before deciding to do a new design for the graphics.
It doesn't have as much added as the other one does.



Code: Select all

;****************************************************************************************************************************************************************************
#Include <My Altered GDIP lib>
#Include <PopUpWindow_V2> 
;****************************************************************************************************************************************************************************
#SingleInstance, Force
SetBatchlines, -1
SetMouseDelay, 1
CoordMode, Mouse, Screen
#NoEnv
GDIP_STARTUP()

ScaleFactor := 1
FontList := []
testList := GetFontNames( 1 )
for k, v in testList	{
	if( inStr( k , "@" ) )
		FontList.Push( SubStr( k , 2 ) )
	else 
		FontList.Push( k )
}
Gui, 1:+AlwaysOnTop
;~ Gui, 1:Color, 22262a
;~ Gui, 1:Color, 585a5f
Gui, 1:Color, acacac
;~ Gui, 1:Color, 12161a

Bob := New SCDDL( { Parent: 1 , X: 10 , Y: 10 , ScaleFactor: ScaleFactor , List: FontList , Bind: "TestFunction" } )
Bob := New SCDDL( { Parent: 1 , X: 10 , Y: 50 * ScaleFactor , ScaleFactor: ScaleFactor , List: FontList , Bind: "TestFunction" } )

Gui, 1:Font, s12, Segoe UI
Gui, 1:Add, DDL, % "xm y" ( 10 + Bob.H ) * ScaleFactor * 2 + ( 10 * ScaleFactor ) " w300 r10" , item1||item 2|item3|item 4|item|item|item|item|item|item|item|
Gui, 1:Add, Edit, xm w200 r1

Gui, 1:Show, % "w" 500 * ScaleFactor " h" 200 * ScaleFactor

;~ FontList := [ "A" , "B" , "C" , "D" , "E" , "F" , "G" , "B" , "C" , "D" , "E" , "F" , "G" ]



return
GuiClose:
GuiContextMenu:
*ESC::ExitApp

TestFunction( obj := "" ){
	static hz := 500
	;~ ToolTip, % "Here in bind: " obj.Selected
	if( obj.List[ obj.Selected ] = "Segoe UI" ){
		Loop, 3 
			SoundBeep, hz + A_Index * 100 
	}
}


RALT::
	;~ Bob.List := [ "A" , "B" , "C" , "D" , "E" , "F" , "G" , "B" , "C" , "D" , "E" , "F" , "G" ]
	;~ Bob._UpdateDefaults()
	Bob.ChangeList( [ "A" , "B" , "C" , "D" , "E" , "F" , "G" , "B" , "C" , "D" , "E" , "F" , "G" , "B" , "C" , "D" , "E" , "F" , "G" , "B" , "C" , "D" , "E" , "F" , "G" , "B" , "C" , "D" , "E" , "F" , "G" , "B" , "C" , "D" , "E" , "F" , "G" , "B" , "C" , "D" , "E" , "F" , "G" , "B" , "C" , "D" , "E" , "F" , "G" , "B" , "C" , "D" , "E" , "F" , "G" , "B" , "C" , "D" , "E" , "F" , "G" ] )
	return



GetFontNames(charset){ ;https://www.autohotkey.com/boards/viewtopic.php?t=12416#p386353
   hDC := DllCall("GetDC", "UInt", 0, "Ptr")
   VarSetCapacity(LOGFONT, 92, 0)
   NumPut(charset, &LOGFONT + 23, "UChar")
   DllCall("EnumFontFamiliesEx", "Ptr", hDC, "Ptr", 0 , "Ptr", RegisterCallback("EnumFontFamExProc", "F", 4) , "Ptr", pFonts := Object(Fonts := {}), "UInt", 0)
   ObjRelease(pFonts), DllCall("ReleaseDC", "Ptr", 0, "Ptr", hDC)
   Return Fonts
}
EnumFontFamExProc(lpelfe, lpntme, FontType, lParam)
{
   font := StrGet(lpelfe + 28)
   Object(lParam)[font] := ""
   Return true
}


;********************************************************************************************************************************************************
;********************************************************************************************************************************************************
;********************************************************************************************************************************************************
class SCDDL	{
	
	__New( obj := "" ){
		
		This._SetDefaults()
		This._UpdateDefaults( obj )
		
		This._CreateWindows()
		This._AddMainButton()
		This._AddPanelControls()
		This._AddSliderThumbControl()
		This._AddSliderMainControl()
		This._DrawDDLMAIN()
		
		
	}
	_SetDefaults(){
		
		This.ScaleFactor := 1
		
		This.Parent := ""
		
		
		
		
		This.DDLMAIN := {}
		This.X := This.DDLMAIN.X := 10
		This.Y := This.DDLMAIN.Y := 10
		This.W := This.DDLMAIN.W := 340
		This.H := This.DDLMAIN.H := 40
		
		
		
		This.DDLMain.FontColorTop := "0xFFF0F0F0"
		This.DDLMain.FontColorBottom := "0xFF000000"
		This.DDLMain.Font := "Segoe UI" 
		This.DDLMain.FontSize := 12
		
		This.DDLMain.Button := { X: "" , Y: "" , W: "" , H: "" }
		
		This.DDLBody := {}
		This.DDLBody.X := 10
		This.DDLBody.Y := 10
		This.DDLBody.W := 330
		This.DDLBody.H := 280
		
		This.Output := ""
		
		This.List := ""
		This.Active := 0
		This.Selected := 1
		This.StartingPosition := 1
		This.DisplayCount := 13
		
		This.DDLBody.FontColorTop := "0xFFF0F0F0"
		This.DDLBody.FontColorBottom := "0xFF000000"
		This.DDLBody.Font := "Segoe UI" 
		This.DDLBody.FontSize := 12
		
		This.HKBind := This._LBUTTONHK.Bind( This )
		This.Slider := {}
		
		This.Range := ""
		
		
		This.Slider.X := 300
		This.Slider.W := 25
		This.Slider.Top := 5
		This.Slider.Bottom := 275
		This.Slider.H := This.Slider.Bottom - This.Slider.Top
		

		This.Slider.Thumb := { X: 302 , Y: 7 , W: 21 , H: 90 }
		
		
		
		
		This.Panels := []
		This.PanelHandles := []
		y := 5 - 21
		loop, % This.DisplayCount	
			This.Panels[ A_Index ] := { X: 5 , Y: y += 21 , W: 290 , H: 20 }
		
		
		This.WheelActive := 0
		This.WheelInterval := 1
		
		OnMessage( 0x020A , This._WheelChange.Bind( This ) )
		
		This.Hover := ""
		This.LastHover := ""
		This.HoverTimer := This._Hover.Bind( This )
		
	}
	_SetTimer( Timer , Time := 30 ){
		local bd := Timer
		SetTimer, % bd , % Time
	}
	ChangeList( list ){
		This.List := list
		;~ This._UpdateDefaults()
		
		This.Selected := 1
		This.StartingPosition := 1
		
		;~ This.Active := 0
		This._DrawDDLMain()
		if( This.Active ){
			;~ This._DrawDDLBODY()
			This.Active := 0
			This._SetControlPosition()
			This.DDLBody.ClearWindow( 1 )
			bd := This.HKBind 
			HotKey, ~LButton, % bd , Off
		}
		
	}
	_WheelChange( input ){
		if( This.WheelActive )
			return
		if( This.ft := !This.ft )
			return
		This.WheelActive := 1
		Dir := ( (input >> 16 ) > 0x7FFF ) || ( ( input < 0 ) ? ( 1 ) : ( 0 ) )
		MouseGetPos,,, win, ctrl, 2
		if( !Dir && win = This.DDLBody.Hwnd ){
			if( ( This.StartingPosition -= 3 ) < 1 )
				This.StartingPosition := 1
			This._SetControlPosition()
		}else if( Dir && win = This.DDLBody.Hwnd ){
			if( ( This.StartingPosition += 3 ) > This.List.Length() )
				This.StartingPosition := This.List.Length()
			This._SetControlPosition()
		}else if( !Dir && ctrl = This.DDLMain.Hwnd ){
			if( --This.Selected < 1 )
				This.Selected := 1
			This.StartingPosition := This.Selected
			This._DrawDDLMain()
			if( This.Active ){
				This.StartingPosition := This.Selected
				This._SetControlPosition()
			}
			This._CallFunction()
		}else if( Dir && ctrl = This.DDLMain.Hwnd ){
			if( ++This.Selected > This.List.Length() )
				This.Selected := This.List.Length()
			This.StartingPosition := This.Selected
			This._DrawDDLMain()
			if( This.Active ){
				This.StartingPosition := This.Selected
				This._SetControlPosition()
			}
			This._CallFunction()
		}
		This.WheelActive := 0
	}
	_CallFunction(){
		if( This.Bind )
			Try{
				This.Bind.Call()
			}
	}
	_SetControlPosition(){
		This.Range := This.Slider.Bottom - This.Slider.Top - This.Slider.Thumb.H
		This.Interval := This.Range / This.List.Length()
		This.Slider.Thumb.Y := ABS( Ceil( This.Interval * ( This.StartingPosition + 1 ) ) )
		GuiControl, % This.DDLBody.Hwnd ":Move" , % This.Slider.Thumb.Hwnd, % "y" This.Slider.Thumb.Y * This.ScaleFactor
		This._DrawDDLBODY()
	}
	_Hover(){
		ToolTip, here
	}
	_AddSliderMainControl(){
		Gui, % This.DDLBody.Hwnd ":Add", Text, % "x" This.Slider.X * This.ScaleFactor " y" This.Slider.Top * This.ScaleFactor " w" This.Slider.W * This.ScaleFactor " h" This.Slider.Bottom * This.ScaleFactor " hwndhwnd" 
		bd := This._AdjustSliderTrack.Bind( This )
		GuiControl, % This.DDLBody.Hwnd ":+G" , % hwnd , % bd
	}
	_AddSliderThumbControl(){
		Gui, % This.DDLBody.Hwnd ":Add", Text, % "x" This.Slider.Thumb.X * This.ScaleFactor " y" This.Slider.Thumb.Y * This.ScaleFactor " w" This.Slider.Thumb.W * This.ScaleFactor " h" This.Slider.Thumb.H * This.ScaleFactor " hwndhwnd" 
		bd := This._AdjustSliderThumb.Bind( This )
		GuiControl, % This.DDLBody.Hwnd ":+G" , % hwnd , % bd
		This.Slider.Thumb.Hwnd := hwnd
	}
	_AddPanelControls(){
		loop, % This.DisplayCount	{
			Gui, % This.DDLBody.Hwnd ":Add", Text, % "x" This.Panels[ A_Index ].X * This.ScaleFactor " y" This.Panels[ A_Index ].Y * This.ScaleFactor " w" This.Panels[ A_Index ].W * This.ScaleFactor " h" This.Panels[ A_Index ].H * This.ScaleFactor " hwndhwnd"
			This.Panels[ A_Index ].Hwnd := hwnd
			This.PanelHandles[ hwnd ] := A_Index 
			bd := This._SelectPanel.Bind( This )
			GuiControl, % This.DDLBody.Hwnd ":+G" , % hwnd , % bd
		}
	}
	_UpdateDefaults( obj := "" ){
		local k , v
		for k, v in obj	
			This[ k ] := obj[ k ]
		This.DDLMain.Button := { X: 298 * This.ScaleFactor , Y: 5 * This.ScaleFactor , W: 37 * This.ScaleFactor , H: 30 * This.ScaleFactor }
		( This.X != "" ) ? ( This.DDLMAIN.X := This.X )
		( This.Y != "" ) ? ( This.DDLMAIN.Y := This.Y )
		if( obj.Bind )
			This.Bind := func( obj.Bind ).Bind( This )
		
		
		;~ Interval := Floor( This.Slider.H / This.List.Length())
		
		;~ Thumb := ( This.Slider.H ) - ( interval * This.List.Length() )
		
		;~ if( Thumb < 60 ){ 
			;~ InterVal -= 1
			;~ Thumb += InterVal
		;~ }
		;~ if( Thumb < 60 ){ 
			;~ InterVal -= 1
			;~ Thumb += InterVal
		;~ }
		;~ if( Thumb < 60 ){ 
			;~ InterVal -= 1
			;~ Thumb += InterVal
		;~ }
		;~ This.Slider.Thumb := { X: 302 , Y: 7 , W: 21 , H: Thumb }
	}
	_CreateWindows(){
		This.DDLMain := New PopUpWindow( { AutoShow: 1 , X: This.DDLMAIN.X , Y: This.DDLMAIN.Y , W: This.DDLMAIN.W * This.ScaleFactor , H: This.DDLMAIN.H * This.ScaleFactor , Options: " -DPIScale +AlwaysOnTop +Parent" This.Parent } )
		This.DDLBody := New PopUpWindow( { AutoShow: 1 , X: This.DDLBody.X , Y: This.DDLBody.Y , W: This.DDLBody.W * This.ScaleFactor , H: This.DDLBody.H * This.ScaleFactor , Options: " -DPIScale +AlwaysOnTop +Owner" This.DDLMain.Hwnd } )
	}
	_AddMainButton(){
		local hwnd , bd 
		This.DDLMain.Button := { X: 298 * This.ScaleFactor , Y: 5 * This.ScaleFactor , W: 37 * This.ScaleFactor , H: 30 * This.ScaleFactor }
		Gui, % This.DDLMain.Hwnd ":Add", Text, % "x" This.DDLMain.Button.X " y" This.DDLMain.Button.Y " w" This.DDLMain.Button.W " h" This.DDLMain.Button.H " hwndhwnd"
		This.DDLMain.Button.Hwnd := hwnd
		bd := This._ToggleDDL.Bind( This )
		GuiCOntrol, % This.DDLMain.Hwnd ":+G" , % Hwnd , % bd
	}
	_AdjustSliderTrack(){
		
		ToolTip, here is slider
	}
	_AdjustSliderThumb(){
		CoordMode, Mouse, Client
		While( GetKeyState( "LButton" ) ){
			MouseGetPos, x, y
			y /= This.ScaleFactor
			if( ( y - This.Slider.Thumb.H / 2 ) < ( This.Slider.Top + 1 ) )
				This.Slider.Thumb.Y := This.Slider.Top + 1
			else if( ( y + This.Slider.Thumb.H / 2 ) > This.Slider.Bottom - 1 )
				This.Slider.Thumb.Y := This.Slider.Bottom - This.Slider.Thumb.H - 1
			else
				This.Slider.Thumb.Y := y - This.Slider.Thumb.H / 2
			ListLength := This.List.Length()
			This.Range := This.Slider.Bottom - This.Slider.Top - This.Slider.Thumb.H
			This.Interval := This.Range / ListLength
			This.StartingPosition := Floor( ( This.Slider.Thumb.Y - This.Slider.Top ) / This.Interval ) + 1
			This._DrawDDLBODY()
		}
		GuiControl, % This.DDLBody.Hwnd ":Move" , % This.Slider.Thumb.Hwnd, % "y" This.Slider.Thumb.Y * This.ScaleFactor
		
		
		
		;~ Interval := Floor( This.Slider.H / This.List.Length())
		
		;~ Thumb := ( This.Slider.H ) - ( interval * This.List.Length() )
		
		;~ if( Thumb < 60 ){ 
			;~ InterVal -= 1
			;~ Thumb += InterVal
		;~ }
		;~ if( Thumb < 60 ){ 
			;~ InterVal -= 1
			;~ Thumb += InterVal
		;~ }
		;~ if( Thumb < 60 ){ 
			;~ InterVal -= 1
			;~ Thumb += InterVal
		;~ }
		;~ ToolTip, % This.Slider.H "`n" Thumb "`n" interval * This.List.Length()
		
		
	}
	_ToggleDDL(){
		if( This.Active := !This.Active ){
			WinGetPos, x, y,,, % "ahk_Id " This.DDLMain.Hwnd
			This.DDLBody.UpdateSettings( { X: x + ( 5 * This.ScaleFactor ) , Y: y + ( This.DDLMain.H ) , W: "" , H: "" } , UpdateGraphics := 0 )
			This._DrawDDLBody()
			;~ This._DrawDDLMAIN()
			bd := This.HKBind 
			HotKey, ~LButton, % bd , On
		}else{
			This.DDLBody.ClearWindow( 1 )
		;~ This._DrawDDLMAIN()
			bd := This.HKBind 
			HotKey, ~LButton, % bd , Off
		}
		This._DrawDDLMAIN()
	}
	_LBUTTONHK(){
		MouseGetPos,,, win, ctrl, 2
		if( win != This.DDLBody.Hwnd && ctrl != This.DDLMain.Button.Hwnd ){
			bd := This.HKBind 
			HotKey, ~LButton, % bd , Off
			This.Active := 0
			This.DDLBody.ClearWindow( 1 )
			This._DrawDDLMAIN()
		}
	}
	_SelectPanel(){
		MouseGetPos,,,, ctrl, 2
		if( This.List[ This.PanelHandles[ ctrl ] + This.StartingPosition - 1 ] != "" ){
			This.Output := This.List[ This.PanelHandles[ ctrl ] + This.StartingPosition - 1 ]
			This.Selected := This.PanelHandles[ ctrl ] + This.StartingPosition - 1
			This._DrawDDLBODY()
			bd := This.HKBind 
			HotKey, ~LButton, % bd , Off
			This.Active := 0
			This.DDLBody.ClearWindow( 1 )
			This._DrawDDLMAIN()
		}
	}
	_DrawDDLMAIN(){
		This.DDLMain.ClearWindow()
		Brush := Gdip_BrushCreateSolid( "0xFF444444" ) , Gdip_FillRoundedRectangle( This.DDLMain.G , Brush , 5 * This.ScaleFactor , 5 * This.ScaleFactor , 290 * This.ScaleFactor , 30 * This.ScaleFactor , 9 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_CreateLineBrushFromRect( 299 * This.ScaleFactor , 7 * This.ScaleFactor , 36 * This.ScaleFactor , 27 * This.ScaleFactor , "0xFFBEBEBE" , "0xFF525252" , 1 , 1 ) , Gdip_FillRoundedRectangle( This.DDLMain.G , Brush , 298 * This.ScaleFactor , 5 * This.ScaleFactor , 37 * This.ScaleFactor , 30 * This.ScaleFactor , 9 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFFF0F0F0" ) , Gdip_TextToGraphics( This.DDLMain.G , ( !This.Active ) ? ( "6" ) : ( "5" ) , "s" 18 * This.ScaleFactor " Center vCenter Bold c" Brush " x" 293 * This.ScaleFactor " y" -2 * This.ScaleFactor  , "Webdings" , 50 * This.ScaleFactor , 50 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_TextToGraphics( This.DDLMain.G , This.List[ This.Selected ] , "s" 14 * This.ScaleFactor " Center vCenter c" Brush " x" 6 * This.ScaleFactor " y" 7 * This.ScaleFactor  , "Segoe Ui" , 290 * This.ScaleFactor , 30 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFFF0F0F0" ) , Gdip_TextToGraphics( This.DDLMain.G , This.List[ This.Selected ] , "s" 14 * This.ScaleFactor " Center vCenter c" Brush " x" 5 * This.ScaleFactor " y" 6 * This.ScaleFactor  , "Segoe Ui" , 290 * This.ScaleFactor , 30 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_CreateLineBrush( 7 * This.ScaleFactor , 5 * This.ScaleFactor , 150 * This.ScaleFactor , 35 * This.ScaleFactor , "0xFF444444" , "0xFF000000" , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 1 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawRoundedRectangle( This.DDLMain.G , Pen , 5 * This.ScaleFactor , 5 * This.ScaleFactor , 290 * This.ScaleFactor , 30 * This.ScaleFactor , 8 * This.ScaleFactor ) , Gdip_DeletePen( Pen )
		Brush := Gdip_CreateLineBrush( 7 * This.ScaleFactor , 5 * This.ScaleFactor , 150 * This.ScaleFactor , 35 * This.ScaleFactor , "0xaaaaaaaa" , "0xFF000000" , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 1 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawRoundedRectangle( This.DDLMain.G , Pen , 6 * This.ScaleFactor , 6 * This.ScaleFactor , 288 * This.ScaleFactor , 28 * This.ScaleFactor , 9 * This.ScaleFactor ) , Gdip_DeletePen( Pen )
		This.DDLMain.UpdateWindow()
	}
	_DrawDDLBODY(){
		This.DDLBody.ClearWindow()
		Brush := Gdip_BrushCreateSolid( "0xFF999999" ) , Gdip_FillRoundedRectangle( This.DDLBody.G , Brush , 0 * This.ScaleFactor , 0 * This.ScaleFactor , 330 * This.ScaleFactor , 280 * This.ScaleFactor , 5 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
		
		
		;~ Brush := Gdip_BrushCreateSolid( "0x99999999" ) , Gdip_FillRoundedRectangle( This.DDLBody.G , Brush , 0 * This.ScaleFactor , 0 * This.ScaleFactor , 330 * This.ScaleFactor , 280 * This.ScaleFactor , 5 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
		
		;~ Brush := Gdip_CreateLineBrushFromRect( 0 * This.ScaleFactor , 0 * This.ScaleFactor , 330 * This.ScaleFactor , 280 * This.ScaleFactor , "0x00BEBEBE" , "0xff999999" , 1 , 1 )
		;~ Gdip_FillRoundedRectangle( This.DDLBody.G , Brush , 0 * This.ScaleFactor , 0 * This.ScaleFactor , 330 * This.ScaleFactor , 280 * This.ScaleFactor , 5 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
		
		
		
		
		Brush := Gdip_BrushCreateSolid( "0x66000000" ) , Gdip_FillRoundedRectangle( This.DDLBody.G , Brush , 300 * This.ScaleFactor , 5 * This.ScaleFactor , 25 * This.ScaleFactor , 270 * This.ScaleFactor , 5 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
		y := 5
		loop, 13	{
			cTog := !cTog
			if( This.Selected = A_Index + This.StartingPosition - 1 )
				Brush := Gdip_BrushCreateSolid( "0xFF3399ff" ) , Gdip_FillRoundedRectangle( This.DDLBody.G , Brush , 5 * This.ScaleFactor , y * This.ScaleFactor , 290 * This.ScaleFactor , 20 * This.ScaleFactor , 5 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
			else if( This.Hover = A_Index )
				Brush := Gdip_BrushCreateSolid( "0x993399ff" ) , Gdip_FillRoundedRectangle( This.DDLBody.G , Brush , 5 * This.ScaleFactor , y * This.ScaleFactor , 290 * This.ScaleFactor , 20 * This.ScaleFactor , 5 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
			else	
				Brush := Gdip_BrushCreateSolid( ( cTog ) ? ( "0xFF333333" ) : ( "0xFF444444" ) ) , Gdip_FillRoundedRectangle( This.DDLBody.G , Brush , 5 * This.ScaleFactor , y * This.ScaleFactor , 290 * This.ScaleFactor , 20 * This.ScaleFactor , 5 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
			if( This.List[ A_Index + This.StartingPosition - 1 ] != "" )
				Brush := Gdip_BrushCreateSolid( "0xFFF0F0F0" ) , Gdip_TextToGraphics( This.DDLBody.G , This.List[ A_Index + This.StartingPosition - 1 ] , "s" 12 * This.ScaleFactor " left  vCenter Bold -Wrap c" Brush " x" 14 * This.ScaleFactor " y" y * This.ScaleFactor + 1 , "Segoe ui" , 270 * This.ScaleFactor , 20 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
			y += 21
		}
		
		
		;~ Brush := Gdip_CreateLineBrushFromRect( 302 * This.ScaleFactor , 7 * This.ScaleFactor , 21 * This.ScaleFactor , 90 * This.ScaleFactor , "0xFF777777" , "0xFF333333" , 1 , 1 ) , Gdip_FillRoundedRectangle( This.DDLBody.G , Brush , 302 * This.ScaleFactor , 7 * This.ScaleFactor , 21 * This.ScaleFactor , 90 * This.ScaleFactor , 5 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_CreateLineBrushFromRect( This.Slider.Thumb.X * This.ScaleFactor , This.Slider.Thumb.Y * This.ScaleFactor , This.Slider.Thumb.W * This.ScaleFactor , This.Slider.Thumb.H * This.ScaleFactor , "0xFF777777" , "0xFF333333" , 1 , 1 ) , Gdip_FillRoundedRectangle( This.DDLBody.G , Brush , This.Slider.Thumb.X * This.ScaleFactor , This.Slider.Thumb.Y * This.ScaleFactor , This.Slider.Thumb.W * This.ScaleFactor , This.Slider.Thumb.H * This.ScaleFactor , 5 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
		
		
		;~ Brush := Gdip_BrushCreateSolid( "0xFF333333" ) , Gdip_FillRectangle( This.DDLBody.G , Brush , ( This.Slider.Thumb.X + 3 ) * This.ScaleFactor , ( This.Slider.Thumb.Y + 44 ) * This.ScaleFactor , 15 * This.ScaleFactor , 3 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF333333" ) , Gdip_FillRectangle( This.DDLBody.G , Brush , ( This.Slider.Thumb.X + 3 ) * This.ScaleFactor , ( This.Slider.Thumb.Y + ( This.Slider.Thumb.H / 2 ) - 5 ) * This.ScaleFactor , 15 * This.ScaleFactor , 3 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
		;~ Brush := Gdip_BrushCreateSolid( "0xFF333333" ) , Gdip_FillRectangle( This.DDLBody.G , Brush , ( This.Slider.Thumb.X + 3 ) * This.ScaleFactor , ( This.Slider.Thumb.Y + 48 ) * This.ScaleFactor , 15 * This.ScaleFactor , 3 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF333333" ) , Gdip_FillRectangle( This.DDLBody.G , Brush , ( This.Slider.Thumb.X + 3 ) * This.ScaleFactor , ( This.Slider.Thumb.Y + ( This.Slider.Thumb.H / 2 ) ) * This.ScaleFactor , 15 * This.ScaleFactor , 3 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
		;~ Brush := Gdip_BrushCreateSolid( "0xFF333333" ) , Gdip_FillRectangle( This.DDLBody.G , Brush , ( This.Slider.Thumb.X + 3 ) * This.ScaleFactor , ( This.Slider.Thumb.Y + 52 ) * This.ScaleFactor , 15 * This.ScaleFactor , 3 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF333333" ) , Gdip_FillRectangle( This.DDLBody.G , Brush , ( This.Slider.Thumb.X + 3 ) * This.ScaleFactor , ( This.Slider.Thumb.Y + ( This.Slider.Thumb.H / 2 ) + 5 ) * This.ScaleFactor , 15 * This.ScaleFactor , 3 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
		;~ Brush := Gdip_BrushCreateSolid( "0xFF333333" ) , Gdip_FillRectangle( This.DDLBody.G , Brush , ( This.Slider.Thumb.X + 3 ) * This.ScaleFactor , ( This.Slider.Thumb.Y + 40 ) * This.ScaleFactor , 15 * This.ScaleFactor , 3 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
		This.DDLBody.UpdateWindow()
	}
}
Last edited by Hellbent on 09 Feb 2022, 19:20, edited 1 time in total.

malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: Examples of Non-Standard GUIs (ActiveX, GDI, etc.)

Post by malcev » 09 Feb 2022, 19:19

Thank You!
Will play.

robmar-zl
Posts: 24
Joined: 05 Feb 2015, 04:57

Re: Examples of Non-Standard GUIs (ActiveX, GDI, etc.)

Post by robmar-zl » 15 Mar 2022, 01:51

My Desktop Launcher:
Image

In Action -
Image

Right Click for Submenu above Icon

Config File -> Launcher will be generated on Start
link = link of the parent icon
all others = link of the sub icon

Code: Select all

[reddit]
link = https://www.reddit.com
de = https://www.reddit.com/r/de/new/
granturismo = https://www.reddit.com/r/granturismo/new/
simracing = https://www.reddit.com/r/simracing/new/
formula1 = https://www.reddit.com/r/formula1/new/
fifa = https://www.reddit.com/r/fifa/new/

[discord]
link = https://discord.com/channels/@me

[twitter]
link = https://twitter.com/i/trends

[youtube]
link = https://www.youtube.com/

ozzii
Posts: 481
Joined: 30 Oct 2013, 06:04

Re: Examples of Non-Standard GUIs (ActiveX, GDI, etc.)

Post by ozzii » 15 Mar 2022, 06:51

Nice

User avatar
joedf
Posts: 8937
Joined: 29 Sep 2013, 17:08
Location: Canada
Contact:

Re: Examples of Non-Standard GUIs (ActiveX, GDI, etc.)

Post by joedf » 15 Mar 2022, 10:14

@robmar-zl That's neat! makes me think of when I used to use an iMac or RocketDock on windows. :+1:
Mind sharing the code?
Image Image Image Image Image
Windows 10 x64 Professional, Intel i5-8500, NVIDIA GTX 1060 6GB, 2x16GB Kingston FURY Beast - DDR4 3200 MHz | [About Me] | [About the AHK Foundation] | [Courses on AutoHotkey]
[ASPDM - StdLib Distribution] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library]

robmar-zl
Posts: 24
Joined: 05 Feb 2015, 04:57

Re: Examples of Non-Standard GUIs (ActiveX, GDI, etc.)

Post by robmar-zl » 16 Mar 2022, 01:33

joedf wrote:
15 Mar 2022, 10:14
@robmar-zl That's neat! makes me think of when I used to use an iMac or RocketDock on windows. :+1:
It's inspired by RocketDock and other launcher but much more flexible because of autohotkey
joedf wrote:
15 Mar 2022, 10:14
Mind sharing the code?
Sure, here ist the code:
(a lot of copy and paste code - finished the first working version yesterday. Needs a bit of code review and optimization :D )

And you have to change it to your monitor resolution at these 3 lines of code:
x=1280 ; middle of monitor
Gui, MAIN:Show, w2560 h1440 , MAIN
y=400 -> height where the launcher appears

launcher.ahk

Code: Select all

Process,Priority,,R
#NoEnv
#SingleInstance force
#Persistent
#MaxThreadsPerHotkey,1 ; no re-entrant hotkey handling
#InstallKeybdHook
SetCapsLockState, AlwaysOff 
SetWorkingDir, %A_ScriptDir%
SetBatchLines, -1
ListLines, Off
SetTitleMatchMode, RegEx ; Find window titles by regex
DetectHiddenWindows,On
SetWinDelay, -1
SetKeyDelay, -1
SetTitleMatchMode, 2

CustomColor = 080808
OnMessage(0x200, "WM_MOUSEMOVE")

; --- get ini Data and put it into global variables
FileRead, ini, buttons.ini
global ini  

sections := ini_getAllSectionNames(ini)                         ; <- Get a list of all section names.
global sectionsArray := StrSplit(sections, ",")

gui, MAIN: +hwndguiId
Gui,MAIN: +ToolWindow -SysMenu -Caption +LastFound
Gui,MAIN: Color, %CustomColor%
WinSet, TransColor, %CustomColor%

x=1280 ; middle of monitor
xS:=x+18
y=400
yS:=y+18
y_sub:=y-100
yS_sub:=y_sub+18

number_of_sections = % sectionsArray.MaxIndex()
x_delta := (number_of_sections)*45 +9
x := x - x_delta
xS := xS - x_delta

Loop % sectionsArray.MaxIndex()
{
    this_section := sectionsArray[a_index]

	Gui, MAIN: Add, Picture, v%this_section%S  HWNDh%this_section%S x%xS% y%yS% h64 w64, buttons/%this_section%.png
	Gui, MAIN: Add, Picture, v%this_section%L  HWNDh%this_section%L x%x% y%y%  h100 w100, buttons/%this_section%.png
	GuiControl,MAIN:  HIDE, %this_section%L
	
	keys := ini_getAllKeyNames(ini, this_section)
	keysArray := StrSplit(keys, ",")

	number_of_keys = % keysArray.MaxIndex()
	x_sub_delta := (number_of_keys-1)*45 -45
	x_sub := x - x_sub_delta
	xS_sub := x + 18 - x_sub_delta

	Loop % keysArray.MaxIndex()
	{
		this_key := keysArray[a_index]

		if ( this_key != "link" )
		{
			Gui, MAIN: Add, Picture, v%this_section%%this_key%S  HWNDh%this_section%%this_key%S x%xS_sub% y%yS_sub% h64 w64, buttons/%this_section%/%this_key%.png
			Gui, MAIN: Add, Picture, v%this_section%%this_key%L  HWNDh%this_section%%this_key%L x%x_sub% y%y_sub%  h100 w100, buttons/%this_section%/%this_key%.png
			GuiControl,MAIN:  HIDE, %this_section%%this_key%S
			GuiControl,MAIN:  HIDE, %this_section%%this_key%L

			x_sub := x_sub +90
			xS_sub := xS_sub +90
		}
	}
	
	x := x+90
	xS := xS+90
}

Gui, MAIN: +E0x02000000 +E0x00080000 ; WS_EX_COMPOSITED & WS_EX_LAYERED => Double Buffer

WM_MOUSELEAVE:=0x2A3
cbSize:=A_PtrSize=4?16:24
TME_LEAVE:=0x00000002
dwFlags:=TME_LEAVE

VarSetCapacity(TRACKMOUSEEVENT, cbSize,0)
NumPut(cbSize, TRACKMOUSEEVENT, 0, "Uint")
NumPut(dwFlags, TRACKMOUSEEVENT, 4, "Uint")
NumPut(guiId, TRACKMOUSEEVENT, 8, "Ptr")
; NumPut(0, TRACKMOUSEEVENT, 8+A_PtrSize, "Uint") ; Not needed

if !DllCall("User32.dll\TrackMouseEvent", "Ptr", &TRACKMOUSEEVENT)
	Msgbox fail
else
	OnMessage(WM_MOUSELEAVE, "WM_MOUSELEAVE")
	
Gui, MAIN:Show, w2560 h1440 , MAIN

return

WM_MOUSEMOVE(wParam, lParam, Msg, hwnd)
{
	MouseGetPos,,,, c
	GuiControlGet, OutputVarControl, Name, % c
	
	init_buttons()

	global TRACKMOUSEEVENT
	OnMessage(0x200, "WM_MOUSEMOVE", 0)
	DllCall("User32.dll\TrackMouseEvent", "Ptr", &TRACKMOUSEEVENT)

	Loop % sectionsArray.MaxIndex()
	{
		this_section := sectionsArray[a_index]
		
		keys := ini_getAllKeyNames(ini, this_section)
		keysArray := StrSplit(keys, ",")
 
		IfEqual, OutputVarControl, %this_section%S
		{
			close_sub_buttons()
			GuiControl,MAIN: HIDE, %this_section%S	
			GuiControl,MAIN: SHOW, %this_section%L
		}
		
		Loop % keysArray.MaxIndex()
		{
			this_key := keysArray[a_index]
			IfEqual, OutputVarControl, %this_section%%this_key%S
			{
				Loop % keysArray.MaxIndex()
				{
					this_key2 := keysArray[a_index]
					GuiControl,MAIN: SHOW, %this_section%%this_key2%S	
					GuiControl,MAIN: HIDE, %this_section%%this_key2%L
				}
				GuiControl,MAIN: HIDE, %this_section%%this_key%S	
				GuiControl,MAIN: SHOW, %this_section%%this_key%L
			}
		}
	}
}

WM_MOUSELEAVE(wParam, lParam, Msg )
{
	init_buttons()
	OnMessage(0x200, "WM_MOUSEMOVE")
}


init_buttons()
{
	Loop % sectionsArray.MaxIndex()
	{
		this_section := sectionsArray[a_index]

		GuiControl,MAIN:  SHOW, %this_section%S
		GuiControl,MAIN:  HIDE, %this_section%L
	}
	return
}

close_sub_buttons()
{
	Loop % sectionsArray.MaxIndex()
	{
		this_section := sectionsArray[a_index]
		keys := ini_getAllKeyNames(ini, this_section)
		keysArray := StrSplit(keys, ",")
 
		Loop % keysArray.MaxIndex()
		{
			this_key := keysArray[a_index]
			if ( this_key != "link" )
			{
				GuiControl,MAIN: HIDE, %this_section%%this_key%S	
				GuiControl,MAIN: HIDE, %this_section%%this_key%L	
			}
		}
	} 
	return
}


~LButton::
	MouseGetPos, MouseX, MouseY, MouseWin, MouseCtl, 2
	
	close_sub_buttons()
	
	Loop % sectionsArray.MaxIndex()
	{
		this_section := sectionsArray[a_index]
		keys := ini_getAllKeyNames(ini, this_section)
		keysArray := StrSplit(keys, ",")
 
		if ( MouseCtl != "" )
		{
			If (MouseCtl = h%this_section%S || MouseCtl = h%this_section%L) 
			{
				URL := ini_getValue(ini, this_section, "link")   
				Run, %URL%
			} 
			
			Loop % keysArray.MaxIndex()
			{
				this_key := keysArray[a_index]
				If (MouseCtl = h%this_section%%this_key%S || MouseCtl = h%this_section%%this_key%L) 
				{
					URL := ini_getValue(ini, this_section, this_key)   
					Run, %URL%
				}
			}
		}
	}
	
return
	


~RButton::
	MouseGetPos, MouseX, MouseY, MouseWin, MouseCtl, 2
	
	Loop % sectionsArray.MaxIndex()
	{
		this_section := sectionsArray[a_index]
		keys := ini_getAllKeyNames(ini, this_section)
		keysArray := StrSplit(keys, ",")
 
		If (MouseCtl = h%this_section%S || MouseCtl = h%this_section%L) 
		{
			Loop % keysArray.MaxIndex()
			{
				this_key := keysArray[a_index]
				if ( this_key != "link" )
				{
					GuiControl,MAIN: SHOW, %this_section%%this_key%S	
				}
			}
		} 
	}
return


ini_getValue(ByRef _Content, _Section, _Key, _PreserveSpace = False)
{
    If (_Section = "")
        _Section = (?:\[.*])?
    Else
    {
         _Section = \[\s*?\Q%_Section%\E\s*?]
    }
    ; Note: The regex of this function was rewritten by Mystiq.
    RegEx = `aiU)(?:\R|^)\s*%_Section%\s*(?:\R\s*|\R\s*.+\s*=\s*.*?\s*(?=\R)|\R\s*[;#].*?(?=\R))*\R\s*\Q%_Key%\E\s*=(.*)(?=\R|$)
/*
    RegEx := "`aiU)"
      . "(?:\R|^)\s*" . _Section . "\s*"         ;-- section
      . "(?:"
      . "\R\s*"                           ;-- empty lines
      . "|\R\s*[\w\s]+\s*=\s*.*?\s*(?=\R)"      ;-- OR other key=value pairs
      . "|\R\s*[;#].*?(?=\R)"                  ;-- OR commented lines
      . ")*"
      . "\R\s*\Q" . _Key . "\E\s*=(.*)(?=\R|$)"   ;-- match
*/
   
    If RegExMatch(_Content, RegEx, Value)
    {
        If Not _PreserveSpace
        {
            Value1 = %Value1% ; Trim spaces.
            FirstChar := SubStr(Value1, 1, 1)
            If (FirstChar = """" AND SubStr(Value1, 0, 1)= """"
                OR FirstChar = "'" AND SubStr(Value1, 0, 1)= "'")
            {
                StringTrimLeft, Value1, Value1, 1
                StringTrimRight, Value1, Value1, 1
            }
        }
        ErrorLevel = 0
    }
    Else
    {
        ErrorLevel = 1
        Value1 =
    }
    Return Value1
}

ini_getAllKeyNames(ByRef _Content, _Section = "", ByRef _count = "")
{
    RegEx = `aisUmS)^.*(?:\s*\[\s*?.*\s*?]\s*|\s*?(.+)\s*?=.*).*$
    If (_Section != "")
        KeyNames := RegExReplace(ini_getSection(_Content, _Section), RegEx, "$1", Match)
    Else
        KeyNames := RegExReplace(_Content, RegEx, "$1", Match)
    If Match
    {
        KeyNames := RegExReplace(KeyNames, "S)\R+", ",")
        ; Workaround, sometimes it catches sections. Whitespaces only should be eliminated also.
        KeyNames := RegExReplace(KeyNames, "S)\[.*?],+|,+$|,+ +", "") 
        StringReplace, KeyNames, KeyNames, `,, `,, UseErrorLevel
        _count := ErrorLevel ? ErrorLevel : 0
        StringTrimLeft, KeyNames, KeyNames, 1
        ErrorLevel = 0
    }
    Else
    {
        ErrorLevel = 1
        _count = 0
        KeyNames =
    }
    Return KeyNames
}

ini_getSection(ByRef _Content, _Section)
{
    If (_Section = "")
        _Section = (?:\[.*])?
    Else
         _Section = \[\s*?\Q%_Section%\E\s*?]
    RegEx = `aisUS)^.*(%_Section%\s*\R?.*)(?:\R*\s*(?:\[.*?|\R))?$
    If RegExMatch(_Content, RegEx, Value)
        ErrorLevel = 0
    Else
    {
        ErrorLevel = 1
        Value1 =
    }
    Return Value1
}

ini_getAllSectionNames(ByRef _Content, ByRef _count = "")
{
    RegEx = `aisUmS)^.*(?:\s*\[\s*?(.*)\s*?]\s*|.+=.*).*$
    SectionNames := RegExReplace(_Content, RegEx, "$1", MatchNum)
    If MatchNum
    {
        SectionNames := RegExReplace(SectionNames, "S)\R+", ",", _count)
        ; Workaround, whitespaces only should be eliminated.
        SectionNames := RegExReplace(SectionNames, "S),+ +", "") 
        StringReplace, SectionNames, SectionNames, `,, `,, UseErrorLevel
        _count := ErrorLevel ? ErrorLevel : 0
        _count := _count ? _count : 0
        StringTrimRight, SectionNames, SectionNames, 1
        ErrorLevel = 0
    }
    Else
    {
        ErrorLevel = 1
        _count = 0
        SectionNames =
    }
    Return SectionNames
}
Example of
buttons.ini

Code: Select all

[reddit]
link = https://www.reddit.com/r/popular/
de = https://www.reddit.com/r/de/new/
granturismo = https://www.reddit.com/r/granturismo/new/
simracing = https://www.reddit.com/r/simracing/new/
formula1 = https://www.reddit.com/r/formula1/new/
fifa = https://www.reddit.com/r/fifa/new/

[twitter]
link = https://twitter.com/i/trends

[youtube]
link = https://www.youtube.com/

[mydealz]
link = https://www.mydealz.de/
idealo = https://www.idealo.de/
geizhals = https://geizhals.de/
Icons
https://filehorst.de/d/ehfcvmoa

Post Reply

Return to “Scripts and Functions (v1)”