Crop bitmap and export as Base64 string? ( Create Icons ) Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
Hellbent
Posts: 2109
Joined: 23 Sep 2017, 13:34

Crop bitmap and export as Base64 string? ( Create Icons )

25 Mar 2022, 02:49

Two items.

First:
Take a bitmap and crop a circle out of it and save as a new bitmap?

Second:
Save a bitmap as a Base64 string and push it to the clipboard?


Details:
I'm trying to create a little tool that I can use to make circular icons on the fly and clipboard a resized copy converted to base64.

Here is a little demo of what I have now.
Animation.gif
Animation.gif (805.94 KiB) Viewed 4126 times

This is the part of the code that needs the cropping done.

Code: Select all

;Capture screen clip. 
	Main.InputPBitmap := Gdip_BitmapFromScreen( Main.Gui1.X "|" Main.Gui1.Y "|" Main.Position.W "|" Main.Position.H ) 
	;*************************************************
	; In here I need to create a bitmap of the cropped image 
	;
	;
	;************************************************
And this is the section that deals with converting to base64 and pushing to the clipboard

Code: Select all

ClipboardBase64:
	Clipboard := ""
	sleep, 100
	 ;Main.OutPBitmap ;<--------- output pBitmap
	 ;Main.OutHBitmap ;<--------- output hBitmap
	 
	;******
	
	
	return
Full code (requires a copy of the GDIP.ahk lib)

Code: Select all

;****************************************************************************************************************************************************************************
#Include <My Altered GDIP lib> ;  <---------       GDIP.ahk

;****************************************************************************************************************************************************************************
#SingleInstance, Force
SetBatchlines, -1
GDIP_STARTUP()

Main := {}
Main.InputPBitmap := ""
Main.InputHBitmap := ""
Main.OutPBitmap := ""
Main.OutHBitmap := ""
Main.OGBit := 60

Main.Position := { X: 0 , Y: 0 , W: 60 , H: 60 }
Main.SliderValue := Main.Position.W


Gui, New, +AlwaysOnTop hwndhwnd
Main.GuiHwnd := hwnd
Gui, Add, Text, xm ym w200 hwndhwnd , % Main.SliderValue
Main.TextHwnd := hwnd
Gui, Add, Button, xm  w300 gCaptureScreen, Capture New Icon
Gui, Add, Picture, xm w300 h300 hwndhwnd 0xE
Main.PicHwnd := hwnd
Gui, Add, Slider, xm w300 Range10-300 hwndhwnd AltSubmit ToolTip gAdjustSlider, % Main.SliderValue
Main.SliderHwnd := hwnd
Gui, Add, Button, xm w300 gClipboardBase64 , Clipboard Base64
Gui, Show

Main.Gui1 := New PopUpWindow( { AutoShow: 1 , X: 1200 , Y: 100 , W: 300 , H: 300 , Options: " -DPIScale +AlwaysOnTop +ToolWindow " } )

return
GuiClose:
GuiContextMenu:
*ESC::ExitApp

RAlt::PopUpWindow.Helper()

ClipboardBase64:
	Clipboard := ""
	sleep, 100
	 ;Main.OutPBitmap ;<--------- output pBitmap
	 ;Main.OutHBitmap ;<--------- output hBitmap
	 
	;******
	
	return

AdjustSlider:
	GuiControlGet, out,, % Main.SliderHwnd
	Main.Position.H := Main.Position.W := Main.SliderValue := out
	Gdip_DisposeImage( Main.OutPBitmap )
	DeleteObject( Main.OutHBitmap )
	Main.OutPBitmap := Gdip_CreateBitmap( Main.SliderValue  , Main.SliderValue ) , G := Gdip_GraphicsFromImage( Main.OutPBitmap ) , Gdip_SetSmoothingMode( G , 2 )
	Gdip_DrawImage( G , Main.InputPBitmap , 0 , 0 , Main.SliderValue , Main.SliderValue , 0 , 0 , Main.OGBit , Main.OGBit ) 
	;~ Pen := Gdip_CreatePen( "0xFF000000" , 3 ) , Gdip_DrawEllipse( G , Pen , 1 , 1 , Main.SliderValue - 3 , Main.SliderValue - 3 ) , Gdip_DeletePen( Pen )
	Gdip_DeleteGraphics( G )
	Main.OutHBitmap := Gdip_CreateHBITMAPFromBitmap( Main.OutPBitmap )
	SetImage( Main.PicHwnd , Main.OutHBitmap )
	GuiControl, % Main.GuiHwnd ":" , % Main.TextHwnd , % Main.Position.W
	return
	
CaptureScreen:
	CoordMode, Mouse, Screen
	CoordMode, ToolTip, Screen
	MouseGetPos, x, y
	Main.Gui1.UpdateSettings( { X: x - ( Main.Position.W / 2 ) , Y: y - ( Main.Position.H / 2 ) } )
	Main.Gui1.DrawBitmap( HB_BITMAP_MAKER( Main.Position ) , { X: 0 , Y: 0 , W: Main.Gui1.W , H: Main.Gui1.H } , dispose := 1 , AutoUpdate := 1 )
	Main.Active := 1
	lw := ""
	While( !GetKeyState( "ctrl" ) ){
		ToolTip, Press "Ctrl" to capture icon. `nUse Wheel And Arrow Keys To Adjust Size Position ( Shift ) , x + Main.Position.W , y + Main.Position.W
		if( lw != Main.Position.W && lw := Main.Position.W )
			GuiControl, % Main.GuiHwnd ":" , % Main.TextHwnd , % Main.Position.W
			
		MouseGetPos, x, y
		Main.Gui1.UpdateSettings( { X: x - ( Main.Position.W / 2 ) , Y: y - ( Main.Position.H / 2 ) } )
		Main.Gui1.ShowWindow()
	}
	ToolTip,
	Main.Gui1.ClearWindow( 1 )
	Main.SliderValue := Main.Position.W
	GuiControl, % Main.GuiHwnd ":" , % Main.SliderHwnd , % Main.SliderValue
	
	;Capture screen clip. 
	Main.InputPBitmap := Gdip_BitmapFromScreen( Main.Gui1.X "|" Main.Gui1.Y "|" Main.Position.W "|" Main.Position.H ) 
	;*************************************************
	; In here I need to create a bitmap of the cropped image and draw a border ring around it
	;
	;
	;************************************************
	G := Gdip_GraphicsFromImage( Main.InputPBitmap ) , Gdip_SetSmoothingMode( G , 2 )
	;~ Pen := Gdip_CreatePen( "0xFF000000" , 3 ) , Gdip_DrawEllipse( G , Pen , 1 , 1 , Main.Position.W - 3 , Main.Position.H - 3 ) , Gdip_DeletePen( Pen )
	Gdip_DeleteGraphics( G )
	Main.OGBit := Main.Position.W
	Main.InputHBitmap := Gdip_CreateHBITMAPFromBitmap( Main.InputPBitmap )
	SetImage( Main.PicHwnd , Main.InputHBitmap )
	Main.Active := 0
	GuiControl, % Main.GuiHwnd ":" , % Main.TextHwnd , % Main.Position.W
	return

#If ( Main.Active )
	
	+WheelUp::
		( ( Main.Position.W -= 2 ) < 10 ) ? ( Main.Position.W := 10 ) : ( Main.Position.H := Main.Position.W , Main.Gui1.ClearWindow() , Main.Gui1.DrawBitmap( HB_BITMAP_MAKER( Main.Position ) , { X: 0 , Y: 0 , W: Main.Gui1.W , H: Main.Gui1.H } , dispose := 1 , AutoUpdate := 1 ) )
		sleep, 30
		return
	+WheelDown::
		( ( Main.Position.W += 2 ) > 300 ) ? ( Main.Position.W := 300 ) : ( Main.Position.H := Main.Position.W , Main.Gui1.ClearWindow() , Main.Gui1.DrawBitmap( HB_BITMAP_MAKER( Main.Position ) , { X: 0 , Y: 0 , W: Main.Gui1.W , H: Main.Gui1.H } , dispose := 1 , AutoUpdate := 1 ) )
		sleep, 30
		return
	
	*Up::
		if( GetKeyState( "Shift" ) )
			MouseMove, 0, -10, 0, R
		else
			MouseMove, 0, -1, 0, R
		return
	*Down::
		if( GetKeyState( "Shift" ) )
			MouseMove, 0, +10, 0, R
		else
			MouseMove, 0, +1, 0, R
		return	
	*Left::
		if( GetKeyState( "Shift" ) )
			MouseMove, -10, 0, 0, R
		else
			MouseMove, -1, 0, 0, R
		return	
	*Right::
		if( GetKeyState( "Shift" ) )
			MouseMove, +10, 0, 0, R
		else
			MouseMove, +1, 0, 0, R
		return				
#If

HB_BITMAP_MAKER( obj := "" , ScaleFactor := 1 ){
	;Bitmap Created Using: HB Bitmap Maker
	pBitmap := Gdip_CreateBitmap( 301 * ScaleFactor , 301 * ScaleFactor ) , G := Gdip_GraphicsFromImage( pBitmap ) , Gdip_SetSmoothingMode( G , 3 )
	Pen := Gdip_CreatePen( "0xFFff0000" , 1 ) , Gdip_DrawRectangle( G , Pen , 0 * ScaleFactor , 0 * ScaleFactor , obj.W * ScaleFactor , obj.H * ScaleFactor ) , Gdip_DeletePen( Pen )
	Gdip_SetSmoothingMode( G , 2 )
	Pen := Gdip_CreatePen( "0xFF3399FF" , 1 ) , Gdip_DrawEllipse( G , Pen , 0 * ScaleFactor , 0 * ScaleFactor , obj.W * ScaleFactor , obj.H * ScaleFactor ) , Gdip_DeletePen( Pen )
	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(){
		UpdateLayeredWindow( This.hwnd , This.hdc , This.X , This.Y , This.W , This.H )
	}
	ClearWindow( AutoUpdate := 0 ){
		Gdip_GraphicsClear( This.G )
		if( Autoupdate )
			This.UpdateWindow()
	}
	DrawBitmap( pBitmap , obj , dispose := 1 , AutoUpdate := 0 ){
		Gdip_DrawImage( This.G , pBitmap , obj.X , obj.Y , obj.W , obj.H )
		if( dispose )
			Gdip_DisposeImage( pBitmap )
		if( Autoupdate )
			This.UpdateWindow()
	}
	PaintBackground( color := "0xFF000000" , AutoUpdate := 0 ){
		if( isObject( color ) ){
			Brush := Gdip_BrushCreateSolid( ( color.HasKey( "Color" ) ) ? ( color.Color ) : ( "0xFF000000" ) ) 
			if( color.Haskey( "Round" ) )
				Gdip_FillRoundedRectangle( This.G , Brush , color.X , color.Y , color.W , color.H , color.Round )
			else
				Gdip_FillRectangle( This.G , Brush , color.X , color.Y , color.W , color.H ) 
		}else{
			Brush := Gdip_BrushCreateSolid( color ) 
			Gdip_FillRectangle( This.G , Brush , -1 , -1 , This.W + 2 , This.H + 2 ) 
		}
		Gdip_DeleteBrush( Brush )
		if( AutoUpdate )
			This.UpdateWindow()
	}
	DeleteWindow( GDIPShutdown := 0 ){
		Gui, % This.Hwnd ":Destroy"
		SelectObject( This.hdc , This.obm )
		DeleteObject( This.hbm )
		DeleteDC( This.hdc )
		Gdip_DeleteGraphics( This.G )
		hwnd := This.Hwnd
		for k, v in PopUpWindow.Windows[ Hwnd ]
			This[k] := ""
		PopUpWindow.Windows[ Hwnd ] := ""
		if( GDIPShutdown ){
			Gdip_Shutdown( PopUpWindow.pToken )
			PopUpWindow.pToken := ""
		}
	}
	_OnClose( wParam ){
		if( wParam = 0xF060 ){	;SC_CLOSE ;[ clicking on the gui close button ]
			Try{
				Gui, % PopUpWindow.HelperHwnd ":Destroy"
				SoundBeep, 555
			}
		}
	}
	CreateCachedBitmap( pBitmap , Dispose := 0 ){
		local pCachedBitmap
		if( This.CachedBitmap )
			This.DisposeCachedbitmap()
		DllCall( "gdiplus\GdipCreateCachedBitmap" , "Ptr" , pBitmap , "Ptr" , this.G , "PtrP" , pCachedBitmap )
		This.CachedBitmap := pCachedBitmap
		if( Dispose )
			Gdip_DisposeImage( pBitmap )
	}
	DrawCachedBitmap( AutoUpdate := 0 ){
		DllCall( "gdiplus\GdipDrawCachedBitmap" , "Ptr" , this.G , "Ptr" , This.CachedBitmap , "Int" , 0 , "Int" , 0 )
		if( AutoUpdate )
			This.UpdateWindow()
	}
	DisposeCachedbitmap(){
		DllCall( "gdiplus\GdipDeleteCachedBitmap" , "Ptr" , This.CachedBitmap )
	}
	Helper(){
		local hwnd , MethodList := ["__New","UpdateSettings","ShowWindow","HideWindow","UpdateWindow","ClearWindow","DrawBitmap","PaintBackground","DeleteWindow" , "AddTrigger" , "DrawTriggers", "CreateCachedBitmap" , "DrawCachedBitmap" , "DisposeCachedbitmap" ]
		Gui, New, +AlwaysOnTop +ToolWindow +HwndHwnd
		PopUpWindow.HelperHwnd := hwnd
		Gui, Add, Edit, xm ym w250 r1 Center hwndhwnd, Gui1
		PopUpWindow.EditHwnd := hwnd
		loop, % MethodList.Length()	
			Gui, Add, Button, xm y+1 w250 r1 gPopUpWindow._HelperClip, % MethodList[ A_Index ]
		Gui, Show,,
		OnMessage( 0x112 , This._OnClose.Bind( hwnd ) )
	}
	_HelperClip(){
		local ClipList 
		
		GuiControlGet, out, % PopUpWindow.HelperHwnd ":", % PopUpWindow.EditHwnd	
		
		ClipList := 		{ 	__New: 					" := New PopUpWindow( { AutoShow: 1 , X: 0 , Y: 0 , W: A_ScreenWidth , H: A_ScreenHeight , Options: "" -DPIScale +AlwaysOnTop "" } )"
							,	UpdateSettings:			".UpdateSettings( { X: """" , Y: """" , W: """" , H: """" } , UpdateGraphics := 0 )"
							,	ShowWindow:				".ShowWindow( Title := """" )"
							,	HideWindow:				".HideWindow()"
							,	UpdateWindow:			".UpdateWindow()"
							,	ClearWindow:			".ClearWindow( AutoUpdate := 0 )"
							,	DrawBitmap:				".DrawBitmap( pBitmap := """" , { X: 0 , Y: 0 , W: " Out ".W , H: " Out ".H } , dispose := 1 , AutoUpdate := 0 )"
							,	PaintBackground:		".PaintBackground( color := ""0xFF000000"" , AutoUpdate := 0 )  "  ";{ Color: ""0xFF000000"" , X: 2 , Y: 2 , W: " Out ".W - 4 , H: " Out ".H - 4 , Round: 10 }"
							,	DeleteWindow:			".DeleteWindow( GDIPShutdown := 0 )"
							,	AddTrigger:				".AddTrigger( { X: """" , Y: """" , W: """" , H: """" , Value: """" , Label: """" } )"	
							,	DrawTriggers:			".DrawTriggers( color := ""0xFFFF0000"" , AutoUpdate := 0 )"	
							,	CreateCachedBitmap:		".CreateCachedBitmap( pBitmap , Dispose := 0 )"	
							,	DrawCachedBitmap: 		".DrawCachedBitmap( AutoUpdate := 0 )"	
							,	DisposeCachedbitmap:	".DisposeCachedbitmap()"	}
							
		clipboard := Out ClipList[ A_GuiControl ]
		
	}
}
Last edited by Hellbent on 25 Jun 2023, 03:06, edited 1 time in total.
teadrinker
Posts: 4373
Joined: 29 Mar 2015, 09:41
Contact:

Re: Crop bitmap and export as Base64 string?

25 Mar 2022, 07:16

Hellbent wrote: Take a bitmap and crop a circle out of it and save as a new bitmap?
Create the new bitmap, fill the circle with the white brush, bitblt the hDC of the new bitmap to the old one with SRCAND flag.
User avatar
Hellbent
Posts: 2109
Joined: 23 Sep 2017, 13:34

Re: Crop bitmap and export as Base64 string?

25 Mar 2022, 11:29

mikeyww wrote:
25 Mar 2022, 04:28
#2: viewtopic.php?f=76&t=82873
Is there no way to do it without the extra lib?

Code: Select all

#include q:\vis2\lib\Vis2.ahk ; https://www.autohotkey.com/boards/viewtopic.php?t=36047
base64 := Vis2.stdlib.Gdip_EncodeBitmapTo64string(snap, "JPG")
Second question. Why does it use "JPG" if it is returning a string?
User avatar
mikeyww
Posts: 27202
Joined: 09 Sep 2014, 18:38

Re: Crop bitmap and export as Base64 string?

25 Mar 2022, 11:49

You could always just put those functions directly into your script (and rewrite them!). :)
User avatar
boiler
Posts: 17222
Joined: 21 Dec 2014, 02:44

Re: Crop bitmap and export as Base64 string?

25 Mar 2022, 12:28

Hellbent wrote: Why does it use "JPG" if it is returning a string?
Because it's telling it to convert it from BMP format to JPG, which is much smaller. What will be stored in the Base64 string will be the data for a JPG image, not a BMP.
User avatar
Hellbent
Posts: 2109
Joined: 23 Sep 2017, 13:34

Re: Crop bitmap and export as Base64 string?

25 Mar 2022, 12:58

boiler wrote:
25 Mar 2022, 12:28
Hellbent wrote: Why does it use "JPG" if it is returning a string?
Because it's telling it to convert it from BMP format to JPG, which is much smaller. What will be stored in the Base64 string will be the data for a JPG image, not a BMP.
Makes sense. Thank you!
mikeyww wrote:
25 Mar 2022, 11:49
You could always just put those functions directly into your script (and rewrite them!). :)
Will do!


Any idea how to get this to output in one line?

Code: Select all


;******************************************************************************************************************
;******************************************************************************************************************
Gdip_EncodeBitmapTo64string(pBitmap, ext, Quality=75) { ;Excised from https://www.autohotkey.com/boards/viewtopic.php?t=36047

         if Ext not in BMP,DIB,RLE,JPG,JPEG,JPE,JFIF,GIF,TIF,TIFF,PNG
               return -1
         Extension := "." Ext

         DllCall("gdiplus\GdipGetImageEncodersSize", "uint*", nCount, "uint*", nSize)
         VarSetCapacity(ci, nSize)
         DllCall("gdiplus\GdipGetImageEncoders", "uint", nCount, "uint", nSize, Ptr, &ci)
         if !(nCount && nSize)
            return -2



            Loop, %nCount%
            {
                  sString := StrGet(NumGet(ci, (idx := (48+7*A_PtrSize)*(A_Index-1))+32+3*A_PtrSize), "UTF-16")
                  if !InStr(sString, "*" Extension)
                     continue

                  pCodec := &ci+idx
                  break
            }


         if !pCodec
               return -3

         if (Quality != 75)
         {
               Quality := (Quality < 0) ? 0 : (Quality > 100) ? 100 : Quality
               if Extension in .JPG,.JPEG,.JPE,.JFIF
               {
                     DllCall("gdiplus\GdipGetEncoderParameterListSize", Ptr, pBitmap, Ptr, pCodec, "uint*", nSize)
                     VarSetCapacity(EncoderParameters, nSize, 0)
                     DllCall("gdiplus\GdipGetEncoderParameterList", Ptr, pBitmap, Ptr, pCodec, "uint", nSize, Ptr, &EncoderParameters)
                     Loop, % NumGet(EncoderParameters, "UInt")
                     {
                        elem := (24+(A_PtrSize ? A_PtrSize : 4))*(A_Index-1) + 4 + (pad := A_PtrSize = 8 ? 4 : 0)
                        if (NumGet(EncoderParameters, elem+16, "UInt") = 1) && (NumGet(EncoderParameters, elem+20, "UInt") = 6)
                        {
                              p := elem+&EncoderParameters-pad-4
                              NumPut(Quality, NumGet(NumPut(4, NumPut(1, p+0)+20, "UInt")), "UInt")
                              break
                        }
                     }
               }
         }

         DllCall("ole32\CreateStreamOnHGlobal", "ptr",0, "int",true, "ptr*",pStream)
         DllCall("gdiplus\GdipSaveImageToStream", "ptr",pBitmap, "ptr",pStream, "ptr",pCodec, "uint",p ? p : 0)

         DllCall("ole32\GetHGlobalFromStream", "ptr",pStream, "uint*",hData)
         pData := DllCall("GlobalLock", "ptr",hData, "uptr")
         nSize := DllCall("GlobalSize", "uint",pData)

         VarSetCapacity(Bin, nSize, 0)
         DllCall("RtlMoveMemory", "ptr",&Bin , "ptr",pData , "uint",nSize)
         DllCall("GlobalUnlock", "ptr",hData)
         DllCall(NumGet(NumGet(pStream + 0, 0, "uptr") + (A_PtrSize * 2), 0, "uptr"), "ptr",pStream)
         DllCall("GlobalFree", "ptr",hData)
         
         DllCall("Crypt32.dll\CryptBinaryToString", "ptr",&Bin, "uint",nSize, "uint",0x01, "ptr",0, "uint*",base64Length)
         VarSetCapacity(base64, base64Length*2, 0)
         DllCall("Crypt32.dll\CryptBinaryToString", "ptr",&Bin, "uint",nSize, "uint",0x01, "ptr",&base64, "uint*",base64Length)
         Bin := ""
         VarSetCapacity(Bin, 0)
         VarSetCapacity(base64, -1)

         return base64
      }
;******************************************************************************************************************
;******************************************************************************************************************

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

Re: Crop bitmap and export as Base64 string?

25 Mar 2022, 14:58

teadrinker wrote:
25 Mar 2022, 07:16
Hellbent wrote: Take a bitmap and crop a circle out of it and save as a new bitmap?
Create the new bitmap, fill the circle with the white brush, bitblt the hDC of the new bitmap to the old one with SRCAND flag.
I'm not really familiar with the whole DC, bitblt stuff. I have used bitblt to draw on a window before but that is about it.

This is the best I could interpret. ( doesn't work )

Code: Select all

	;Capture screen clip. 
	Main.InputPBitmap := Gdip_BitmapFromScreen( Main.Gui1.X "|" Main.Gui1.Y "|" Main.Position.W "|" Main.Position.H ) 
	
	Main.HDC1 := CreateCompatibleDC()
	Main.HBM1 := CreateDIBSection( Main.Position.W , Main.Position.H )
	Main.OBM1 := SelectObject( Main.HDC1 , Main.HBM1 )
	Main.G1 := Gdip_GraphicsFromHDC( Main.HDC1 )
	Gdip_DrawImage( Main.G1 , Main.InputPBitmap , 0 , 0 , Main.Position.W , Main.Position.H )
	
	Main.HDC2 := CreateCompatibleDC()
	Main.HBM2 := CreateDIBSection( Main.Position.W , Main.Position.H )
	Main.OBM2 := SelectObject( Main.HDC2 , Main.HBM2 )
	Main.G2 := Gdip_GraphicsFromHDC( Main.HDC2 )
	Brush := Gdip_BrushCreateSolid( "0xFFFFFFFF" ) , Gdip_FillEllipse( Main.G2 , Brush , 0 , 0 , Main.Position.W , Main.Position.H ) , Gdip_DeleteBrush( Brush )
	
	BitBlt( Main.HDC1 , 0 , 0 , Main.Position.W , Main.Position.H , Main.HDC2 , 0 , 0 , 0x008800C6 ) 
	pbit := CreateCompatibleBitmap( Main.HDC1 , Main.Position.W , Main.Position.H )
	hBit := Gdip_CreateHBITMAPFromBitmap( pbit )
	
	SetImage( Main.PicHwnd , hBit )
Any assistance is appreciated.
teadrinker
Posts: 4373
Joined: 29 Mar 2015, 09:41
Contact:

Re: Crop bitmap and export as Base64 string?

25 Mar 2022, 16:30

Code: Select all

destFile := "rounded.png"

AntiAlias := 4, SRCAND := 0x008800C6

pToken := Gdip_Startup()
pBitmap := Gdip_BitmapFromScreen("0|0|100|100")
hBitmap := Gdip_CreateHBITMAPFromBitmap(pBitmap)
hDcImage := CreateCompatibleDC()
oBmImage := SelectObject(hDcImage, hBitmap)

Gdip_GetImageDimensions(pBitmap, W, H)

hBmMask := CreateDIBSection(W, H)
hDcMask := CreateCompatibleDC()
oBmMask := SelectObject(hDcMask, hBmMask)
G := Gdip_GraphicsFromHDC(hDcMask)
Gdip_SetSmoothingMode(G, AntiAlias)
pBrush := Gdip_BrushCreateSolid(0xFFFFFFFF)

Gdip_FillEllipse(G, pBrush, 0, 0, W, H)
Gdip_DeleteBrush(pBrush), Gdip_DeleteGraphics(G)

BitBlt(hDcImage, 0, 0, W, H, hDcMask, 0, 0, SRCAND)

SelectObject(hDcImage, oBmImage), SelectObject(hDcMask, oBmMask)
DeleteDC(hDcImage), DeleteDC(hDcMask), DeleteObject(hBmMask)
Gdip_DisposeImage(pBitmap)

VarSetCapacity(BITMAP, size := 16 + A_PtrSize*2, 0)
DllCall("GetObject", "Ptr", hBitmap, "UInt", size, "Ptr", &BITMAP)
pPix := NumGet(BITMAP, 16 + A_PtrSize)

pNewBimap := Gdip_CreateBitmap(W, H)
Gdip_LockBits(pNewBimap, 0, 0, W, H, Stride, Scan0, data)
Loop % H
   DllCall("RtlMoveMemory", "Ptr", Scan0 + Stride*(H - A_Index), "Ptr", pPix + Stride*(A_Index - 1), "Ptr", Stride)
Gdip_UnlockBits(pNewBimap, data)
Gdip_SaveBitmapToFile(pNewBimap, destFile)

Gdip_DisposeImage(pNewBimap), DeleteObject(hBitmap), Gdip_Shutdown(pToken)
User avatar
Hellbent
Posts: 2109
Joined: 23 Sep 2017, 13:34

Re: Crop bitmap and export as Base64 string?

26 Mar 2022, 06:07

Does anyone know how to get this to output in one line?

i.e. I don't want this.

Code: Select all

iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/NlyAAAAAXNSR0IArs4c6QAA
AARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAARxSURBVGhD7Vsx
aNtAFNXo0VPJ6NFjIWCaTaNHjx08aMjg0WNGlxI0haZ06NgEEzo0kECGjk0oJkOh
dungsQklZMiQhAweOqj/Sf/k0+WrtmPZ1ok++iA+/fv3/92/f6c71fmPBcMVQMWl
6KnFKJfLa57ntY6Pjz9fXFxc393dBZNIcrck/6VNqFQqVVaVX5CRFRh7enp6Ljk0
KweDwbBDyJ3zcHR3d/eDZHRWxMg/J3CTqwHClgbgDRk0Mg1cFPf29o7QwWzC8oBQ
w5yTjFoGKaLekxmLT3Zl+odeloxYNilX9Bc62lDuOs+G/nfZgFUQKwBN7RdsYnbA
ernKEJ7AUaPReMmmzg84KzSSO2biNMI4xyNrcjRXeNOyU8biLyjOLTGnMUjswmzA
tlBSmncie5P5sy1ZtMz6kjJbSEvnR3ZlMrCDokpL2z0tilNvRXm7KCqxidh/s0vp
oPleJWHrR1eRlqoGu5aCqn/kbA2DwrB+jgQmgwa3enX/Jyga3bRRxhuQVMF2Hux3
5YzdO/vWlypYz8ubW1qWk+sydieicEHouvU6uxrBa29tSYJF4fbbdzgwGKN39vVc
Erzq7wTrzkbQ6RtltZ2gp8vNw6z1Sbz8fc2uRkCci4Khw07g6AbZ6DARW0h2t1SS
BEKyMR1vI2geJstscxjLLjvsVJzaZjJsFZUxulHG380aRUAYBawDz53NoBvqOAma
4t8aE/pIRumjqdQ8HMYyejuhjrAetUmDMZZnnQJxkEFy0YlGolGdWnlXjXJcNgw6
NW1+S+WHm6ExyXosr5ioR7K+chIdBD1czs73fHLQO4nq6Z1CbYn6mR4hdJiAo5Gw
hx6NcsJI9D79rcrCBrnXY0Y6ul7kJDqp45McDIRByhmpjURbwnPzd1q5+m0QKxHZ
SEuS12pJAiENJejddY97Es+kEAVD5xCGqBt1VIfqiiGX5oD53PydVq5+G8ROkh32
vFThR+UIMxrJsMwMQV02klMjipGO557JuN4TQlq3Lc0HZuwwwZ2YtLSysEFVpieZ
hA5lJP/GXIaRrCNBvY2pkpaSnc3heA4X9S3J5Hh7SQuyJFA0VvQjn6v7h5EkVCQ6
5bU1dpf20j9+DiWh4vBhxK5G2H712pcFi8GD/U9H7CoD2y7pTKgo9Nx4lxUD1xTS
yV8RiGsjdnMM3KpLwrYz9XwaLxFSBdvZbrejPbQEXERJlWwlrnpxdcTuPQZO6qWK
thLfjbFr6SjKKCMJkzuTr01x6yYpsI3xy8I0yMunSU8lX4pPD0z0wWDwS1KWdyJR
4RaUXZkeHNrWXZ3S6pq8ZZgFtmXtqbLyJGDhlpTnjfz9ZTbAeZDUSF6YqbMKHN65
m9OZhHEakMjykr2RjedKUNMCr1p4A5GMWBbxheCTlp55gBBf9qeJ2C7SBqrFJqwG
MACGSAZmRYQvH6Tn5r/8lJA8sg51bBHh6D9f8VYNzHFs3PG9Ixk9c1bHR62IGnx3
wirtApILTlMAjJYJKq7jGVYArrIgOM5f1z9AQFVlQvIAAAAASUVORK5CYII=

Code: Select all


;******************************************************************************************************************
;******************************************************************************************************************
Gdip_EncodeBitmapTo64string(pBitmap, ext, Quality=75) { ;Excised from https://www.autohotkey.com/boards/viewtopic.php?t=36047

         if Ext not in BMP,DIB,RLE,JPG,JPEG,JPE,JFIF,GIF,TIF,TIFF,PNG
               return -1
         Extension := "." Ext

         DllCall("gdiplus\GdipGetImageEncodersSize", "uint*", nCount, "uint*", nSize)
         VarSetCapacity(ci, nSize)
         DllCall("gdiplus\GdipGetImageEncoders", "uint", nCount, "uint", nSize, Ptr, &ci)
         if !(nCount && nSize)
            return -2



            Loop, %nCount%
            {
                  sString := StrGet(NumGet(ci, (idx := (48+7*A_PtrSize)*(A_Index-1))+32+3*A_PtrSize), "UTF-16")
                  if !InStr(sString, "*" Extension)
                     continue

                  pCodec := &ci+idx
                  break
            }


         if !pCodec
               return -3

         if (Quality != 75)
         {
               Quality := (Quality < 0) ? 0 : (Quality > 100) ? 100 : Quality
               if Extension in .JPG,.JPEG,.JPE,.JFIF
               {
                     DllCall("gdiplus\GdipGetEncoderParameterListSize", Ptr, pBitmap, Ptr, pCodec, "uint*", nSize)
                     VarSetCapacity(EncoderParameters, nSize, 0)
                     DllCall("gdiplus\GdipGetEncoderParameterList", Ptr, pBitmap, Ptr, pCodec, "uint", nSize, Ptr, &EncoderParameters)
                     Loop, % NumGet(EncoderParameters, "UInt")
                     {
                        elem := (24+(A_PtrSize ? A_PtrSize : 4))*(A_Index-1) + 4 + (pad := A_PtrSize = 8 ? 4 : 0)
                        if (NumGet(EncoderParameters, elem+16, "UInt") = 1) && (NumGet(EncoderParameters, elem+20, "UInt") = 6)
                        {
                              p := elem+&EncoderParameters-pad-4
                              NumPut(Quality, NumGet(NumPut(4, NumPut(1, p+0)+20, "UInt")), "UInt")
                              break
                        }
                     }
               }
         }

         DllCall("ole32\CreateStreamOnHGlobal", "ptr",0, "int",true, "ptr*",pStream)
         DllCall("gdiplus\GdipSaveImageToStream", "ptr",pBitmap, "ptr",pStream, "ptr",pCodec, "uint",p ? p : 0)

         DllCall("ole32\GetHGlobalFromStream", "ptr",pStream, "uint*",hData)
         pData := DllCall("GlobalLock", "ptr",hData, "uptr")
         nSize := DllCall("GlobalSize", "uint",pData)

         VarSetCapacity(Bin, nSize, 0)
         DllCall("RtlMoveMemory", "ptr",&Bin , "ptr",pData , "uint",nSize)
         DllCall("GlobalUnlock", "ptr",hData)
         DllCall(NumGet(NumGet(pStream + 0, 0, "uptr") + (A_PtrSize * 2), 0, "uptr"), "ptr",pStream)
         DllCall("GlobalFree", "ptr",hData)
         
         DllCall("Crypt32.dll\CryptBinaryToString", "ptr",&Bin, "uint",nSize, "uint",0x01, "ptr",0, "uint*",base64Length)
         VarSetCapacity(base64, base64Length*2, 0)
         DllCall("Crypt32.dll\CryptBinaryToString", "ptr",&Bin, "uint",nSize, "uint",0x01, "ptr",&base64, "uint*",base64Length)
         Bin := ""
         VarSetCapacity(Bin, 0)
         VarSetCapacity(base64, -1)

         return base64
      }
;******************************************************************************************************************
;******************************************************************************************************************

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

Re: Crop bitmap and export as Base64 string?

26 Mar 2022, 17:42

teadrinker wrote:
26 Mar 2022, 08:23
See CRYPT_STRING_NOCRLF flag.
Thank you. I also used CRYPT_STRING_BASE64 to remove the headers.

I was also able to pull out what I needed from the code you posted earlier ( Thank you ).
I have a basic prototype done now, just need to write a new draft and tweak a few of the values, however it is more or less the way I "need it to be" as is, so if I get too busy this is how it will stand.

Animation.gif
Animation.gif (489.03 KiB) Viewed 3700 times

Code: Select all

;****************************************************************************************************************************************************************************
;Written By: Hellbent
;Date Started: Mar 25th, 2022
;Last Edit: Mar 26th, 2022
;Name: Quick Icon Maker v1.1
;resources: 
;			https://www.autohotkey.com/boards/viewtopic.php?f=76&t=101960&p=453285#p453181 ;export Base64
;			https://www.autohotkey.com/boards/viewtopic.php?f=76&t=101960&p=453285#p453292 ;crop image
;****************************************************************************************************************************************************************************
#Include <My Altered GDIP lib> ;  <---------       GDIP.ahk
;****************************************************************************************************************************************************************************
#SingleInstance, Force
SetBatchlines, -1
GDIP_STARTUP()

Main := {}

Main.DivAmount := 15000 ;output split string count

Main.Change := 0

Main.InputPBitmap := ""
Main.InputHBitmap := ""
Main.OutPBitmap := ""
Main.OutHBitmap := ""
Main.OGBit := 60

Main.Position := { X: 0 , Y: 0 , W: 60 , H: 60 }
Main.SliderValue := Main.Position.W

Main.RingColor := "000000"
Main.RingAlpha := "FF"

Main.MasterPBitmap := Gdip_CreateBitmap( 300 , 300 )
Main.MasterG := Gdip_GraphicsFromImage( Main.MasterPBitmap ) , Gdip_SetSmoothingMode( Main.MasterG , 2 )
Main.MasterHBitmap := ""

Main.OutputVarName := "QuickIcon"

Gui, New, +AlwaysOnTop hwndhwnd
Main.GuiHwnd := hwnd

;~ Gui, Color, 32363a , 22262a
;~ Gui, Font, cffff00

Gui, Add, CheckBox, xm ym w90 Checked hwndhwnd gAdjustSlider , Add Border
Main.CheckBoxHwnd := hwnd

Gui, Add, Edit, x+10 w70 r1 Center Limit2 hwndhwnd gAdjustSlider , % Main.RingAlpha
Main.Edit1Hwnd := hwnd

Gui, Add, Edit, x+10 w120 r1 Center Limit6 hwndhwnd gAdjustSlider , % Main.RingColor
Main.Edit2Hwnd := hwnd

Gui, Add, Radio, xm w50 hwndhwnd Group gAdjustSlider , 1px
Main.Radio1Hwnd := hwnd

Gui, Add, Radio, x+10 w50 Checked hwndhwnd gAdjustSlider , 3px
Main.Radio2Hwnd := hwnd

Gui, Add, Radio, x+10 w50 hwndhwnd gAdjustSlider , 5px
Main.Radio3Hwnd := hwnd

Gui, Add, Button, xm  w300 gCaptureScreen, Capture New Icon

Gui, -DPIScale

Gui, Add, Picture, xm w300 h300 hwndhwnd 0xE
Main.PicHwnd := hwnd

Gui, +DPIScale

Gui, Add, Text, xm  w200 hwndhwnd , % Main.SliderValue
Main.TextHwnd := hwnd

Gui, Add, Slider, xm w300 Range10-300 hwndhwnd AltSubmit gAdjustSlider, % Main.SliderValue
Main.SliderHwnd := hwnd

Gui, Add, Edit, c0000FF xm w300 hwndhwnd Center, % Main.OutputVarName
Main.Edit3Hwnd := hwnd

Gui, Add, Button, xm w300 gClipboardBase64 , Clipboard Base64

Gui, Add, Button, xm w300 gClipboardBitmapFunction , Clipboard [ B64  ->  pBitmap ] Function

Gui, Show,, Quick Icon Maker

Main.Gui1 := New PopUpWindow( { AutoShow: 1 , X: 1200 , Y: 100 , W: 300 , H: 300 , Options: " -DPIScale +AlwaysOnTop +ToolWindow " } )

return
GuiClose:
GuiContextMenu:
*ESC::ExitApp


/*
Setup( obj ){
	
	obj.Active := 0
	obj.DivAmount := 15000 ;output split string count
	obj.Change := 0 
	
	obj.Display := {}
	obj.Display.pBitmap := ""
	obj.Display.hBitmap := ""
	obj.Display.G := ""
	obj.Display.Size := 300
	
	obj.Master := {}
	obj.Master.pBitmap := ""
	obj.Master.hBitmap := ""
	obj.Master.Size := 60
	
	
;~ Main.InputPBitmap := ""
;~ Main.InputHBitmap := ""
;~ Main.OutPBitmap := ""
;~ Main.OutHBitmap := ""
;~ Main.OGBit := 60

;~ Main.Position := { X: 0 , Y: 0 , W: 60 , H: 60 }
;~ Main.SliderValue := Main.Position.W

;~ Main.RingColor := "000000"
;~ Main.RingAlpha := "FF"

;~ Main.MasterPBitmap := Gdip_CreateBitmap( 300 , 300 )
;~ Main.MasterG := Gdip_GraphicsFromImage( Main.MasterPBitmap ) , Gdip_SetSmoothingMode( Main.MasterG , 2 )
;~ Main.MasterHBitmap := ""

;~ Main.OutputVarName := "QuickIcon"

	
	return obj 
}

CreateWindow(){
	
}


*/





;******************************************************************************************************************
;******************************************************************************************************************
;******************************************************************************************************************
;******************************************************************************************************************
;******************************************************************************************************************
;******************************************************************************************************************

ClipboardBase64:
	if( !Main.Change )
		gosub, AdjustSlider
	Clipboard := ""
	sleep, 100
	GuiControlGet, out , % Main.GuiHwnd ":" , % Main.Edit3Hwnd  
	( ( Main.OutputVarName := out ) = "" ) ? ( "QuickIcon" )
	out :=  Main.OutputVarName  Main.SliderValue "x" Main.SliderValue " := """ Gdip_EncodeBitmapTo64string( Main.OutPBitmap , "PNG" , 100 ) """"
	startpos := 1 
	Loop, % loopCount := Ceil( StrLen( out ) / Main.DivAmount ) {
		if( A_Index = 1 )
			output := SubStr( out , startpos , Main.DivAmount ) """"
		else
			output .= "`n" Main.OutputVarName  Main.SliderValue "x" Main.SliderValue " .= """ SubStr( out , startpos , Main.DivAmount ) """"
		StartPos += Main.DivAmount
	}
	Clipboard := substr( output , 1 , StrLen( output ) - 1 )
	GuiControl, % Main.GuiHwnd ":" , % Main.Edit3Hwnd , % Main.OutputVarName
	sleep, 300
	SoundBeep
	return

