AHK GUIs - Can parts of a window be made invisible? Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Gary-Atlan82
Posts: 74
Joined: 07 Mar 2023, 05:20

AHK GUIs - Can parts of a window be made invisible?

02 Aug 2023, 16:02

I want to create a simple pop up window that I want use to select a value with the mouse wheel.

The GUI pops up while right click is down and closes when its released, only mouse wheel should be used.

I want to populate the GUIs fields with predetermined values:

Code: Select all

MyNumRange1 := "10-80"
MyColours := ["Pink", "Yellow", "Black", "Blue", "Red", "white", "Green"]
MyNumRange2 := "91-97"
Output := SelectionGUI(MyNumRange1, MyColours, MyNumRange2)
When I release right click, OutPut Should look like:

Code: Select all

Output := ["40", "Blue", "94"]
I have designed the GUI to look like this:
Image


I have become somewhat comfortable writing functions, that part I understand but I have no experience with writing GUIs, I have always wanted to. I have watched Hellbent do some amazing stuff with them too.

The thing that is giving me worry is how to handle numbers. I want to be able to increment/decrement a number in a field by units of 10, a whole number or by a decimal. All with just the mouse wheel.

I was thinking if I make parts of the window the GUI belongs to invisible, so the window is actually larger than it seems, then I can trigger certain events depending on the "zone" the mouse in. I created this graphic to better explain:
Image


But is it possible to actually do this, as in make parts of the window entirely invisible, does win WIN32 and AHK even support this?

I have looked around for AHK code that decrement numbers in a variety of manner and I have only managed to find examples using DLLs.

If someone knows of a solution done with AHK I would love to know.

Also if you have better ideas I would really like to know, my experience in GUIs are limited.


PS:I have heard AHK V2 has much better GUI support with Objects etc but due to libraries I rely on I am stuck on V1 for now.
off
Posts: 176
Joined: 18 Nov 2022, 21:54

Re: AHK GUIs - Can parts of a window be made invisible?

02 Aug 2023, 22:42

Hello!

I dont fully understand what you wanted, but i managed to create this scrollable selection gui (kinda bad looking, since this only test)
This script will just open up GUI when you right click anywhere, and its scrollable. Release RMB and MsgBox will tell you what is the output.

Code: Select all

CoordMode, Mouse, Screen

choices := "Choice 1|Choice 2|Choice 3"
choiceAll := StrSplit(choices, "|")
maxScroll := choiceAll.Length()

RButton::
MouseGetPos, mpX, mpY

Gui RMBMenu: -Caption +LastFound
Gui RMBMenu: Add, ListBox, w100 x0 y0 gsubmit vscrollText +AltSubmit, % choices
Gui RMBMenu: Show, % "x" mpX + 10 . " y" mpY . " w100 h15"

Send, {Down}
GoSub, submit

Hotkey, *WheelUp, wUp, On
Hotkey, *WheelUp, Off
Hotkey, *WheelDown, wDown, On
Return

RButton Up::
Gui RMBMenu: Destroy

Hotkey, *WheelUp, Off
Hotkey, *WheelDown, Off

MsgBox, % choiceAll[scrollText]
Return

wUp:
If (scrollText <= 1)
	HotKey, *WheelUp, Off
If (scrollText < maxScroll)
	Hotkey, *WheelDown, wDown, On
	
GuiControlGet stPos, RMBMenu: Pos, scrollText
GuiControl RMBMenu: Move, scrollText, % "y" stPosY + 13
Send, {Up}

If (scrollText <= 1)
	HotKey, *WheelUp, Off
If (scrollText < maxScroll)
Return

wDown:
If (scrollText >= maxScroll)
	HotKey, *WheelDown, Off
If (scrollText > 1)
	Hotkey, *WheelUp, wUp, On
	
GuiControlGet stPos, RMBMenu: Pos, scrollText
GuiControl RMBMenu: Move, scrollText, % "y" stPosY - 13
Send, {Down}

If (scrollText >= maxScroll)
	HotKey, *WheelDown, Off
If (scrollText > 1)
Return

submit:
Gui, Submit, NoHide
Return

Again, im still can't understand your wanted result, but this is maybe the basic for that.

EDIT:
After i re-read your post, i get that you wanted if the Mouse is above the GUI after holding Right Click, the value should increase/decrease by 0.1/0.5 decimal (my guess is 0.1 :shrug:). If the Mouse is ON the GUI, the value should in/decrease by 1. And if the Mouse is under the GUI, value will in/decrease by 10.

But then it hit me, what the purpose of Color name in the selection? What is the usage for the second number list? Please help me by clearing things up, and correct me if im wrong at some point. We can always discuss about that. And sorry for my limited english.

- Off
My Creations
IMG2HotString - Send image file easily with your hotstring!
CtrlSend - A small solution for sending keys to window in background that doesn't accept ControlSend's key
ControlProcess
User avatar
Hellbent
Posts: 2114
Joined: 23 Sep 2017, 13:34

Re: AHK GUIs - Can parts of a window be made invisible?  Topic is solved

03 Aug 2023, 02:30

I'm not sure if this is what you are looking for or not.
If you have any questions feel free to ask.

.
tf 1.gif
tf 1.gif (249.78 KiB) Viewed 892 times
.

Code: Select all

;****************************************************************************************************************************************************************************
#Include <My Altered GDIP lib> ;GDIP:  https://www.autohotkey.com/boards/viewtopic.php?f=6&t=6517
;~ #Include <PopUpWindow_V2> ; At the bottom of the script 
;****************************************************************************************************************************************************************************
#SingleInstance, Force
SetBatchLines, -1
Gdip_Startup()

CanUse := 1 ;For demo. Turns on the RButton Hotkey

return

*ESC::ExitApp

SelectionGUI( set1 , set2 , set3 ){ ;Pass 3 sets of data ( each has a current value a max value a min value and an optional replacement array of text values )
	;**********
	Sections := 3 
	SectionWidth := 100
	SectionHeight := 30
	Margin := 10
	;**********
	CoordMode, Mouse, Screen 
	MouseGetPos, x , y 
	;**********
	w := Sections * SectionWidth + ( Sections + 1 ) * Margin  
	h := SectionHeight + 2 * Margin
	x := x - w / 2
	y := y - h / 2
	;**********
	global MyGui := New PopUpWindow( { AutoShow: 1 , X: x , Y: y , W: w , H: h , Options: " +AlwaysOnTop -DPIScale +E0x20 +ToolWindow " } ) ;+E0x20 = click through window
	;**********
	;transfer values to the window object to make passing values to the drawing function easier.
	MyGui.Sections := Sections
	MyGui.SectionWidth := SectionWidth
	MyGui.SectionHeight := SectionHeight
	MyGui.Margin := Margin
	;**********
	MyGui.MyValues := []
	MyGui.MyValues[ 1 ] := Set1
	MyGui.MyValues[ 2 ] := Set2
	MyGui.MyValues[ 3 ] := Set3
	;**********
	DrawWindow( MyGui )
	;**********
	MyGui.Active := 1
	;**********
}
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
#If ( CanUse ) ;For demo purposes. If you  wanted to have a way of turning on and off the RButton hotkey you can change the value of "CanUse"

	RButton:: ;RButton down
		set1 := { CurrentValue: 10 , MaxValue: 80 , MinValue: 10 }
		set2 := { CurrentValue: 1 , MaxValue: 7 , MinValue: 1 , TextReplacementArray: [ "Pink", "Yellow", "Black", "Blue", "Red", "white", "Green"] }
		set3 := { CurrentValue: 91 , MaxValue: 97 , MinValue: 91 }
		SelectionGUI( set1 , set2 , set3 )
		keyWait, RButton
		return
		
	;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
	;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

	RButton Up::

		Loop, 3	{
			
			if( MyGui.MyValues[ A_Index ].Haskey( "TextReplacementArray" ) )
				v%A_Index% := MyGui.MyValues[ A_Index ].TextReplacementArray[ MyGui.MyValues[ A_Index ].CurrentValue ]
			else 
				v%A_Index% := MyGui.MyValues[ A_Index ].CurrentValue
		
		}
		
		;()___()___()___()___()___()
		;()___()___()___()___()___()
		output := [ v1 , v2 , v3 ]   ;<<<---- Your output [ 10 , "Pink" , 92 ]
		;()___()___()___()___()___()
		;()___()___()___()___()___()
		
		MyGui.Active := 0
		MyGui.DeleteWindow()
		MyGui := ""
		
		Msgbox, % output[ 1 ] "`n" output[ 2 ] "`n" output[ 3 ]
		return
#If 

;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