ClipboardBitmapFunction:
	Clipboard := ""
	sleep, 100
	Clipboard := ClipBitmapFunction()
	SoundBeep
	return
;******************************************************************************************************************
;******************************************************************************************************************

AdjustSlider:
	GuiControlGet, out,, % Main.SliderHwnd
	out += Mod( out , 2 )
	Main.Position.H := Main.Position.W := Main.SliderValue := out
	Gdip_DisposeImage( Main.OutPBitmap )
	DeleteObject( Main.OutHBitmap )
	Main.OutPBitmap := Gdip_CreateBitmap( Main.SliderValue  , Main.SliderValue ) , G := Gdip_GraphicsFromImage( Main.OutPBitmap ) , Gdip_SetSmoothingMode( G , 2 ) , Gdip_SetInterpolationMode( G , 7 )
	Gdip_DrawImage( G , Main.InputPBitmap , 0 , 0 , Main.SliderValue , Main.SliderValue , 0 , 0 , Main.OGBit , Main.OGBit ) 
	DrawRing( Main , G )
	Gdip_DeleteGraphics( G )
	Main.OutHBitmap := Gdip_CreateHBITMAPFromBitmap( Main.OutPBitmap )
	SetImage( Main.PicHwnd , Main.OutHBitmap )
	GuiControl, % Main.GuiHwnd ":" , % Main.TextHwnd , % Main.Position.W
	Main.Change := 1
	return
;******************************************************************************************************************
;******************************************************************************************************************
	
CaptureScreen:
	CoordMode, Mouse, Screen
	CoordMode, ToolTip, Screen
	MouseGetPos, x, y
	Main.Gui1.UpdateSettings( { X: x - ( Main.Position.W / 2 ) , Y: y - ( Main.Position.H / 2 ) } )
	Main.Gui1.DrawBitmap( HB_BITMAP_MAKER( Main.Position ) , { X: 0 , Y: 0 , W: Main.Gui1.W , H: Main.Gui1.H } , dispose := 1 , AutoUpdate := 1 )
	Main.Active := 1
	lw := ""
	While( !GetKeyState( "ctrl" ) ){
		ToolTip, Press "Ctrl" to capture icon. `nUse Wheel And Arrow Keys To Adjust Size Position ( Shift ) , x + Main.Position.W , y + Main.Position.W
		if( lw != Main.Position.W && lw := Main.Position.W )
			GuiControl, % Main.GuiHwnd ":" , % Main.TextHwnd , % Main.Position.W
			
		MouseGetPos, x, y
		Main.Gui1.UpdateSettings( { X: x - ( Main.Position.W / 2 ) , Y: y - ( Main.Position.H / 2 ) } )
		Main.Gui1.ShowWindow()
	}
	ToolTip,
	Main.Gui1.ClearWindow( 1 )
	Main.SliderValue := Main.Position.W
	GuiControl, % Main.GuiHwnd ":" , % Main.SliderHwnd , % Main.SliderValue
	Main.InputPBitmap := Gdip_BitmapFromScreen( Main.Gui1.X "|" Main.Gui1.Y "|" Main.Position.W "|" Main.Position.H ) 
	CreateCroppedIconBitmap( Main ) 
	DrawImage( Main )
	Main.OGBit := Main.Position.W
	Main.Active := 0
	GuiControl, % Main.GuiHwnd ":" , % Main.TextHwnd , % Main.Position.W
	Main.Change := 0
	return
;******************************************************************************************************************
;******************************************************************************************************************

DrawRing( obj , G ){
	GuiControlGet, check , % obj.GuiHwnd ":" , %  obj.CheckBoxHwnd
	if( check ){
		GuiControlGet, alpha , % obj.GuiHwnd ":" , % obj.Edit1Hwnd
		( alpha = "" ) ? ( alpha := "FF" )
		GuiControlGet, color , % obj.GuiHwnd ":" , % obj.Edit2Hwnd
		( color = "" ) ? ( color := "000000" )
		loop, 3	{
			GuiControlGet, ringWidth , % obj.GuiHwnd ":" , % obj[ "Radio" A_Index "Hwnd" ]
			if( ringWidth ){
				ringWidth := A_Index * 2 - 1
				break
			}
		}
		Pen := Gdip_CreatePen( "0x" alpha color , ringWidth ) 
		
		, Gdip_DrawEllipse( G , Pen 
								, ( ringWidth = 1 ) ? ( 1 ) : ( ( ringWidth = 3 ) ? ( 1 ) : ( 2 ) ) 																			;x
								, ( ringWidth = 1 ) ? ( 1 ) : ( ( ringWidth = 3 ) ? ( 1 ) : ( 3 ) ) 																			;y
								
								;~ , ( ringWidth = 5 ) ? ( obj.Position.H - ringWidth - 1 ) : ( obj.Position.H - ringWidth ) 
								, ( ringWidth = 1 ) ? ( obj.Position.H - 2 ) : ( obj.Position.H - ringWidth ) 																	;w
								
								;~ , ( ringWidth = 5 ) ? ( obj.Position.H - ringWidth - 1 ) : ( obj.Position.H - ringWidth ) ) 
								, ( ringWidth = 1 ) ? ( obj.Position.H - 2 ) : ( ( ringWidth = 5 ) ? ( obj.Position.H - ringWidth - 1 ) : ( obj.Position.H - ringWidth ) ) ) 	;h
		
		, Gdip_DeletePen( Pen )
	}
}

;******************************************************************************************************************
;******************************************************************************************************************

DrawImage( obj ){
	Gdip_GraphicsClear( obj.MasterG )
	Gdip_DrawImage( obj.MasterG , obj.InputPBitmap , 0 , 0 , obj.Position.W , obj.Position.H )
	DrawRing( obj , obj.MasterG )
	obj.InputHBitmap := Gdip_CreateHBITMAPFromBitmap( obj.MasterPBitmap )
	SetImage( obj.PicHwnd , obj.InputHBitmap )
	DeleteObject( obj.InputHBitmap )
}

CreateCroppedIconBitmap( main ){ ; https://www.autohotkey.com/boards/viewtopic.php?f=76&t=101960&p=453285#p453292 
	Main.HBM1 := Gdip_CreateHBITMAPFromBitmap( Main.InputPBitmap )
	Main.HDC1 := CreateCompatibleDC()
	Main.OBM1 := SelectObject( Main.HDC1 , Main.HBM1 )
	
	Main.HBM2 := CreateDIBSection( Main.Position.W , Main.Position.H )
	Main.HDC2 := CreateCompatibleDC()
	Main.OBM2 := SelectObject( Main.HDC2 , Main.HBM2 )
	
	Main.G1 := Gdip_GraphicsFromHDC( Main.HDC2 )
	Gdip_SetSmoothingMode( Main.G1 , 4 ) ;, Gdip_SetInterpolationMode( Main.G1 , 7 )
	Brush := Gdip_BrushCreateSolid( "0xFFFFFFFF" ) , Gdip_FillEllipse( Main.G1 , Brush , 1 , 1 , Main.Position.W - 2 , Main.Position.H - 2 ) , Gdip_DeleteBrush( Brush )
	BitBlt( Main.HDC1 , 0 , 0 , Main.Position.W , Main.Position.H , Main.HDC2 , 0 , 0 , 0x008800C6 ) ;SRCAND
	
	SelectObject( Main.HDC1 , Main.OBM1 ) , SelectObject( Main.HDC2 , Main.OBM2 )
	DeleteDC( Main.HDC1 ), DeleteDC( Main.HDC2 ) , DeleteObject( Main.HBM2 )
	Gdip_DisposeImage( Main.InputPBitmap )

	VarSetCapacity(BITMAP, size := 16 + A_PtrSize*2, 0)
	DllCall("GetObject", "Ptr", Main.HBM1 , "UInt", size, "Ptr", &BITMAP)
	pPix := NumGet(BITMAP, 16 + A_PtrSize)
	
	Main.InputPBitmap := Gdip_CreateBitmap( Main.Position.W , Main.Position.H )
	Gdip_LockBits( Main.InputPBitmap , 0 , 0 , Main.Position.W , Main.Position.H , Stride , Scan0 , data )
	
	Loop % Main.Position.W
	   DllCall("RtlMoveMemory", "Ptr", Scan0 + Stride * ( Main.Position.W - A_Index ) , "Ptr" , pPix + Stride*(A_Index - 1), "Ptr", Stride)
	   
	Gdip_UnlockBits( Main.InputPBitmap , data )
	DeleteObject( Main.HBM1 )
}
;******************************************************************************************************************
;******************************************************************************************************************
#If ( Main.Active )
	
	+WheelUp::
		( ( Main.Position.W -= 2 ) < 10 ) ? ( Main.Position.W := 10 ) : ( Main.Position.H := Main.Position.W , Main.Gui1.ClearWindow() , Main.Gui1.DrawBitmap( HB_BITMAP_MAKER( Main.Position ) , { X: 0 , Y: 0 , W: Main.Gui1.W , H: Main.Gui1.H } , dispose := 1 , AutoUpdate := 1 ) )
		sleep, 30
		return
	+WheelDown::
		( ( Main.Position.W += 2 ) > 300 ) ? ( Main.Position.W := 300 ) : ( Main.Position.H := Main.Position.W , Main.Gui1.ClearWindow() , Main.Gui1.DrawBitmap( HB_BITMAP_MAKER( Main.Position ) , { X: 0 , Y: 0 , W: Main.Gui1.W , H: Main.Gui1.H } , dispose := 1 , AutoUpdate := 1 ) )
		sleep, 30
		return
	
	*Up::
		if( GetKeyState( "Shift" ) )
			MouseMove, 0, -10, 0, R
		else
			MouseMove, 0, -1, 0, R
		return
	*Down::
		if( GetKeyState( "Shift" ) )
			MouseMove, 0, +10, 0, R
		else
			MouseMove, 0, +1, 0, R
		return	
	*Left::
		if( GetKeyState( "Shift" ) )
			MouseMove, -10, 0, 0, R
		else
			MouseMove, -1, 0, 0, R
		return	
	*Right::
		if( GetKeyState( "Shift" ) )
			MouseMove, +10, 0, 0, R
		else
			MouseMove, +1, 0, 0, R
		return				
#If

;******************************************************************************************************************
;******************************************************************************************************************
Gdip_EncodeBitmapTo64string(pBitmap, ext, Quality=75) { ;Excised from https://www.autohotkey.com/boards/viewtopic.php?t=36047
	if Ext not in BMP,DIB,RLE,JPG,JPEG,JPE,JFIF,GIF,TIF,TIFF,PNG
        return -1
	Extension := "." Ext
	DllCall("gdiplus\GdipGetImageEncodersSize", "uint*", nCount, "uint*", nSize)
	VarSetCapacity(ci, nSize)
	DllCall("gdiplus\GdipGetImageEncoders", "uint", nCount, "uint", nSize, Ptr, &ci)
	if !(nCount && nSize)
		return -2
	Loop, % nCount {
		sString := StrGet(NumGet(ci, (idx := (48+7*A_PtrSize)*(A_Index-1))+32+3*A_PtrSize), "UTF-16")
		if !InStr(sString, "*" Extension)
			continue
		pCodec := &ci+idx
		break
	}
	if !pCodec
		return -3
	if (Quality != 75){
		Quality := (Quality < 0) ? 0 : (Quality > 100) ? 100 : Quality
		if Extension in .JPG,.JPEG,.JPE,.JFIF
		{
			DllCall("gdiplus\GdipGetEncoderParameterListSize", Ptr, pBitmap, Ptr, pCodec, "uint*", nSize)
			VarSetCapacity(EncoderParameters, nSize, 0)
			DllCall("gdiplus\GdipGetEncoderParameterList", Ptr, pBitmap, Ptr, pCodec, "uint", nSize, Ptr, &EncoderParameters)
			Loop, % NumGet(EncoderParameters, "UInt") {
				elem := (24+(A_PtrSize ? A_PtrSize : 4))*(A_Index-1) + 4 + (pad := A_PtrSize = 8 ? 4 : 0)
				if (NumGet(EncoderParameters, elem+16, "UInt") = 1) && (NumGet(EncoderParameters, elem+20, "UInt") = 6){
					p := elem+&EncoderParameters-pad-4
					NumPut(Quality, NumGet(NumPut(4, NumPut(1, p+0)+20, "UInt")), "UInt")
					break
				}
			}
		}
	}
	DllCall("ole32\CreateStreamOnHGlobal", "ptr",0, "int",true, "ptr*",pStream)
	DllCall("gdiplus\GdipSaveImageToStream", "ptr",pBitmap, "ptr",pStream, "ptr",pCodec, "uint",p ? p : 0)
    DllCall("ole32\GetHGlobalFromStream", "ptr",pStream, "uint*",hData)
	pData := DllCall("GlobalLock", "ptr",hData, "uptr")
	nSize := DllCall("GlobalSize", "uint",pData)
	VarSetCapacity(Bin, nSize, 0)
	DllCall("RtlMoveMemory", "ptr",&Bin , "ptr",pData , "uint",nSize)
	DllCall("GlobalUnlock", "ptr",hData)
	DllCall(NumGet(NumGet(pStream + 0, 0, "uptr") + (A_PtrSize * 2), 0, "uptr"), "ptr",pStream)
	DllCall("GlobalFree", "ptr",hData)
	DllCall("Crypt32.dll\CryptBinaryToString", "ptr",&Bin, "uint",nSize, "uint",0x01, "ptr",0, "uint*",base64Length)
	VarSetCapacity(base64, base64Length*2, 0)				
	;*************************	
	;https://www.autohotkey.com/boards/viewtopic.php?f=76&t=101960&p=453367#p453387
	DllCall("Crypt32.dll\CryptBinaryToString", "ptr",&Bin, "uint",nSize, "uint", 0x40000001 , "ptr",&base64, "uint*",base64Length) ; [ 0x40000001 = CRYPT_STRING_NOCRLF ( 0x40000000 ) And CRYPT_STRING_BASE64 ( 0x00000001 ) ]
	;*************************
	Bin := ""
	VarSetCapacity(Bin, 0)
	VarSetCapacity(base64, -1)
	return  base64
}
;******************************************************************************************************************
;******************************************************************************************************************

;Layered window class
;####################################################################################################################################################################################
;####################################################################################################################################################################################
;####################################################################################################################################################################################
;####################################################################################################################################################################################
class PopUpWindow	{
	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 
	}
	UpdateSettings( obj := "" , UpdateGraphics := 0 ){
		local k , v
		if( IsObject( obj ) )
			for k, v in obj
				This[ k ] := obj[ k ]
		( This.X = "Center" ) ? ( This.X := ( A_ScreenWidth - This.W ) / 2 ) 	
		( This.Y = "Center" ) ? ( This.Y := ( A_ScreenHeight - This.H ) / 2 ) 	
		if( UpdateGraphics ){
			This._DestroyWindowsGraphics()
			This._CreateWindowGraphics()
		}
	}
	_CreateWindow(){
		local hwnd
		Gui , New, % " +LastFound +E0x80000 hwndhwnd -Caption  " This.Options
		PopUpWindow.Index++
		This.Index := PopUpWindow.Index
		PopUpWindow.Windows[ PopUpWindow.Index ] := This
		This.Hwnd := hwnd
		PopUpWindow.Handles[ hwnd ] := PopUpWindow.Index
		if( This.GdipStartUp && !PopUpWindow.pToken )
			PopUpWindow.pToken := GDIP_STARTUP()
	}
	_DestroyWindowsGraphics(){
		Gdip_DeleteGraphics( This.G )
		SelectObject( This.hdc , This.obm )
		DeleteObject( This.hbm )
		DeleteDC( This.hdc )
	}
	_CreateWindowGraphics(){
		This.hbm := CreateDIBSection( This.W , This.H )
		This.hdc := CreateCompatibleDC()
		This.obm := SelectObject( This.hdc , This.hbm )
		This.G := Gdip_GraphicsFromHDC( This.hdc )
		Gdip_SetSmoothingMode( This.G , This.Smoothing )
	}
	ShowWindow( Title := "" ){
		Gui , % This.Hwnd ":Show", % "x" This.X " y" This.Y " w" This.W " h" This.H " NA", % Title
	}
	HideWindow(){
		Gui , % This.Hwnd ":Hide",
	}
	UpdateWindow(){
		UpdateLayeredWindow( This.hwnd , This.hdc , This.X , This.Y , This.W , This.H )
	}
	ClearWindow( AutoUpdate := 0 ){
		Gdip_GraphicsClear( This.G )
		if( Autoupdate )
			This.UpdateWindow()
	}
	DrawBitmap( pBitmap , obj , dispose := 1 , AutoUpdate := 0 ){
		Gdip_DrawImage( This.G , pBitmap , obj.X , obj.Y , obj.W , obj.H )
		if( dispose )
			Gdip_DisposeImage( pBitmap )
		if( Autoupdate )
			This.UpdateWindow()
	}
}
;**********************************************************************
;**********************************************************************
ClipBitmapFunction(){
	local abc 
	abc =
	( `join`r`n
B64ToPBitmap( Input ){
	local ptr , uptr , pBitmap , pStream , hData , pData , Dec , DecLen , B64
	VarSetCapacity( B64 , strlen( Input ) << !!A_IsUnicode )
	B64 := Input
	If !DllCall("Crypt32.dll\CryptStringToBinary" ( ( A_IsUnicode ) ? ( "W" ) : ( "A" ) ), Ptr := A_PtrSize ? "Ptr" : "UInt" , &B64, "UInt", 0, "UInt", 0x01, Ptr, 0, "UIntP", DecLen, Ptr, 0, Ptr, 0)
		Return False
	VarSetCapacity( Dec , DecLen , 0 )
	If !DllCall("Crypt32.dll\CryptStringToBinary" (A_IsUnicode ? "W" : "A"), Ptr, &B64, "UInt", 0, "UInt", 0x01, Ptr, &Dec, "UIntP", DecLen, Ptr, 0, Ptr, 0)
		Return False
	DllCall("Kernel32.dll\RtlMoveMemory", Ptr, pData := DllCall("Kernel32.dll\GlobalLock", Ptr, hData := DllCall( "Kernel32.dll\GlobalAlloc", "UInt", 2,  UPtr := A_PtrSize ? "UPtr" : "UInt" , DecLen, UPtr), UPtr) , Ptr, &Dec, UPtr, DecLen)
	DllCall("Kernel32.dll\GlobalUnlock", Ptr, hData)
	DllCall("Ole32.dll\CreateStreamOnHGlobal", Ptr, hData, "Int", True, Ptr "P", pStream)
	DllCall("Gdiplus.dll\GdipCreateBitmapFromStream",  Ptr, pStream, Ptr "P", pBitmap)
	return pBitmap
}
	)
	return abc
}
HB_BITMAP_MAKER( obj := "" , ScaleFactor := 1 ){
	pBitmap := Gdip_CreateBitmap( 301 * ScaleFactor , 301 * ScaleFactor ) , G := Gdip_GraphicsFromImage( pBitmap ) , Gdip_SetSmoothingMode( G , 3 )
	Pen := Gdip_CreatePen( "0xFFff0000" , 1 ) , Gdip_DrawRectangle( G , Pen , 0 * ScaleFactor , 0 * ScaleFactor , obj.W * ScaleFactor , obj.H * ScaleFactor ) , Gdip_DeletePen( Pen )
	Gdip_SetSmoothingMode( G , 2 )
	Pen := Gdip_CreatePen( "0xFF3399FF" , 1 ) , Gdip_DrawEllipse( G , Pen , 0 * ScaleFactor , 0 * ScaleFactor , obj.W * ScaleFactor , obj.H * ScaleFactor ) , Gdip_DeletePen( Pen )
	Gdip_DeleteGraphics( G )
	return pBitmap
}
Thank you again @boiler And @mikeyww for your help.
User avatar
Hellbent
Posts: 2109
Joined: 23 Sep 2017, 13:34