#If ( MyGui.Active )
	
	WheelUp::
		CoordMode, Mouse , Screen
		MouseGetPos, x , y
		
		x -= MyGui.X
		
	
		currentSection := ""
		
		if( x <= ( MyGui.SectionWidth + MyGui.Margin * 1.5 ) ){
			currentSection := 1
		}else if( x <= ( MyGui.SectionWidth * 2 + MyGui.Margin * 2.5 )  ){
			currentSection := 2
		}else{
			currentSection := 3
		}
		
		if( y < MyGui.Y ){
			
			if( !MyGui.MyValues[ currentSection ].HasKey( "TextReplacementArray" ) ){
				MyGui.MyValues[ currentSection ].CurrentValue += 0.1
				if( MyGui.MyValues[ currentSection ].CurrentValue > MyGui.MyValues[ currentSection ].MaxValue ){
					MyGui.MyValues[ currentSection ].CurrentValue := MyGui.MyValues[ currentSection ].MaxValue
				}
				DrawWindow( MyGui )
				
			}
			
		}else if( y <= MyGui.Y + MyGui.H ){
			MyGui.MyValues[ currentSection ].CurrentValue += 1
			if( MyGui.MyValues[ currentSection ].CurrentValue > MyGui.MyValues[ currentSection ].MaxValue ){
				MyGui.MyValues[ currentSection ].CurrentValue := MyGui.MyValues[ currentSection ].MaxValue
			}
			DrawWindow( MyGui )
				
		}else{
			MyGui.MyValues[ currentSection ].CurrentValue += 10
			if( MyGui.MyValues[ currentSection ].CurrentValue > MyGui.MyValues[ currentSection ].MaxValue ){
				MyGui.MyValues[ currentSection ].CurrentValue := MyGui.MyValues[ currentSection ].MaxValue
			}
			DrawWindow( MyGui )
		}
		sleep, 30
		return
	;#################################
	;#################################
	WheelDown::
		CoordMode, Mouse , Screen
		MouseGetPos, x , y
		x -= MyGui.X
		currentSection := ""
		if( x <= ( MyGui.SectionWidth + MyGui.Margin * 1.5 ) ){
			currentSection := 1
		}else if( x <= ( MyGui.SectionWidth * 2 + MyGui.Margin * 2.5 )  ){
			currentSection := 2
		}else{
			currentSection := 3
		}
		if( y < MyGui.Y ){
			if( !MyGui.MyValues[ currentSection ].HasKey( "TextReplacementArray" ) ){
				MyGui.MyValues[ currentSection ].CurrentValue -= 0.1
				if( MyGui.MyValues[ currentSection ].CurrentValue < MyGui.MyValues[ currentSection ].MinValue ){
					MyGui.MyValues[ currentSection ].CurrentValue := MyGui.MyValues[ currentSection ].MinValue
				}
				DrawWindow( MyGui )
			}
		}else if( y <= MyGui.Y + MyGui.H ){
			MyGui.MyValues[ currentSection ].CurrentValue -= 1
			if( MyGui.MyValues[ currentSection ].CurrentValue < MyGui.MyValues[ currentSection ].MinValue ){
				MyGui.MyValues[ currentSection ].CurrentValue := MyGui.MyValues[ currentSection ].MinValue
			}
			DrawWindow( MyGui )
				
		}else{
			MyGui.MyValues[ currentSection ].CurrentValue -= 10
			if( MyGui.MyValues[ currentSection ].CurrentValue < MyGui.MyValues[ currentSection ].MinValue ){
				MyGui.MyValues[ currentSection ].CurrentValue := MyGui.MyValues[ currentSection ].MinValue
			}
			DrawWindow( MyGui )
		}
		Sleep, 30
		return
	
#If
;*******************************************************************
DrawWindow( obj ){
	obj.ClearWindow()
	obj.DrawBitmap( WindowGraphics( obj ) , { X: 0 , Y: 0 , W: obj.W , H: obj.H } , dispose := 1 , AutoUpdate := 1 )
}
;*******************************************************************
WindowGraphics( obj ){
	pBitmap := Gdip_CreateBitmap( obj.W , obj.H ) 
	G := Gdip_GraphicsFromImage( pBitmap ) 
	Gdip_SetSmoothingMode( G , 2 )
	x := 2
	y := 2 
	w := obj.W - 4
	h := obj.H - 4
	Brush := Gdip_BrushCreateSolid( "0x99000000" ) 
	Gdip_FillRoundedRectangle( G , Brush , x , y , w , h , 5 ) 
	Gdip_DeleteBrush( Brush )
	x := obj.Margin
	y := obj.Margin
	w := obj.SectionWidth
	h := obj.SectionHeight
	sectionColors := [ "0x99336699" , "0x993388bb" , "0x9933aaff" ]
	Loop, % obj.Sections	{
		Brush := Gdip_BrushCreateSolid( sectionColors[ A_Index ] ) 
		Gdip_FillRoundedRectangle( G , Brush , x , y , w , h , 5 ) 
		Gdip_DeleteBrush( Brush )
		if( obj.MyValues[ A_Index ].Haskey( "TextReplacementArray" ) )
			value := obj.MyValues[ A_Index ].TextReplacementArray[ obj.MyValues[ A_Index ].CurrentValue ]
		else 
			value := obj.MyValues[ A_Index ].CurrentValue
		Brush := Gdip_BrushCreateSolid( "0xFFFFFFFF" ) 
		Gdip_TextToGraphics( G , value , "s" 16  " Center vCenter Bold c" Brush " x" x " y" y , "Segoe UI" , w , h ) 
		Gdip_DeleteBrush( Brush )
		x += obj.Margin + obj.SectionWidth
	}
	Gdip_DeleteGraphics( G )
	return pBitmap
}

;Layered Window Class
;####################################################################################################################################################################################
;####################################################################################################################################################################################
;####################################################################################################################################################################################
;####################################################################################################################################################################################
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( alpha := 255 ){
		UpdateLayeredWindow( This.hwnd , This.hdc , This.X , This.Y , This.W , This.H , alpha )
	}
	ClearWindow( AutoUpdate := 0 , Color := "" ){
		if( color != "" )
			Gdip_GraphicsClear( This.G , color )
		else
			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 ]
		
	}
}
Gary-Atlan82
Posts: 74
Joined: 07 Mar 2023, 05:20

Re: AHK GUIs - Can parts of a window be made invisible?

03 Aug 2023, 15:12

Yes that is exactly what I had in mind. You are genius, I cannot thank you enough. I understand much better now. I learnt allot here, I did not know it was as easy as += 10 or += 0.1 to implement an incrementing solution!

You know I was thinking of mentioning you with, @Hellbent, but decided against it as I thought it would be in bad etiquette, imagine my surprise when you not only showed up but actually wrote the program that I had in mind to a "t". Really thank you so much for this most helpful and insightful post.

I really like your way of working with GUIs, using custom images made in Paint/Photoshop as controls. I am rewatching your series on GUIs but I wonder is the method you are using here the same method you use in the tools your released publicly such as Color Picker and in your GUI series?

I inspected the window while it was open with the AHK spy tool, it does not seem to detect anything, no window title etc. AHK GUI controls etc, are fully transparent to the spy window, their greatest strength for me.

If I may, I have two questions:
  • With this Gdip aproach, is it possible to turn a control to drop a down control that when clicked, reveals all its items, on the condition that it has strings, like colour names?
  • Is it possible to have a combination of this method (Gdip drawings?) and a native AHK GUI window?
Gary-Atlan82
Posts: 74
Joined: 07 Mar 2023, 05:20

Re: AHK GUIs - Can parts of a window be made invisible?

03 Aug 2023, 15:15

@off
Hey thanks for this. It works as I wanted it to in the case of strings. Very insightful and will go through it more careful to figure out how you achieved this. Cheers!
User avatar
Hellbent
Posts: 2114
Joined: 23 Sep 2017, 13:34

Re: AHK GUIs - Can parts of a window be made invisible?

04 Aug 2023, 03:36

Gary-Atlan82 wrote:
03 Aug 2023, 15:12
Yes that is exactly what I had in mind. You are genius, I cannot thank you enough. I understand much better now. I learnt allot here, I did not know it was as easy as += 10 or += 0.1 to implement an incrementing solution!
You're welcome.
I have been using ahk for around 8 years now and I still pick up new things on the regular. I haven't even started trying to learn V2 yet so I'm sure that there is more than enough to keep me learning new things for years to come.
You know I was thinking of mentioning you with, @Hellbent, but decided against it as I thought it would be in bad etiquette, imagine my surprise when you not only showed up but actually wrote the program that I had in mind to a "t". Really thank you so much for this most helpful and insightful post.
I'm glad that it was what you were looking for, I wasn't sure based on the subject name lol.
I don't mind being mentioned, I just don't always have the time or patience to reply or to give the reply you might be hoping for.
Often I will see a notification but not have the time at that moment and then end up forgetting all about it.