Re: Crop bitmap and export as Base64 string?

25 Jun 2023, 02:50

I have created a new version of this script ( QUICK ICON MAKER ). It is still an early draft but it does currently allow the creation of B64 and .png Icons.

This script requires a copy of the gdi+ lib for ahk and WINDOWS 8 or higher!

It currently Hardcodes the icon size to 64px by 64px. , and a few features are yet to be added.
You can clipboard any of the saved icons by clicking on them at the bottom of the window.
20230625033751.png
20230625033751.png (287.55 KiB) Viewed 2844 times
.
Icon Maker 2.gif
Icon Maker 2.gif (882.58 KiB) Viewed 2844 times
.

Code: Select all

;****************************************************************************************************************************************************************************
#Include <My Altered GDIP lib> ;<<<<<<<<<<<<<<<<<<---------------------------     gdip.ahk
;~ #Include <PopUpWindow_V2> ; At the bottom of the script 
;~ #Include <Gen 3 Buttons> ; 
;~ #Include <HB Vectors v2> 
;~ #Include, <HB Icon Buttons ( LW Ani Buttons )>
;****************************************************************************************************************************************************************************
#SingleInstance, Force
SetBatchLines, -1
#NoEnv
SetWorkingDir, % A_ScriptDir
Gdip_Startup()

IfNotExist, % A_ScriptDir "\Saved Icon Images\"
	FileCreateDir, % A_ScriptDir "\Saved Icon Images\"

Theme1 := NewTheme()
GuiButtonType1.SetSessionDefaults( Theme1.All , Theme1.Default , Theme1.Hover , Theme1.Pressed )

Gui1 := {}
Gui1.Controls := {}
Gui1.Handles := []
Gui1.Scale := 1

;<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|
Gui1.ImageBackgroundColor := "0xFF22262a" ;<<<<<========<
;<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|

Gui1.SelectedShape := "Triangle"
Gui1.ShapesArray := [ "Rectangle" , "Rounded Rectangle" , "Circle" , "Triangle" , "Pentagon" , "Hexagon" , "Heptagon" , "Octagon" , "Hexadecagon" ]
Gui1.Display := {}
Gui1.Display.pBitmap := Gdip_CreateBitmap( 400 , 400 )

Gui1.Image := {}
Gui1.Image.BackupBitmap := Gui1.Image.pBitmap := Gdip_CreateBitmapFromFile( Gui1.FilePath )
Gui1.Image.Scale := 1
Gui1.Image.X := 0
Gui1.Image.Y := 0

;####################################################

Gui1.SavedImagePaths := []
Loop, % A_ScriptDir "\Saved Icon Images\*.png"	
{
	Gui1.SavedImagePaths.Push( A_LoopFileFullPath )
	
}

Gui1.SavedB64Bitmaps := []
Loop, % A_ScriptDir "\Saved Icon Images\*.txt"	
{
	FileRead, out , % A_LoopFileFullPath
	if( out ){
		Gui1.SavedB64Bitmaps.Push( B64ToPBitmap( out ) )
	}
	
}

;**********************************************

Gui1.IconPages := []
page := 0

Loop, % Gui1.SavedB64Bitmaps.Length()	{
	
	if( A_Index = 1 || !mod( inDex , 10 ) ){
		page++
		Gui1.IconPages[ page ] := []
		inDex := 0
	}
	Gui1.IconPages[ page ][ ++Index ] := Gui1.SavedB64Bitmaps[ A_Index ]
}

Gui1.CurrentPage := page
Gui1.NumberOfPages := page
;**********************************************

Gui, New, +AlwaysOnTop -DPIScale HwndHwnd 
Gui1.Hwnd := hwnd

Gui, Font, % ( 12 / ( A_ScreenDPI / 96 ) ) * Gui1.Scale " cFFFFFF"
Gui, Color, % Background := "32363a" , 42464a

cc := Gui1.Controls.DisplayPicture := { X: 50 , Y: 50 , W: 400 , H: 400 , Method: "" }
Gui, Add, Picture, % "x" cc.X " y" cc.Y " w" cc.W " h" cc.H " 0xE hwndhwnd"
cc.Hwnd := hwnd
Gui1.Handles[ hwnd ] := cc

;<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|

cc := Gui1.Controls.Image_Y_Slider := { X: 455 , Y: 50 , W: 20 , H: 400 }
Gui, Add, Progress , % "x" cc.X " y" cc.Y " w" cc.W " h" cc.H " hwndhwnd Background"
cc.Hwnd := hwnd 

cc := Gui1.Controls.Image_Y_Thumb := { X: 455 , Y: 50 , W: 20 , H: 50 }
Gui, Add, Progress , % "x" cc.X " y" cc.Y " w" cc.W " h" cc.H " hwndhwnd BackgroundRed"
cc.Hwnd := hwnd

cc := Gui1.Controls.Image_X_Slider := { X: 50 , Y: 455 , W: 400 , H: 20 }
Gui, Add, Progress , % "x" cc.X " y" cc.Y " w" cc.W " h" cc.H " hwndhwnd Background"
cc.Hwnd := hwnd

cc := Gui1.Controls.Image_X_Thumb := { X: 50 , Y: 455 , W: 50 , H: 20 }
Gui, Add, Progress , % "x" cc.X " y" cc.Y " w" cc.W " h" cc.H " hwndhwnd BackgroundF0F0F0 cRed" , 100
cc.hwnd := hwnd

;<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|

Gui1.Controls.CaptureImageFromScreenButton := New HButton( { Owner: Gui1.Hwnd , X: 500 , Y: 30 , W: 300 , H: 40 , Text: "Capture A New Image From The Screen" , Label: "CaptureNewImageFromScreen" }  )

Gui1.Controls.LoadImageFromClipboardButton := New HButton( { Owner: Gui1.Hwnd , X: 500 , Y: 70 , W: 300 , H: 40 , Text: "Load Image From Clipboard" , Label: "LoadImageFromClipboard" } )

Gui1.Controls.LoadImageFromFileButton := New HButton( { Owner: Gui1.Hwnd , X: 500 , Y: 110 , W: 300 , H: 40 , Text: "Load Image From File" , Label: "LoadImageFromFile" }  )

Gui, Add, Edit, % "x" 500 " y" 160 " w" 230 " r1 " " -VScroll "

Gui1.Controls.GetFilePathButton := New HButton( { Owner: Gui1.Hwnd , X: 740 , Y: 150 , W: 60 , H: 40 , Text: "Get" , Label: "GetImageFilePath" }  )

;<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|

Gui, Add, Text, x500 y200 Section , ScaleFactor


GlowRadio_1.Settings.FontSize := 12
GlowRadio_1.Settings.ButtonRestColor := "0xFF440000"
GlowRadio_1.Settings.RestColor := "0xFF82868a"
GlowRadio_1.Settings.ActiveColor := "0xFFFF0000"
GlowRadio_1.Settings.Scalefactor := 1
GlowRadio_1.Settings.Owner := Gui1.Hwnd
GlowRadio_1.Settings.BackgroundColor := "0xFF32363a"
GlowRadio_1.Settings.Y_Offset := 1
GlowRadio_1.Settings.X_Offset := 5
GlowRadio_1.Settings.Label := "SetImageScale"

Gui1.ScaleList := [ "0.5" , "1.0" , "1.5" , "2.0" , "3.0" , "5.0" ]

Gui1.Controls.ScaleRadios := []
Gui1.Controls.ScaleRadios[ 1 ] := New GlowRadio_1( { X: x := 500 , Y: 220 , W: w := 52 , State: 0 , Text: "0.5" } )
Gui1.Controls.ScaleRadios[ 2 ] := New GlowRadio_1( { X: x += w , Y: 220 , W: w , State: 1 , Text: "1.0" } )
Gui1.Controls.ScaleRadios[ 3 ] := New GlowRadio_1( { X: x += w , Y: 220 , W: w , State: 0 , Text: "1.5" } )
Gui1.Controls.ScaleRadios[ 4 ] := New GlowRadio_1( { X: x += w , Y: 220 , W: w , State: 0 , Text: "2.0" } )
Gui1.Controls.ScaleRadios[ 5 ] := New GlowRadio_1( { X: x += w , Y: 220 , W: w , State: 0 , Text: "3.0" } )
Gui1.Controls.ScaleRadios[ 6 ] := New GlowRadio_1( { X: x += w , Y: 220 , W: w , State: 0 , Text: "5.0" } )

;#################################################################################################

Gui, Add, Text, x500 y+10 Section , Shape

;#############################

Gui, Add, Text, x500 y315 Section , Border Thickness

GlowRadio_1.Settings.FontSize := "11"
GlowRadio_1.Settings.GroupName := "Group_2"
GlowRadio_1.Settings.Label := "SetBorderThickness"

Gui1.BorderThicknessList := [ "0" , "1" , "2" , "3" , "4" , "5" , "10" ]

Gui1.Controls.BorderThicknessRadios := []
Gui1.Controls.BorderThicknessRadios[ 1 ] := New GlowRadio_1( { X: x := 500 , Y: y := 335 , W: w := 45 , State: 0 , Text: "0" } )
Gui1.Controls.BorderThicknessRadios[ 2 ] := New GlowRadio_1( { X: x += w , Y: y , W: w , State: 1 , Text: "1" } )
Gui1.Controls.BorderThicknessRadios[ 3 ] := New GlowRadio_1( { X: x += w , Y: y , W: w , State: 0 , Text: "2" } )
Gui1.Controls.BorderThicknessRadios[ 4 ] := New GlowRadio_1( { X: x += w , Y: y , W: w , State: 0 , Text: "3" } )
Gui1.Controls.BorderThicknessRadios[ 5 ] := New GlowRadio_1( { X: x += w , Y: y , W: w , State: 0 , Text: "4" } )
Gui1.Controls.BorderThicknessRadios[ 6 ] := New GlowRadio_1( { X: x += w , Y: y , W: w , State: 0 , Text: "5" } )
Gui1.Controls.BorderThicknessRadios[ 7 ] := New GlowRadio_1( { X: x += w , Y: y , W: w , State: 0 , Text: "10" } )

;********************************************

Gui, Show, x700 w820 h600

;********************************************

BoundFunc := Func( "TestFunction" ).Bind( Gui1 )
		
Gui1.ShapeListDDL := New DropDownListv1( { rows: 				3
										, X:					500 
										, Y: 					270
										, Bind: 				BoundFunc
										, ScaleFactor: 			1
										, W: 					280 
										, FontSize: 			14 
										, FontColor: 			"0xFFFF0000" 
										, Font: 				"Segoe UI" 
										, Parent: 				Gui1.Hwnd 
										, Selected:     		4	
										, HighlightFontColor:   "0xFFFFFFFF"	
										, List: 				Gui1.ShapesArray } )	
										
;********************************************

Gui1.Controls.SaveB64 := New HButton( { Owner: Gui1.Hwnd , X: x := 635 , Y: 370 , W: w := 55 , H: 120 , Text: "        B64" , Label: "SaveNewB64Icon" } , { FontOptions: "Top Center " } )
QuickIcon64x64 := "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"
FloppyDiskBitmap := B64ToPBitmap( QuickIcon64x64 )

G := Gdip_GraphicsFromImage( HButton.Button[ Gui1.Controls.SaveB64 ].Bitmaps.Default.pBitmap )
Gdip_DrawImage( G , FloppyDiskBitmap, 10 , 38 , 35 , 35 )
Gdip_DeleteGraphics( G )

G := Gdip_GraphicsFromImage( HButton.Button[ Gui1.Controls.SaveB64 ].Bitmaps.Hover.pBitmap )
Gdip_DrawImage( G , FloppyDiskBitmap, 5 , 35 , 45 , 45 )
Gdip_DeleteGraphics( G )

G := Gdip_GraphicsFromImage( HButton.Button[ Gui1.Controls.SaveB64 ].Bitmaps.Pressed.pBitmap )
Gdip_DrawImage( G , FloppyDiskBitmap, 7 , 36 , 41 , 41 )
Gdip_DeleteGraphics( G )

DeleteObject( HButton.Button[ Gui1.Controls.SaveB64 ].Bitmaps.Default.hBitmap )
DeleteObject( HButton.Button[ Gui1.Controls.SaveB64 ].Bitmaps.Hover.hBitmap )
DeleteObject( HButton.Button[ Gui1.Controls.SaveB64 ].Bitmaps.Pressed.hBitmap )

HButton.Button[ Gui1.Controls.SaveB64 ].Bitmaps.Default.hBitmap := Gdip_CreateHBITMAPFromBitmap( HButton.Button[ Gui1.Controls.SaveB64 ].Bitmaps.Default.pBitmap )
HButton.Button[ Gui1.Controls.SaveB64 ].Bitmaps.Hover.hBitmap := Gdip_CreateHBITMAPFromBitmap( HButton.Button[ Gui1.Controls.SaveB64 ].Bitmaps.Hover.pBitmap )
HButton.Button[ Gui1.Controls.SaveB64 ].Bitmaps.Pressed.hBitmap := Gdip_CreateHBITMAPFromBitmap( HButton.Button[ Gui1.Controls.SaveB64 ].Bitmaps.Pressed.pBitmap )
HButton._DisplayButton( Gui1.Controls.SaveB64 , HButton.Button[ Gui1.Controls.SaveB64 ].Bitmaps.Default.hBitmap )

Gui1.Controls.SavePng := New HButton( { Owner: Gui1.Hwnd , X: x += w + 5 , Y: 370 , W: w , H: 120 , Text: "        .png" , Label: "SavePNGToFIle" } , { FontOptions: "Top Center " } )

PNGICON64x64 := "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"

PNG_ICON_Bitmap := B64ToPBitmap( PNGICON64x64 )

G := Gdip_GraphicsFromImage( HButton.Button[ Gui1.Controls.SavePng ].Bitmaps.Default.pBitmap )
Gdip_DrawImage( G , PNG_ICON_Bitmap, 10 , 38 , 35 , 35 )
Gdip_DeleteGraphics( G )

G := Gdip_GraphicsFromImage( HButton.Button[ Gui1.Controls.SavePng ].Bitmaps.Hover.pBitmap )
Gdip_DrawImage( G , PNG_ICON_Bitmap, 5 , 35 , 45 , 45 )
Gdip_DeleteGraphics( G )

G := Gdip_GraphicsFromImage( HButton.Button[ Gui1.Controls.SavePng ].Bitmaps.Pressed.pBitmap )
Gdip_DrawImage( G , PNG_ICON_Bitmap, 5 , 36 , 45 , 45 )
Gdip_DeleteGraphics( G )

DeleteObject( HButton.Button[ Gui1.Controls.SavePng ].Bitmaps.Default.hBitmap )
DeleteObject( HButton.Button[ Gui1.Controls.SavePng ].Bitmaps.Hover.hBitmap )
DeleteObject( HButton.Button[ Gui1.Controls.SavePng ].Bitmaps.Pressed.hBitmap )

HButton.Button[ Gui1.Controls.SavePng ].Bitmaps.Default.hBitmap := Gdip_CreateHBITMAPFromBitmap( HButton.Button[ Gui1.Controls.SavePng ].Bitmaps.Default.pBitmap )
HButton.Button[ Gui1.Controls.SavePng ].Bitmaps.Hover.hBitmap := Gdip_CreateHBITMAPFromBitmap( HButton.Button[ Gui1.Controls.SavePng ].Bitmaps.Hover.pBitmap )
HButton.Button[ Gui1.Controls.SavePng ].Bitmaps.Pressed.hBitmap := Gdip_CreateHBITMAPFromBitmap( HButton.Button[ Gui1.Controls.SavePng ].Bitmaps.Pressed.pBitmap )
HButton._DisplayButton( Gui1.Controls.SavePng , HButton.Button[ Gui1.Controls.SavePng ].Bitmaps.Default.hBitmap )

Gui1.Controls.ClipboardB64 := New HButton( { Owner: Gui1.Hwnd , X: x += w + 5 , Y: 370 , W: w , H: 120 , Text: "        B64" , Label: "ClipboardBase64" } , { FontOptions: "Top Center " } )

ClipBoardIcon64x64 := "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"
Clipboard_ICON_Bitmap := B64ToPBitmap( ClipBoardIcon64x64 )

G := Gdip_GraphicsFromImage( HButton.Button[ Gui1.Controls.ClipboardB64 ].Bitmaps.Default.pBitmap )
Gdip_DrawImage( G , Clipboard_ICON_Bitmap, 10 , 38 , 35 , 35 )
Gdip_DeleteGraphics( G )

G := Gdip_GraphicsFromImage( HButton.Button[ Gui1.Controls.ClipboardB64 ].Bitmaps.Hover.pBitmap )
Gdip_DrawImage( G , Clipboard_ICON_Bitmap, 5 , 35 , 45 , 45 )
Gdip_DeleteGraphics( G )

G := Gdip_GraphicsFromImage( HButton.Button[ Gui1.Controls.ClipboardB64 ].Bitmaps.Pressed.pBitmap )
Gdip_DrawImage( G , Clipboard_ICON_Bitmap, 5 , 36 , 45 , 45 )
Gdip_DeleteGraphics( G )

DeleteObject( HButton.Button[ Gui1.Controls.ClipboardB64 ].Bitmaps.Default.hBitmap )
DeleteObject( HButton.Button[ Gui1.Controls.ClipboardB64 ].Bitmaps.Hover.hBitmap )
DeleteObject( HButton.Button[ Gui1.Controls.ClipboardB64 ].Bitmaps.Pressed.hBitmap )

HButton.Button[ Gui1.Controls.ClipboardB64 ].Bitmaps.Default.hBitmap := Gdip_CreateHBITMAPFromBitmap( HButton.Button[ Gui1.Controls.ClipboardB64 ].Bitmaps.Default.pBitmap )
HButton.Button[ Gui1.Controls.ClipboardB64 ].Bitmaps.Hover.hBitmap := Gdip_CreateHBITMAPFromBitmap( HButton.Button[ Gui1.Controls.ClipboardB64 ].Bitmaps.Hover.pBitmap )
HButton.Button[ Gui1.Controls.ClipboardB64 ].Bitmaps.Pressed.hBitmap := Gdip_CreateHBITMAPFromBitmap( HButton.Button[ Gui1.Controls.ClipboardB64 ].Bitmaps.Pressed.pBitmap )
HButton._DisplayButton( Gui1.Controls.ClipboardB64 , HButton.Button[ Gui1.Controls.ClipboardB64 ].Bitmaps.Default.hBitmap )

Gui1.ShapeOutline := { X: 0 , Y: 0 , W: 100 , H: 100 , Radius: 50 , Type: "Rounded Rectangle" , Angle: 270 , Thickness: 1 }
Gui1.ShapeColor := "0xFFFF0000"
SetupNewImage( Gui1 , Gui1.Image.pBitmap )

cc := Gui1.OutputIconWindow := New PopUpWindow( { AutoShow: 1 , X: 500 , Y: 365 , W: 128 * Gui1.Scale , H: 128 * Gui1.Scale , Options: " +AlwaysOnTop -DPIScale Parent" Gui1.Hwnd } ) 

Brush := Gdip_BrushCreateHatch( "0x66000000" , "0x66ffffff" , 52 ) 
, Gdip_FillRoundedRectangle( Gui1.OutputIconWindow.G , Brush , 2 * Gui1.Scale , 2 * Gui1.Scale , ( cc.W - 4 ) * Gui1.Scale , ( cc.H - 4 ) * Gui1.Scale , 15 * Gui1.Scale ) 
, Gdip_DeleteBrush( Brush )

Gui1.OutputIconWindow.PaintBackground( { Color: "0xFFFF0000" , X: 32 , Y: 32 , W: 64 , H: 64 , Round: 10 } , AutoUpdate := 1 ) 

;********************************************************************************

cc := Gui1.IconStripWindow := New PopUpWindow( { AutoShow: 1 , X: 55 , Y: 500 , W: 750 * Gui1.Scale , H: 80 * Gui1.Scale , Options: " +AlwaysOnTop -DPIScale Parent" Gui1.Hwnd } ) 

Gui1.IconButtons := []
x := 7
Loop, % 10	{
	obj := { Alpha: 		255 
			, PulseLength: 	5 
			, PulseRate: 	1 
			, Animate:		"Pulse" 
			, X: 			x 
			, Y: 			8 
			, W: 			64 
			, H: 			64 
			, pBitmap: 		Gui1.IconPages[ Gui1.CurrentPage ][ A_Index ]
			, Parent: 		cc.Hwnd 
			, Label:		"IconButtonLabel" }
	x += 70		
	Gui1.IconButtons[ A_Index ] := New IconButtons( obj )
	bd := Func( "IconButtonLabel" ).Bind( Gui1 )
	GuiControl, % Gui1.IconButtons[ A_Index ].Window.Hwnd ":+G" , % Gui1.IconButtons[ A_Index ].Control.Hwnd , IconButtonLabel
}

DrawSavedIcons( Gui1 )

Gui1.Controls.StripLeftButton := New HButton( { Owner: Gui1.Hwnd , X: 5 , Y:500  , W: 50 , H: 80 , Text: "3" , Label: "SavedIconPageDown" } , { Font: "WebDings" , FontSize: 26 } )
Gui1.Controls.StripRightButton := New HButton( { Owner: Gui1.Hwnd , X: 765 , Y:500  , W: 50 , H: 80 , Text: "4" , Label: "SavedIconPageUp" } , { Font: "WebDings" , FontSize: 26 } )

;********************************************************************************

GlowRadio_1.Settings.FontSize := "11"
GlowRadio_1.Settings.GroupName := "Group_3"
GlowRadio_1.Settings.Label := "SetDisplayType"

Gui1.Controls.TypeRadios := []
Gui1.Controls.TypeRadios[ 1 ] := New GlowRadio_1( { X: x := 50 , Y: y := 478 , W: w := 75 , State: 0 , Text: ".png" } )
Gui1.Controls.TypeRadios[ 2 ] := New GlowRadio_1( { X: x += w , Y: y , W: w , State: 1 , Text: "B64" } )

;********************************************************************************

OnMessage( 0x201 , Func( "ClickEvent" ).Bind( Gui1 ) )
OnMessage( 0x020A , Func( "WheelEvent" ).Bind( Gui1 ) )

Gui1.Controls.DirectionControl := New PositionButtons( { Scale: .4 , Parent: Gui1.Hwnd , X: 10 / 0.3 , Y: 3 / 0.3 , Bind: [ Func("MoveShapeUp").Bind( Gui1 ) , Func("MoveShapeDown").Bind( Gui1 ) , Func("MoveShapeLeft").Bind( Gui1 ) , Func("MoveShapeRight").Bind( Gui1 ) ] } )

cc := Gui1.ColorWheelWindow := New PopUpWindow( { AutoShow: 1 , X: 10 , Y: 60 , W: 30 , H: 380 , Options: " +AlwaysOnTop -DPIScale Parent" Gui1.Hwnd } ) 

cc.PaintBackground( color := "0xFF000000" , AutoUpdate := 0 ) 
cc.DrawBitmap( CreateColorWheelBitmap( Gui1 ) , { X: 0 , Y: 0 , W: cc.W , H: cc.H } , dispose := 1 , AutoUpdate := 1 )

return
GuiClose:
;~ GuiContextMenu:
;~ *ESC::
	ExitApp

;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
CreateColorWheelBitmap( Gui1 ){
	cc := Gui1.ColorWheelWindow
	pBitmap := Gdip_CreateBitmap( w := cc.W * Gui1.Scale , h := cc.H * Gui1.Scale ) 
	G := Gdip_GraphicsFromImage( pBitmap ) 
	
	Gdip_SetSmoothingMode( G , 1 )
	HueRate := 1 / Gui1.Scale
	SatRate := 1 / h 
	Sat := 1 
	lum := 0.5
	
	
	x := 1 
	Loop, % w	{
		y := 1 , Hue := 1
		Loop, % h {
			Gdip_SetPixel( pBitmap, x , y , "0xFF" SubStr( HSL_ToRGB( hue , sat , lum ) , 3 ) )
			y++ , hue += HueRate 
		}
		x++ , Sat -= SatRate
	}
	
	
	Gdip_DeleteGraphics( G )
	return pBitmap
}
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

MoveShapeUp( Gui1 ){
	ly := Gui1.ShapeOutline.Y
	
	( GetKeyState( "Ctrl" ) ) ? ( Gui1.ShapeOutline.Y -= 100 ) : ( GetKeyState( "Shift" ) ) ? ( Gui1.ShapeOutline.Y -= 10 ) : ( Gui1.ShapeOutline.Y -= 1 )
	( Gui1.ShapeOutline.Y < ( Gui1.ShapeOutline.H / 2 ) * -1 ) ? ( Gui1.ShapeOutline.Y := ( Gui1.ShapeOutline.H / 2 ) * -1 )
	
	if( ly != Gui1.ShapeOutline.Y )
		UpdateWindow( Gui1 )
	
	return
}

MoveShapeDown( Gui1 ){
	ly := Gui1.ShapeOutline.Y
	
	( GetKeyState( "Ctrl" ) ) ? ( Gui1.ShapeOutline.Y += 100 ) : ( GetKeyState( "Shift" ) ) ? ( Gui1.ShapeOutline.Y += 10 ) : ( Gui1.ShapeOutline.Y += 1 )
	( Gui1.ShapeOutline.Y > 400 - ( Gui1.ShapeOutline.H / 2 ) ) ? ( Gui1.ShapeOutline.Y := 400 - ( Gui1.ShapeOutline.H / 2 ) ) 
	
	if( ly != Gui1.ShapeOutline.Y )
		UpdateWindow( Gui1 )
	return
}

MoveShapeLeft( Gui1 ){
	lx := Gui1.ShapeOutline.X
	
	( GetKeyState( "Ctrl" ) ) ? ( Gui1.ShapeOutline.X -= 100 ) : ( GetKeyState( "Shift" ) ) ? ( Gui1.ShapeOutline.X -= 10 ) : ( Gui1.ShapeOutline.X -= 1 )
	( Gui1.ShapeOutline.X < ( Gui1.ShapeOutline.W / 2 ) * -1 ) ? ( Gui1.ShapeOutline.X := ( Gui1.ShapeOutline.W / 2 ) * -1 )
	
	if( lx != Gui1.ShapeOutline.X )
		UpdateWindow( Gui1 )
	return
}

MoveShapeRight( Gui1 ){
	lx := Gui1.ShapeOutline.X
	
	( GetKeyState( "Ctrl" ) ) ? ( Gui1.ShapeOutline.X += 100 ) : ( GetKeyState( "Shift" ) ) ? ( Gui1.ShapeOutline.X += 10 ) : ( Gui1.ShapeOutline.X += 1 )
	( Gui1.ShapeOutline.X > 400 - ( Gui1.ShapeOutline.W / 2 ) ) ? ( Gui1.ShapeOutline.X := 400 - ( Gui1.ShapeOutline.W / 2 ) ) 
	
	if( lx != Gui1.ShapeOutline.X )
		UpdateWindow( Gui1 )
	return
}

LoadImageFromFile:
	ToolTip, Currently Not Available
	sleep, 2000
	ToolTip
	return

GetImageFilePath:
	ToolTip, Currently Not Available
	sleep, 2000
	ToolTip
	return

SetDisplayType:
	ToolTip, Not enabled yet
	sleep, 1500
	ToolTip
	return 
	
	
ClipboardBase64:
	Clipboard := ""
	sleep, 500
	out :=  Gdip_EncodeBitmapTo64string( Gui1.CroppedBitmap , "PNG" , 100 )
	Clipboard := Out
	SoundBeep
	return

SaveNewB64Icon:
	out :=  Gdip_EncodeBitmapTo64string( Gui1.CroppedBitmap , "PNG" , 100 )
	name := "Icon_B64_" A_Now ".txt"
	FileAppend, % out , % A_ScriptDir "\Saved Icon Images\" name
	
	Gui1.SavedB64Bitmaps.push( Gdip_CloneBitmapArea( Gui1.CroppedBitmap , 0 , 0 , 64 , 64 ) )
	
	;**********************************************
	Gui1.IconPages := []
	page := 0

	Loop, % Gui1.SavedB64Bitmaps.Length()	{
		
		if( A_Index = 1 || !mod( inDex , 10 ) ){
			page++
			Gui1.IconPages[ page ] := []
			inDex := 0
			
		}
		
		Gui1.IconPages[ page ][ ++Index ] := Gui1.SavedB64Bitmaps[ A_Index ]
	}

	Gui1.CurrentPage := page
	Gui1.NumberOfPages := page
	
	DrawSavedIcons( Gui1 )
	;**********************************************
	SoundBeep
	return