I really like your way of working with GUIs, using custom images made in Paint/Photoshop as controls. I am rewatching your series on GUIs but I wonder is the method you are using here the same method you use in the tools your released publicly such as Color Picker and in your GUI series?
Most of my videos are a bit behind how I do things now but they do cover much of the basics and beyond.
For the last few years I have been moving more and more to layered ( user drawn ) windows because of the control it gives, the downside has been that there's not really any control types that can be used. I have started creating a number of control types for layered windows but all of them are still barely more developed than proof of concept or first draft at best.

This script was like that color picker but I didn't bother really creating a structure around controls ( The sections of the window didn't really need to be conceptual "Controls" , but they do share some commonalities ).

Here are two things to try to remember, if you can really understand them you can create just about anything you want.

1. There is no "Window" ( there is no spoon ). What you really have are

- Pixels
- Triggers
- Actions

2. Windows and controls are just about literally the same things.

:crazy:

I inspected the window while it was open with the AHK spy tool, it does not seem to detect anything, no window title etc. AHK GUI controls etc, are fully transparent to the spy window, their greatest strength for me.
I had added the window option +E0x20 which makes the window clickthrough. This also removes the ability to ping the window or triggering some of the window messages OnMessage() such as 0x200 ( mouse movement over the window ).
I don't think that you really needed it but since there wasn't a need to directly interact with the window I just added it in for the hell of it.

If I may, I have two questions:
  • With this Gdip aproach, is it possible to turn a control to drop a down control that when clicked, reveals all its items, on the condition that it has strings, like colour names?
  • Is it possible to have a combination of this method (Gdip drawings?) and a native AHK GUI window?
1. Yes it is very possible to add a dropdown list using the GDIP aproach.
Adding that in can be anywhere from rather simple to very complex. It really comes down to the features you want. The simplest method is to create a simple window with rows of text that can detect where you clicked based on simple rectangles. That window would be toggled by clicking on the text in the main window.
When I say simple I have to put a bit of an asterisk on it because it does require some level of understanding the whole pixel, trigger, actions thing.
Fortunately I may have a control that you can use if you are running windows 8 or higher.
This control is still an early draft but I have used it in a few projects and besides the fact that it can't take a really long list ( 200+ items ) I haven't had it bug out on me yet.

I took the code I gave you earlier and used some duct tape to add a dropdownlist to the center section of the window. If you end up using the ddl control you can add a bit of logic, etc. to better integrate it in. I have no problem offering assistance if needed.

.
tf 3.gif
tf 3.gif (196.95 KiB) Viewed 821 times
.

Code: Select all

;****************************************************************************************************************************************************************************
#Include <My Altered GDIP lib> ;GDIP:  https://www.autohotkey.com/boards/viewtopic.php?f=6&t=6517
;~ #Include <PopUpWindow_V2> ; At the bottom of the script 
;****************************************************************************************************************************************************************************
#SingleInstance, Force
SetBatchLines, -1
Gdip_Startup()

CanUse := 1 ;For demo. Turns on the RButton Hotkey

return

*ESC::ExitApp



SelectionGUI( set1 , set2 , set3 ){ ;Pass 3 sets of data ( each has a current value a max value a min value and an optional replacement array of text values )
	;**********
	Sections := 3 
	SectionWidth := 150
	SectionHeight := 30
	Margin := 10
	;**********
	CoordMode, Mouse, Screen 
	MouseGetPos, x , y 
	;**********
	w := Sections * SectionWidth + ( Sections + 1 ) * Margin  
	h := SectionHeight + 2 * Margin
	x := x - w / 2
	y := y - h / 2
	;**********
	global MyGui := New PopUpWindow( { AutoShow: 1 , X: x , Y: y , W: w , H: h , Options: " +AlwaysOnTop -DPIScale +ToolWindow " } ) ;+E0x20 = click through window
	;**********
	
	;********************************************
	
	MyList := Set2.TextReplacementArray
	
	;~ BoundFunc := Func( "TestFunction" ).Bind( MyGui )
			
	MyGui.MyCenterDDL := New DropDownListv1( { rows: 				3
											, X:					170 
											, Y: 					10
											;~ , Bind: 				BoundFunc
											, ScaleFactor: 			1
											, W: 					150 
											, FontSize: 			15 
											, FontColor: 			"0xFFFF0000" 
											, Font: 				"Segoe UI" 
											, Parent: 				MyGui.Hwnd 
											, Selected:     		1	
											, HighlightFontColor:   "0xFFFFFFFF"	
											, List: 				MyList } )	
											
	;********************************************
	
	
	;**********
	;transfer values to the window object to make passing values to the drawing function easier.
	MyGui.Sections := Sections
	MyGui.SectionWidth := SectionWidth
	MyGui.SectionHeight := SectionHeight
	MyGui.Margin := Margin
	;**********
	MyGui.MyValues := []
	MyGui.MyValues[ 1 ] := Set1
	MyGui.MyValues[ 2 ] := Set2
	MyGui.MyValues[ 3 ] := Set3
	;**********
	DrawWindow( MyGui )
	;**********
	MyGui.Active := 1
	;**********
}
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
#If ( CanUse ) ;For demo purposes. If you  wanted to have a way of turning on and off the RButton hotkey you can change the value of "CanUse"

	RButton:: ;RButton down
		set1 := { CurrentValue: 10 , MaxValue: 80 , MinValue: 10 }
		set2 := { CurrentValue: 1 , MaxValue: 7 , MinValue: 1 , TextReplacementArray: [ "Pink", "Yellow", "Black", "Blue", "Red", "white", "Green"] }
		set3 := { CurrentValue: 91 , MaxValue: 97 , MinValue: 91 }
		SelectionGUI( set1 , set2 , set3 )
		keyWait, RButton
		return
		
	;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
	;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

	RButton Up::
		
		MyGui.MyValues[ 2 ].CurrentValue := MyGui.MyCenterDDL.Selected
		
		Loop, 3	{
			
			if( MyGui.MyValues[ A_Index ].Haskey( "TextReplacementArray" ) )
				v%A_Index% := MyGui.MyValues[ A_Index ].TextReplacementArray[ MyGui.MyValues[ A_Index ].CurrentValue ]
			else 
				v%A_Index% := MyGui.MyValues[ A_Index ].CurrentValue
		
		}
		
		
		;()___()___()___()___()___()
		;()___()___()___()___()___()
		output := [ v1 , v2 , v3 ]   ;<<<---- Your output [ 10 , "Pink" , 92 ]
		;()___()___()___()___()___()
		;()___()___()___()___()___()
		
		MyGui.Active := 0
		MyGui.DeleteWindow()
		MyGui := ""
		
		;~ Msgbox, % output[ 1 ] "`n" output[ 2 ] "`n" output[ 3 ]
		ToolTip, % output[ 1 ] "`n" output[ 2 ] "`n" output[ 3 ]
		return
#If 

;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
CheckDDL( MyGui ){
	MouseGetPos,,, win , ctrl , 2
	if( ctrl = MyGui.MyCenterDDL.ToggleButton.Hwnd || win = MyGui.MyCenterDDL.Gui2.Hwnd )
		return 1
	return 0
}
;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

#If ( MyGui.Active && !CheckDDL( MyGui ) )
	
	WheelUp::
		CoordMode, Mouse , Screen
		MouseGetPos, x , y 
		x -= MyGui.X
		currentSection := ""
		if( x <= ( MyGui.SectionWidth + MyGui.Margin * 1.5 ) ){
			currentSection := 1
		}else if( x <= ( MyGui.SectionWidth * 2 + MyGui.Margin * 2.5 )  ){
			return
			currentSection := 2
		}else{
			currentSection := 3
		}
		
		if( y < MyGui.Y ){
			
			if( !MyGui.MyValues[ currentSection ].HasKey( "TextReplacementArray" ) ){
				MyGui.MyValues[ currentSection ].CurrentValue += 0.1
				if( MyGui.MyValues[ currentSection ].CurrentValue > MyGui.MyValues[ currentSection ].MaxValue ){
					MyGui.MyValues[ currentSection ].CurrentValue := MyGui.MyValues[ currentSection ].MaxValue
				}
				DrawWindow( MyGui )
				
			}
			
		}else if( y <= MyGui.Y + MyGui.H ){
			MyGui.MyValues[ currentSection ].CurrentValue += 1
			if( MyGui.MyValues[ currentSection ].CurrentValue > MyGui.MyValues[ currentSection ].MaxValue ){
				MyGui.MyValues[ currentSection ].CurrentValue := MyGui.MyValues[ currentSection ].MaxValue
			}
			DrawWindow( MyGui )
				
		}else{
			MyGui.MyValues[ currentSection ].CurrentValue += 10
			if( MyGui.MyValues[ currentSection ].CurrentValue > MyGui.MyValues[ currentSection ].MaxValue ){
				MyGui.MyValues[ currentSection ].CurrentValue := MyGui.MyValues[ currentSection ].MaxValue
			}
			DrawWindow( MyGui )
		}
		return
	;#################################
	;#################################
	WheelDown::
		CoordMode, Mouse , Screen
		MouseGetPos, x , y
		x -= MyGui.X
		currentSection := ""
		if( x <= ( MyGui.SectionWidth + MyGui.Margin * 1.5 ) ){
			currentSection := 1
		}else if( x <= ( MyGui.SectionWidth * 2 + MyGui.Margin * 2.5 )  ){
			currentSection := 2
		}else{
			currentSection := 3
		}
		if( y < MyGui.Y ){
			if( !MyGui.MyValues[ currentSection ].HasKey( "TextReplacementArray" ) ){
				MyGui.MyValues[ currentSection ].CurrentValue -= 0.1
				if( MyGui.MyValues[ currentSection ].CurrentValue < MyGui.MyValues[ currentSection ].MinValue ){
					MyGui.MyValues[ currentSection ].CurrentValue := MyGui.MyValues[ currentSection ].MinValue
				}
				DrawWindow( MyGui )
			}
		}else if( y <= MyGui.Y + MyGui.H ){
			MyGui.MyValues[ currentSection ].CurrentValue -= 1
			if( MyGui.MyValues[ currentSection ].CurrentValue < MyGui.MyValues[ currentSection ].MinValue ){
				MyGui.MyValues[ currentSection ].CurrentValue := MyGui.MyValues[ currentSection ].MinValue
			}
			DrawWindow( MyGui )
				
		}else{
			MyGui.MyValues[ currentSection ].CurrentValue -= 10
			if( MyGui.MyValues[ currentSection ].CurrentValue < MyGui.MyValues[ currentSection ].MinValue ){
				MyGui.MyValues[ currentSection ].CurrentValue := MyGui.MyValues[ currentSection ].MinValue
			}
			DrawWindow( MyGui )
		}
		return
	
#If
;*******************************************************************
DrawWindow( obj ){
	obj.ClearWindow()
	obj.DrawBitmap( WindowGraphics( obj ) , { X: 0 , Y: 0 , W: obj.W , H: obj.H } , dispose := 1 , AutoUpdate := 1 )
}
;*******************************************************************
WindowGraphics( obj ){
	pBitmap := Gdip_CreateBitmap( obj.W , obj.H ) 
	G := Gdip_GraphicsFromImage( pBitmap ) 
	Gdip_SetSmoothingMode( G , 2 )
	x := 2
	y := 2 
	w := obj.W - 4
	h := obj.H - 4
	Brush := Gdip_BrushCreateSolid( "0x99000000" ) 
	Gdip_FillRoundedRectangle( G , Brush , x , y , w , h , 5 ) 
	Gdip_DeleteBrush( Brush )
	x := obj.Margin
	y := obj.Margin
	w := obj.SectionWidth
	h := obj.SectionHeight
	;~ sectionColors := [ "0x99336699" , "0x993388bb" , "0x9933aaff" ]
	sectionColors := [ "0xFF22262a" , "0x993388bb" , "0xFF32363a" ]
	Loop, % obj.Sections	{
		if( A_Index = 2 ){
			x += obj.Margin + obj.SectionWidth
			continue
		}
		Brush := Gdip_BrushCreateSolid( sectionColors[ A_Index ] ) 
		Gdip_FillRoundedRectangle( G , Brush , x , y , w , h , 5 ) 
		Gdip_DeleteBrush( Brush )
		if( obj.MyValues[ A_Index ].Haskey( "TextReplacementArray" ) )
			value := obj.MyValues[ A_Index ].TextReplacementArray[ obj.MyValues[ A_Index ].CurrentValue ]
		else 
			value := obj.MyValues[ A_Index ].CurrentValue
		
		Loop, 2	{
			( A_Index = 1 ) ? ( Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , x += 1 , y += 1 ) : ( Brush := Gdip_BrushCreateSolid( "0xFFFF0000" ) , x -= 1 , y -= 1 )
			Gdip_TextToGraphics( G , value , "s" 15  " Center vCenter Bold c" Brush " x" x " y" y , "Segoe UI" , w , h ) 
			Gdip_DeleteBrush( Brush )
		}
		x += obj.Margin + obj.SectionWidth
	}
	Gdip_DeleteGraphics( G )
	return pBitmap
}

;Layered Window Class
;####################################################################################################################################################################################
;####################################################################################################################################################################################
;####################################################################################################################################################################################
;####################################################################################################################################################################################
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( alpha := 255 ){
		UpdateLayeredWindow( This.hwnd , This.hdc , This.X , This.Y , This.W , This.H , alpha )
	}
	ClearWindow( AutoUpdate := 0 , Color := "" ){
		if( color != "" )
			Gdip_GraphicsClear( This.G , color )
		else
			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 ]
		
	}
}

;*******************&&&&&&&&&&&&&&&&&&&&&&&&************************************&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
;*******************&&&&&&&&&&&&&&&&&&&&&&&&************************************&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
;*******************&&&&&&&&&&&&&&&&&&&&&&&&************************************&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
class DropDownListv1	{

	Value[]{
		Get{
			return This.List[ This.Selected ]
		}
	}
	__New( obj := "" ){
		This._SetDefaults()
		This._UpdateDefaults( obj )
		This._CreateWindows()
		This._CreateControls()
		This._DrawHeader()
		This._SetTimer( This.HoverTimer , 100 )
		;~ SoundBeep 777
	}
	_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.FontColor := "0xFFFFFFFF"
		
		
		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.MainColor := "0xFF32363a"
		
		
		
		
		;~ This.ArrowColor := "0xFF000000"
		This.ArrowColor := "0xFFFF0000"
		
		
		
		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.PanelColor1 := "0xFF22262a"
		
		
		
		;~ This.PanelColor2 := "0xFFEFEFEF"
		This.PanelColor2 := "0xFF12161a"
		
		
		
		
		;~ This.HighLightPanelColor := "0x3300AAFF"
		This.HighLightPanelColor := "0x33ff0000"
		
		
		
		;~ This.SelectedPanelColor := "0x990099FF"
		This.SelectedPanelColor := "0x99ff2222"
		
		
		
		
		This.SelectedFontColor := This.FontColor
		
		
		;~ This.HighlightFontColor := This.FontColor
		This.HighlightFontColor := "0xFFFFFFFF"
		
		
		This.HeaderFontColor := This.FontColor
		
		;~ This.SliderTrackColor := "0xFFDCDCDC"
		This.SliderTrackColor := "0xFF12161a"
		
		
		
		;~ This.SliderButtonColor := "0xFFFFFFFF"
		This.SliderButtonColor := "0xFF22262a"
		
		
		
		;~ This.SliderRidgeColor := "0x33333333"
		This.SliderRidgeColor := "0x66ff0000"
		
		
		This.BorderColor := "0x33000000"
		;~ This.BorderColor := "0xff0000ff"
		This.Hovered := ""
		This.PanelControls := []
		This.Active := 0
		This.CallBind := This._CallBind.Bind( This )
		This.HoverTimer := This._Hover.Bind( This )
		
		
		;~ This.FocusColor := "0x990099FF"
		This.FocusColor := "0x99ff0000"
		
		
		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( !IsObject( obj.Bind ) && obj.Bind )
			This.Bind := func( obj.Bind ).Bind( This )
		
		if( This.Rows < 5 )
			This.Rows := 5
		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
		