SavedIconPageDown:
	if( Gui1.CurrentPage > 1 ){
		Gui1.CurrentPage--
		DrawSavedIcons( Gui1 )
		
	}
	return
	
SavedIconPageUp:
	if( Gui1.CurrentPage < Gui1.NumberOfPages ){
		Gui1.CurrentPage++
		DrawSavedIcons( Gui1 )
		
	}
	return	

DrawSavedIcons( Gui1 ){
	
		
	cc := Gui1.IconStripWindow
	
	cc.ClearWindow()
	
	cc.PaintBackground( { Color: "0xFF22262a" , X: 2 , Y: 2 , W: 705 , H: cc.H - 4 , Round: 10 } , AutoUpdate := 1 ) 
	cc.PaintBackground( { Color: "0xFF12161a" , X: x := 7 , Y: 8 , W: 64 , H: cc.H - 16 , Round: 10 } , AutoUpdate := 1 ) 
	cc.PaintBackground( { Color: "0xFF12161a" , X: x += 70 , Y: 8 , W: 64 , H: cc.H - 16 , Round: 10 } , AutoUpdate := 1 ) 
	cc.PaintBackground( { Color: "0xFF12161a" , X: x += 70 , Y: 8 , W: 64 , H: cc.H - 16 , Round: 10 } , AutoUpdate := 1 ) 
	cc.PaintBackground( { Color: "0xFF12161a" , X: x += 70 , Y: 8 , W: 64 , H: cc.H - 16 , Round: 10 } , AutoUpdate := 1 ) 
	cc.PaintBackground( { Color: "0xFF12161a" , X: x += 70 , Y: 8 , W: 64 , H: cc.H - 16 , Round: 10 } , AutoUpdate := 1 ) 
	cc.PaintBackground( { Color: "0xFF12161a" , X: x += 70 , Y: 8 , W: 64 , H: cc.H - 16 , Round: 10 } , AutoUpdate := 1 ) 
	cc.PaintBackground( { Color: "0xFF12161a" , X: x += 70 , Y: 8 , W: 64 , H: cc.H - 16 , Round: 10 } , AutoUpdate := 1 ) 
	cc.PaintBackground( { Color: "0xFF12161a" , X: x += 70 , Y: 8 , W: 64 , H: cc.H - 16 , Round: 10 } , AutoUpdate := 1 ) 
	cc.PaintBackground( { Color: "0xFF12161a" , X: x += 70 , Y: 8 , W: 64 , H: cc.H - 16 , Round: 10 } , AutoUpdate := 1 ) 
	cc.PaintBackground( { Color: "0xFF12161a" , X: x += 70 , Y: 8 , W: 64 , H: cc.H - 16 , Round: 10 } , AutoUpdate := 1 ) 
	
	x := 7
	Loop, % Gui1.IconPages[ Gui1.CurrentPage ].Length()	{
		
		Brush := Gdip_BrushCreateHatch( "0x66000000" , "0x66ffffff" , 52 ) 
		, Gdip_FillRectangle( cc.G , Brush , x * Gui1.Scale , 8 * Gui1.Scale , 64 * Gui1.Scale , 64 * Gui1.Scale ) 
		, Gdip_DeleteBrush( Brush )
		
		x += 70
		
	}
	
	Loop, 10	{
		Gui1.IconButtons[ A_Index ].Bitmap.pBitmap := Gui1.IconPages[ Gui1.CurrentPage ][ A_Index ]
		Gui1.IconButtons[ A_Index ].Draw()
	}
	
	
	
	
	
	cc.UpdateWindow()
	
}



SavePNGToFIle:
	SoundBeep
	path := A_ScriptDir "\Saved Icon Images\Icon_" A_Now ".png"
	Gdip_SaveBitmapToFile( Gui1.CroppedBitmap , path , 100 )

	return


TestFunction( Gui1 ){
	Gui1.SelectedShape := Gui1.ShapesArray[ Gui1.ShapeListDDL.Selected ]
	Gui1.ShapeOutline.Type := Gui1.SelectedShape
	if(  Gui1.SelectedShape = "Rectangle" )
		Gui1.ShapeOutline.Angle := 45
	else
		Gui1.ShapeOutline.Angle := 270
	UpdateWindow( Gui1 )
	return
}

CaptureNewImageFromScreen:
	Target := New DrawTarget()
	pBitmap := Gdip_BitmapFromScreen( Target.X "|" Target.Y "|" Target.W "|" Target.H  )
	SetupNewImage( Gui1 , pBitmap )
	return


SetBorderThickness:

	Gui1.ShapeOutline.Thickness := Gui1.BorderThicknessList[ Gui1.Controls.BorderThicknessRadios[ 1 ].GetSelected() ]
	UpdateWindow( Gui1 )
	return

SetImageScale:
	
	
	
	Gui1.Image.Scale := Gui1.ScaleList[ Gui1.Controls.ScaleRadios[ 1 ].GetSelected() ]
	
	
	
	SetupNewImage( Gui1 , Gui1.Image.BackupBitmap )
	return

rotateShape:
	Gui1.ShapeOutline.Angle += 3
	UpdateWindow( Gui1 )
	return


SetupNewImage( Gui1 , nBitmap ){
	
	;~ Gdip_DisposeImage( Gui1.Image.BackupBitmap )
	;~ Gdip_DisposeImage( Gui1.Image.pBitmap )
	
	Gui1.Image.BackupBitmap := nBitmap
	
	W := Gdip_GetImageWidth( nBitmap )
	H := Gdip_GetImageHeight( nBitmap )
	w += 600
	h += 600
	
	pBitmap := Gdip_CreateBitmap( w  , h  )
	G := Gdip_GraphicsFromImage( pBitmap )
	Gdip_SetInterpolationMode(G, 7)
	Brush := Gdip_BrushCreateSolid( Gui1.ImageBackgroundColor )
	Gdip_FillRectangle( G , Brush , -2 , -2 , w + 4 , h + 4 )
	Gdip_DeleteBrush( Brush )
	
	Gdip_DrawImage( G , nBitmap, 300 , 300 , w - 600 , h - 600 )
	Gdip_DeleteGraphics( G )

	Gui1.Image.pBitmap := pBitmap
	
	
	
	Gui1.Image.W := Gdip_GetImageWidth( Gui1.Image.pBitmap )
	Gui1.Image.H := Gdip_GetImageHeight( Gui1.Image.pBitmap )
	
	w := Gui1.Image.W *= Gui1.Image.Scale
	h := Gui1.Image.H *= Gui1.Image.Scale
	Gui1.Image.X := -300 * Gui1.Image.Scale
	Gui1.Image.Y := -300 * Gui1.Image.Scale
	
	G := Gdip_GraphicsFromImage( Gui1.Display.pBitmap )
	Gdip_SetInterpolationMode(G, 7)
	Brush := Gdip_BrushCreateSolid( "0xFF000000" )
	Gdip_FillRectangle( G , Brush , -10 , -10 , 500 , 500 )
	Gdip_DeleteBrush( Brush )
	Gdip_DrawImage( G , pBitmap , Gui1.Image.X , Gui1.Image.Y , w , h )
	
	DrawShape( Gui1 , G )
	
	
	
	hBitmap := Gdip_CreateHBITMAPFromBitmap( Gui1.Display.pBitmap )
	SetImage( Gui1.Controls.DisplayPicture.hwnd , hBitmap )
	DeleteObject( hBitmap )
	Gdip_DeleteGraphics( G )
	
	cc := Gui1.Controls.Image_X_Thumb
	cc.X :=  Gui1.Controls.Image_X_Slider.X
	
	
	if( w <= 400 ){
		cc.W := 400
		GuiControl, % Gui1.Hwnd ":Move" , % Gui1.Controls.Image_X_Thumb.Hwnd , % "x" cc.X " y" cc.Y " w" cc.W " h" cc.H
		cc.TScale := 0
	}else if( w <= 750 ){
		cc.W := 800 - w 
		GuiControl, % Gui1.Hwnd ":Move" , % Gui1.Controls.Image_X_Thumb.Hwnd , % "x" cc.X " y" cc.Y " w" cc.W " h" cc.H
		cc.TScale := 1
	}else{
		cc.W := 50
		cc.TScale := w / 400 
		GuiControl, % Gui1.Hwnd ":Move" , % Gui1.Controls.Image_X_Thumb.Hwnd , % "x" cc.X " y" cc.Y " w" cc.W " h" cc.H
	}
	;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
	cc := Gui1.Controls.Image_Y_Thumb
	cc.Y :=  Gui1.Controls.Image_Y_Slider.Y
	if( h <= 400 ){
		cc.H := 400
		GuiControl, % Gui1.Hwnd ":Move" , % Gui1.Controls.Image_Y_Thumb.Hwnd , % "x" cc.X " y" cc.Y " w" cc.W " h" cc.H
		cc.TScale := 0
	}else if( h <= 750 ){
		cc.H := 800 - h
		GuiControl, % Gui1.Hwnd ":Move" , % Gui1.Controls.Image_Y_Thumb.Hwnd , % "x" cc.X " y" cc.Y " w" cc.W " h" cc.H
		cc.TScale := 1
	}else{
		cc.H := 50
		cc.TScale := h / 400 
		GuiControl, % Gui1.Hwnd ":Move" , % Gui1.Controls.Image_Y_Thumb.Hwnd , % "x" cc.X " y" cc.Y " w" cc.W " h" cc.H
	}
	;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
	
}


ClickEvent( Gui1 , w , l , msg , hwnd ){
	
	CoordMode, Mouse, Client
	MouseGetPos, x , y
	x /= Gui1.Scale
	y /= Gui1.Scale
	for k , v in [ "Image_Y_Slider" , "Image_X_Slider" ]	{
		cc := Gui1.Controls[ v ]
		str := SubStr( v , 1 , strlen( v ) - 6 ) "Thumb"
		thumb := Gui1.Controls[ str ]
		if( x >= cc.X && x <= cc.X + cc.W && y >= cc.Y && y <= cc.Y + cc.H ){
			if( Thumb.TScale ){
				SetThumbPosition( Gui1 , cc , Thumb , v )
				Sleep, 30
				return 1
			}
		}
	}
	cc := Gui1.Controls.DisplayPicture
	if( x >= cc.X && x <= cc.X + cc.W && y >= cc.Y && y <= cc.Y + cc.H ){
		x -= 50 
		y -= 50 
		MouseVector := New Vector( x , y )
		ShapeVector := New Vector( Gui1.ShapeOutline.X + Gui1.ShapeOutline.W / 2  , Gui1.ShapeOutline.Y + Gui1.ShapeOutline.H / 2 )
		Gui1.AngleVector := New Vector( Gui1.ShapeOutline.X - 20 + 7 , Gui1.ShapeOutline.Y + Gui1.ShapeOutline.H / 2 )
		LeftVector := New Vector( Gui1.AngleVector )
		Gui1.ColorVector := New Vector( Gui1.AngleVector.X , Gui1.ShapeOutline.Y + Gui1.ShapeOutline.H / 2 + 20 )
		if( MouseVector.Dist( ShapeVector ) < Gui1.ShapeOutline.Radius ){
			While( GetKeyState( "LButton" , "P" ) ){
				MouseGetPos, x , y
				x -= 50 
				y -= 50 
				if( x < 0 )
					x := 0
				else if( x > 400 * Gui1.Scale )	
					x := 400 * Gui1.Scale 
				if( y < 0 )
					y := 0
				else if( y > 400 * Gui1.Scale )
					y := 400 * Gui1.Scale 
				Gui1.ShapeOutline.X := x - Gui1.ShapeOutline.Radius
				Gui1.ShapeOutline.Y := y - Gui1.ShapeOutline.Radius
				UpdateWindow( Gui1 )
				Sleep, 30
			}
		}else if( MouseVector.Dist( LeftVector ) < 15 ){
			While( GetKeyState( "LButton" , "P" ) ){
				MouseGetPos, x , y
				x -= 50 
				y -= 50 
				MouseVector := New Vector( x , y )
				MouseVector.Sub( { X: Gui1.ShapeOutline.X + Gui1.ShapeOutline.W / 2 , Y: Gui1.ShapeOutline.Y + Gui1.ShapeOutline.H / 2 } )
				Gui1.ShapeOutline.Angle := MouseVector.GetAngle()
				UpdateWindow( Gui1 )
				Sleep, 30
			}
		}else if( MouseVector.Dist( Gui1.ColorVector ) < 15 ){
			colorGui := New PopUpWindow( { AutoShow: 1 , X: x + 100, Y: y - 25  , W: 50 , H: 50 , Options: " +AlwaysOnTop -DPIScale +Owner" Gui1.Hwnd } ) 
			While( GetKeyState( "LButton" , "P" ) ){
				CoordMode, Mouse, Screen
				CoordMode, Pixel, Screen
				MouseGetPos, x , y
				PixelGetColor, OutColor , x , y , RGB 
				colorGui.X := x + 100
				colorGui.Y := y - 25
				colorGui.PaintBackground( { color: "0xFF" SubStr( OutColor , 3 ) , X: 2 , Y: 2 , W: colorGui.W - 4 , H: colorGui.H - 4 , Round: 10 } , AutoUpdate := 1 ) 
				Gui1.ShapeColor := "0xFF" SubStr( OutColor , 3 )
				UpdateWindow( Gui1 )
				Sleep, 30
			}
			colorGui.DeleteWindow()
		}
	}
	cc := Gui1.IconStripWindow
	if( x >= cc.X && x <= cc.X + cc.W && y >= cc.Y && y <= cc.Y + cc.H ){
		tx := x 
		ty := y 
		x -= cc.X
		y -= cc.Y
		Loop, 10	{
			cc := Gui1.IconButtons[ A_Index ].Window
			if( x >= cc.X && x <= cc.X + cc.W && y >= cc.Y && y <= cc.Y + cc.H ){
				if( Gui1.IconPages[ Gui1.CurrentPage ][ A_Index ] ){
					Clipboard := ""
					sleep, 500
					out :=  Gdip_EncodeBitmapTo64string( Gui1.SavedB64Bitmaps[ ( Gui1.CurrentPage * 10 - 10 ) + A_Index  ] , "PNG" , 100 )
					Clipboard := Out
					SoundBeep
				}
				return 1
			}
		}
	}
	return 
}


SetThumbPosition( Gui1 , Slider , Thumb , ControlName  ){
	
	CoordMode, Mouse, Client
	
	While( GetKeyState( "LButton" , "P" ) ){
		MouseGetPos, x , y
		change := 0
		if( ControlName = "Image_X_Slider" ){
			if( x < Slider.X + Thumb.W / 2 && x != lx ){
				lx := x
				Thumb.X := Slider.X
				change := 1
			}else if( x > Slider.X + Slider.W - Thumb.W / 2 && x != lx ){
				lx := x
				Thumb.X := Slider.X + Slider.W - Thumb.W
				change := 1
			}else if( x != lx ){
				lx := x
				Thumb.X := x - Thumb.W / 2
				change := 1
			}
			
			if( change ){
				MoveSliderThumbControl( Gui1 , Thumb )
				if( Gui1.Image.W >= 750 ){
					Gui1.Image.X := ( Slider.X - Thumb.X )  
					Gui1.Image.X *= Thumb.TScale
				}else{
					Gui1.Image.X := ( Slider.X - Thumb.X )  
				}
				UpdateWindow( Gui1 )
			}
			
		}else if( ControlName = "Image_Y_Slider" ){
			if( y < Slider.Y + Thumb.H / 2 && y != ly ){
				ly := y
				Thumb.Y := Slider.Y
				change := 1
			}else if( y > Slider.Y + Slider.H - Thumb.H / 2 && y != ly ){
				ly := y
				Thumb.Y := Slider.Y + Slider.H - Thumb.H
				change := 1
			}else if( y != ly ){
				ly := y
				Thumb.Y := y - Thumb.H / 2
				change := 1
			}
			
			if( change ){
				MoveSliderThumbControl( Gui1 , Thumb )
				if( Gui1.Image.H >= 750 ){
					Gui1.Image.Y := ( Slider.Y - Thumb.Y )  
					Gui1.Image.Y *= Thumb.TScale
				}else{
					Gui1.Image.Y := ( Slider.Y - Thumb.Y )  
				}
				UpdateWindow( Gui1 )
			}
			
			
		}
		
	
	}
	
}

;<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|

WheelEvent( Gui1 , input ){
	static Busy
	
	if( Busy )
		return
	
	Busy := 1
	
	MouseGetPos,,,, ctrl , 2
	
	cc := Gui1.Controls.DisplayPicture
	
	if( cc.Hwnd != ctrl ){
		busy := 0
		return 
		
	}
	
	Dir := ( (input >> 16 ) > 0x7FFF ) || ( ( input < 0 ) ? ( 1 ) : ( 0 ) )
	cc := Gui1.ShapeOutline
	
	if( Dir ){ ;wheel Up
		
		if( GetKeyState( "Shift" ) ){
			
			if( cc.W < Gui1.Controls.DisplayPicture.W - 10 ){
				cc.X -= 5
				cc.Y -= 5
				cc.W += 10
				cc.H += 10
				cc.Radius += 5
				UpdateWindow( Gui1 )
			}
			
		}else{
			if( cc.W < Gui1.Controls.DisplayPicture.W ){
				cc.X -= 1
				cc.Y -= 1
				cc.W += 2
				cc.H += 2
				cc.Radius += 1
				UpdateWindow( Gui1 )
			}
			
		}
		
	}else{ ;wheel down
		
		if( GetKeyState( "Shift" ) ){
			if( cc.W > 50 ){
				cc.X += 5
				cc.Y += 5
				cc.W -= 10
				cc.H -= 10
				cc.Radius -= 5
			}else if( cc.W != 50 ){
				out := ( 50 - cc.W )
			}
			UpdateWindow( Gui1 )
		}else{
			if( cc.W > 50 ){
				cc.X += 1
				cc.Y += 1
				cc.W -= 2
				cc.H -= 2
				cc.Radius -= 1
			}
			UpdateWindow( Gui1 )
		}
	}
	
	Busy := 0
	return 1
}
;<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|
LoadImageFromClipboard:
	clip := Clipboard
	nStr := SubStr( Clip , StrLen( Clip ) - 2 ) 
	
	if( nStr = "png" || nStr = "jpg" ){
		
		Gdip_DisposeImage( Gui1.Image.pBitmap )

		Gui1.Image.pBitmap := Gdip_CreateBitmapFromFile( clip )
	}else{
		Gdip_DisposeImage( Gui1.Image.pBitmap )
		Gui1.Image.pBitmap := Gdip_CreateBitmapFromClipboard()
	}
	
	SetupNewImage( Gui1 , Gui1.Image.pBitmap )
	
	return
;<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|

UpdateWindow( Gui1 ){
	G := Gdip_GraphicsFromImage( Gui1.Display.pBitmap )
	Gdip_SetSmoothingMode( G , 2 )
	Gdip_SetInterpolationMode(G, 7)
	Brush := Gdip_BrushCreateSolid( "0xFF000000" )
	Gdip_FillEllipse( G , Brush , -500 , -500 , 1400 , 1400 )
	Gdip_DeleteBrush( Brush )

	Gdip_DrawImage( G , Gui1.Image.pBitmap , Gui1.Image.X , Gui1.Image.Y , Gui1.Image.W , Gui1.Image.H )
	
	DrawShape( Gui1 , G )
	
	hBitmap := Gdip_CreateHBITMAPFromBitmap( Gui1.Display.pBitmap )
	SetImage( Gui1.Controls.DisplayPicture.hwnd , hBitmap )
	DeleteObject( hBitmap )
	Gdip_DeleteGraphics( G )
}

DrawShape( Gui1 , G ){
	
	cc := Gui1.ShapeOutline
	Pen := Gdip_CreatePen( "0xFF3399FF" , ceil( 1 * Gui1.Scale ) ) 
	, Gdip_DrawRectangle( G , Pen , cc.X * Gui1.Scale , cc.Y * Gui1.Scale , cc.W * Gui1.Scale , cc.H * Gui1.Scale ) 
	, Gdip_DeletePen( Pen )
	
	;Angle vector
	cc := Gui1.ShapeOutline
	x := cc.X - 20
	y := cc.Y  + cc.H / 2 - 7
	w := 15
	h := 15
	Pen := Gdip_CreatePen( "0xFF3399FF" , ceil( 2 * Gui1.Scale ) ) 
	, Gdip_DrawEllipse( G , Pen , X * Gui1.Scale , Y * Gui1.Scale , W * Gui1.Scale , H * Gui1.Scale ) 
	, Gdip_DeletePen( Pen )
	
	;Color vector
	cc := Gui1.ShapeOutline
	x := Gui1.ShapeOutline.X - 20
	y := Gui1.ShapeOutline.Y + Gui1.ShapeOutline.H / 2 + 20
	w := 15
	h := 15
	Pen := Gdip_CreatePen( "0xFF3399FF" , ceil( 2 * Gui1.Scale ) ) 
	, Gdip_DrawEllipse( G , Pen , X * Gui1.Scale , Y * Gui1.Scale , W * Gui1.Scale , H * Gui1.Scale ) 
	, Gdip_DeletePen( Pen )
	
	Color := Gui1.ShapeColor
	if( Gui1.SelectedShape = "Triangle" ){
		
		Radius := Floor( Gui1.ShapeOutline.W / 2 - Gui1.ShapeOutline.Thickness )
		Gui1.MyShape := MyShape := PolygonShapes( New Vector( Gui1.ShapeOutline.X + Gui1.ShapeOutline.W / 2 , Gui1.ShapeOutline.Y + Gui1.ShapeOutline.H / 2 ) , Radius , Gui1.ShapeOutline.angle , Gui1.Sides := 3 , returnString := 1 , AddExtraWrapArm := 1  )
		
		DrawPolygon( G , MyShape , Color , 1 )
	}else if( Gui1.SelectedShape = "Pentagon" ){
		Gui1.MyShape := MyShape := PolygonShapes( New Vector( Gui1.ShapeOutline.X + Gui1.ShapeOutline.W / 2 , Gui1.ShapeOutline.Y + Gui1.ShapeOutline.H / 2 ) , Gui1.ShapeOutline.W / 2 , Gui1.ShapeOutline.angle , Gui1.Sides := 5 , returnString := 1 , AddExtraWrapArm := 1  )
		
		DrawPolygon( G , MyShape , Color , 1 )
	}else if( Gui1.SelectedShape = "Hexagon" ){
		Gui1.MyShape := MyShape := PolygonShapes( New Vector( Gui1.ShapeOutline.X + Gui1.ShapeOutline.W / 2 , Gui1.ShapeOutline.Y + Gui1.ShapeOutline.H / 2 ) , Gui1.ShapeOutline.W / 2 , Gui1.ShapeOutline.angle , Gui1.Sides := 6 , returnString := 1 , AddExtraWrapArm := 1  )
		
		DrawPolygon( G , MyShape , Color  , 1 )
	}else if( Gui1.SelectedShape = "Heptagon" ){
		Gui1.MyShape := MyShape := PolygonShapes( New Vector( Gui1.ShapeOutline.X + Gui1.ShapeOutline.W / 2 , Gui1.ShapeOutline.Y + Gui1.ShapeOutline.H / 2 ) , Gui1.ShapeOutline.W / 2 , Gui1.ShapeOutline.angle , Gui1.Sides := 7 , returnString := 1 , AddExtraWrapArm := 1  )
		
		DrawPolygon( G , MyShape , Color , 1 )
	}else if( Gui1.SelectedShape = "Octagon" ){
		Gui1.MyShape := MyShape := PolygonShapes( New Vector( Gui1.ShapeOutline.X + Gui1.ShapeOutline.W / 2 , Gui1.ShapeOutline.Y + Gui1.ShapeOutline.H / 2 ) , Gui1.ShapeOutline.W / 2 , Gui1.ShapeOutline.angle , Gui1.Sides := 8 , returnString := 1 , AddExtraWrapArm := 1  )
		
		DrawPolygon( G , MyShape , Color , 1 )
	}else if( Gui1.SelectedShape = "Hexadecagon" ){
		Gui1.MyShape := MyShape := PolygonShapes( New Vector( Gui1.ShapeOutline.X + Gui1.ShapeOutline.W / 2 , Gui1.ShapeOutline.Y + Gui1.ShapeOutline.H / 2 ) , Gui1.ShapeOutline.W / 2 , Gui1.ShapeOutline.angle , Gui1.Sides := 16 , returnString := 1 , AddExtraWrapArm := 1  )
		
		DrawPolygon( G , MyShape , Color , 1 )
	}else if( Gui1.SelectedShape = "Circle" ){
		cc := Gui1.ShapeOutline
		x := cc.X + ceil( Gui1.ShapeOutline.Thickness / 2 ) + 1
		y := cc.Y + ceil( Gui1.ShapeOutline.Thickness / 2 ) + 1
		w := cc.W - Gui1.ShapeOutline.Thickness - 2
		h := cc.H - Gui1.ShapeOutline.Thickness - 2
		
		Pen := Gdip_CreatePen( Color , ceil( 1 * Gui1.Scale ) ) 
		, Gdip_DrawEllipse( G , Pen , X * Gui1.Scale , Y * Gui1.Scale , W * Gui1.Scale , H * Gui1.Scale ) 
		, Gdip_DeletePen( Pen )
		
	}else if( Gui1.SelectedShape = "Rectangle" ){
		
		Radius := Floor( Gui1.ShapeOutline.W / 2 - Gui1.ShapeOutline.Thickness )
		Gui1.MyShape := MyShape := PolygonShapes( New Vector( Gui1.ShapeOutline.X + Gui1.ShapeOutline.W / 2 , Gui1.ShapeOutline.Y + Gui1.ShapeOutline.H / 2 ) , Radius , Gui1.ShapeOutline.angle , Gui1.Sides := 4 , returnString := 1 , AddExtraWrapArm := 1  )
		
		DrawPolygon( G , MyShape , Color , 1 )
	
	}else if( Gui1.SelectedShape = "Rounded Rectangle" ){
		cc := Gui1.ShapeOutline
		x := cc.X + ceil( Gui1.ShapeOutline.Thickness / 2 ) + 1
		y := cc.Y + ceil( Gui1.ShapeOutline.Thickness / 2 ) + 1
		w := cc.W - Gui1.ShapeOutline.Thickness - 2
		h := cc.H - Gui1.ShapeOutline.Thickness - 2
		
		
		Pen := Gdip_CreatePen( Color , ceil( Gui1.ShapeOutline.Thickness * Gui1.Scale ) ) 
		, Gdip_DrawRoundedRectangle( G , Pen , X * Gui1.Scale , Y * Gui1.Scale , W * Gui1.Scale , H * Gui1.Scale , 10 * Gui1.Scale ) 
		, Gdip_DeletePen( Pen )
		
		
	}
	
	
	CreateCroppedIcon( Gui1 )
	
}