		if( ( This.ThumbRange / 0.5 ) < This.List.Length() ){
			
			Msgbox, 262144, Error, The list you are using exceeds the current maximum length. `n1
			exitApp
		}
		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.Interval -= 0.5
			This.TotalInterval := This.Interval * This.List.Length()
			This.ThumbHeight := This.ThumbRange - This.TotalInterval
			
		}
		
		if( ( This.ThumbHeight ) < 30 || !This.Interval ){
			
			Msgbox, 262144, Error, % "The list you are using exceeds the current maximum length. `n2 " 
			exitApp
		}
		
		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 )
			;~ This.Gui2.ClearWindow( 1 )
			;~ ToolTip, % "Here`n" This.Gui2.hwnd
		}
	}
	_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.StartingPosition := floor( ( This.Thumb.Y - This.ThumbMinY ) / This.Interval )
					
					
					
				}
				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 )
		
		;**************************************
		;~ ToolTip, % This.BorderColor
		Pen := Gdip_CreatePen( This.BorderColor , 1 ) , 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.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( "0xFF0000FF" ) , 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 )
		
		;~ Bob := This.BorderColor
		;~ Brush := Gdip_BrushCreateSolid( Bob ) , 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  , This.Font , ( 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  , This.Font , ( 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  , This.Font , ( 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()
	}
}
You can find the class for the DDL at the bottom of the script and you can compare and contrast the difference between the values in it and the values found in this version found here to see how you go about altering the colors / theme.

.
Image
.

https://www.autohotkey.com/boards/viewtopic.php?f=6&t=3851&start=340#p453660

Here are some of the values that you are looking for.

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 hard coded the values in the copy in your script but they can be set from outside the class in the same way that you add the new control.

example:

Code: Select all

MyList := Set2.TextReplacementArray		
	MyGui.MyCenterDDL := New DropDownListv1( { rows: 				3
											, X:					170 
											, Y: 					10
											;~ , Bind: 				BoundFunc
											, ScaleFactor: 			1
											, W: 					150 
											, FontSize: 			15 
											, FontColor: 			"0xFFFF0000" 
											, Font: 				"Segoe UI" 
											, Parent: 				MyGui.Hwnd 
											, Selected:     		1	
											, HighlightFontColor:   "0xFFFFFFFF"	
											, List: 				MyList } )	


2. If you are running windows 8 or higher you can add normal controls to the layered window. It is getting too late for me today but I'll try to create an example tomorrow.

3. You can just go fully with a normal gui. Perhaps now that @off likely knows what you are trying to do he can create an example of a possible way to do it?



Anyways, that's all for now. If you have any questions related to the above let me know.
Gary-Atlan82
Posts: 74
Joined: 07 Mar 2023, 05:20

Re: AHK GUIs - Can parts of a window be made invisible?

04 Aug 2023, 11:47

@Hellbent
For the last few years I have been moving more and more to layered ( user drawn ) windows because of the control it gives, the downside has been that there's not really any control types that can be used. I have started creating a number of control types for layered windows but all of them are still barely more developed than proof of concept or first draft at best.
I look forward to whatever result stemming from this, if you ever share it. I am sure it will be amazing.
1. There is no "Window" ( there is no spoon ). What you really have are

- Pixels
- Triggers
- Actions

1. Windows and controls are just about literally the same things.
I will keep this in mind going forward then, as I come to learn amore about GDI as well

Your changes to the original script you share on here (yesterday?) are quite something. GDI is quite clearly the way to go here, especially if what you want is unconventional windows that are highly interactive.
Also that thread you shared is amazing, some of the GUI examples, there like the one with the radio dials you shared, are exactly what I have been looking for.
It is getting too late for me today but I'll try to create an example tomorrow.
You have shared with me plenty man, I have resolved to take it slow and learn more about GDI, mostly using your code throughout the forums.
Anyways, that's all for now. If you have any questions related to the above let me know.
Thanks allot man, much appreciated.
User avatar
Hellbent
Posts: 2114
Joined: 23 Sep 2017, 13:34

Re: AHK GUIs - Can parts of a window be made invisible?

05 Aug 2023, 02:35

Gary-Atlan82 wrote:
04 Aug 2023, 11:47

Your changes to the original script you share on here (yesterday?) are quite something. GDI is quite clearly the way to go here, especially if what you want is unconventional windows that are highly interactive.
Also that thread you shared is amazing, some of the GUI examples, there like the one with the radio dials you shared, are exactly what I have been looking for.
Gdip is an awesome library, combine it with layered windows and you have the ability to do things that would be near impossible otherwise.
I can't even imagine the amount of effort it would take to create something as simple as this without using GDI+.

.
gdip 1.gif
gdip 1.gif (372.11 KiB) Viewed 762 times
.

But Gdi+ is only the "Pixels" part of what I had said. You still have to deal with triggers and actions.
Keep things simple to begin with and try to getting used to thing about the basics of how the thing you want to make works.
For example, most controls are combinations of buttons, checkboxes, radios, and edits. If you can figure out the logic for those controls you can create most control types ( stay away from edit types lol ). Like really, how does a button work? What about a checkbox, how does it work at a logical level? ( Those were rhetorical ).

If you want to learn how to use the lib, I recommend working through the tutorial examples found here:
https://www.autohotkey.com/boards/viewtopic.php?f=6&t=6517

Once you have played around with a layered window ( via the examples ) you can have a look at that popUpWindow class and you will see that it is just a wrapper for the stuff you were doing in the tuts. You can use the class or you can use the methods used in the tuts.

Tools also make a big difference.

.
bitmaps.gif
bitmaps.gif (983.54 KiB) Viewed 762 times
.

Code: Select all

;****************************************************************************************************************************************************************************
#Include <My Altered GDIP lib> ;<<<<<<<<<<<<<<<<<<---------------------------     gdip.ahk
#Include <PopUpWindow_V2> ; At the bottom of the script 
;****************************************************************************************************************************************************************************
#SingleInstance, Force
SetBatchLines, -1
Gdip_Startup()



MyGui := New PopUpWindow( { AutoShow: 1 , X: "Center" , Y: "Center" , W: 450 , H: 70 , Options: " +AlwaysOnTop -DPIScale " } ) 
MyGui.DrawBitmap( HB_BITMAP_MAKER( ScaleFactor := 1 ) , { X: 0 , Y: 0 , W: MyGui.W , H: MyGui.H } , dispose := 1 , AutoUpdate := 1 )


return
GuiClose:
GuiContextMenu:
*ESC::ExitApp

RALT::PopUpWindow.Helper()




HB_BITMAP_MAKER( ScaleFactor := 1 ){
	;Bitmap Created Using: HB Bitmap Maker
	pBitmap := Gdip_CreateBitmap( 450 * ScaleFactor , 70 * ScaleFactor ) , G := Gdip_GraphicsFromImage( pBitmap ) , Gdip_SetSmoothingMode( G , 2 )
	;~ Brush := Gdip_BrushCreateSolid( "0xFF333333" ) , Gdip_FillRectangle( G , Brush , -10 * ScaleFactor , -10 * ScaleFactor , 600 * ScaleFactor , 200 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_BrushCreateSolid( "0x99000000" ) , Gdip_FillRoundedRectangle( G , Brush , 11 * ScaleFactor , 11 * ScaleFactor , 418 * ScaleFactor , 49 * ScaleFactor , 15 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_BrushCreateHatch( "0xff880000" , "0xFF000000" , 39 ) , Gdip_FillRoundedRectangle( G , Brush , 10 * ScaleFactor , 10 * ScaleFactor , 417 * ScaleFactor , 47 * ScaleFactor , 15 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_CreateLineBrushFromRect( 12 * ScaleFactor , 15 * ScaleFactor , 413 * ScaleFactor , 40 * ScaleFactor , "0xFFFF0000" , "0xFF000000" , 1 , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 2 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawRoundedRectangle( G , Pen , 10 * ScaleFactor , 10 * ScaleFactor , 417 * ScaleFactor , 47 * ScaleFactor , 15 * ScaleFactor ) , Gdip_DeletePen( Pen )
	;section 1
	Brush := Gdip_CreateLineBrush( 62 * ScaleFactor , 14 * ScaleFactor , 87 * ScaleFactor , 13 * ScaleFactor , "0x66880000" , "0x66000000" , 1 ) , Gdip_FillRoundedRectangle( G , Brush , 20 * ScaleFactor , 15 * ScaleFactor , 130 * ScaleFactor , 40 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	;section 1
	Brush := Gdip_CreateLineBrush( 62 * ScaleFactor , 14 * ScaleFactor , 87 * ScaleFactor , 13 * ScaleFactor , "0x33F0F0F0" , "0x66000000" , 1 ) , Gdip_FillRoundedRectangle( G , Brush , 20 * ScaleFactor , 15 * ScaleFactor , 130 * ScaleFactor , 40 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	;section 1
	Brush := Gdip_CreateLineBrushFromRect( 21 * ScaleFactor , 14 * ScaleFactor , 127 * ScaleFactor , 40 * ScaleFactor , "0x66ff0000" , "0x66000000" , 1 , 1 ) , Gdip_FillRoundedRectangle( G , Brush , 20 * ScaleFactor , 15 * ScaleFactor , 130 * ScaleFactor , 40 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_CreateLineBrushFromRect( 22 * ScaleFactor , 17 * ScaleFactor , 128 * ScaleFactor , 37 * ScaleFactor , "0xFFFF0000" , "0xFF000000" , 1 , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 1 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawRoundedRectangle( G , Pen , 20 * ScaleFactor , 15 * ScaleFactor , 130 * ScaleFactor , 40 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeletePen( Pen )
	Brush := Gdip_CreateLineBrushFromRect( 31 * ScaleFactor , 22 * ScaleFactor , 112 * ScaleFactor , 31 * ScaleFactor , "0xFF000000" , "0xFF32363a" , 1 , 1 ) , Gdip_FillEllipse( G , Brush , 25 * ScaleFactor , 18 * ScaleFactor , 120 * ScaleFactor , 32 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_BrushCreateSolid( "0xFFff0000" ) , Gdip_TextToGraphics( G , "56" , "s" 20 * ScaleFactor " Center vCenter Bold NoWrap c" Brush " x" 19 * ScaleFactor " y" 15 * ScaleFactor  , "MV Boli" , 130 * ScaleFactor , 40 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_TextToGraphics( G , "56" , "s" 20 * ScaleFactor " Center vCenter Bold NoWrap c" Brush " x" 21 * ScaleFactor " y" 17 * ScaleFactor  , "MV Boli" , 130 * ScaleFactor , 40 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_BrushCreateSolid( "0xFF880000" ) , Gdip_TextToGraphics( G , "56" , "s" 20 * ScaleFactor " Center vCenter Bold NoWrap c" Brush " x" 20 * ScaleFactor " y" 16 * ScaleFactor  , "MV Boli" , 130 * ScaleFactor , 40 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_CreateLineBrushFromRect( 25 * ScaleFactor , 21 * ScaleFactor , 119 * ScaleFactor , 28 * ScaleFactor , "0xFFFF0000" , "0xFF000000" , 1 , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 3 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawEllipse( G , Pen , 25 * ScaleFactor , 18 * ScaleFactor , 120 * ScaleFactor , 32 * ScaleFactor ) , Gdip_DeletePen( Pen )
	Brush := Gdip_CreateLineBrushFromRect( 25 * ScaleFactor , 21 * ScaleFactor , 119 * ScaleFactor , 28 * ScaleFactor , "0xFF000000" , "0x99FF0000" , 1 , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 2 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawEllipse( G , Pen , 25 * ScaleFactor , 19 * ScaleFactor , 120 * ScaleFactor , 30 * ScaleFactor ) , Gdip_DeletePen( Pen )
	;section 3
	Brush := Gdip_BrushCreateSolid( "0xFF333333" ) , Gdip_FillRoundedRectangle( G , Brush , 290 * ScaleFactor , 15 * ScaleFactor , 130 * ScaleFactor , 40 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	Gdip_DeleteGraphics( G )
	return pBitmap
}










The Bitmap maker can allow you to see what types of things you can do with gdip and allow you to make simple prototypes.
https://www.autohotkey.com/boards/viewtopic.php?f=6&t=62550



Some tips about how to use the popupwindow class:
https://www.autohotkey.com/boards/viewtopic.php?f=76&t=119325#p530316
Last edited by Hellbent on 05 Aug 2023, 02:37, edited 1 time in total.
User avatar
Hellbent
Posts: 2114
Joined: 23 Sep 2017, 13:34

Re: AHK GUIs - Can parts of a window be made invisible?

05 Aug 2023, 20:12

The graphics example from above coded in. ( Create your own design )
Why Red? Because that's the theme that the ddl has and I didn't want to change it :D

.
gdip 2.gif
gdip 2.gif (210.89 KiB) Viewed 684 times
.

Code: Select all

;****************************************************************************************************************************************************************************
#Include <My Altered GDIP lib> ;<<<<<<<<<<<<<<<<<<---------------------------     gdip.ahk
#Include <PopUpWindow_V2> ; At the bottom of the script 
;****************************************************************************************************************************************************************************
#SingleInstance, Force
SetBatchLines, -1
Gdip_Startup()

CanUse := 1

return

*ESC::ExitApp

;~ RALT::PopUpWindow.Helper()

SelectionGUI( set1 , set2 , set3 ){ ;Pass 3 sets of data ( each has a current value a max value a min value and an optional replacement array of text values )
	;**********
	Sections := 3 
	SectionWidth := 130
	SectionHeight := 40
	Margin := 15
	;**********
	CoordMode, Mouse, Screen 
	MouseGetPos, x , y 
	;**********
	w := 450 
	h := 70
	x := x - w / 2
	y := y - h / 2
	;**********
	global MyGui := New PopUpWindow( { AutoShow: 1 , X: x , Y: y , W: w , H: h , Options: " +AlwaysOnTop -DPIScale +ToolWindow " } ) ;+E0x20 = click through window
	;**********
	
	
	;********************************************
	MyList := Set2.TextReplacementArray		
	MyGui.MyCenterDDL := New DropDownListv1( { rows: 				1
											, X:					155
											, Y: 					15
											, ScaleFactor: 			1
											, W: 					130 
											, FontSize: 			17 
											, FontColor: 			"0xFFFF0000" 
											, MainColor: 			"0xFF0F1011" 
											, Font: 				"MV Boli" 
											, Parent: 				MyGui.Hwnd 
											, Selected:     		1	
											, HighlightFontColor:   "0xFFFFFFFF"
											, FontOptions:			"Center vCenter NoWrap Bold "
											, List: 				MyList } )	
											
	;********************************************
	MyGui.Controls.Section1 := { X: 20 , Y: 15 , W: 130 , H: 40 }
	for k , v in Set1
		MyGui.Controls.Section1[ k ] := Set1[ k ]
	
	;**********
	;transfer values to the window object to make passing values to the drawing function easier.
	MyGui.Sections := Sections
	MyGui.SectionWidth := SectionWidth
	MyGui.SectionHeight := SectionHeight
	MyGui.Margin := Margin
	;**********
	MyGui.MyValues := []
	MyGui.MyValues[ 1 ] := Set1
	MyGui.MyValues[ 2 ] := Set2
	MyGui.MyValues[ 3 ] := Set3
	;**********
	DrawWindow( MyGui )
	;**********
	MyGui.Active := 1
	;**********
}

;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
#If ( CanUse ) ;For demo purposes. If you  wanted to have a way of turning on and off the RButton hotkey you can change the value of "CanUse"

	RButton:: ;RButton down
		set1 := { CurrentValue: 10 , MaxValue: 80 , MinValue: 10 }
		set2 := { CurrentValue: 1 , MaxValue: 7 , MinValue: 1 , TextReplacementArray: [ "Pink", "Yellow", "Black", "Blue", "Red", "white", "Green"] }
		set3 := { CurrentValue: 91 , MaxValue: 97 , MinValue: 91 }
		SelectionGUI( set1 , set2 , set3 )
		keyWait, RButton
		return
		
	;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
	;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

	RButton Up::
		
		MyGui.MyValues[ 2 ].CurrentValue := MyGui.MyCenterDDL.Selected
		
		Loop, 3	{
			
			if( MyGui.MyValues[ A_Index ].Haskey( "TextReplacementArray" ) )
				v%A_Index% := MyGui.MyValues[ A_Index ].TextReplacementArray[ MyGui.MyValues[ A_Index ].CurrentValue ]
			else 
				v%A_Index% := MyGui.MyValues[ A_Index ].CurrentValue
		
		}
		
		
		;()___()___()___()___()___()
		;()___()___()___()___()___()
		output := [ v1 , v2 , v3 ]   ;<<<---- Your output [ 10 , "Pink" , 92 ]
		;()___()___()___()___()___()
		;()___()___()___()___()___()
		
		MyGui.MyCenterDDL.Delete()
		
		MyGui.Active := 0
		MyGui.DeleteWindow()
		MyGui := ""
		
		;~ Msgbox, % output[ 1 ] "`n" output[ 2 ] "`n" output[ 3 ]
		ToolTip, % output[ 1 ] "`n" output[ 2 ] "`n" output[ 3 ]
		return
#If 

;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
CheckDDL( MyGui ){
	MouseGetPos,,, win , ctrl , 2
	if( ctrl = MyGui.MyCenterDDL.ToggleButton.Hwnd || win = MyGui.MyCenterDDL.Gui2.Hwnd )
		return 1
	return 0
}
;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

#If ( MyGui.Active && !CheckDDL( MyGui ) )
	
	WheelUp::
		CoordMode, Mouse , Screen
		MouseGetPos, x , y 
		x -= MyGui.X
		currentSection := ""
		if( x <= ( MyGui.SectionWidth + MyGui.Margin * 1.5 ) ){
			currentSection := 1
		}else if( x <= ( MyGui.SectionWidth * 2 + MyGui.Margin * 2.5 )  ){
			return
			currentSection := 2
		}else{
			currentSection := 3
		}
		
		if( y < MyGui.Y ){
			
			if( !MyGui.MyValues[ currentSection ].HasKey( "TextReplacementArray" ) ){
				MyGui.MyValues[ currentSection ].CurrentValue += 0.1
				if( MyGui.MyValues[ currentSection ].CurrentValue > MyGui.MyValues[ currentSection ].MaxValue ){
					MyGui.MyValues[ currentSection ].CurrentValue := MyGui.MyValues[ currentSection ].MaxValue
				}
				DrawWindow( MyGui )
				
			}
			
		}else if( y <= MyGui.Y + MyGui.H ){
			MyGui.MyValues[ currentSection ].CurrentValue += 1
			if( MyGui.MyValues[ currentSection ].CurrentValue > MyGui.MyValues[ currentSection ].MaxValue ){
				MyGui.MyValues[ currentSection ].CurrentValue := MyGui.MyValues[ currentSection ].MaxValue
			}
			DrawWindow( MyGui )
				
		}else{
			MyGui.MyValues[ currentSection ].CurrentValue += 10
			if( MyGui.MyValues[ currentSection ].CurrentValue > MyGui.MyValues[ currentSection ].MaxValue ){
				MyGui.MyValues[ currentSection ].CurrentValue := MyGui.MyValues[ currentSection ].MaxValue
			}
			DrawWindow( MyGui )
		}
		return
	;#################################
	;#################################
	WheelDown::
		CoordMode, Mouse , Screen
		MouseGetPos, x , y
		x -= MyGui.X
		currentSection := ""
		if( x <= ( MyGui.SectionWidth + MyGui.Margin * 1.5 ) ){
			currentSection := 1
		}else if( x <= ( MyGui.SectionWidth * 2 + MyGui.Margin * 2.5 )  ){
			currentSection := 2
		}else{
			currentSection := 3
		}
		if( y < MyGui.Y ){
			if( !MyGui.MyValues[ currentSection ].HasKey( "TextReplacementArray" ) ){
				MyGui.MyValues[ currentSection ].CurrentValue -= 0.1
				if( MyGui.MyValues[ currentSection ].CurrentValue < MyGui.MyValues[ currentSection ].MinValue ){
					MyGui.MyValues[ currentSection ].CurrentValue := MyGui.MyValues[ currentSection ].MinValue
				}
				DrawWindow( MyGui )
			}
		}else if( y <= MyGui.Y + MyGui.H ){
			MyGui.MyValues[ currentSection ].CurrentValue -= 1
			if( MyGui.MyValues[ currentSection ].CurrentValue < MyGui.MyValues[ currentSection ].MinValue ){
				MyGui.MyValues[ currentSection ].CurrentValue := MyGui.MyValues[ currentSection ].MinValue
			}
			DrawWindow( MyGui )
				
		}else{
			MyGui.MyValues[ currentSection ].CurrentValue -= 10
			if( MyGui.MyValues[ currentSection ].CurrentValue < MyGui.MyValues[ currentSection ].MinValue ){
				MyGui.MyValues[ currentSection ].CurrentValue := MyGui.MyValues[ currentSection ].MinValue
			}
			DrawWindow( MyGui )
		}
		return
	
#If
;*******************************************************************

;*******************************************************************
DrawWindow( obj ){
	obj.ClearWindow()
	obj.DrawBitmap( WindowGraphics( obj ) , { X: 0 , Y: 0 , W: obj.W , H: obj.H } , dispose := 1 , AutoUpdate := 1 )
}
;*******************************************************************
WindowGraphics( obj , ScaleFactor := 1 ){
	;Bitmap Created Using: HB Bitmap Maker
	pBitmap := Gdip_CreateBitmap( 450 * ScaleFactor , 70 * ScaleFactor ) , G := Gdip_GraphicsFromImage( pBitmap ) , Gdip_SetSmoothingMode( G , 2 )
	;~ Brush := Gdip_BrushCreateSolid( "0xFF333333" ) , Gdip_FillRectangle( G , Brush , -10 * ScaleFactor , -10 * ScaleFactor , 600 * ScaleFactor , 200 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_BrushCreateSolid( "0x99000000" ) , Gdip_FillRoundedRectangle( G , Brush , 11 * ScaleFactor , 11 * ScaleFactor , 418 * ScaleFactor , 49 * ScaleFactor , 15 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_BrushCreateHatch( "0xff880000" , "0xFF000000" , 39 ) , Gdip_FillRoundedRectangle( G , Brush , 10 * ScaleFactor , 10 * ScaleFactor , 417 * ScaleFactor , 47 * ScaleFactor , 15 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_CreateLineBrushFromRect( 12 * ScaleFactor , 15 * ScaleFactor , 413 * ScaleFactor , 40 * ScaleFactor , "0xFFFF0000" , "0xFF000000" , 1 , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 2 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawRoundedRectangle( G , Pen , 10 * ScaleFactor , 10 * ScaleFactor , 417 * ScaleFactor , 47 * ScaleFactor , 15 * ScaleFactor ) , Gdip_DeletePen( Pen )
	;section 1
	Brush := Gdip_CreateLineBrush( 62 * ScaleFactor , 14 * ScaleFactor , 87 * ScaleFactor , 13 * ScaleFactor , "0x66880000" , "0x66000000" , 1 ) , Gdip_FillRoundedRectangle( G , Brush , 20 * ScaleFactor , 15 * ScaleFactor , 130 * ScaleFactor , 40 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	;section 1
	Brush := Gdip_CreateLineBrush( 62 * ScaleFactor , 14 * ScaleFactor , 87 * ScaleFactor , 13 * ScaleFactor , "0x33F0F0F0" , "0x66000000" , 1 ) , Gdip_FillRoundedRectangle( G , Brush , 20 * ScaleFactor , 15 * ScaleFactor , 130 * ScaleFactor , 40 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	;section 1
	Brush := Gdip_CreateLineBrushFromRect( 21 * ScaleFactor , 14 * ScaleFactor , 127 * ScaleFactor , 40 * ScaleFactor , "0x66ff0000" , "0x66000000" , 1 , 1 ) , Gdip_FillRoundedRectangle( G , Brush , 20 * ScaleFactor , 15 * ScaleFactor , 130 * ScaleFactor , 40 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_CreateLineBrushFromRect( 22 * ScaleFactor , 17 * ScaleFactor , 128 * ScaleFactor , 37 * ScaleFactor , "0xFFFF0000" , "0xFF000000" , 1 , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 1 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawRoundedRectangle( G , Pen , 20 * ScaleFactor , 15 * ScaleFactor , 130 * ScaleFactor , 40 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeletePen( Pen )
	Brush := Gdip_CreateLineBrushFromRect( 31 * ScaleFactor , 22 * ScaleFactor , 112 * ScaleFactor , 31 * ScaleFactor , "0xFF000000" , "0xFF32363a" , 1 , 1 ) , Gdip_FillEllipse( G , Brush , 25 * ScaleFactor , 18 * ScaleFactor , 120 * ScaleFactor , 32 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	
	value := obj.MyValues[ 1 ].CurrentValue
	value := Round( value , 1 )
	if( instr( value , ".0" ) )
		value := StrSplit( value , "." )[ 1 ]
	( StrLen( Value ) > 3  ) ? ( fs := 18 ) : ( fs := 20 )
	Brush := Gdip_BrushCreateSolid( "0xFFff0000" ) , Gdip_TextToGraphics( G , value , "s" fs * ScaleFactor " Center vCenter Bold NoWrap c" Brush " x" 19 * ScaleFactor " y" 15 * ScaleFactor  , "MV Boli" , 130 * ScaleFactor , 40 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_TextToGraphics( G , value , "s" fs * ScaleFactor " Center vCenter Bold NoWrap c" Brush " x" 21 * ScaleFactor " y" 17 * ScaleFactor  , "MV Boli" , 130 * ScaleFactor , 40 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_BrushCreateSolid( "0xFF880000" ) , Gdip_TextToGraphics( G , value , "s" fs * ScaleFactor " Center vCenter Bold NoWrap c" Brush " x" 20 * ScaleFactor " y" 16 * ScaleFactor  , "MV Boli" , 130 * ScaleFactor , 40 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	
	
	Brush := Gdip_CreateLineBrushFromRect( 25 * ScaleFactor , 21 * ScaleFactor , 119 * ScaleFactor , 28 * ScaleFactor , "0xFFFF0000" , "0xFF000000" , 1 , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 3 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawEllipse( G , Pen , 25 * ScaleFactor , 18 * ScaleFactor , 120 * ScaleFactor , 32 * ScaleFactor ) , Gdip_DeletePen( Pen )
	Brush := Gdip_CreateLineBrushFromRect( 25 * ScaleFactor , 21 * ScaleFactor , 119 * ScaleFactor , 28 * ScaleFactor , "0xFF000000" , "0x99FF0000" , 1 , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 2 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawEllipse( G , Pen , 25 * ScaleFactor , 19 * ScaleFactor , 120 * ScaleFactor , 30 * ScaleFactor ) , Gdip_DeletePen( Pen )
	
	;*****************************************
	;section 3
	x := 290
	y := 15
	w := 130 
	h := 40
	
	;~ Brush := Gdip_BrushCreateSolid( "0xFF333333" ) , Gdip_FillRoundedRectangle( G , Brush , x * ScaleFactor , y * ScaleFactor , w * ScaleFactor , h * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	
	;section 1
	Brush := Gdip_CreateLineBrush( ( x + 42 ) * ScaleFactor , 14 * ScaleFactor , 87 * ScaleFactor , 13 * ScaleFactor , "0x66880000" , "0x66000000" , 1 ) , Gdip_FillRoundedRectangle( G , Brush , x * ScaleFactor , y * ScaleFactor , w * ScaleFactor , h * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	;section 1
	Brush := Gdip_CreateLineBrush( ( x + 42 ) * ScaleFactor , 14 * ScaleFactor , 87 * ScaleFactor , 13 * ScaleFactor , "0x33F0F0F0" , "0x66000000" , 1 ) , Gdip_FillRoundedRectangle( G , Brush , x * ScaleFactor , y * ScaleFactor , w * ScaleFactor , h * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	;section 1
	Brush := Gdip_CreateLineBrushFromRect( x * ScaleFactor , y * ScaleFactor , w * ScaleFactor , h * ScaleFactor , "0x66ff0000" , "0x66000000" , 1 , 1 ) , Gdip_FillRoundedRectangle( G , Brush , x * ScaleFactor , y * ScaleFactor , w * ScaleFactor , h * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_CreateLineBrushFromRect( x * ScaleFactor , y * ScaleFactor , w * ScaleFactor , h * ScaleFactor , "0xFFFF0000" , "0xFF000000" , 1 , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 1 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawRoundedRectangle( G , Pen , x * ScaleFactor , y * ScaleFactor , w * ScaleFactor , h * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeletePen( Pen )
	Brush := Gdip_CreateLineBrushFromRect( x * ScaleFactor , y * ScaleFactor , w * ScaleFactor , h * ScaleFactor , "0xFF000000" , "0xFF32363a" , 1 , 1 ) , Gdip_FillEllipse( G , Brush , ( x + 5 ) * ScaleFactor , ( y + 3 ) * ScaleFactor , ( w - 10 ) * ScaleFactor , ( h - 8 ) * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	
	value := obj.MyValues[ 3 ].CurrentValue 
	value := Round( value , 1 )
	if( instr( value , ".0" ) )
		value := StrSplit( value , "." )[ 1 ]
	( StrLen( Value ) > 3  ) ? ( fs := 18 ) : ( fs := 20 )
	Brush := Gdip_BrushCreateSolid( "0xFFff0000" ) , Gdip_TextToGraphics( G , value , "s" fs * ScaleFactor " Center vCenter Bold NoWrap c" Brush " x" (x - 1 ) * ScaleFactor " y" y * ScaleFactor  , "MV Boli" , w * ScaleFactor , h * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_TextToGraphics( G , value , "s" fs * ScaleFactor " Center vCenter Bold NoWrap c" Brush " x" ( x + 1 ) * ScaleFactor " y" ( y + 2 ) * ScaleFactor  , "MV Boli" , w * ScaleFactor , h * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_BrushCreateSolid( "0xFF880000" ) , Gdip_TextToGraphics( G , value , "s" fs * ScaleFactor " Center vCenter Bold NoWrap c" Brush " x" x * ScaleFactor " y" ( y + 1 ) * ScaleFactor  , "MV Boli" , w * ScaleFactor , h * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	
	
	Brush := Gdip_CreateLineBrushFromRect( ( x + 5 ) * ScaleFactor , ( y + 3 ) * ScaleFactor , ( w - 10 ) * ScaleFactor , ( h - 8 ) * ScaleFactor  , "0xFFFF0000" , "0xFF000000" , 1 , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 3 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawEllipse( G , Pen , ( x + 5 ) * ScaleFactor , ( y + 3 ) * ScaleFactor , ( w - 10 ) * ScaleFactor , ( h - 8 ) * ScaleFactor ) , Gdip_DeletePen( Pen )
	Brush := Gdip_CreateLineBrushFromRect( ( x + 5 ) * ScaleFactor , 21 * ScaleFactor , 119 * ScaleFactor , 28 * ScaleFactor , "0xFF000000" , "0x99FF0000" , 1 , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 2 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawEllipse( G , Pen , ( x + 5 ) * ScaleFactor , 19 * ScaleFactor , ( w - 10 ) * ScaleFactor , ( h - 10 ) * ScaleFactor ) , Gdip_DeletePen( Pen )
	
	
	
	Gdip_DeleteGraphics( G )
	return pBitmap
}


;*******************&&&&&&&&&&&&&&&&&&&&&&&&************************************&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
;*******************&&&&&&&&&&&&&&&&&&&&&&&&************************************&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
;*******************&&&&&&&&&&&&&&&&&&&&&&&&************************************&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
class DropDownListv1	{

	Value[]{
		Get{
			return This.List[ This.Selected ]
		}
	}
	__New( obj := "" ){
		This._SetDefaults()
		This._UpdateDefaults( obj )
		This._CreateWindows()
		This._CreateControls()
		This._DrawHeader()
		This._SetTimer( This.HoverTimer , 100 )
		;~ SoundBeep 777
	}
	_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.FontColor := "0xFFFFFFFF"
		
		
		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.MainColor := "0xFF32363a"
		
		
		
		
		;~ This.ArrowColor := "0xFF000000"
		This.ArrowColor := "0xFFFF0000"
		
		
		
		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.PanelColor1 := "0xFF22262a"
		
		
		
		;~ This.PanelColor2 := "0xFFEFEFEF"
		This.PanelColor2 := "0xFF12161a"
		
		
		
		
		;~ This.HighLightPanelColor := "0x3300AAFF"
		This.HighLightPanelColor := "0x33ff0000"
		
		
		
		;~ This.SelectedPanelColor := "0x990099FF"
		This.SelectedPanelColor := "0x99ff2222"
		
		
		
		
		This.SelectedFontColor := This.FontColor
		
		
		;~ This.HighlightFontColor := This.FontColor
		This.HighlightFontColor := "0xFFFFFFFF"
		
		
		This.HeaderFontColor := This.FontColor
		
		;~ This.SliderTrackColor := "0xFFDCDCDC"
		This.SliderTrackColor := "0xFF12161a"
		
		
		
		;~ This.SliderButtonColor := "0xFFFFFFFF"
		This.SliderButtonColor := "0xFF22262a"
		
		
		
		;~ This.SliderRidgeColor := "0x33333333"
		This.SliderRidgeColor := "0x66ff0000"
		
		
		;~ This.BorderColor := "0x33000000"
		This.BorderColor := "0x99880000"
		;~ This.BorderColor := "0xff0000ff"
		This.Hovered := ""
		This.PanelControls := []
		This.Active := 0
		This.CallBind := This._CallBind.Bind( This )
		This.HoverTimer := This._Hover.Bind( This )
		
		
		;~ This.FocusColor := "0x990099FF"
		This.FocusColor := "0x99ff0000"
		
		
		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( !IsObject( obj.Bind ) && obj.Bind )
			This.Bind := func( obj.Bind ).Bind( This )
		
		if( This.Rows < 5 )
			This.Rows := 5
		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
		
		if( ( This.ThumbRange / 0.5 ) < This.List.Length() ){
			
			Msgbox, 262144, Error, The list you are using exceeds the current maximum length. `n1
			exitApp
		}
		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.Interval -= 0.5
			This.TotalInterval := This.Interval * This.List.Length()
			This.ThumbHeight := This.ThumbRange - This.TotalInterval
			
		}
		
		if( ( This.ThumbHeight ) < 30 || !This.Interval ){
			
			Msgbox, 262144, Error, % "The list you are using exceeds the current maximum length. `n2 " 
			exitApp
		}
		
		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 )
			;~ This.Gui2.ClearWindow( 1 )
			;~ ToolTip, % "Here`n" This.Gui2.hwnd
		}
	}
	_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.StartingPosition := floor( ( This.Thumb.Y - This.ThumbMinY ) / This.Interval )
					
					
					
				}
				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 )
		Brush := Gdip_CreateLineBrush( 1 * This.ScaleFactor , 1 * This.ScaleFactor , ( This.W / 2 ) * This.ScaleFactor , ( This.H - 2 ) * This.ScaleFactor , "0xaa880000" , "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 )
		
		;**************************************
		;~ ToolTip, % This.BorderColor
		Pen := Gdip_CreatePen( This.BorderColor , 1 ) , 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.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( "0xFF0000FF" ) , 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 )
		
		;~ Bob := This.BorderColor
		;~ Brush := Gdip_BrushCreateSolid( Bob ) , 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  , This.Font , ( 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  , This.Font , ( 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  , This.Font , ( 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()
	}
}


Gary-Atlan82
Posts: 74
Joined: 07 Mar 2023, 05:20

Re: AHK GUIs - Can parts of a window be made invisible?

11 Aug 2023, 20:12

@Hellbent
You are a genius!
I have some free time coming in few weeks and I will use it to delve into the basic of GDIP and use your codebase a guide.
I will bear in mind lesson about the "There is no spoon" throughout.
Thanks allot for all you shared me and all of us here. Its appreciated.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: bobstoner289, peter_ahk, Spawnova and 350 guests