CreateCroppedIcon( Gui1 ){
	
	pBitmap := Gdip_CreateBitmap( 64 , 64 )
	G := Gdip_GraphicsFromImage( pBitmap )
	Gdip_SetSmoothingMode( G , 2 )
	Gdip_SetInterpolationMode(G, 7)

	sx := ( Gui1.ShapeOutline.X - Gui1.Image.X ) / Gui1.Image.Scale
	sy := ( Gui1.ShapeOutline.Y - Gui1.Image.Y ) / Gui1.Image.Scale
	
	sw := Gui1.ShapeOutline.W / Gui1.Image.Scale
	
	sh := Gui1.ShapeOutline.H / Gui1.Image.Scale
	Gdip_DrawImage( G , Gui1.Image.pBitmap , 0 , 0 , 64 , 64 , sx , sy , sw , sh )
	
	Gdip_DisposeImage( Gui1.CroppedBitmap )

	Gui1.CroppedBitmap := CroppedBitmap := Gdip_CreateBitmap( 64 , 64 )
	G2 := Gdip_GraphicsFromImage( CroppedBitmap )
	Gdip_SetSmoothingMode( G2 , 2 )
	
	
	TextureBrush := Gdip_CreateTextureBrush( pBitmap )
	Gdip_DisposeImage( pBitmap )

	
	Color := Gui1.ShapeColor
	
	if( Gui1.SelectedShape = "Triangle" ){
		w := 64 
		Radius := Floor( w / 2 - Gui1.ShapeOutline.Thickness )
		MyShape := PolygonShapes( New Vector( W / 2 , w / 2 ) , Radius , Gui1.ShapeOutline.angle , Gui1.Sides := 3 , returnString := 1 , AddExtraWrapArm := 1  )
		MyShape2 := PolygonShapes( New Vector( W / 2 , w / 2 ) , Radius + Gui1.ShapeOutline.Thickness , Gui1.ShapeOutline.angle , Gui1.Sides := 3 , returnString := 1 , AddExtraWrapArm := 1  )
		Gdip_FillPolygon( G2 , TextureBrush , MyShape ) , Gdip_DeleteBrush( TextureBrush )
		if( Gui1.ShapeOutline.Thickness )
			DrawPolygon( G2 , MyShape , Color , Gui1.ShapeOutline.Thickness )
		
	}else if( Gui1.SelectedShape = "Pentagon" ){
		w := 64 
		Radius := Floor( w / 2 - Gui1.ShapeOutline.Thickness )
		MyShape := PolygonShapes( New Vector( W / 2 , w / 2 ) , Radius , Gui1.ShapeOutline.angle , Gui1.Sides := 5 , returnString := 1 , AddExtraWrapArm := 1  )
		MyShape2 := PolygonShapes( New Vector( W / 2 , w / 2 ) , Radius + Gui1.ShapeOutline.Thickness , Gui1.ShapeOutline.angle , Gui1.Sides := 3 , returnString := 1 , AddExtraWrapArm := 1  )
		Gdip_FillPolygon( G2 , TextureBrush , MyShape ) , Gdip_DeleteBrush( TextureBrush )
		if( Gui1.ShapeOutline.Thickness )
			DrawPolygon( G2 , MyShape , Color , Gui1.ShapeOutline.Thickness )
	}else if( Gui1.SelectedShape = "Hexagon" ){
		
		w := 64 
		Radius := Floor( w / 2 - Gui1.ShapeOutline.Thickness )
		MyShape := PolygonShapes( New Vector( W / 2 , w / 2 ) , Radius , Gui1.ShapeOutline.angle , Gui1.Sides := 6 , returnString := 1 , AddExtraWrapArm := 1  )
		MyShape2 := PolygonShapes( New Vector( W / 2 , w / 2 ) , Radius + Gui1.ShapeOutline.Thickness , Gui1.ShapeOutline.angle , Gui1.Sides := 3 , returnString := 1 , AddExtraWrapArm := 1  )
		Gdip_FillPolygon( G2 , TextureBrush , MyShape ) , Gdip_DeleteBrush( TextureBrush )
		if( Gui1.ShapeOutline.Thickness )
			DrawPolygon( G2 , MyShape , Color , Gui1.ShapeOutline.Thickness )
		
		
	}else if( Gui1.SelectedShape = "Heptagon" ){
		
		w := 64 
		Radius := Floor( w / 2 - Gui1.ShapeOutline.Thickness )
		MyShape := PolygonShapes( New Vector( W / 2 , w / 2 ) , Radius , Gui1.ShapeOutline.angle , Gui1.Sides := 7 , returnString := 1 , AddExtraWrapArm := 1  )
		MyShape2 := PolygonShapes( New Vector( W / 2 , w / 2 ) , Radius + Gui1.ShapeOutline.Thickness , Gui1.ShapeOutline.angle , Gui1.Sides := 3 , returnString := 1 , AddExtraWrapArm := 1  )
		Gdip_FillPolygon( G2 , TextureBrush , MyShape ) , Gdip_DeleteBrush( TextureBrush )
		if( Gui1.ShapeOutline.Thickness )
			DrawPolygon( G2 , MyShape , Color , Gui1.ShapeOutline.Thickness )
	
	}else if( Gui1.SelectedShape = "Octagon" ){
		
		w := 64 
		Radius := Floor( w / 2 - Gui1.ShapeOutline.Thickness )
		MyShape := PolygonShapes( New Vector( W / 2 , w / 2 ) , Radius , Gui1.ShapeOutline.angle , Gui1.Sides := 8 , returnString := 1 , AddExtraWrapArm := 1  )
		MyShape2 := PolygonShapes( New Vector( W / 2 , w / 2 ) , Radius + Gui1.ShapeOutline.Thickness , Gui1.ShapeOutline.angle , Gui1.Sides := 3 , returnString := 1 , AddExtraWrapArm := 1  )
		Gdip_FillPolygon( G2 , TextureBrush , MyShape ) , Gdip_DeleteBrush( TextureBrush )
		if( Gui1.ShapeOutline.Thickness )
			DrawPolygon( G2 , MyShape , Color , Gui1.ShapeOutline.Thickness )
		
	}else if( Gui1.SelectedShape = "Hexadecagon" ){
		
		w := 64 
		Radius := Floor( w / 2 - Gui1.ShapeOutline.Thickness )
		MyShape := PolygonShapes( New Vector( W / 2 , w / 2 ) , Radius , Gui1.ShapeOutline.angle , Gui1.Sides := 16 , returnString := 1 , AddExtraWrapArm := 1  )
		MyShape2 := PolygonShapes( New Vector( W / 2 , w / 2 ) , Radius + Gui1.ShapeOutline.Thickness , Gui1.ShapeOutline.angle , Gui1.Sides := 3 , returnString := 1 , AddExtraWrapArm := 1  )
		Gdip_FillPolygon( G2 , TextureBrush , MyShape ) , Gdip_DeleteBrush( TextureBrush )
		if( Gui1.ShapeOutline.Thickness )
			DrawPolygon( G2 , MyShape , Color , Gui1.ShapeOutline.Thickness )
	
	}else if( Gui1.SelectedShape = "Circle" ){
		cc := Gui1.ShapeOutline
		
		x := ceil( Gui1.ShapeOutline.Thickness / 2 ) + 1
		y := ceil( Gui1.ShapeOutline.Thickness / 2 ) + 1
		
		w := 64 - Gui1.ShapeOutline.Thickness - 2
		h := 64 - Gui1.ShapeOutline.Thickness - 2
		
		Gdip_FillEllipse( G2 , TextureBrush , X * Gui1.Scale , Y * Gui1.Scale , W * Gui1.Scale , H * Gui1.Scale ) 
		
		if( Gui1.ShapeOutline.Thickness )
			Pen := Gdip_CreatePen( Color , ceil( Gui1.ShapeOutline.Thickness * Gui1.Scale ) ) 
			, Gdip_DrawEllipse( G2 , Pen , X * Gui1.Scale , Y * Gui1.Scale , W * Gui1.Scale , H * Gui1.Scale ) 
			, Gdip_DeletePen( Pen )
		
	}else if( Gui1.SelectedShape = "Rectangle" ){
		
		w := 64 
		Radius := Floor( w / 2 - Gui1.ShapeOutline.Thickness )
		MyShape := PolygonShapes( New Vector( W / 2 , w / 2 ) , Radius , Gui1.ShapeOutline.angle , Gui1.Sides := 4 , returnString := 1 , AddExtraWrapArm := 1  )
		MyShape2 := PolygonShapes( New Vector( W / 2 , w / 2 ) , Radius + Gui1.ShapeOutline.Thickness , Gui1.ShapeOutline.angle , Gui1.Sides := 3 , returnString := 1 , AddExtraWrapArm := 1  )
		Gdip_FillPolygon( G2 , TextureBrush , MyShape ) , Gdip_DeleteBrush( TextureBrush )
		if( Gui1.ShapeOutline.Thickness )
			DrawPolygon( G2 , MyShape , Color , Gui1.ShapeOutline.Thickness )
	
	}else if( Gui1.SelectedShape = "Rounded Rectangle" ){
		cc := Gui1.ShapeOutline
		
		x := ceil( Gui1.ShapeOutline.Thickness / 2 ) + 1
		y := ceil( Gui1.ShapeOutline.Thickness / 2 ) + 1
		
		w := 64 - Gui1.ShapeOutline.Thickness - 2
		h := 64 - Gui1.ShapeOutline.Thickness - 2
		
		Gdip_FillRoundedRectangle( G2 , TextureBrush , X * Gui1.Scale , Y * Gui1.Scale , W * Gui1.Scale , H * Gui1.Scale , 10 * Gui1.Scale ) 
		
		if( Gui1.ShapeOutline.Thickness )
			Pen := Gdip_CreatePen( Color , ceil( Gui1.ShapeOutline.Thickness * Gui1.Scale ) ) 
			, Gdip_DrawRoundedRectangle( G2 , Pen , X * Gui1.Scale , Y * Gui1.Scale , W * Gui1.Scale , H * Gui1.Scale , 10 * Gui1.Scale ) 
			, Gdip_DeletePen( Pen )
		
	}
	

	Gui1.OutputIconWindow.ClearWindow()
	Brush := Gdip_BrushCreateHatch( "0x33000000" , "0x33ffffff" , 52 ) 
	, Gdip_FillRoundedRectangle( Gui1.OutputIconWindow.G , Brush , 2 * Gui1.Scale , 2 * Gui1.Scale , ( Gui1.OutputIconWindow.W - 4 ) * Gui1.Scale , ( Gui1.OutputIconWindow.H - 4 ) * Gui1.Scale , 15 * Gui1.Scale ) 
	, Gdip_DeleteBrush( Brush )
	Gui1.OutputIconWindow.DrawBitmap( CroppedBitmap , { X: 32 , Y: 32 , W: 64 , H: 64 } , dispose := 0 , AutoUpdate := 1 )
	
	
}


MoveSliderThumbControl( Gui1 , Thumb ){
	GuiControl, % Gui1.Hwnd ":Move" , % Thumb.Hwnd , % "x" Thumb.X " y" Thumb.Y " w" Thumb.W " h" Thumb.H
}

NewTheme(){
	local MyButtonDesign := {}
	MyButtonDesign.All := {}
	MyButtonDesign.Default := {}
	MyButtonDesign.Hover := {}
	MyButtonDesign.Pressed := {}
	;********************************
	;All
	MyButtonDesign.All.W := 300 , MyButtonDesign.All.H := 40 , MyButtonDesign.All.Text := "Capture A New Image From The Screen" , MyButtonDesign.All.FontSize := "14" , MyButtonDesign.All.H := "0xff000000" , MyButtonDesign.All.TextBottomColor2 := "0xff52565a" , MyButtonDesign.All.BackgroundColor := "0xFF32363a" , MyButtonDesign.All.ButtonAddGlossy := "0" , MyButtonDesign.All.GlossTopColor := "0x03"
	;********************************
	;Default
	MyButtonDesign.Default.W := 300 , MyButtonDesign.Default.H := 40 , MyButtonDesign.Default.Text := "Capture A New Image From The Screen" , MyButtonDesign.Default.Font := "Arial" , MyButtonDesign.Default.FontOptions := " Bold Center vCenter " , MyButtonDesign.Default.FontSize := "14" , MyButtonDesign.Default.H := "0xff000000" , MyButtonDesign.Default.TextBottomColor2 := "0xff52565a" , MyButtonDesign.Default.TextTopColor1 := "0xFFff0000" , MyButtonDesign.Default.TextTopColor2 := "0xFFff0000" , MyButtonDesign.Default.TextOffsetX := "0" , MyButtonDesign.Default.TextOffsetY := "0" , MyButtonDesign.Default.TextOffsetW := "0" , MyButtonDesign.Default.TextOffsetH := "0" , MyButtonDesign.Default.BackgroundColor := "0xFF32363a" , MyButtonDesign.Default.ButtonOuterBorderColor := "0xFF161B1F" , MyButtonDesign.Default.ButtonCenterBorderColor := "0xFF262B2F" , MyButtonDesign.Default.ButtonInnerBorderColor1 := "0xFF32363A" , MyButtonDesign.Default.ButtonInnerBorderColor2 := "0xFF24292D" , MyButtonDesign.Default.ButtonMainColor1 := "0xFF32363A" , MyButtonDesign.Default.ButtonMainColor2 := "0xFF22262a" , MyButtonDesign.Default.ButtonAddGlossy := "0" , MyButtonDesign.Default.GlossTopColor := "0x03FFFFFF" , MyButtonDesign.Default.GlossTopAccentColor := "05FFFFFF" , MyButtonDesign.Default.GlossBottomColor := "33000000"
	;********************************
	;Hover
	MyButtonDesign.Hover.W := 300 , MyButtonDesign.Hover.H := 40 , MyButtonDesign.Hover.Text := "Capture A New Image From The Screen" , MyButtonDesign.Hover.Font := "Arial" , MyButtonDesign.Hover.FontOptions := " Bold Center vCenter " , MyButtonDesign.Hover.FontSize := "14" , MyButtonDesign.Hover.H := "0xff000000" , MyButtonDesign.Hover.TextBottomColor2 := "0xff52565a" , MyButtonDesign.Hover.TextTopColor1 := "0xFFFFFFFF" , MyButtonDesign.Hover.TextTopColor2 := "0xFFff0000" , MyButtonDesign.Hover.TextOffsetX := "0" , MyButtonDesign.Hover.TextOffsetY := "0" , MyButtonDesign.Hover.TextOffsetW := "0" , MyButtonDesign.Hover.TextOffsetH := "0" , MyButtonDesign.Hover.BackgroundColor := "0xFF32363a" , MyButtonDesign.Hover.ButtonOuterBorderColor := "0x6622262a" , MyButtonDesign.Hover.ButtonCenterBorderColor := "0x33ff0000" , MyButtonDesign.Hover.ButtonInnerBorderColor1 := "0x00440000" , MyButtonDesign.Hover.ButtonInnerBorderColor2 := "0x00440000" , MyButtonDesign.Hover.ButtonMainColor1 := "0xFF880000" , MyButtonDesign.Hover.ButtonMainColor2 := "0xFFff0000" , MyButtonDesign.Hover.ButtonAddGlossy := "1" , MyButtonDesign.Hover.GlossTopColor := "0x03FFFFFF" , MyButtonDesign.Hover.GlossTopAccentColor := "05FFFFFF" , MyButtonDesign.Hover.GlossBottomColor := "33000000"
	;********************************
	;Pressed
	MyButtonDesign.Pressed.W := 300 , MyButtonDesign.Pressed.H := 40 , MyButtonDesign.Pressed.Text := "Capture A New Image From The Screen" , MyButtonDesign.Pressed.Font := "Arial" , MyButtonDesign.Pressed.FontOptions := " Bold Center vCenter " , MyButtonDesign.Pressed.FontSize := "14" , MyButtonDesign.Pressed.H := "0xff000000" , MyButtonDesign.Pressed.TextBottomColor2 := "0xff52565a" , MyButtonDesign.Pressed.TextTopColor1 := "0xFFff0000" , MyButtonDesign.Pressed.TextTopColor2 := "0xFFff0000" , MyButtonDesign.Pressed.TextOffsetX := "0" , MyButtonDesign.Pressed.TextOffsetY := "0" , MyButtonDesign.Pressed.TextOffsetW := "0" , MyButtonDesign.Pressed.TextOffsetH := "0" , MyButtonDesign.Pressed.BackgroundColor := "0xFF32363a" , MyButtonDesign.Pressed.ButtonOuterBorderColor := "0xFF62666a" , MyButtonDesign.Pressed.ButtonCenterBorderColor := "0xFF262B2F" , MyButtonDesign.Pressed.ButtonInnerBorderColor1 := "0xFF32363A" , MyButtonDesign.Pressed.ButtonInnerBorderColor2 := "0xFF151A20" , MyButtonDesign.Pressed.ButtonMainColor1 := "0xFF32363A" , MyButtonDesign.Pressed.ButtonMainColor2 := "0xFF22262a" , MyButtonDesign.Pressed.ButtonAddGlossy := "0" , MyButtonDesign.Pressed.GlossTopColor := "0x03FFFFFF" , MyButtonDesign.Pressed.GlossTopAccentColor := "05FFFFFF" , MyButtonDesign.Pressed.GlossBottomColor := "33000000"
	;********************************
	
	return MyButtonDesign
}

;***********************************************************************************************************************************************************************************************************
;***********************************************************************************************************************************************************************************************************
;***********************************************************************************************************************************************************************************************************
;***********************************************************************************************************************************************************************************************************
;Custom Radio Button Class
class GlowRadio_1	{
	;Written By: Hellbent
	;Date: Aprial 6th , 2022
	;Creates new instances of gui Radio controls and groups
	;New Instance Example: MyRadio := New GlowRadio_1( { Scalefactor: 1 , State: 1 , Y: 10 , Text: "Admin" , BackgroundColor: "0xFF22262A" , Y_Offset: 1 , X_Offset: 5 } )
	;Get Selected Item From Group Example: MyRadio..GetSelected()  ;(Returns the position of the selected radio in it's group )
	;Get The State Of A Radio Example: MyRadio.State    ;Or: MyRadio.GetState() 
	static init := GlowRadio_1._SetDefaults()
	_SetDefaults(){
		This.W := 11 
		This.H := 11
		This.Groups := {}
		This.Index := 0
		This.Settings := {}
		This.Settings.X := 10
		This.Settings.Y := 10
		This.Settings.W := 120
		This.Settings.H := 20
		This.Settings.Text := ""
		This.Settings.ActiveColor := "0xFF67D5D6"
		This.Settings.ButtonRestColor := "0xFF004444"
		This.Settings.RestColor := "0xFF009999"
		This.Settings.State := 0
		This.Settings.Font := "Arial"
		This.Settings.FontSize := 14
		This.Settings.FontOptions := " vCenter Left "
		This.Settings.BackgroundColor := "0xFF22262a"
		This.Settings.GroupName := "Group1"
		This.Settings.Owner := "1"
		This.Settings.GroupIndex := 1
		This.Settings.GroupSelected := 0
		This.Settings.ScaleFactor := 1
		This.Settings.Y_Offset := 5
		This.Settings.X_Offset := 1
	}
	__New( obj := "" ){
		
		This._CreateRadioObject( obj )
		This._CreateControl()
		if( This.State ){
			Loop, % GlowRadio_1.Groups[ This.GroupName ].Members.Length()	{
				GlowRadio_1.Groups[ This.GroupName ].Members[ A_Index ].GroupSelected := GlowRadio_1.Groups[ This.GroupName ].Selected
				GlowRadio_1.Groups[ This.GroupName ].Members[ A_Index ].State := 0
			}
			This.State := 1
		}
		Loop, % GlowRadio_1.Groups[ This.GroupName ].Members.Length()	
			GlowRadio_1.Groups[ This.GroupName ].Members[ A_Index ].Draw()
	}
	_CreateRadioObject( obj := "" ){
		local k , v 
		for k , v in GlowRadio_1.Settings
			This[ k ] := v 
		if( IsObject( obj ) ){
			for k , v in obj 
				if( GlowRadio_1.Settings.HasKey( k ) )
					This[ k ] := v 
			if( obj.HasKey( "GroupName" ) )
				GlowRadio_1.Settings.GroupName := obj.GroupName
		}
	}
	_CreateControl(){
		local hwnd , bd
		Gui, % This.Owner ":Add", Picture, % "x" This.X * This.ScaleFactor " y" This.Y * This.ScaleFactor " w" This.W * This.ScaleFactor " h" This.H * This.ScaleFactor " hwndhwnd 0xE"
		This.Hwnd := hwnd
		++GlowRadio_1.Index
		If( !isObject( GlowRadio_1.Groups[ This.GroupName ] ) ){
			GlowRadio_1.Groups[ This.GroupName ] := {}
			This.Index := GlowRadio_1.Groups[ This.GroupName ].Index := 1
			GlowRadio_1.Groups[ This.GroupName ].Members := []
			( This.State ) ? ( This.GroupSelected := GlowRadio_1.Groups[ This.GroupName ].Selected := This.Index ) : ( This.GroupSelected := GlowRadio_1.Groups[ This.GroupName ].Selected := 0 )
		}else{
			This.Index := ++GlowRadio_1.Groups[ This.GroupName ].Index
			( This.State ) ? ( This.GroupSelected := GlowRadio_1.Groups[ This.GroupName ].Selected := This.Index ) : ( This.GroupSelected := GlowRadio_1.Groups[ This.GroupName ].Selected := GlowRadio_1.Groups[ This.GroupName ].Selected )
		}
		GlowRadio_1.Groups[ This.GroupName ].Members[ This.Index ] := This
		bd := This._SwitchStates.Bind( This )
		GuiControl, % This.Owner ":+G" , % Hwnd , % bd
		GlowRadio_1.Groups[ This.GroupName ].Selected := This.GroupSelected
		GuiControl, % This.Owner ":Focus", % This.Hwnd
		GlowRadio_1.Groups[ This.GroupName ].LastSelected := This.GroupSelected
	}
	_SwitchStates(){
		local cc := GlowRadio_1.Groups[ This.GroupName ] , ls := cc.Selected
		if( This.Index = GlowRadio_1.Groups[ This.GroupName ].LastSelected )
			return
		cc.Selected := This.Index
		Loop, % cc.Members.Length()	{
			cc.Members[ A_Index ].GroupSelected := cc.Selected
			cc.Members[ A_Index ].State := 0
		}
		This.State := 1
		cc.Members[ GlowRadio_1.Groups[ This.GroupName ].LastSelected ].Draw()
		This.Draw()
		GlowRadio_1.Groups[ This.GroupName ].LastSelected := This.Index
		GuiControl, % This.Owner ":Focus", % This.Hwnd
		
		if( This.Label ){
			Try{
				goSub, % This.Label
			}
		}
			
		
	}
	GetState(){
		return 	This.State
	}
	GetSelected(){
		return This.GroupSelected
	}
	Draw(){
		;Bitmap Created Using: HB Bitmap Maker
		local ly := 0
		ScaleFactor := This.ScaleFactor
		pBitmap := Gdip_CreateBitmap( This.W * ScaleFactor , This.H * ScaleFactor ) , G := Gdip_GraphicsFromImage( pBitmap ) , Gdip_SetSmoothingMode( G , 2 )
		Brush := Gdip_BrushCreateSolid( This.BackgroundColor ) , Gdip_FillRectangle( G , Brush , -10 * ScaleFactor , -10 * ScaleFactor , 140 * ScaleFactor , 210 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		;Outer ring
		Pen := Gdip_CreatePen( ( This.State ) ? ( This.ActiveColor ) : ( This.ButtonRestColor ) , 1 ) , Gdip_DrawRectangle( G , Pen , 2 * This.ScaleFactor , ( ( This.H / 2 ) - ( GlowRadio_1.H / 2 ) + 1 ) * This.ScaleFactor , GlowRadio_1.W * This.ScaleFactor , GlowRadio_1.H * This.ScaleFactor ) , Gdip_DeletePen( Pen )
		;inner square
		Brush := Gdip_BrushCreateSolid( ( This.ButtonRestColor ) ) , Gdip_FillRectangle( G , Brush , 4 * ScaleFactor , ( ( This.H / 2 ) - ( GlowRadio_1.H / 2 ) + 3 ) * This.ScaleFactor , 7 * ScaleFactor , 7 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( ( This.State ) ? ( This.ActiveColor ) : ( This.ButtonRestColor ) ) , Gdip_FillRectangle( G , Brush , 5 * ScaleFactor , ( ( This.H / 2 ) - ( GlowRadio_1.H / 2 ) + 4 ) * This.ScaleFactor , 5 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		;bottom layer of text
		if( This.State )
			Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_TextToGraphics( G , This.Text , "s" This.FontSize * ScaleFactor " " This.FontOptions " c" Brush " x" floor( ( GlowRadio_1.W + 5 + 1 + This.X_Offset ) * ScaleFactor ) " y" ly := Floor( ( ( 2 + This.Y_Offset ) * ScaleFactor ) ) , This.Font , Floor( This.W * ScaleFactor ) , Floor( This.H * ScaleFactor ) ) , Gdip_DeleteBrush( Brush )
		else
			Brush := Gdip_BrushCreateSolid(  "0x000000" ) , Gdip_TextToGraphics( G , This.Text , "s" This.FontSize * ScaleFactor " " This.FontOptions " c" Brush " x" Floor( ( GlowRadio_1.W + 5 + 2 + This.X_Offset ) * ScaleFactor ) " y" ly := Floor( ( ( 2 + This.Y_Offset ) * ScaleFactor ) ) , This.Font , Floor( This.W * ScaleFactor ) , floor( This.H * ScaleFactor ) ) , Gdip_DeleteBrush( Brush )
		;top layer of text
		Brush := Gdip_BrushCreateSolid( ( This.State ) ? ( This.ActiveColor ) : ( This.RestColor ) ) , Gdip_TextToGraphics( G , This.Text , "s" This.FontSize * ScaleFactor " " This.FontOptions " c" Brush " x" floor( ( GlowRadio_1.W + 5 + This.X_Offset ) * ScaleFactor ) " y" Floor( ( ly - 1 + This.Y_Offset ) ) , This.Font , Floor( ( This.W - GlowRadio_1.W ) * ScaleFactor ) , Floor( This.H * ScaleFactor ) ) , Gdip_DeleteBrush( Brush )
		Gdip_DeleteGraphics( G )
		hBitmap := Gdip_CreateHBITMAPFromBitmap( pBitmap )
		SetImage( This.Hwnd , hBitmap )
		Gdip_DisposeImage( pBitmap )
		DeleteObject( hBitmap )
	}
}

;*******************&&&&&&&&&&&&&&&&&&&&&&&&************************************&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
;*******************&&&&&&&&&&&&&&&&&&&&&&&&************************************&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
;*******************&&&&&&&&&&&&&&&&&&&&&&&&************************************&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
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()
	}
}
;|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|
;|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|
;|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|
;Function: PolygonShapes 
;Written By: Hellbent
;Date: Jan 16th, 2023
;Last Edit: Jan 18th, 2023 
;Changes:
;Can now set it so that the return string has an extra wrap to close the shape. ( used for "DRAWLINES" or "DRAWPOLYGON" )
;Requires: Vectors class ( #Include <HB Vectors v2> )
;Returns a string or an array of points for a simple closed polygon shape. 
;HomeVector: { X: x position , Y: y position } give an obj with x and y keys. 
;			This is the center of your shape.
;Radius: The radius to use for the shape. How big the shape will be
;StartAngle: The point for the first side of the shape. The rotaion of the shape.
;Sides: The number of sides the shape should have. 3 or more sides
;returnString: Set the fuction to return a "string" of points or an [ array ] of points 
PolygonShapes( HomeVector , Radius := 100 , StartAngle := 0 , Sides := 4 , returnString := 1 , AddExtraWrapArm := 0 ){
	local StartVector , points , SpacingAngle , OutputString
	if( sides < 3 ){
		MsgBox, 262192, Error , A shape requires 3 or more sides.`nWhat you're thinking of is a line or a point.
		return
	}
	StartVector := New Vector( HomeVector )
	StartVector.SetMag( Radius )
	StartVector.SetAngle( StartAngle )
	SpacingAngle := 360 / Sides
	Points := []
	Points[ 1 ] := New Vector( StartVector )
	Points[ 1 ].Add( HomeVector )
	if( returnString )
		OutputString := Points[ 1 ].X "," Points[ 1 ].Y "|"
	Loop, % Sides - 1	{
		StartVector := StartVector.RotateAngle( SpacingAngle , 1 )
		Points[ A_Index + 1 ] := New Vector( StartVector )
		Points[ A_Index + 1 ].Add( HomeVector )
		if( returnString )
			OutputString .= Points[ A_Index + 1 ].X "," Points[ A_Index + 1 ].Y "|"
	}
	if( returnString ){
		OutputString .= Points[ 1 ].X "," Points[ 1 ].Y "|"
		if( AddExtraWrapArm ) ;Adds an extra overlap so that when you use "DrawLines" the shape fully closes regardless of the thickness of the lines.
			OutputString .= Points[ 2 ].X "," Points[ 2 ].Y "|"
		return OutputString
	}
	return Points
}
;|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|
;|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|
;|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|<( )>|
FillPolygon( G , Points := "50 , 50 | 100 , 100 | 150 , 50 | 50 , 50 " , Color := "0xFFFF0000" ){
	Brush := Gdip_BrushCreateSolid( Color ) , Gdip_FillPolygon( G , Brush , Points ) , Gdip_DeleteBrush( Brush )
}
DrawPolygon( G , Points := "50 , 50 | 100 , 100 | 150 , 50 | 50 , 50 " , Color := "0xFF000000" , Thickness := 3 ){
	Pen := Gdip_CreatePen( Color , Thickness ) , Gdip_DrawLines( G , Pen , Points ) , Gdip_DeletePen( Pen )
}
;| ((((()))))***^|^***((((())))) | ((((()))))***^|^***((((())))) | ((((()))))***^|^***((((())))) | ((((()))))***^|^***((((())))) | ((((()))))***^|^***((((())))) | ((((()))))***^|^***((((())))) | ((((()))))***^|^***((((())))) |;
;| ((((()))))***^|^***((((())))) | ((((()))))***^|^***((((())))) | ((((()))))***^|^***((((())))) | ((((()))))***^|^***((((())))) | ((((()))))***^|^***((((())))) | ((((()))))***^|^***((((())))) | ((((()))))***^|^***((((())))) |;
;| ((((()))))***^|^***((((())))) | ((((()))))***^|^***((((())))) | ((((()))))***^|^***((((())))) | ((((()))))***^|^***((((())))) | ((((()))))***^|^***((((())))) | ((((()))))***^|^***((((())))) | ((((()))))***^|^***((((())))) |;


;~ class Commands	extends DockItDraw {
class Commands {
	GetWinHwnd( option := "A" ){
		return WinActive( option )
	}
	GetWinTitle( hwnd ){
		local out 
		WinGetTitle, out , % "ahk_id " hwnd
		return out
	}
	GetWinPos( hwnd ){
		local x , y , w , h 
		WinGetPos, x , y , w , h , % "ahk_id " hwnd 
		return { X: x , Y: y , W: w , H: h }
	}
	GetMousePos( mode := "Screen" ){
		local x , y 
		CoordMode, Mouse, % mode
		MouseGetPos, x , y 
		return { X: x , Y: y }
	}
}

class DrawTarget extends Commands	{
	__New(){
		local pos := This.GetMousePos()
		This.State := 0
		This.Color := "0xFFFF0000"
		This.X1 := pos.X
		This.X2 := 0
		This.Y1 := pos.Y
		This.Y2 := 0
		This.X := pos.X
		This.Y := pos.Y
		This.W := 0
		This.H := 0
		This.Gui1 := New PopUpWindow( { AutoShow: 1 , X: pos.X - 500 , Y: pos.Y - 500 , W: 1001 , H: 1001 , Options: " +AlwaysOnTop -DPIScale +ToolWindow +E0x20" } ) 
		This._SetStartingPos()
		This._SetEndingPos()
		return { X: This.X , Y: This.Y , W: This.W , H: This.H }
	}
	_SetStartingPos(){
		while( !GetKeyState( "ctrl" ) ){
			ToolTip, Press "ctrl" to set the starting position. `n`nTop left corner.
			pos := This.GetMousePos()
			This.Gui1.UpdateSettings( { X: pos.X - 501 , Y: pos.Y - 501 } )
			This.Draw()
			
			sleep, 30
		}
		This.X1 := pos.X 
		This.Y1 := pos.Y
		This.State := 1
		While( GetKeyState( "ctrl" ) )
			sleep, 30
	}
	_SetEndingPos(){
		while( !GetKeyState( "ctrl" ) ){
			ToolTip, Press "ctrl" to set the ending position. `n`nBottom Right corner.
			pos := This.GetMousePos()
			This.X2 := pos.X 
			This.Y2 := pos.Y
			
			( This.X1 <= This.X2 ) ? ( This.X := This.X1 , This.W := This.X2 - This.X1 ) : ( This.X := This.X2 , This.W := This.X1 - This.X2 )
			( This.Y1 <= This.Y2 ) ? ( This.Y := This.Y1 , This.H := This.Y2 - This.Y1 ) : ( This.Y := This.Y2 , This.H := This.Y1 - This.Y2 )
			This.Gui1.UpdateSettings( { X: This.X - 1 , Y: This.Y - 1 , W: This.W + 2 , H: This.H + 2 } , 1 )
			This.Draw()
			
			sleep, 30
		}
		ToolTip,
		While( GetKeyState( "ctrl" ) )
			sleep, 30
		This.Gui1.DeleteWindow()
	}
	Draw(){
		This.Gui1.ClearWindow()
		if( !This.State ){
			Pen := Gdip_CreatePen( This.Color , 1 ) , Gdip_DrawLine( This.Gui1.G , Pen , 501 , 0 , 501 , 1001 ) , Gdip_DeletePen( Pen )
			Pen := Gdip_CreatePen( This.Color , 1 ) , Gdip_DrawLine( This.Gui1.G , Pen , 0 , 501 , 1001 , 501 ) , Gdip_DeletePen( Pen )
		}else if( This.State = 1 ){
			Pen := Gdip_CreatePen( This.Color , 1 ) , Gdip_DrawRectangle( This.Gui1.G , Pen , 1 , 1  , This.W , This.H ) , Gdip_DeletePen( Pen )
		}
		This.Gui1.UpdateWindow()
	}
}

B64ToPBitmap( Input ){
	local ptr , uptr , pBitmap , pStream , hData , pData , Dec , DecLen , B64
	VarSetCapacity( B64 , strlen( Input ) << !!A_IsUnicode )
	B64 := Input
	If !DllCall("Crypt32.dll\CryptStringToBinary" ( ( A_IsUnicode ) ? ( "W" ) : ( "A" ) ), Ptr := A_PtrSize ? "Ptr" : "UInt" , &B64, "UInt", 0, "UInt", 0x01, Ptr, 0, "UIntP", DecLen, Ptr, 0, Ptr, 0)
		Return False
	VarSetCapacity( Dec , DecLen , 0 )
	If !DllCall("Crypt32.dll\CryptStringToBinary" (A_IsUnicode ? "W" : "A"), Ptr, &B64, "UInt", 0, "UInt", 0x01, Ptr, &Dec, "UIntP", DecLen, Ptr, 0, Ptr, 0)
		Return False
	DllCall("Kernel32.dll\RtlMoveMemory", Ptr, pData := DllCall("Kernel32.dll\GlobalLock", Ptr, hData := DllCall( "Kernel32.dll\GlobalAlloc", "UInt", 2,  UPtr := A_PtrSize ? "UPtr" : "UInt" , DecLen, UPtr), UPtr) , Ptr, &Dec, UPtr, DecLen)
	DllCall("Kernel32.dll\GlobalUnlock", Ptr, hData)
	DllCall("Ole32.dll\CreateStreamOnHGlobal", Ptr, hData, "Int", True, Ptr "P", pStream)
	DllCall("Gdiplus.dll\GdipCreateBitmapFromStream",  Ptr, pStream, Ptr "P", pBitmap)
	return pBitmap
}

;<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|
;<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|
;<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|
;<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|
;<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|

;####################################################################################################################################################################################
;####################################################################################################################################################################################
;#########################################################          #Include, <HB Icon Buttons ( LW Ani Buttons )>          #########################################################
;####################################################################################################################################################################################
;####################################################################################################################################################################################
class IconButtons	{
	;Written By: Hellbent
	;Date: Apr 7th
	;Create Layered Window Buttons From a pBitmap. 
	;Accepts a parent window but can also rest in a window sans parent.
	static init := IconButtons._SetDefaults()
	;#############################################
	;>>>>>     SET THE CLASS DEFAULTS.
	;#############################################
	_SetDefaults(){
		;*****************************
		;>>>>>     Static class Data
		This.Index := 0
		This.Handles := []
		This.CurrentIcon := ""
		This.LastIcon := ""
		This.HoverTimer := This._Hover.Bind( This )
		This.FT := 1
		This.Beep := 0
		;*****************************
		;>>>>>     Window Data
		This.Window := {}
		This.Window.X := 10
		This.Window.Y := 10
		This.Window.W := 10
		This.Window.H := 10
		This.Window.Parent := ""
		This.Window.Hwnd := ""
		This.Window.HDC := ""
		This.Window.OBM := ""
		This.Window.Graphics := ""
		This.Window.HBM := ""
		This.Window.Smoothing := 2
		This.Window.Options := " +AlwaysOnTop -DPIScale +ToolWindow "
		;*****************************
		;>>>>>     Bitmap Data
		This.Bitmap := {}
		This.Bitmap.pBitmap := ""
		This.Bitmap.Alpha := 255
		This.Bitmap.X := 0
		This.Bitmap.Y := 0
		This.Bitmap.W := 10
		This.Bitmap.H := 10
		This.Bitmap.Animate := ""
		This.Bitmap.PulseLength := 5
		This.Bitmap.PulseRate := 1
		;*****************************
		;>>>>>     Control Data
		This.Control := {}
		This.Control.X := 0
		This.Control.Y := 0
		This.Control.W := 10
		This.Control.H := 10
		This.Control.Hwnd := ""
		This.Control.CanHover := 1
	}
	;#############################################
	;>>>>>     CREATE A NEW ICON BUTTON.  				Prototype: >>>>>   Obj := { X: 494 , Y: 242 , W: 130 , H: 26 , Parent: ParentHwnd , pBitmap: pBitmap , Bind: "" , BoundObject: "" }
	;#############################################
	__New( obj := "" ){ 
		This._GetDefaults()
		This._UpdateDefaults( obj )
		This._CreateWindow()
		This._CreateWindowGraphics()
		This._CreateControl()
		This.Draw()
		IconButtons.Handles[ This.Control.Hwnd ] := This
		if( IconButtons.Beep )
			SoundBeep, 500
		if( This.Control.CanHover && IconButtons.FT && !IconButtons.FT := !IconButtons.FT )
			IconButtons._SetHoverTimer( 60 )
	}
	;#############################################
	;>>>>>     LOAD NEW BUTTON WITH ITS DEFAULTS.
	;#############################################
	_GetDefaults(){
		local k , v 
		This.Window := {}
		for k , v in IconButtons.Window
			This.Window[ k ] := v 
		This.Bitmap := {}
		for k , v in IconButtons.Bitmap
			This.Bitmap[ k ] := v 
		This.Control := {}
		for k , v in IconButtons.Control
			This.Control[ k ] := v 
	}
	;#############################################
	;>>>>>     UPDATE THE NEW BUTTON WITH THE USER SUPPLIED DATA.
	;#############################################
	_UpdateDefaults( obj := "" ){
		local k , v 
		if( !IsObject( obj ) )
			return 2
		for k , v in obj 	{
			if( This[ "Window" ].HasKey( k ) )
				This[ "Window" ][ k ] := obj[ k ] 
		}
		for k , v in [ "W" , "H" , "pBitmap" , "Alpha" , "Animate" , "PulseLength" , "PulseRate" ]	{
			if( obj.HasKey( v ) )
				This[ "Bitmap" ][ v ] := obj[ v ]
		}
		for k , v in [ "W" , "H" , "CanHover" ]	{
			if( obj.HasKey( v ) )
				This[ "Control" ][ v ] := obj[ v ]
		}
	}
	;#############################################
	;>>>>>     CREATE A NEW GUI ( LAYERED WINDOW ). USED AS THE CANVAS FOR THE NEW BUTTON.
	;#############################################
	_CreateWindow(){
		local hwnd
		if( This.Window.Parent ){
			Gui , New, % " +LastFound +E0x80000 hwndhwnd -Caption  " This.Window.Options " +Parent" This.Window.Parent
		}else
			Gui , New, % " +LastFound +E0x80000 hwndhwnd -Caption  " This.Window.Options
		This.Window.Hwnd := hwnd
		This.ShowWindow()
	}
	;#############################################
	;>>>>>     CREATE A CONTROL TRIGGER. USED TO DETECT IF THE MOUSE IS OVER OR IS PRESSING THE BUTTON
	;#############################################
	_CreateControl(){
		local hwnd , bd
		Gui, % This.Window.Hwnd ":Add", Text, % "x" This.Control.X " y" This.Control.Y " w" This.Control.W " h" This.Control.H " hwndhwnd"
		This.Control.Hwnd := hwnd
		
	}
	;#############################################
	;>>>>>     DESTROY THE GRAPHICS OBJECTS. USED WHEN A BUTTON IS DESTROYED OR WHEN IT IS RESIZED
	;#############################################
	_DestroyWindowsGraphics(){
		Gdip_DeleteGraphics( This.Window.Graphics )
		SelectObject( This.Window.HDC , This.Window.OBM )
		DeleteObject( This.Window.hbm )
		DeleteDC( This.Window.hdc )
	}
	;#############################################
	;>>>>>     CREATE THE GRAPHICS OBJECTS. DONE WHEN A NEW BUTTON IS CREATED AND WHEN IT IS RESIZED
	;#############################################
	_CreateWindowGraphics(){
		This.Window.hbm := CreateDIBSection( This.Window.W , This.Window.H )
		This.Window.hdc := CreateCompatibleDC()
		This.Window.obm := SelectObject( This.Window.hdc , This.Window.hbm )
		This.Window.Graphics := Gdip_GraphicsFromHDC( This.Window.hdc )
		Gdip_SetSmoothingMode( This.Window.Graphics , This.Window.Smoothing )
	}
	;#############################################
	;>>>>>     SET A TIMER TO DETECT MOUSE HOVER. 
	;#############################################
	_SetHoverTimer( State := "Off" ){
		local bd := This.HoverTimer
		SetTimer, % bd , % State
	}
	;#############################################
	;>>>>>     DETECT IF THE CURSOR IS OVER THE BUTTON
	;#############################################
	_Hover(){
		local ctrl , cc 
		static bu := { X: "" , Y: "" , W: "" , H: "" } , index := 0
		MouseGetPos,,,, ctrl, 2 
		if( !This.LastIcon && !This.Handles[ ctrl ].Control.CanHover )
			return
		if( This.Handles[ ctrl ].Bitmap.w && This.LastIcon != ctrl && !This.LastIcon ){
			This.LastIcon := ctrl
			cc := This.Handles[ ctrl ]
			bu.X := cc.Window.X
			bu.Y := cc.Window.Y
			bu.W := cc.Window.W
			bu.H := cc.Window.H
			Index := 0
		}else if( This.LastIcon && This.LastIcon = ctrl){
			if( This.Handles[ This.LastIcon ].Bitmap.Animate = "Pulse" ){
				cc := This.Handles[ This.LastIcon ]
				if( ++Index <= This.Handles[ This.LastIcon ].Bitmap.PulseLength ){
					cc.Set( { X: cc.Window.X -= This.Handles[ This.LastIcon ].Bitmap.PulseRate , Y: cc.Window.Y -= This.Handles[ This.LastIcon ].Bitmap.PulseRate , W: cc.Window.W += 2 * This.Handles[ This.LastIcon ].Bitmap.PulseRate , H: cc.Window.H += 2 * This.Handles[ This.LastIcon ].Bitmap.PulseRate } , 1 )
					cc.Draw()
				}else if( Index <= ( 2 * This.Handles[ This.LastIcon ].Bitmap.PulseLength ) ){
					cc.Set( { X: cc.Window.X += This.Handles[ This.LastIcon ].Bitmap.PulseRate , Y: cc.Window.Y += This.Handles[ This.LastIcon ].Bitmap.PulseRate , W: cc.Window.W -= 2 * This.Handles[ This.LastIcon ].Bitmap.PulseRate , H: cc.Window.H -= 2 * This.Handles[ This.LastIcon ].Bitmap.PulseRate } , 1 )
					cc.Draw()
				}else
					Index := 0
			}else if( This.Handles[ This.LastIcon ].Bitmap.Animate = "Spin" ){
				cc := This.Handles[ This.LastIcon ]
				if( ++Index < 6 ){
					cc.Set( { X: cc.Window.X -= 1 , Y: cc.Window.Y -= 1 , W: cc.Window.W += 2 , H: cc.Window.H += 2 } , 1 )
					cc.Draw()
				}else if( Index < 11 ){
					cc.Set( { X: cc.Window.X += 1 , Y: cc.Window.Y += 1 , W: cc.Window.W -= 2 , H: cc.Window.H -= 2 } , 1 )
					cc.Draw()
				}else
					Index := 0
			}
		}else if( This.LastIcon && This.LastIcon != ctrl ){
			cc := This.Handles[ This.LastIcon ]
			cc.Set( { X: bu.X , Y: bu.Y , W: bu.W , H: bu.H } , 1 )
			cc.Draw()
			This.LastIcon := ""
		}
	}
	;#############################################
	;>>>>>     IN CLASS METHOD TO SHOW THE BUTTON
	;#############################################
	ShowWindow(){
		Gui , % This.Window.Hwnd ":Show", NA
	}
	;#############################################
	;>>>>>     IN CLASS METHOD TO HIDE THE BUTTON
	;#############################################
	HideWindow(){
		Gui , % This.Hwnd ":Hide",
	}
	;#############################################
	;>>>>>     SET THE BUTTON WITH NEW DATA AFTER IT HAS BEEN CREATED.
	;#############################################
	Set( obj := "" , updateGraphics := 0 ){
		local k , v 
		if( !IsObject( obj ) )
			return 2
		for k , v in obj 	{
			if( This[ "Window" ].HasKey( k ) )
				This[ "Window" ][ k ] := obj[ k ] 
		}
		for k , v in [ "W" , "H" , "pBitmap" , "Alpha" , "Animate" , "PulseLength" , "PulseRate" ]	{
			if( obj.HasKey( v ) )
				This[ "Bitmap" ][ v ] := obj[ v ]
		}
		for k , v in [ "W" , "H" , "CanHover" ]	{
			if( obj.HasKey( v ) )
				This[ "Control" ][ v ] := obj[ v ]
		}
		if( updateGraphics ){
			This._DestroyWindowsGraphics()
			This._CreateWindowGraphics()
			This._MoveControl()
		}
	}
	_MoveControl(){
		GuiControl, % This.Window.Hwnd ":Move", % This.Control.Hwnd , % "w" This.Control.W " h" This.Control.H
	}
	;#############################################
	;>>>>>     UPDATE THE BUTTON WITH ITS NEW GRAPHHICS. ( UPDATE VISUAL CHANGES MADE )
	;#############################################
	UpdateWindow(){
		UpdateLayeredWindow( This.Window.hwnd , This.Window.hdc , This.Window.X , This.Window.Y , This.Window.W , This.Window.H , This.Bitmap.Alpha )
	}
	;#############################################
	;>>>>>     CLEAR THE GRAPHICS. ( REQUIRES A UPDATE TO SHOW )
	;#############################################
	ClearWindow( AutoUpdate := 0 ){
		Gdip_GraphicsClear( This.Window.Graphics )
		if( Autoupdate )
			This.UpdateWindow()
	}
	;#############################################
	;>>>>>     DRAW THE BUTTON
	;#############################################
	Draw(){
		This.ClearWindow()	
		Gdip_DrawImage( This.Window.Graphics , This.Bitmap.pBitmap , This.Bitmap.X , This.Bitmap.Y , This.Bitmap.W , This.Bitmap.H )
		This.UpdateWindow()
	}
}
;####################################################################################################################################################################################
;####################################################################################################################################################################################
;###################################################          END OF CLASS             YOU LOOK FAT IN THOSE GENES...          ######################################################
;####################################################################################################################################################################################
;####################################################################################################################################################################################
;******************************************************************************************************************
;******************************************************************************************************************
Gdip_EncodeBitmapTo64string(pBitmap, ext, Quality=75) { ;Excised from https://www.autohotkey.com/boards/viewtopic.php?t=36047
	if Ext not in BMP,DIB,RLE,JPG,JPEG,JPE,JFIF,GIF,TIF,TIFF,PNG
        return -1
	Extension := "." Ext
	DllCall("gdiplus\GdipGetImageEncodersSize", "uint*", nCount, "uint*", nSize)
	VarSetCapacity(ci, nSize)
	DllCall("gdiplus\GdipGetImageEncoders", "uint", nCount, "uint", nSize, Ptr, &ci)
	if !(nCount && nSize)
		return -2
	Loop, % nCount {
		sString := StrGet(NumGet(ci, (idx := (48+7*A_PtrSize)*(A_Index-1))+32+3*A_PtrSize), "UTF-16")
		if !InStr(sString, "*" Extension)
			continue
		pCodec := &ci+idx
		break
	}
	if !pCodec
		return -3
	if (Quality != 75){
		Quality := (Quality < 0) ? 0 : (Quality > 100) ? 100 : Quality
		if Extension in .JPG,.JPEG,.JPE,.JFIF
		{
			DllCall("gdiplus\GdipGetEncoderParameterListSize", Ptr, pBitmap, Ptr, pCodec, "uint*", nSize)
			VarSetCapacity(EncoderParameters, nSize, 0)
			DllCall("gdiplus\GdipGetEncoderParameterList", Ptr, pBitmap, Ptr, pCodec, "uint", nSize, Ptr, &EncoderParameters)
			Loop, % NumGet(EncoderParameters, "UInt") {
				elem := (24+(A_PtrSize ? A_PtrSize : 4))*(A_Index-1) + 4 + (pad := A_PtrSize = 8 ? 4 : 0)
				if (NumGet(EncoderParameters, elem+16, "UInt") = 1) && (NumGet(EncoderParameters, elem+20, "UInt") = 6){
					p := elem+&EncoderParameters-pad-4
					NumPut(Quality, NumGet(NumPut(4, NumPut(1, p+0)+20, "UInt")), "UInt")
					break
				}
			}
		}
	}
	DllCall("ole32\CreateStreamOnHGlobal", "ptr",0, "int",true, "ptr*",pStream)
	DllCall("gdiplus\GdipSaveImageToStream", "ptr",pBitmap, "ptr",pStream, "ptr",pCodec, "uint",p ? p : 0)
    DllCall("ole32\GetHGlobalFromStream", "ptr",pStream, "uint*",hData)
	pData := DllCall("GlobalLock", "ptr",hData, "uptr")
	nSize := DllCall("GlobalSize", "uint",pData)
	VarSetCapacity(Bin, nSize, 0)
	DllCall("RtlMoveMemory", "ptr",&Bin , "ptr",pData , "uint",nSize)
	DllCall("GlobalUnlock", "ptr",hData)
	DllCall(NumGet(NumGet(pStream + 0, 0, "uptr") + (A_PtrSize * 2), 0, "uptr"), "ptr",pStream)
	DllCall("GlobalFree", "ptr",hData)
	DllCall("Crypt32.dll\CryptBinaryToString", "ptr",&Bin, "uint",nSize, "uint",0x01, "ptr",0, "uint*",base64Length)
	VarSetCapacity(base64, base64Length*2, 0)				
	;*************************	
	;https://www.autohotkey.com/boards/viewtopic.php?f=76&t=101960&p=453367#p453387
	DllCall("Crypt32.dll\CryptBinaryToString", "ptr",&Bin, "uint",nSize, "uint", 0x40000001 , "ptr",&base64, "uint*",base64Length) ; [ 0x40000001 = CRYPT_STRING_NOCRLF ( 0x40000000 ) And CRYPT_STRING_BASE64 ( 0x00000001 ) ]
	;*************************
	Bin := ""
	VarSetCapacity(Bin, 0)
	VarSetCapacity(base64, -1)
	return  base64
}
;******************************************************************************************************************
;******************************************************************************************************************

;************
;Vector Class
;**************************************************************************************************************************************************************************
;00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 
;00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 
;00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 
;**************************************************************************************************************************************************************************
Class Vector	{
	;Written By: HB
	;Date: Sept 23rd, 2022
	;Last Edit: Sept 24th, 2022
	;Purpose: Vector math class 
	;Credit: Rohwedder 
	;Resources: 
		;Line intercept concepts and code: https://www.autohotkey.com/boards/viewtopic.php?f=76&t=37175
		;Create an Arrow: https://www.autohotkey.com/boards/viewtopic.php?f=76&t=92039&p=479129#p478944
		;Getting an angle: https://www.autohotkey.com/boards/viewtopic.php?f=76&t=108760&p=483661#p483678
		;Setting an Angle: https://www.autohotkey.com/boards/viewtopic.php?f=76&t=108760&p=483786#p483811
		;
		
	static RadToDeg := 45 / ATan( 1 ) 
		, DegToRad := ATan( 1 ) / 45 
		
	__New( x := 0 , y := 0 , rotate := 0 ){ 
		if( IsObject( x ) ){
			if( rotate = 3 ){
				This.X := x.X * -1
				,This.Y := x.Y * -1
			}else if( rotate = 2 ){
				This.X := x.Y 
				,This.Y := x.X * -1
			}else if( rotate = 1 ){
				This.X := x.Y * -1
				,This.Y := x.X 
			}else{
				This.X := x.X
				,This.Y := x.Y
			}
		}else{
			if( rotate = 3 ){
				This.X := X * -1
				,This.Y := Y * -1
			}else if( rotate = 2 ){
				This.X := Y 
				,This.Y := X * -1
			}else if( rotate = 1 ){
				This.X := Y * -1
				,This.Y := X 
			}else{
				This.X := X
				,This.Y := Y
			}
		}
	}
	Add( x , y := "" ){
		if( IsObject( x ) ){
			This.X += x.X
			,This.Y += x.Y
		}else if( y = "" ){
			This.X += x 
			,This.Y += x
		}else{
			This.X += x 
			,This.Y += y 
		}
	}
	Sub( x , y := "" ){
		if( IsObject( x ) ){
			This.X -= x.X
			,This.Y -= x.Y
		}else if( y = "" ){
			This.X -= X
			,This.Y -= X
		}else{
			This.X -= X
			,This.Y -= Y
		}
	}
	Div( x , y := "" ){
		if( IsObject( x ) ){
			This.X /= x.X
			,This.Y /= x.Y
		}else if( x && y = "" ){
			This.X /= x 
			,This.Y /= x 
		}else{
			This.X /= X
			,This.Y /= Y
		}
	}
	Mult( x , y := "" ){
		if( IsObject( x ) ){
			This.X *= x.X
			,This.Y *= x.Y
		}else if( x && y = "" ){
			This.X *= x 
			,This.Y *= x 
		}else{
			This.X *= X
			,This.Y *= Y
		}
	}
	Dist( x , y := "" ){
		if( IsObject( x ) )
			return Sqrt( ( ( This.X - x.X ) **2 ) + ( ( This.Y - x.Y ) **2 ) )
		else 
			return Sqrt( ( ( This.X - X ) **2 ) + ( ( This.Y - Y ) **2 ) )
	}
	GetMag(){
		return Sqrt( This.X * This.X + This.Y * This.Y )
	}
	SetMag( magnitude ){
		local m := This.GetMag()
		This.X := This.X * magnitude / m
		,This.Y := This.Y * magnitude / m
	}
	MagSq(){
		return This.GetMag()**2
	}	
	Dot( x , y := "" ){
		if( IsObject( x ) )
			return ( This.X * x.X ) + ( This.Y * x.Y )
		else
			return ( This.X * X ) + ( This.Y * Y )
	}
	Cross( x , y := "" ){
		if( IsObject( x ) )
			return This.X * x.Y - This.Y * x.X
		else
			return This.X * Y - This.Y * X
		
	}
	Norm(){
		local m := This.GetMag()
		This.X /= m
		This.Y /= m
	}
	GetAngle(){ 
		local angle 
		( (  angle := Vector.RadToDeg * DllCall( "msvcrt\atan2" , "Double" , This.Y , "Double" , This.X , "CDECL Double" ) ) < 0 ) ? ( angle += 360 )
		return angle
	}
	SetAngle( newAngle := 0 , NewVector := 0 ){
		local Angle := This.GetAngle()
		, ChangeAngle := newAngle - Angle 
		, Co := Cos( Vector.DegToRad * ChangeAngle )
		, Si := Sin( Vector.DegToRad * ChangeAngle )
		, X := This.X 
		, Y := This.Y
		, X2 := X * Co - Y * Si 
		, Y2 := X * Si + Y * Co 
		
		if( !NewVector )
			This.X := X2 , This.Y := Y2
		else 
			return New Vector( X2 , Y2 )
	}
	RotateAngle( rotationAmount := 90 , NewVector := 0 ){
		local Co := Cos( Vector.DegToRad * rotationAmount )
		, Si := Sin( Vector.DegToRad * rotationAmount )
		, X := This.X 
		, Y := This.Y
		, X2 := X * Co - Y * Si 
		, Y2 := X * Si + Y * Co 
		
		if( !NewVector )
			This.X := X2 , This.Y := Y2
		else 
			return New Vector( X2 , Y2 )
	}
	;********************************************
	;class methods
	TestLineInterceptPoint( interceptPoint , Line1 , Line2 ){ ; Line = { Start: { X: , Y: } , End: { X: , Y: } } , interceptPoint = { X: , Y: }
		local
		for k , v in [ "X" , "Y" ]	
			M%v%_Min := min( Line1.Start[ v ] , Line1.End[ v ] )
			,M%v%_Max := max( Line1.Start[ v ] , Line1.End[ v ] )
			,L%v%_Min := min( Line2.Start[ v ] , Line2.End[ v ] )
			,L%v%_Max := max( Line2.Start[ v ] , Line2.End[ v ] )
		if( !( interceptPoint.X < Mx_Min || interceptPoint.X > Mx_Max || interceptPoint.X < Lx_Min || interceptPoint.X > Lx_Max ) && !( interceptPoint.Y < My_Min || interceptPoint.Y > My_Max || interceptPoint.Y < Ly_Min || interceptPoint.Y > Ly_Max ) )
			return 1
		return 0
	}
	GetLineInterceptPoint( Line1 , Line2 ){ ; Line = { Start: { X: , Y: } , End: { X: , Y: } }
		local A1 := Line1.End.Y - Line1.Start.Y
		,B1 := Line1.Start.X - Line1.End.X
		,C1 := A1 * Line1.Start.X + B1 * Line1.Start.Y
		,A2 := Line2.End.Y - Line2.Start.Y
		,B2 := Line2.Start.X - Line2.End.X
		,C2 := A2 * Line2.Start.X + B2 * Line2.Start.Y
		,Denominator := A1 * B2 - A2 * B1 
		return New Vector( { X: ( ( B2 * C1 - B1 * C2 ) / Denominator )  , Y: ( ( A1 * C2 - A2 * C1 ) / Denominator ) } )
	}
	;********************************************
}
;**************************************************************************************************************************************************************************
;00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 
;00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 
;00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 
;**************************************************************************************************************************************************************************
;****************************************************************************************************************************************************************************************
;****************************************************************************************************************************************************************************************
;****************************************************************************************************************************************************************************************
;****************************************************************************************************************************************************************************************
;****************************************************************************************************************************************************************************************
Class HButton	{
	;Gen 3 Button Class By Hellbent
	static init , Button := [] , Active , LastControl , HoldCtrl 
	
	__New( Input := "" , All := "" , Default := "" , Hover := "" , Pressed := "" ){
		
		local hwnd 
		
			;If this is the first time the class is being used.
		if( !HButton.init && HButton.init := 1 )
			
				;Set a timer to watch to see if the cursor goes over one of the controls.
			HButton._SetHoverTimer()
			
		This._CreateNewButtonObject( hwnd := This._CreateControl( Input ) , Input )
		
		This._BindButton( hwnd , Input )
		
		This._GetButtonBitmaps( hwnd , Input , All , Default , Hover , Pressed )
		
		This._DisplayButton( hwnd , HButton.Button[hwnd].Bitmaps.Default.hBitmap )
		
		return hwnd
	}

	_DisplayButton( hwnd , hBitmap){
		
		SetImage( hwnd , hBitmap )
		
	}
	
	_GetButtonBitmaps( hwnd , Input := "" , All := "" , Default := "" , Hover := "" , Pressed := "" ){
	
		HButton.Button[hwnd].Bitmaps := GuiButtonType1.CreateButtonBitmapSet( Input , All , Default , Hover , Pressed )
		
	}
	
	_CreateNewButtonObject( hwnd , Input ){
		
		local k , v  
		
		HButton.Button[ hwnd ] := {}
		
		for k , v in Input
			
			HButton.Button[ hwnd ][ k ] := v
		
		HButton.Button[ hwnd ].Hwnd := hwnd
		
	}
	
	_CreateControl( Input ){
		
		local hwnd
		
		Gui , % Input.Owner ":Add" , Pic , % "x" Input.X " y" Input.Y " w" Input.W " h" Input.H " hwndhwnd 0xE"  
		
		return hwnd
		
	}
	
	_BindButton( hwnd , Input ){
		
		local bd
		
		bd := This._OnClick.Bind( This )
		
		GuiControl, % Input.Owner ":+G" , % hwnd , % bd
		
	}
	
	_SetHoverTimer( timer := "" ){
		
		local HoverTimer 

		if( !HButton.HoverTimer ) 
			
			HButton.HoverTimer := ObjBindMethod( HButton , "_OnHover" ) 
		
		HoverTimer := HButton.HoverTimer
		
		SetTimer , % HoverTimer , % ( Timer ) ? ( Timer ) : ( 100 )
		
	}
	
	_OnHover(){
		
		local Ctrl
		
		MouseGetPos,,,,ctrl,2
		
		if( HButton.Button[ ctrl ] && !HButton.Active ){
			
			HButton.Active := 1
			
			HButton.LastControl := ctrl
			
			HButton._DisplayButton( ctrl , HButton.Button[ ctrl ].Bitmaps.Hover.hBitmap )
			
		}else if( HButton.Active && ctrl != HButton.LastControl ){
			
			HButton.Active := 0
			
			HButton._DisplayButton( HButton.LastControl , HButton.Button[ HButton.LastControl ].Bitmaps.Default.hBitmap )

		}
		
	}
	
	_OnClick(){
		
		local Ctrl, last
		
		HButton._SetHoverTimer( "Off" )
		
		MouseGetPos,,,, Ctrl , 2
		last := ctrl
		HButton._SetFocus( ctrl )
		HButton._DisplayButton( last , HButton.Button[ last ].Bitmaps.Pressed.hBitmap )
		
		While(GetKeyState("LButton"))
			sleep, 60
		
		HButton._SetHoverTimer()
		
		loop, 2
			This._OnHover()
		
		MouseGetPos,,,, Ctrl , 2
		
		if(ctrl!=last){
			
			HButton._DisplayButton( last , HButton.Button[ last ].Bitmaps.Default.hBitmap )
		
		}else{
			HButton._DisplayButton( last , HButton.Button[ last ].Bitmaps.Hover.hBitmap )
			if( HButton.Button[ last ].Label ){
			
			if(IsFunc( HButton.Button[ last ].Label ) )
				
				fn := Func( HButton.Button[ last ].Label )
				, fn.Call()
				
			else 
				
				gosub, % HButton.Button[ last ].Label
			}
		
		}
		
	}
	
	_SetFocus( ctrl ){
		
		GuiControl, % HButton.Button[ ctrl ].Owner ":Focus" , % ctrl
		
	}
	
	DeleteButton( hwnd ){
		
		for k , v in HButton.Button[ hwnd ].Bitmaps
				Gdip_DisposeImage( HButton.Button[hwnd].Bitmaps[k].pBitmap )
				, DeleteObject( HButton.Button[ hwnd ].Bitmaps[k].hBitmap )
				
		GuiControl , % HButton.Button[ hwnd ].Owner ":Move", % hwnd , % "x-1 y-1 w0 h0" 
		HButton.Button[ hwnd ] := ""
	}
	
}
;****************************************************************************************************************************************************************************************
;****************************************************************************************************************************************************************************************
;****************************************************************************************************************************************************************************************
;****************************************************************************************************************************************************************************************
;****************************************************************************************************************************************************************************************
Class GuiButtonType1	{

	static List := [ "Default" , "Hover" , "Pressed" ]
	
	_CreatePressedBitmap(){
		
		local arr := [] , Bitmap := {} , fObj := This.CurrentBitmapData.Pressed
		
		Bitmap.pBitmap := Gdip_CreateBitmap( fObj.W , fObj.H ) , G := Gdip_GraphicsFromImage( Bitmap.pBitmap ) , Gdip_SetSmoothingMode( G , 2 )
		
		Brush := Gdip_BrushCreateSolid( fObj.BackgroundColor ) , Gdip_FillRectangle( G , Brush , -1 , -1 , fObj.W+2 , fObj.H+2 ) , Gdip_DeleteBrush( Brush )
		
		Brush := Gdip_BrushCreateSolid( fObj.ButtonOuterBorderColor ) , Gdip_FillRoundedRectangle( G , Brush , 3 , 4 , fObj.W-7 , fObj.H-7 , 5 ) , Gdip_DeleteBrush( Brush )
		
		Brush := Gdip_CreateLineBrushFromRect( 0 , 0 , fObj.W , fObj.H , fObj.ButtonInnerBorderColor1 , fObj.ButtonInnerBorderColor2 , 1 , 1 ) , Gdip_FillRoundedRectangle( G , Brush , 2 , 3 , fObj.W-5 , fObj.H-8 , 5 ) , Gdip_DeleteBrush( Brush )
		
		Brush := Gdip_CreateLineBrushFromRect( 0 , 0 , fObj.W-7 , fObj.H-10 , fObj.ButtonMainColor1 , fObj.ButtonMainColor2 , 1 , 1 ) , Gdip_FillRoundedRectangle( G , Brush , 5 , 5 , fObj.W-11 , fObj.H-12 , 5 ) , Gdip_DeleteBrush( Brush )
			
		Brush := Gdip_CreateLineBrushFromRect( 0 , 2 , fObj.W , fObj.H , fObj.TextBottomColor1 , fObj.TextBottomColor2 , 1 , 1 )
		
		arr := [ { X: -1 , Y: -1 } , { X: 0 , Y: -1 } , { X: 1 , Y: -1 } , { X: -1 , Y: 0 } , { X: 1 , Y: 0 } , { X: -1 , Y: 1 } , { X: 0 , Y: 1 } , { X: 1 , Y: 1 } ]
		
		Loop, % 8
			
			Gdip_TextToGraphics( G , fObj.Text , "s" fObj.FontSize " " fObj.FontOptions " c" Brush " x" 1 + arr[A_Index].X + fObj.TextOffsetX " y" 3 + arr[A_Index].Y + fObj.TextOffsetY , fObj.Font , fObj.W + fObj.TextOffsetW , fObj.H + fObj.TextOffsetH )
	
		Brush := Gdip_CreateLineBrushFromRect( 0 , 2 , fObj.W , fObj.H , fObj.TextTopColor1 , fObj.TextTopColor2 , 1 , 1 )
		
		Gdip_TextToGraphics( G , fObj.Text , "s" fObj.FontSize " " fObj.FontOptions " c" Brush " x" 1 + fObj.TextOffsetX " y" 3 + fObj.TextOffsetY , fObj.Font , fObj.W + fObj.TextOffsetW , fObj.H + fObj.TextOffsetH )
	
	if( fObj.ButtonAddGlossy ){
		
		Brush := Gdip_BrushCreateSolid( fObj.GlossTopColor ) , Gdip_FillRectangle( G , Brush , 5 , 10 , fObj.W-11 , ( fObj.H / 2 ) - 10   ) , Gdip_DeleteBrush( Brush )

		Brush := Gdip_BrushCreateSolid( fObj.GlossTopAccentColor ) , Gdip_FillRectangle( G , Brush , 10 , 12 , fObj.W-21 , fObj.H / 15 ) , Gdip_DeleteBrush( Brush )
		
		Brush := Gdip_BrushCreateSolid( fObj.GlossBottomColor ) , Gdip_FillRectangle( G , Brush , 5  , 10 + ( fObj.H / 2 ) - 10 , fObj.W-11 , ( fObj.H / 2 ) - 7 ) , Gdip_DeleteBrush( Brush )
				
	}

		Gdip_DeleteGraphics( G )
		
		Bitmap.hBitmap := Gdip_CreateHBITMAPFromBitmap( Bitmap.pBitmap )
		
		return Bitmap
	}
	
	_CreateHoverBitmap(){
		
		local arr := [] , Bitmap := {} , fObj := This.CurrentBitmapData.Hover
		
		Bitmap.pBitmap := Gdip_CreateBitmap( fObj.W , fObj.H ) , G := Gdip_GraphicsFromImage( Bitmap.pBitmap ) , Gdip_SetSmoothingMode( G , 2 )
		
		Brush := Gdip_BrushCreateSolid( fObj.BackgroundColor ) , Gdip_FillRectangle( G , Brush , -1 , -1 , fObj.W+2 , fObj.H+2 ) , Gdip_DeleteBrush( Brush )
		
		Brush := Gdip_BrushCreateSolid( fObj.ButtonOuterBorderColor ) , Gdip_FillRoundedRectangle( G , Brush , 2 , 3 , fObj.W-5 , fObj.H-7 , 5 ) , Gdip_DeleteBrush( Brush )
		
		Brush := Gdip_BrushCreateSolid( fObj.ButtonCenterBorderColor ) , Gdip_FillRoundedRectangle( G , Brush , 3 , 4 , fObj.W-7 , fObj.H-9 , 5 ) , Gdip_DeleteBrush( Brush )
		
		Brush := Gdip_CreateLineBrushFromRect( 0 , 0 , fObj.W , fObj.H-10 , fObj.ButtonInnerBorderColor1 , fObj.ButtonInnerBorderColor2 , 1 , 1 ) , Gdip_FillRoundedRectangle( G , Brush , 4 , 5 , fObj.W-9 , fObj.H-11 , 5 ) , Gdip_DeleteBrush( Brush )
		
		Brush := Gdip_CreateLineBrushFromRect( 5 , 7 , fObj.W-11 , fObj.H-14 , fObj.ButtonMainColor1 , fObj.ButtonMainColor2 , 1 , 1 ) , Gdip_FillRoundedRectangle( G , Brush , 5 , 7 , fObj.W-11 , fObj.H-14 , 5 ) , Gdip_DeleteBrush( Brush )
		
		Brush := Gdip_CreateLineBrushFromRect( 0 , 2 , fObj.W , fObj.H , fObj.TextBottomColor1 , fObj.TextBottomColor2 , 1 , 1 )
		
		arr := [ { X: -1 , Y: -1 } , { X: 0 , Y: -1 } , { X: 1 , Y: -1 } , { X: -1 , Y: 0 } , { X: 1 , Y: 0 } , { X: -1 , Y: 1 } , { X: 0 , Y: 1 } , { X: 1 , Y: 1 } ]
		
		Loop, % 8
			
			Gdip_TextToGraphics( G , fObj.Text , "s" fObj.FontSize " " fObj.FontOptions " c" Brush " x" 0 + arr[A_Index].X + fObj.TextOffsetX " y" 2 + arr[A_Index].Y + fObj.TextOffsetY , fObj.Font , fObj.W + fObj.TextOffsetW , fObj.H + fObj.TextOffsetH )
	
		Brush := Gdip_CreateLineBrushFromRect( 0 , 2 , fObj.W , fObj.H , fObj.TextTopColor1 , fObj.TextTopColor2 , 1 , 1 )
		
		Gdip_TextToGraphics( G , fObj.Text , "s" fObj.FontSize " " fObj.FontOptions " c" Brush " x" 0 + fObj.TextOffsetX " y" 2 + fObj.TextOffsetY , fObj.Font , fObj.W + fObj.TextOffsetW , fObj.H + fObj.TextOffsetH )
	
		if( fObj.ButtonAddGlossy = 1 ){
			
			Brush := Gdip_BrushCreateSolid( fObj.GlossTopColor ) , Gdip_FillRectangle( G , Brush , 6 , 10 , fObj.W-13 , ( fObj.H / 2 ) - 10   ) , Gdip_DeleteBrush( Brush )
			
			Brush := Gdip_BrushCreateSolid( fObj.GlossTopAccentColor ) , Gdip_FillRectangle( G , Brush , 10 , 12 , fObj.W-21 , fObj.H / 15 ) , Gdip_DeleteBrush( Brush )
			
			Brush := Gdip_BrushCreateSolid( fObj.GlossBottomColor ) , Gdip_FillRectangle( G , Brush , 6  , 10 + ( fObj.H / 2 ) - 10 , fObj.W-13 , ( fObj.H / 2 ) - 7 ) , Gdip_DeleteBrush( Brush )
					
		}
	
		Gdip_DeleteGraphics( G )
		
		Bitmap.hBitmap := Gdip_CreateHBITMAPFromBitmap( Bitmap.pBitmap )
		
		return Bitmap
		
	}
	
	_CreateDefaultBitmap(){
		
		local arr := [] , Bitmap := {} , fObj := This.CurrentBitmapData.Default
		
		Bitmap.pBitmap := Gdip_CreateBitmap( fObj.W , fObj.H ) , G := Gdip_GraphicsFromImage( Bitmap.pBitmap ) , Gdip_SetSmoothingMode( G , 2 )
	
		Brush := Gdip_BrushCreateSolid( fObj.BackgroundColor ) , Gdip_FillRectangle( G , Brush , -1 , -1 , fObj.W+2 , fObj.H+2 ) , Gdip_DeleteBrush( Brush )
	
		Brush := Gdip_BrushCreateSolid( fObj.ButtonOuterBorderColor ) , Gdip_FillRoundedRectangle( G , Brush , 2 , 3 , fObj.W-5 , fObj.H-7 , 5 ) , Gdip_DeleteBrush( Brush )
		
		Brush := Gdip_BrushCreateSolid( fObj.ButtonCenterBorderColor ) , Gdip_FillRoundedRectangle( G , Brush , 3 , 4 , fObj.W-7 , fObj.H-9 , 5 ) , Gdip_DeleteBrush( Brush )
	
		Brush := Gdip_CreateLineBrushFromRect( 0 , 0 , fObj.W , fObj.H-10 , fObj.ButtonInnerBorderColor1 , fObj.ButtonInnerBorderColor2 , 1 , 1 ) , Gdip_FillRoundedRectangle( G , Brush , 4 , 5 , fObj.W-9 , fObj.H-11 , 5 ) , Gdip_DeleteBrush( Brush )
	
		Brush := Gdip_CreateLineBrushFromRect( 5 , 7 , fObj.W-11 , fObj.H-14 , fObj.ButtonMainColor1 , fObj.ButtonMainColor2 , 1 , 1 ) , Gdip_FillRoundedRectangle( G , Brush , 5 , 7 , fObj.W-11 , fObj.H-14 , 5 ) , Gdip_DeleteBrush( Brush )
		
		Brush := Gdip_CreateLineBrushFromRect( 0 , 2 , fObj.W , fObj.H , fObj.TextBottomColor1 , fObj.TextBottomColor2 , 1 , 1 )
		
		arr := [ { X: -1 , Y: -1 } , { X: 0 , Y: -1 } , { X: 1 , Y: -1 } , { X: -1 , Y: 0 } , { X: 1 , Y: 0 } , { X: -1 , Y: 1 } , { X: 0 , Y: 1 } , { X: 1 , Y: 1 } ]
		
		Loop, % 8
			
			Gdip_TextToGraphics( G , fObj.Text , "s" fObj.FontSize " " fObj.FontOptions " c" Brush " x" 0 + arr[A_Index].X + fObj.TextOffsetX " y" 2 + arr[A_Index].Y + fObj.TextOffsetY , fObj.Font , fObj.W + fObj.TextOffsetW , fObj.H + fObj.TextOffsetH )
	
		Brush := Gdip_CreateLineBrushFromRect( 0 , 2 , fObj.W , fObj.H , fObj.TextTopColor1 , fObj.TextTopColor2 , 1 , 1 )
		
		Gdip_TextToGraphics( G , fObj.Text , "s" fObj.FontSize " " fObj.FontOptions " c" Brush " x" 0 + fObj.TextOffsetX " y" 2 + fObj.TextOffsetY , fObj.Font , fObj.W + fObj.TextOffsetW , fObj.H + fObj.TextOffsetH )
	
		if( fObj.ButtonAddGlossy ){
		
			Brush := Gdip_BrushCreateSolid( fObj.GlossTopColor ) , Gdip_FillRectangle( G , Brush , 6 , 10 , fObj.W-13 , ( fObj.H / 2 ) - 10   ) , Gdip_DeleteBrush( Brush )
			
			Brush := Gdip_BrushCreateSolid( fObj.GlossTopAccentColor ) , Gdip_FillRectangle( G , Brush , 10 , 12 , fObj.W-21 , fObj.H / 15 ) , Gdip_DeleteBrush( Brush )
			
			Brush := Gdip_BrushCreateSolid( fObj.GlossBottomColor ) , Gdip_FillRectangle( G , Brush , 6  , 10 + ( fObj.H / 2 ) - 10 , fObj.W-13 , ( fObj.H / 2 ) - 7 ) , Gdip_DeleteBrush( Brush )
				
		}
	
		Gdip_DeleteGraphics( G )
		
		Bitmap.hBitmap := Gdip_CreateHBITMAPFromBitmap( Bitmap.pBitmap )
		
		return Bitmap
		
	}
	
	_GetMasterDefaultValues(){ ;Default State
		
		local Default := {}
		
		Default.pBitmap := "" 
		, Default.hBitmap := ""
		, Default.Font := "Arial"
		, Default.FontOptions := " Bold Center vCenter "
		, Default.FontSize := "12"
		, Default.Text := "Button"
		, Default.W := 10
		, Default.H := 10
		, Default.TextBottomColor1 := "0x0002112F"
		, Default.TextBottomColor2 := Default.TextBottomColor1
		, Default.TextTopColor1 := "0xFFFFFFFF"
		, Default.TextTopColor2 := "0xFF000000"
		, Default.TextOffsetX := 0
		, Default.TextOffsetY := 0
		, Default.TextOffsetW := 0
		, Default.TextOffsetH := 0
		, Default.BackgroundColor := "0xFF22262A"
		, Default.ButtonOuterBorderColor := "0xFF161B1F"	
		, Default.ButtonCenterBorderColor := "0xFF262B2F"	
		, Default.ButtonInnerBorderColor1 := "0xFF3F444A"
		, Default.ButtonInnerBorderColor2 := "0xFF24292D"
		, Default.ButtonMainColor1 := "0xFF272C32"
		, Default.ButtonMainColor2 := "" Default.ButtonMainColor1
		, Default.ButtonAddGlossy := 0
		, Default.GlossTopColor := "0x11FFFFFF"
		, Default.GlossTopAccentColor := "0x05FFFFFF"	
		, Default.GlossBottomColor := "0x33000000"
		
		return Default
		
	}
	
	_GetMasterHoverValues(){ ;Hover State
		
		local Default := {}
		
		Default.pBitmap := ""
		, Default.hBitmap := ""
		, Default.Font := "Arial"
		, Default.FontOptions := " Bold Center vCenter "
		, Default.FontSize := "12"
		, Default.Text := "Button"
		, Default.W := 10
		, Default.H := 10
		, Default.TextBottomColor1 := "0x0002112F"
		, Default.TextBottomColor2 := Default.TextBottomColor1
		, Default.TextTopColor1 := "0xFFFFFFFF"
		, Default.TextTopColor2 := "0xFF000000"
		, Default.TextOffsetX := 0
		, Default.TextOffsetY := 0
		, Default.TextOffsetW := 0
		, Default.TextOffsetH := 0
		, Default.BackgroundColor := "0xFF22262A"
		, Default.ButtonOuterBorderColor := "0xFF161B1F"	
		, Default.ButtonCenterBorderColor := "0xFF262B2F"	
		, Default.ButtonInnerBorderColor1 := "0xFF3F444A"
		, Default.ButtonInnerBorderColor2 := "0xFF24292D"
		, Default.ButtonMainColor1 := "0xFF373C42"
		, Default.ButtonMainColor2 := "" Default.ButtonMainColor1
		, Default.ButtonAddGlossy := 0
		, Default.GlossTopColor := "0x11FFFFFF"
		, Default.GlossTopAccentColor := "0x05FFFFFF"	
		, Default.GlossBottomColor := "0x33000000"
		
		return Default
		
	}
	
	_GetMasterPressedValues(){ ;Pressed State
		
		local Default := {}
		
		Default.pBitmap := ""
		, Default.hBitmap := ""
		, Default.Font := "Arial"
		, Default.FontOptions := " Bold Center vCenter "
		, Default.FontSize := "12"
		, Default.Text := "Button"
		, Default.W := 10
		, Default.H := 10
		, Default.TextBottomColor1 := "0x0002112F"
		, Default.TextBottomColor2 := Default.TextBottomColor1
		, Default.TextTopColor1 := "0xFFFFFFFF"
		, Default.TextTopColor2 := "0xFF000000"
		, Default.TextOffsetX := 0
		, Default.TextOffsetY := 0
		, Default.TextOffsetW := 0
		, Default.TextOffsetH := 0
		, Default.BackgroundColor := "0xFF22262A"
		, Default.ButtonOuterBorderColor := "0xFF62666a"
		, Default.ButtonCenterBorderColor := "0xFF262B2F"	
		, Default.ButtonInnerBorderColor1 := "0xFF151A20"
		, Default.ButtonInnerBorderColor2 := "0xFF151A20"
		, Default.ButtonMainColor1 := "0xFF12161a"
		, Default.ButtonMainColor2 := "0xFF33383E"
		, Default.ButtonAddGlossy := 0
		, Default.GlossTopColor := "0x11FFFFFF"
		, Default.GlossTopAccentColor := "0x05FFFFFF"	
		, Default.GlossBottomColor := "0x33000000"
	
		return Default
		
	}
	
	SetSessionDefaults( All := "" , Default := "" , Hover := "" , Pressed := "" ){ ;Set the default values based on user input
		
		This.SessionBitmapData := {} 
		, This.Preset := 1
		, This.init := 0
		
		This._LoadDefaults("SessionBitmapData")
		
		This._SetSessionData( All , Default , Hover , Pressed )
		
	}
	
	_SetSessionData( All := "" , Default := "" , Hover := "" , Pressed := "" ){
		
		local index , k , v , i , j
	
		if( IsObject( All ) ){
			
			Loop, % GuiButtonType1.List.Length()	{
				index := A_Index
				For k , v in All
					This.SessionBitmapData[ GuiButtonType1.List[ index ] ][ k ] := v
			}
		}
		
		For k , v in GuiButtonType1.List
			if( isObject( %v% ) )
				For i , j in %v%
					This.SessionBitmapData[ GuiButtonType1.List[ k ] ][ i ] := j
				
	}
	
	_LoadDefaults( input := "" ){
		
		This.CurrentBitmapData := "" , This.CurrentBitmapData := {}
			
		For k , v in This.SessionBitmapData
			This.CurrentBitmapData[k] := {}
		
		This[ input ].Default := This._GetMasterDefaultValues()
		, This[ input ].Hover := This._GetMasterHoverValues()
		, This[ input ].Pressed := This._GetMasterPressedValues()
		
	}
	
	_SetCurrentBitmapDataFromSessionData(){
		
		local k , v , i , j
			
		This.CurrentBitmapData := "" , This.CurrentBitmapData := {}
			
		For k , v in This.SessionBitmapData
		{
			This.CurrentBitmapData[k] := {}
			
			For i , j in This.SessionBitmapData[k]
				
				This.CurrentBitmapData[k][i] := j

		}
		
	}
	
	_UpdateCurrentBitmapData( All := "" , Default := "" , Hover := "" , Pressed := "" ){
		
		local k , v , i , j
		
		if( IsObject( All ) ){
			
			Loop, % GuiButtonType1.List.Length()	{
				
				index := A_Index
			
				For k , v in All
					
					This.CurrentBitmapData[ GuiButtonType1.List[ index ] ][ k ] := v
					
			}
		}
		
		For k , v in GuiButtonType1.List
			
			if( isObject( %v% ) )
				
				For i , j in %v%
					
					This.CurrentBitmapData[ GuiButtonType1.List[ k ] ][ i ] := j
				
	}
	
	_UpdateInstanceData( obj := ""){
		
		For k , v in GuiButtonType1.List	
			
			This.CurrentBitmapData[v].Text := obj.Text
			, This.CurrentBitmapData[v].W := obj.W
			, This.CurrentBitmapData[v].H := obj.H
			
	}

	CreateButtonBitmapSet( obj := "" ,  All := "" , Default := "" , Hover := "" , Pressed := ""  ){ ;Create a new button
		
		local Bitmaps := {}
		
		if( This.Preset )
				
			This._SetCurrentBitmapDataFromSessionData()
			
		else
			
			This._LoadDefaults( "CurrentBitmapData" )
			
		This._UpdateCurrentBitmapData( All , Default , Hover , Pressed )
		
		This._UpdateInstanceData( obj )
		 
		Bitmaps.Default := This._CreateDefaultBitmap()
		, Bitmaps.Hover := This._CreateHoverBitmap()
		, Bitmaps.Pressed := This._CreatePressedBitmap()
		
		return Bitmaps
		
	}
	
}
;****************************************************************************************************************************************************************************************
;****************************************************************************************************************************************************************************************
;****************************************************************************************************************************************************************************************
;****************************************************************************************************************************************************************************************
;****************************************************************************************************************************************************************************************
;####################################################################################################################################################################################
;####################################################################################################################################################################################
;####################################################################################################################################################################################
;####################################################################################################################################################################################
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 ]
		
	}
}

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

		if( This.Pressed = 1 ){
			Brush := Gdip_BrushCreateSolid( "0xAA3399FF" ) , Gdip_FillRectangle( This.G , Brush , ( 106 - This.XOffset ) * This.Scale , ( 38 - This.YOffset ) * This.Scale , 68 * This.Scale , 15 * This.Scale ) , Gdip_DeleteBrush( Brush )
			Brush := Gdip_BrushCreateSolid( "0x99336699" ) , Gdip_FillRectangle( This.G , Brush , ( 106 - This.XOffset ) * This.Scale , ( 53 - This.YOffset ) * This.Scale , 68 * This.Scale , 15 * This.Scale ) , Gdip_DeleteBrush( Brush )
		}else if( This.Active = 1 ){
			Brush := Gdip_BrushCreateSolid( "0x993399FF" ) , Gdip_FillRectangle( This.G , Brush , ( 106 - This.XOffset ) * This.Scale , ( 38 - This.YOffset ) * This.Scale , 68 * This.Scale , 15 * This.Scale ) , Gdip_DeleteBrush( Brush )
			Brush := Gdip_BrushCreateSolid( "0x66336699" ) , Gdip_FillRectangle( This.G , Brush , ( 106 - This.XOffset ) * This.Scale , ( 53 - This.YOffset ) * This.Scale , 68 * This.Scale , 15 * This.Scale ) , Gdip_DeleteBrush( Brush )
		}else{
			Brush := Gdip_BrushCreateSolid( "0x66F0F0F0" ) , Gdip_FillRectangle( This.G , Brush , ( 106 - This.XOffset ) * This.Scale , ( 38 - This.YOffset ) * This.Scale , 68 * This.Scale , 15 * This.Scale ) , Gdip_DeleteBrush( Brush )
			Brush := Gdip_BrushCreateSolid( "0x66000000" ) , Gdip_FillRectangle( This.G , Brush , ( 106 - This.XOffset ) * This.Scale , ( 53 - This.YOffset ) * This.Scale , 68 * This.Scale , 15 * This.Scale ) , Gdip_DeleteBrush( Brush )
		}
		if( This.Pressed = 1 )
			Brush := Gdip_BrushCreateSolid( "0xFFF0F0F0" ) , Gdip_TextToGraphics( This.G , "5" , "s" 22 * This.Scale " Center vCenter  c" Brush " x" ( 104 - This.XOffset ) * This.Scale " y" ( 37 - This.YOffset ) * This.Scale , "Webdings" , 74 * This.Scale , 36 * This.Scale ) , Gdip_DeleteBrush( Brush )
		else	
			Brush := Gdip_BrushCreateSolid( "0xFFF0F0F0" ) , Gdip_TextToGraphics( This.G , "5" , "s" 22 * This.Scale " Center vCenter  c" Brush " x" ( 104 - This.XOffset ) * This.Scale " y" ( 36 - This.YOffset ) * This.Scale , "Webdings" , 74 * This.Scale , 36 * This.Scale ) , Gdip_DeleteBrush( Brush )
		;***************************************************************************************************************************
		;***************************************************************************************************************************
		;Button 2
		
		
		
		if( This.Pressed = 2 ){
			Brush := Gdip_CreateLineBrushFromRect( ( 107 - This.XOffset ) * This.Scale , ( 78 - This.YOffset ) * This.Scale , 70 * This.Scale , 36 * This.Scale , "0xFF12161a" , "0xFF22262a" , 1 , 1 ) , Gdip_FillRoundedRectangle( This.G , Brush , ( 103 - This.XOffset ) * This.Scale , ( 76 - This.YOffset ) * This.Scale , 74 * This.Scale , 36 * This.Scale , 5 * This.Scale ) , Gdip_DeleteBrush( Brush )
			Brush := Gdip_CreateLineBrushFromRect( ( 103 - This.XOffset ) * This.Scale , ( 79 - This.YOffset ) * This.Scale , 74 * This.Scale , 35 * This.Scale , "0xFF02050a" , "0xFF22262a" , 1 , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 1 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawRoundedRectangle( This.G , Pen , ( 103 - This.XOffset ) * This.Scale , ( 76 - This.YOffset ) * This.Scale , 74 * This.Scale , 36 * This.Scale , 5 * This.Scale ) , Gdip_DeletePen( Pen )
		}else{
			Brush := Gdip_CreateLineBrushFromRect( ( 107 - This.XOffset ) * This.Scale , ( 78 - This.YOffset ) * This.Scale , 70 * This.Scale , 36 * This.Scale , "0xFF32363a" , "0xFF22262a" , 1 , 1 ) , Gdip_FillRoundedRectangle( This.G , Brush , ( 103 - This.XOffset ) * This.Scale , ( 76 - This.YOffset ) * This.Scale , 74 * This.Scale , 36 * This.Scale , 5 * This.Scale ) , Gdip_DeleteBrush( Brush )
			Brush := Gdip_CreateLineBrushFromRect( ( 103 - This.XOffset ) * This.Scale , ( 79 - This.YOffset ) * This.Scale , 74 * This.Scale , 35 * This.Scale , "0xFF3F4752" , "0xFF1C2024" , 1 , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 1 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawRoundedRectangle( This.G , Pen , ( 103 - This.XOffset ) * This.Scale , ( 76 - This.YOffset ) * This.Scale , 74 * This.Scale , 36 * This.Scale , 5 * This.Scale ) , Gdip_DeletePen( Pen )
		}
		if( This.Pressed = 2 ){
			Brush := Gdip_BrushCreateSolid( "0xAA3399FF" ) , Gdip_FillRectangle( This.G , Brush , ( 106 - This.XOffset ) * This.Scale , ( 79 - This.YOffset ) * This.Scale , 68 * This.Scale , 15 * This.Scale ) , Gdip_DeleteBrush( Brush )
			Brush := Gdip_BrushCreateSolid( "0x99336699" ) , Gdip_FillRectangle( This.G , Brush , ( 106 - This.XOffset ) * This.Scale , ( 94 - This.YOffset ) * This.Scale , 68 * This.Scale , 15 * This.Scale ) , Gdip_DeleteBrush( Brush )
		}else if( This.Active = 2 ){
			Brush := Gdip_BrushCreateSolid( "0x993399FF" ) , Gdip_FillRectangle( This.G , Brush , ( 106 - This.XOffset ) * This.Scale , ( 79 - This.YOffset ) * This.Scale , 68 * This.Scale , 15 * This.Scale ) , Gdip_DeleteBrush( Brush )
			Brush := Gdip_BrushCreateSolid( "0x66336699" ) , Gdip_FillRectangle( This.G , Brush , ( 106 - This.XOffset ) * This.Scale , ( 94 - This.YOffset ) * This.Scale , 68 * This.Scale , 15 * This.Scale ) , Gdip_DeleteBrush( Brush )
		}else{
			Brush := Gdip_BrushCreateSolid( "0x66F0F0F0" ) , Gdip_FillRectangle( This.G , Brush , ( 106 - This.XOffset ) * This.Scale , ( 79 - This.YOffset ) * This.Scale , 68 * This.Scale , 15 * This.Scale ) , Gdip_DeleteBrush( Brush )
			Brush := Gdip_BrushCreateSolid( "0x66000000" ) , Gdip_FillRectangle( This.G , Brush , ( 106 - This.XOffset ) * This.Scale , ( 94 - This.YOffset ) * This.Scale , 68 * This.Scale , 15 * This.Scale ) , Gdip_DeleteBrush( Brush )
		}
		if( This.Pressed = 2 )
			Brush := Gdip_BrushCreateSolid( "0xFFF0F0F0" ) , Gdip_TextToGraphics( This.G , "6" , "s" 22 * This.Scale " Center vCenter  c" Brush " x" ( 104 - This.XOffset ) * This.Scale " y" ( 77 - This.YOffset ) * This.Scale , "Webdings" , 74 * This.Scale , 36 * This.Scale ) , Gdip_DeleteBrush( Brush )
		else
			Brush := Gdip_BrushCreateSolid( "0xFFF0F0F0" ) , Gdip_TextToGraphics( This.G , "6" , "s" 22 * This.Scale " Center vCenter  c" Brush " x" ( 104 - This.XOffset ) * This.Scale " y" ( 76 - This.YOffset ) * This.Scale , "Webdings" , 74 * This.Scale , 36 * This.Scale ) , Gdip_DeleteBrush( Brush )
		;***************************************************************************************************************************
		;***************************************************************************************************************************
		;Button 3
		if( This.Pressed = 3 ){
			Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_FillPie( This.G , Brush , ( 49 - This.XOffset ) * This.Scale , ( 39 - This.YOffset ) * This.Scale , 95 * This.Scale , 70 * This.Scale , 90 , 180 ) , Gdip_DeleteBrush( Brush )
			Brush := Gdip_CreateLineBrushFromRect( ( 51 - This.XOffset ) * This.Scale , ( 44 - This.YOffset ) * This.Scale , 44 * This.Scale , 65 * This.Scale , "0xFF12161a" , "0xFF22262a" , 1 , 1 ) , Gdip_FillPie( This.G , Brush , ( 51 - This.XOffset ) * This.Scale , ( 41 - This.YOffset ) * This.Scale , 89 * This.Scale , 66 * This.Scale , 90 , 180 ) , Gdip_DeleteBrush( Brush )
		}else{
			Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_FillPie( This.G , Brush , ( 49 - This.XOffset ) * This.Scale , ( 39 - This.YOffset ) * This.Scale , 95 * This.Scale , 70 * This.Scale , 90 , 180 ) , Gdip_DeleteBrush( Brush )
			Brush := Gdip_CreateLineBrushFromRect( ( 51 - This.XOffset ) * This.Scale , ( 44 - This.YOffset ) * This.Scale , 44 * This.Scale , 65 * This.Scale , "0xFF32363a" , "0xFF22262a" , 1 , 1 ) , Gdip_FillPie( This.G , Brush , ( 51 - This.XOffset ) * This.Scale , ( 41 - This.YOffset ) * This.Scale , 89 * This.Scale , 66 * This.Scale , 90 , 180 ) , Gdip_DeleteBrush( Brush )
		}
		if( This.Pressed = 3 )
			Brush := Gdip_BrushCreateSolid( "0xAA3399FF" ) , Gdip_FillPie( This.G , Brush , ( 53 - This.XOffset ) * This.Scale , ( 44 - This.YOffset ) * This.Scale , 81 * This.Scale , 59 * This.Scale , 180 , 90 ) , Gdip_DeleteBrush( Brush )
		else if( This.Active = 3 )
			Brush := Gdip_BrushCreateSolid( "0x993399FF" ) , Gdip_FillPie( This.G , Brush , ( 53 - This.XOffset ) * This.Scale , ( 44 - This.YOffset ) * This.Scale , 81 * This.Scale , 59 * This.Scale , 180 , 90 ) , Gdip_DeleteBrush( Brush )
		else 
			Brush := Gdip_BrushCreateSolid( "0x66F0F0F0" ) , Gdip_FillPie( This.G , Brush , ( 53 - This.XOffset ) * This.Scale , ( 44 - This.YOffset ) * This.Scale , 81 * This.Scale , 59 * This.Scale , 180 , 90 ) , Gdip_DeleteBrush( Brush )
		if( This.Pressed = 3 )
			Brush := Gdip_BrushCreateSolid( "0x99336699" ) , Gdip_FillPie( This.G , Brush , ( 53 - This.XOffset ) * This.Scale , ( 44 - This.YOffset ) * This.Scale , 81 * This.Scale , 59 * This.Scale , 90 , 90 ) , Gdip_DeleteBrush( Brush )
		else if( This.Active = 3 )
			Brush := Gdip_BrushCreateSolid( "0x66336699" ) , Gdip_FillPie( This.G , Brush , ( 53 - This.XOffset ) * This.Scale , ( 44 - This.YOffset ) * This.Scale , 81 * This.Scale , 59 * This.Scale , 90 , 90 ) , Gdip_DeleteBrush( Brush )
		else
			Brush := Gdip_BrushCreateSolid( "0x66000000" ) , Gdip_FillPie( This.G , Brush , ( 53 - This.XOffset ) * This.Scale , ( 44 - This.YOffset ) * This.Scale , 81 * This.Scale , 59 * This.Scale , 90 , 90 ) , Gdip_DeleteBrush( Brush )
		if( This.Pressed = 3 )
			Brush := Gdip_BrushCreateSolid( "0xFFF0F0F0" ) , Gdip_TextToGraphics( This.G , "3" , "s" 22 * This.Scale " Center vCenter  c" Brush " x" ( 49 - This.XOffset ) * This.Scale " y" ( 40 - This.YOffset ) * This.Scale , "Webdings" , 55 * This.Scale , 70 * This.Scale ) , Gdip_DeleteBrush( Brush )
		else	
			Brush := Gdip_BrushCreateSolid( "0xFFF0F0F0" ) , Gdip_TextToGraphics( This.G , "3" , "s" 22 * This.Scale " Center vCenter  c" Brush " x" ( 49 - This.XOffset ) * This.Scale " y" ( 39 - This.YOffset ) * This.Scale , "Webdings" , 55 * This.Scale , 70 * This.Scale ) , Gdip_DeleteBrush( Brush )
		;***************************************************************************************************************************
		;***************************************************************************************************************************
		;Button 4
		if( This.Pressed = 4 ){
			Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_FillPie( This.G , Brush , ( 136 - This.XOffset ) * This.Scale , ( 39 - This.YOffset ) * This.Scale , 95 * This.Scale , 70 * This.Scale , 90 , -180 ) , Gdip_DeleteBrush( Brush )
			Brush := Gdip_CreateLineBrushFromRect( ( 51 - This.XOffset ) * This.Scale , ( 44 - This.YOffset ) * This.Scale , 44 * This.Scale , 65 * This.Scale , "0xFF12161a" , "0xFF22262a" , 1 , 1 ) , Gdip_FillPie( This.G , Brush , ( 140 - This.XOffset ) * This.Scale , ( 41 - This.YOffset ) * This.Scale , 89 * This.Scale , 66 * This.Scale , 90 , -180 ) , Gdip_DeleteBrush( Brush )
		}else{
			Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_FillPie( This.G , Brush , ( 136 - This.XOffset ) * This.Scale , ( 39 - This.YOffset ) * This.Scale , 95 * This.Scale , 70 * This.Scale , 90 , -180 ) , Gdip_DeleteBrush( Brush )
			Brush := Gdip_CreateLineBrushFromRect( ( 51 - This.XOffset ) * This.Scale , ( 44 - This.YOffset ) * This.Scale , 44 * This.Scale , 65 * This.Scale , "0xFF32363a" , "0xFF22262a" , 1 , 1 ) , Gdip_FillPie( This.G , Brush , ( 140 - This.XOffset ) * This.Scale , ( 41 - This.YOffset ) * This.Scale , 89 * This.Scale , 66 * This.Scale , 90 , -180 ) , Gdip_DeleteBrush( Brush )
		}
		if( This.Pressed = 4 ){
			Brush := Gdip_BrushCreateSolid( "0xAA3399FF" ) , Gdip_FillPie( This.G , Brush , ( 146 - This.XOffset ) * This.Scale , ( 44 - This.YOffset ) * This.Scale , 81 * This.Scale , 59 * This.Scale , -90 , 90 ) , Gdip_DeleteBrush( Brush )
			Brush := Gdip_BrushCreateSolid( "0x99336699" ) , Gdip_FillPie( This.G , Brush , ( 146 - This.XOffset ) * This.Scale , ( 44 - This.YOffset ) * This.Scale , 81 * This.Scale , 59 * This.Scale , 90 , -90 ) , Gdip_DeleteBrush( Brush )
		}else if( This.Active = 4 ){
			Brush := Gdip_BrushCreateSolid( "0x993399FF" ) , Gdip_FillPie( This.G , Brush , ( 146 - This.XOffset ) * This.Scale , ( 44 - This.YOffset ) * This.Scale , 81 * This.Scale , 59 * This.Scale , -90 , 90 ) , Gdip_DeleteBrush( Brush )
			Brush := Gdip_BrushCreateSolid( "0x66336699" ) , Gdip_FillPie( This.G , Brush , ( 146 - This.XOffset ) * This.Scale , ( 44 - This.YOffset ) * This.Scale , 81 * This.Scale , 59 * This.Scale , 90 , -90 ) , Gdip_DeleteBrush( Brush )
		}else{
			Brush := Gdip_BrushCreateSolid( "0x66F0F0F0" ) , Gdip_FillPie( This.G , Brush , ( 146 - This.XOffset ) * This.Scale , ( 44 - This.YOffset ) * This.Scale , 81 * This.Scale , 59 * This.Scale , -90 , 90 ) , Gdip_DeleteBrush( Brush )
			Brush := Gdip_BrushCreateSolid( "0x66000000" ) , Gdip_FillPie( This.G , Brush , ( 146 - This.XOffset ) * This.Scale , ( 46 - This.YOffset ) * This.Scale , 81 * This.Scale , 59 * This.Scale , 90 , -90 ) , Gdip_DeleteBrush( Brush )
		}
		if( This.Pressed = 4 )
			Brush := Gdip_BrushCreateSolid( "0xFFF0F0F0" ) , Gdip_TextToGraphics( This.G , "4" , "s" 22 * This.Scale " Center vCenter  c" Brush " x" ( 179 - This.XOffset ) * This.Scale " y" ( 40 - This.YOffset ) * This.Scale , "Webdings" , 55 * This.Scale , 70 * This.Scale ) , Gdip_DeleteBrush( Brush )
		else
			Brush := Gdip_BrushCreateSolid( "0xFFF0F0F0" ) , Gdip_TextToGraphics( This.G , "4" , "s" 22 * This.Scale " Center vCenter  c" Brush " x" ( 179 - This.XOffset ) * This.Scale " y" ( 39 - This.YOffset ) * This.Scale , "Webdings" , 55 * This.Scale , 70 * This.Scale ) , Gdip_DeleteBrush( Brush )
		;inner circle  
		;***************************************************************************************************************************
		;***************************************************************************************************************************
		;~ Brush := Gdip_BrushCreateSolid( "0x2266AAFF" ) , Gdip_FillEllipse( This.G , Brush , ( 45 - This.XOffset ) * This.Scale , ( 26 - This.YOffset ) * This.Scale , 190 * This.Scale , 94 * This.Scale ) , Gdip_DeleteBrush( Brush )
	}
}
;**************************************************************************************************************************************************************************************************************
;**************************************************************************************************************************************************************************************************************
;**************************************************************************************************************************************************************************************************************
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
;**************************************
HSL_ToRGB(hue, sat:=1, lum:=0.5 ) {
; Function by [VxE]. See > http://www.wikipedia.org/wiki/HSV_color_space
; HSL to/from RGB conversion functions by [VxE]. Freely avalable @ http://www.autohotkey.com/community/viewtopic.php?f=2&t=88707
; Converts a hue/sat/lum into a 24-bit RGB color code. Input: 0 <= hue <= 360, 0 <= sat <= 1, 0 <= lum <= 1. 

   Static i24 := 0xFFFFFF, i40 := 0xFFFFFF0000, hx := "0123456789ABCDEF"

; Transform the decimal inputs into 24-bit integers. Integer arithmetic is nice..
   sat := ( sat * i24 ) & i24
   lum := ( lum * i24 ) & i24
   hue := ( hue * 0xB60B60 >> 8 ) & i24 ; conveniently, 360 * 0xB60B60 = 0xFFFFFF00

; Determine the chroma value and put it in the 'sat' var since the saturation value is not used after this.
   sat := lum + Round( sat * ( i24 - Abs( i24 - lum - lum ) ) / 0x1FFFFFE )

; Calculate the base values for red and blue (green's base value is the hue)
   red := hue < 0xAAAAAA ? hue + 0x555555 : hue - 0xAAAAAA
   blu := hue < 0x555555 ? hue + 0xAAAAAA : hue - 0x555555

; Run the blue value through the cases
   If ( blu < 0x2AAAAB )
      blu := sat + 2 * ( i24 - 6 * blu ) * ( lum - sat ) / i24 >> 16
   Else If ( blu < 0x800000 )
      blu := sat >> 16
   Else If ( blu < 0xAAAAAA )
      blu := sat + 2 * ( i24 - 6 * ( 0xAAAAAA - blu ) ) * ( lum - sat ) / i24 >> 16
   Else
      blu := 2 * lum - sat >> 16

; Run the red value through the cases
   If ( red < 0x2AAAAB )
      red := sat + 2 * ( i24 - 6 * red ) * ( lum - sat ) / i24 >> 16
   Else If ( red < 0x800000 )
      red := sat >> 16
   Else If ( red < 0xAAAAAA )
      red := sat + 2 * ( i24 - 6 * ( 0xAAAAAA - red ) ) * ( lum - sat ) / i24 >> 16
   Else
      red := 2 * lum - sat >> 16

; Run the green value through the cases
   If ( hue < 0x2AAAAB )
      hue := sat + 2 * ( i24 - 6 * hue ) * ( lum - sat ) / i24 >> 16
   Else If ( hue < 0x800000 )
      hue := sat >> 16
   Else If ( hue < 0xAAAAAA )
      hue := sat + 2 * ( i24 - 6 * ( 0xAAAAAA - hue ) ) * ( lum - sat ) / i24 >> 16
    Else
      hue := 2 * lum - sat >> 16

; Return the values in RGB as a hex integer
   Return "0x" SubStr( hx, ( red >> 4 ) + 1, 1 ) SubStr( hx, ( red & 15 ) + 1, 1 )
         . SubStr( hx, ( hue >> 4 ) + 1, 1 ) SubStr( hx, ( hue & 15 ) + 1, 1 )
         . SubStr( hx, ( blu >> 4 ) + 1, 1 ) SubStr( hx, ( blu & 15 ) + 1, 1 )
} ; END - HSL_ToRGB( hue, sat, lum )
;*****************************************************

***Edit***
Updated code with some new features.
Last edited by Hellbent on 25 Jun 2023, 22:53, edited 1 time in total.
User avatar
RDC
Posts: 112
Joined: 29 Jan 2023, 10:22

Re: Crop bitmap and export as Base64 string? ( Create Icons )

25 Jun 2023, 06:25

Wow, this looks really nice. Anyone know where to get the "My Altered GDIP lib" from?
I have Gdip.ahk and Gdip_All.ahk and neither seem to work with this. :(
User avatar
Hellbent
Posts: 2109
Joined: 23 Sep 2017, 13:34

Re: Crop bitmap and export as Base64 string? ( Create Icons )

25 Jun 2023, 11:19

RDC wrote:
25 Jun 2023, 06:25
Wow, this looks really nice. Anyone know where to get the "My Altered GDIP lib" from?
I have Gdip.ahk and Gdip_All.ahk and neither seem to work with this. :(
You should be able to just replace the gdip lib I am using with the path to your copy of the gdip lib. There is no difference besides the name I gave the file. Use your full path ( #Include C\\...\gdip.ahk ).
User avatar
Hellbent
Posts: 2109
Joined: 23 Sep 2017, 13:34

Re: Crop bitmap and export as Base64 string? ( Create Icons )

25 Jun 2023, 22:59

I made a few changes and added in a few new things.

You can do fine adjustments to the icon capture area by using the direction control at the top of the window.
The direction controls are context sensitive, hold "Shift" to move 10px at a time, and press "ctrl" to move 100 px at a time.
Icon Maker 3.gif
Icon Maker 3.gif (422.11 KiB) Viewed 2741 times
.


You can find the updated script here:

viewtopic.php?f=76&t=101960#p527284
User avatar
RDC
Posts: 112
Joined: 29 Jan 2023, 10:22

Re: Crop bitmap and export as Base64 string? ( Create Icons )

26 Jun 2023, 07:54

Hellbent wrote:
25 Jun 2023, 11:19
You should be able to just replace the gdip lib I am using with the path to your copy of the gdip lib. There is no difference besides the name I gave the file. Use your full path ( #Include C\\...\gdip.ahk ).

Thank you. I should have tried that first before asking. But at least now I get to see your new update. This thing is awesome!! I will be playing with it for at least a few hours now.
User avatar
Hellbent
Posts: 2109
Joined: 23 Sep 2017, 13:34

Re: Crop bitmap and export as Base64 string? ( Create Icons )

26 Jun 2023, 12:56

@RDC Here is a few examples of how to go about using the icons.

How to.

1. Using an overlay window ( user drawn window / layered window )

layered window class included.


.
Icon Maker 4.gif
Icon Maker 4.gif (415.99 KiB) Viewed 2691 times
.

Code: Select all

;****************************************************************************************************************************************************************************
#Include <My Altered GDIP lib> ;<<<<<<<<<<<<<<<<<<---------------------------     gdip.ahk ( Replace this with the path and name of your copy of GDIP lib for ahk v1.1 )
;~ #Include <PopUpWindow_V2> ; At the bottom of the script 
;****************************************************************************************************************************************************************************

#SingleInstance, Force

SetBatchLines, -1

;Load the GDI+ lib
Gdip_Startup()

;The Base 64 string for the icon image
MyIcon_B64 := "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"

;create a pBitmap from the Base 64 string.
MyIcon_Bitmap := B64ToPBitmap( MyIcon_B64 )

;Create a new layered window object.
Gui1 := New PopUpWindow( { AutoShow: 1 , X: 400 , Y: "Center" , W: 128 , H: 128 , Options: " +AlwaysOnTop -DPIScale +ToolWindow " } ) 

;Clear the graphics if anything was already drawn to them.
Gui1.ClearWindow()

;Paint the background of the layered windows graphics.
Gui1.PaintBackground( { Color: "0xaa000000" , X: 2 , Y: 2 , W: Gui1.W - 4 , H: Gui1.H - 4 , Round: 10 } , AutoUpdate := 0 )

;Draw the Icon pBitmap onto the layered windows graphics.
Gui1.DrawBitmap( MyIcon_Bitmap , { X: 32 , Y: 32 , W: 64 , H: 64 } , dispose := 0 , AutoUpdate := 0 )

;Update the window with the new graphics ( the background and icon )
Gui1.UpdateWindow()

return ;End of auto-execute section

;Exit routine
GuiClose:
GuiContextMenu:
*ESC::ExitApp

;Launch the layered window class helper tool.
RALT::PopUpWindow.Helper()

;Convert a Base 64 string into a pBitmap
B64ToPBitmap( Input ){
	local ptr , uptr , pBitmap , pStream , hData , pData , Dec , DecLen , B64
	VarSetCapacity( B64 , strlen( Input ) << !!A_IsUnicode )
	B64 := Input
	If !DllCall("Crypt32.dll\CryptStringToBinary" ( ( A_IsUnicode ) ? ( "W" ) : ( "A" ) ), Ptr := A_PtrSize ? "Ptr" : "UInt" , &B64, "UInt", 0, "UInt", 0x01, Ptr, 0, "UIntP", DecLen, Ptr, 0, Ptr, 0)
		Return False
	VarSetCapacity( Dec , DecLen , 0 )
	If !DllCall("Crypt32.dll\CryptStringToBinary" (A_IsUnicode ? "W" : "A"), Ptr, &B64, "UInt", 0, "UInt", 0x01, Ptr, &Dec, "UIntP", DecLen, Ptr, 0, Ptr, 0)
		Return False
	DllCall("Kernel32.dll\RtlMoveMemory", Ptr, pData := DllCall("Kernel32.dll\GlobalLock", Ptr, hData := DllCall( "Kernel32.dll\GlobalAlloc", "UInt", 2,  UPtr := A_PtrSize ? "UPtr" : "UInt" , DecLen, UPtr), UPtr) , Ptr, &Dec, UPtr, DecLen)
	DllCall("Kernel32.dll\GlobalUnlock", Ptr, hData)
	DllCall("Ole32.dll\CreateStreamOnHGlobal", Ptr, hData, "Int", True, Ptr "P", pStream)
	DllCall("Gdiplus.dll\GdipCreateBitmapFromStream",  Ptr, pStream, Ptr "P", pBitmap)
	return pBitmap
}




;This is the layered window class. 
;It can be saved in another file and used via #Include (As seen at the top of the script)
;
;
;####################################################################################################################################################################################
;####################################################################################################################################################################################
;####################################################################################################################################################################################
;####################################################################################################################################################################################
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 ]
		
	}
}



2. Drawing icons onto a normal gui

*Note* This method will require drawing a background under the icon if you plan on drawing it over and over again.
Use Gui, Add, Pic,, hBitmap: as another option.

.
Icon Maker 5.gif
Icon Maker 5.gif (761.72 KiB) Viewed 2691 times
.

Code: Select all

;****************************************************************************************************************************************************************************
#Include <My Altered GDIP lib> ;<<<<<<<<<<<<<<<<<<---------------------------     gdip.ahk ( Replace this with the path and name of your copy of GDIP lib for ahk v1.1 )
;****************************************************************************************************************************************************************************

#SingleInstance, Force
SetBatchLines, -1

;Load the GDI+ lib
Gdip_Startup()

;<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|
;<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|
;<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|

;The Base 64 string for the icon image
MyIcon_B64 := "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"

;create a pBitmap from the Base 64 string.
MyIcon_pBitmap := B64ToPBitmap( MyIcon_B64 )

;create a hBitmap from the icon pBitmap
MyIcon_hBitmap := Gdip_CreateHBITMAPFromBitmap( MyIcon_pBitmap )

;Dispose of the icon pBitmap to free memory.
Gdip_DisposeImage( MyIcon_pBitmap )

;<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|
;<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|
;<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|

;Create a new gui
Gui, New, +AlwaysOnTop +HwndGui1Hwnd

Gui, Margin, 50 , 50

;Add your other controls.
;
;

;Add a picture control to the gui and add the option "0xE" so that it can accept bitmaps to be drawn on it.
Gui, Add, Picture, xm ym w64 h64 0xE hwndIconPicHwnd

;Draw the icon hBitmap onto the picture control.
SetImage( IconPicHwnd , MyIcon_hBitmap )

;Add your other controls.
;
;

;show the window. ( add / change options as needed )
Gui, Show, x400

;<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|
;<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|
;<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|

return ;End of auto-execute section

;Exit routine
GuiClose:
GuiContextMenu:
*ESC::ExitApp

;Convert a Base 64 string into a pBitmap
B64ToPBitmap( Input ){
	local ptr , uptr , pBitmap , pStream , hData , pData , Dec , DecLen , B64
	VarSetCapacity( B64 , strlen( Input ) << !!A_IsUnicode )
	B64 := Input
	If !DllCall("Crypt32.dll\CryptStringToBinary" ( ( A_IsUnicode ) ? ( "W" ) : ( "A" ) ), Ptr := A_PtrSize ? "Ptr" : "UInt" , &B64, "UInt", 0, "UInt", 0x01, Ptr, 0, "UIntP", DecLen, Ptr, 0, Ptr, 0)
		Return False
	VarSetCapacity( Dec , DecLen , 0 )
	If !DllCall("Crypt32.dll\CryptStringToBinary" (A_IsUnicode ? "W" : "A"), Ptr, &B64, "UInt", 0, "UInt", 0x01, Ptr, &Dec, "UIntP", DecLen, Ptr, 0, Ptr, 0)
		Return False
	DllCall("Kernel32.dll\RtlMoveMemory", Ptr, pData := DllCall("Kernel32.dll\GlobalLock", Ptr, hData := DllCall( "Kernel32.dll\GlobalAlloc", "UInt", 2,  UPtr := A_PtrSize ? "UPtr" : "UInt" , DecLen, UPtr), UPtr) , Ptr, &Dec, UPtr, DecLen)
	DllCall("Kernel32.dll\GlobalUnlock", Ptr, hData)
	DllCall("Ole32.dll\CreateStreamOnHGlobal", Ptr, hData, "Int", True, Ptr "P", pStream)
	DllCall("Gdiplus.dll\GdipCreateBitmapFromStream",  Ptr, pStream, Ptr "P", pBitmap)
	return pBitmap
}



3. Changing the scripts default icons

.
20230626133735.png
20230626133735.png (28.04 KiB) Viewed 2691 times
.

Code: Select all

;****************************************************************************************************************************************************************************
#Include <My Altered GDIP lib> ;<<<<<<<<<<<<<<<<<<---------------------------     gdip.ahk ( Replace this with the path and name of your copy of GDIP lib for ahk v1.1 )
;****************************************************************************************************************************************************************************

#SingleInstance, Force
SetBatchLines, -1

;Load the GDI+ lib
Gdip_Startup()

;<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|
;<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|
;<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|

;The Base 64 string for the icon image
MyIcon_B64 := "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"

;create a pBitmap from the Base 64 string.
MyIcon_pBitmap := B64ToPBitmap( MyIcon_B64 )

;create a hBitmap from the icon pBitmap
MyIcon_hIcon := Gdip_CreateHICONFromBitmap( MyIcon_pBitmap )

;Dispose of the icon pBitmap to free memory.
Gdip_DisposeImage( MyIcon_pBitmap )

;Set the icon
Menu, Tray, Icon, HICON:%MyIcon_hIcon%

;<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|
;<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|
;<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|

;Demo gui ( shows icon on the gui and in the taskbar )
Gui, Show, w300 h100

;<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|
;<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|
;<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|<<<---#####--->>>|

return ;End of auto-execute section

;Exit routine
GuiClose:
GuiContextMenu:
*ESC::ExitApp

;Convert a Base 64 string into a pBitmap
B64ToPBitmap( Input ){
	local ptr , uptr , pBitmap , pStream , hData , pData , Dec , DecLen , B64
	VarSetCapacity( B64 , strlen( Input ) << !!A_IsUnicode )
	B64 := Input
	If !DllCall("Crypt32.dll\CryptStringToBinary" ( ( A_IsUnicode ) ? ( "W" ) : ( "A" ) ), Ptr := A_PtrSize ? "Ptr" : "UInt" , &B64, "UInt", 0, "UInt", 0x01, Ptr, 0, "UIntP", DecLen, Ptr, 0, Ptr, 0)
		Return False
	VarSetCapacity( Dec , DecLen , 0 )
	If !DllCall("Crypt32.dll\CryptStringToBinary" (A_IsUnicode ? "W" : "A"), Ptr, &B64, "UInt", 0, "UInt", 0x01, Ptr, &Dec, "UIntP", DecLen, Ptr, 0, Ptr, 0)
		Return False
	DllCall("Kernel32.dll\RtlMoveMemory", Ptr, pData := DllCall("Kernel32.dll\GlobalLock", Ptr, hData := DllCall( "Kernel32.dll\GlobalAlloc", "UInt", 2,  UPtr := A_PtrSize ? "UPtr" : "UInt" , DecLen, UPtr), UPtr) , Ptr, &Dec, UPtr, DecLen)
	DllCall("Kernel32.dll\GlobalUnlock", Ptr, hData)
	DllCall("Ole32.dll\CreateStreamOnHGlobal", Ptr, hData, "Int", True, Ptr "P", pStream)
	DllCall("Gdiplus.dll\GdipCreateBitmapFromStream",  Ptr, pStream, Ptr "P", pBitmap)
	return pBitmap
}


Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: mikeyww and 222 guests