Gdip Gui Help!!

Ask gaming related questions (AHK v1.1 and older)
henriquehassi
Posts: 24
Joined: 29 Jul 2020, 17:11

Re: Gdip Gui Help!!

23 Jan 2022, 11:52

@Hellbent
U can help me one more time ? :shock:
I have two images and i want use it to buttons, then when mouse hover the image change the image.
i'm Using

Code: Select all

DiscordLogo := GdipCreateFromBase64(Discord, 2) ;; Transformar 
HDiscordLogo := GdipCreateFromBase64(HDiscord, 2) ;; Transformar
henriquehassi
Posts: 24
Joined: 29 Jul 2020, 17:11

Re: Gdip Gui Help!!

23 Jan 2022, 11:54

i have this module but i don't can use

Code: Select all

class IMGButton {
    __New(obj,Options,Label,Window,vGlobal) {
        This.W := obj.W
        This.H := obj.H
        This.D_Bitmap := Discord
        This.H_Bitmap := HDiscord
        This.Func := obj.Func
        This.Label := Label
        This.Window := Window
        This.Mouse := "Hand"
        This.Hover := 1
        Gui, % Window ": Add" , Picture , % Options " w" This.W " h" This.H " 0xE hwndHwnd", % Label
        This.Hwnd := Hwnd
        %vGlobal%["BTHwnd"]["H" Hwnd] := Label
        BD := THIS.Pressed.BIND( THIS )
        GUICONTROL +G , % Hwnd , % BD
        This.Draw_Default()
    }
    Pressed() {
        if (!This.Draw_Pressed())
            return
        If (This.Func){
            FucRun := This.Func
            %FucRun%(This.Hwnd,A_GuiControl)
        }
    }
    Draw_Default() {
        SetImage( This.Hwnd , This.D_Bitmap )
    }
    Draw_Hover() {
        SetImage( This.Hwnd , This.H_Bitmap )
    }
    Draw_Pressed() {
        SetImage( This.Hwnd , This.D_Bitmap )
        A_Args.MoveTest := 1
        While( GetKeyState( "LButton" ) )
            sleep , 10
        A_Args.MoveTest := 0
        MouseGetPos,,,, ctrl , 2
        if( This.Hwnd != ctrl ) {
            return False
        } else {
            SetImage( This.Hwnd , This.H_Bitmap )
            return True
        }
    }
}
User avatar
Hellbent
Posts: 2109
Joined: 23 Sep 2017, 13:34

Re: Gdip Gui Help!!

23 Jan 2022, 15:05

henriquehassi wrote:
23 Jan 2022, 11:52
@Hellbent
U can help me one more time ? :shock:
I have two images and i want use it to buttons, then when mouse hover the image change the image.
i'm Using
DiscordLogo := GdipCreateFromBase64(Discord, 2) ;; Transformar
HDiscordLogo := GdipCreateFromBase64(HDiscord, 2) ;; Transformar
Is this what you are looking for?

viewtopic.php?f=76&t=94703&p=420573#p420555

Image
henriquehassi
Posts: 24
Joined: 29 Jul 2020, 17:11

Re: Gdip Gui Help!!

24 Jan 2022, 09:08

@Hellbent
Work!!!
thank u very much, u are the best :)
Galaxis
Posts: 73
Joined: 04 Feb 2016, 20:09

Re: Gdip Gui Help!!

10 Apr 2022, 09:16

@Hellbent
I want to make a huge glossy round button. It changes between the PLAY/PAUSE symbols when pressed. I think it'd be stylish for my music themed GUI I'm trying to create.
Don't think I've ever seen any round button examples though.

[Imgur](https://i.imgur.com/p3o5Gwc.png)
User avatar
Hellbent
Posts: 2109
Joined: 23 Sep 2017, 13:34

Re: Gdip Gui Help!!

11 Apr 2022, 19:04

Galaxis wrote:
10 Apr 2022, 09:16
@Hellbent
I want to make a huge glossy round button. It changes between the PLAY/PAUSE symbols when pressed. I think it'd be stylish for my music themed GUI I'm trying to create.
Don't think I've ever seen any round button examples though.

[Imgur](https://i.imgur.com/p3o5Gwc.png)
There are a number of ways that you can go about making buttons. The simplest way is to just use a picture control.
If you are only making one of each type of button you can just work on the image in an editor and then use the same kind of system as that PDF example if you want to use multiple states ( rest , hover , click ).

If you have a bunch of buttons that you want to add a gloss effect to, you can create a transparent gloss image and combine it on top of your button by creating a bitmap of your button, a bitmap of your gloss effect, and a new blank bitmap that you can combine the two images to. You just "Gdip_DrawImage" both of your graphics to the new bitmap and then draw that to your gui. You can also create different variants of your gloss layer and depending on the state of things you use simple logic control to tell it which gloss layer it should use.

The gloss layer is the type of thing that I would use my bitmap maker to create. Just go in and create a few overlapping circles or w/e and then I can use the code from that and combine it on top of the buttons static image.


On the other hand you can go with a layered window and have a truly circle button. See here for some insight.
viewtopic.php?f=76&t=99973

If you are looking for not only the look of a circle but also only being able to interact with the button when you click in the circle and not the rectangle it actually is. You can do that by adding a bit of logic to the top of your buttons routine. With this extra bit of logic you test the distance from where you clicked and the center of the button. If outside the circle you just return.

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

Re: Gdip Gui Help!!

11 Apr 2022, 20:38

***Requires Windows 8 or higher***
This is a class I very recently wrote to do something similar.
The button class doesn't have a control system though because I am writing a more integrated system for it so this isn't plug and play ready.
In this case, each button gives you an object and the hwnd of the control is one of it's keys. With the hwnd you can do all sorts of things, an important one is the ability to bind the button to a function / label / class method. I don't want to go too far down the rabbit hole here so I'll just show how you can bind the buttons in this example to a routine.

Code: Select all

Bind := Func( "Play" ).Bind( someDataObject )
GuiControl, % PlayButton.Window.Hwnd ":+G" , % PlayButton.Control.Hwnd , % Bind

Play( someDataObject ){
	Msgbox, You pressed the button
}
Animation.gif
Animation.gif (240.35 KiB) Viewed 839 times

Requires these classes AND THE GDI+ LIB FOR AHK!!!

You can just paste them to the bottom of the example below, no need save them in separate files.

Bitmap class.

Code: Select all

;####################################################################################################################################################################################
;####################################################################################################################################################################################
;#########################################################################          Bitmap Class           ##########################################################################
;####################################################################################################################################################################################
;####################################################################################################################################################################################
class Bitmap	{
	;Written By: Hellbent
	;Date: Apr 11th, 2022
	;Last Edit: Apr 11th, 2022
	;Version: 1.0
	;Requires: GDI+ Lib for AHK
	;Type: Wrapper Class
	;Purpose: Returns either a object with a pBitmap and related proporties { W: , H: , pBitmap: , G: , SmoothingMode: , InterpolationMode: } ( 6 proporties)
	;#############################################
	;>>>>>     Create A New Blank pBitmap Object 
	;#############################################
	NewpBitmap( w := 100 , h := 100 , smoothingMode := 2 , interpolationMode := 7 ){
		local obj := {}
		obj.pBitmap := Gdip_CreateBitmap( obj.W := w , obj.H := h  )
		obj.G := Gdip_GraphicsFromImage( obj.pBitmap )
		Gdip_SetSmoothingMode( obj.G , obj.SmoothingMode := smoothing )
		Gdip_SetInterpolationMode( obj.G , obj.InterpolationMode := InterpolationMode )
		return obj 
	}
	;#############################################
	;>>>>>     Create A New Array Of pBitmap Objects From A Base64 String ( Cuts Up A Strip )
	;#############################################
	BitmapArrayFromBase64Strip( B64String , StringWidth , StringHeight , SplitSize , Direction := "Width" , smoothingMode := 2 , interpolationMode := 7 , offset := 2 ){
		local arr := [] , iconStrip , LoopCount , x , y
		pBit := Bitmap.B64ToPBitmap( B64String )
		if( Direction = "Width" ){
			LoopCount := StringWidth / SplitSize
			x := 0
			Loop, % LoopCount	{
				arr[ A_Index ] := {}
				arr[ A_Index ].pBitmap := Gdip_CreateBitmap( arr[ A_Index ].W := SplitSize , arr[ A_Index ].H := SplitSize  )
				arr[ A_Index ].G := Gdip_GraphicsFromImage( arr[ A_Index ].pBitmap )
				Gdip_SetSmoothingMode( arr[ A_Index ].G , arr[ A_Index ].SmoothingMode := smoothing )
				Gdip_SetInterpolationMode( arr[ A_Index ].G , arr[ A_Index ].InterpolationMode := InterpolationMode )
				Bitmap.DrawBitmap( pBit , arr[ A_Index ].G , { X: 0 , Y: 0 , W: SplitSize , H: SplitSize , X2: x + offset , Y2: 0 , W2: SplitSize , H2: SplitSize } )
				x += SplitSize
			}
			return arr
		}
	}
	;#############################################
	;>>>>>     Draw A pBitmap Onto A Graphics Layer
	;#############################################
	DrawBitmap( pBitmap , Graphics , pos := "" ){
		local x , y 
		if( IsObject( pos ) ){
			x := ( pos.X != "" ) ? ( pos.X ) : ( 0 )
			y := ( pos.Y != "" ) ? ( pos.Y ) : ( 0 )
			w := ( pos.W != "" ) ? ( pos.W ) : ( Bitmap._GetWidth( pBitmap ) )
			h := ( pos.H != "" ) ? ( pos.H ) : ( Bitmap._GetHeight( pBitmap ) )
			sx := ( pos.X2 != "" ) ? ( pos.X2 ) : ( 0 )
			sy := ( pos.Y2 != "" ) ? ( pos.Y2 ) : ( 0 )
			sw := ( pos.W2 != "" ) ? ( pos.W2 ) : ( Bitmap._GetWidth( pBitmap ) )
			sh := ( pos.H2 != "" ) ? ( pos.H2 ) : ( Bitmap._GetHeight( pBitmap ) )
			Gdip_DrawImage( Graphics , pBitmap , x , y , w , h , sx , sy , sw , sh )
		}
	}
	;#############################################
	;>>>>>     Create A New pBitmap Object From A Base64 String
	;#############################################
	BitmapFromBase64( string , smoothingMode := 2 , interpolationMode := 7 ){
		local obj := {}
		obj.pBitmap := Bitmap.B64ToPBitmap( String )
		obj.W := Bitmap._GetWidth( obj.pBitmap )
		obj.H := Bitmap._GetHeight( obj.pBitmap )
		obj.G := Gdip_GraphicsFromImage( obj.pBitmap )
		Gdip_SetSmoothingMode( obj.G , obj.SmoothingMode := smoothing )
		Gdip_SetInterpolationMode( obj.G , obj.InterpolationMode := InterpolationMode )
		return obj
	}
	;#############################################
	;>>>>>     Get The Width Of A pBitmap
	;#############################################
	_GetWidth( pBitmap ){
		return Gdip_GetImageWidth( pBitmap )
	}
	;#############################################
	;>>>>>     Get The Height Of A pBitmap
	;#############################################
	_GetHeight( pBitmap ){
		return Gdip_GetImageHeight( pBitmap )
	}
	;#############################################
	;>>>>>     Convert A Base64 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
	}
}
Icon Buttons Class

Code: Select all

;####################################################################################################################################################################################
;####################################################################################################################################################################################
;#########################################################          #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 := 1
		;*****************************
		;>>>>>     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
		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...          ######################################################
;####################################################################################################################################################################################
;####################################################################################################################################################################################
Layered Window Class ( PopUpWindow )

Code: Select all

;####################################################################################################################################################################################
;####################################################################################################################################################################################
;####################################################################################################################################################################################
;####################################################################################################################################################################################
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 ){
		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 ]
		
	}
}
Examples:

Code: Select all

;****************************************************************************************************************************************************************************
#Include <My Altered GDIP lib> ;<<<<<<<<<<<<<<<<<<---------------------------     gdip.ahk
;#Include <PopUpWindow_V2> 
;#Include <Bitmap Class v1.0>
;#Include <Icon Buttons Class v1.0>
;****************************************************************************************************************************************************************************
#SingleInstance, Force
SetBatchLines, -1
Gdip_Startup()

;Parent Gui. ( Layered Window Requires Windows 8+ )
Gui1 := New PopUpWindow( { AutoShow: 1 , X: 200 , Y: "Center" , W: 390 , H: 220 , Options: " -DPIScale +AlwaysOnTop " } )
Gui1.PaintBackground( { Color: "0x66000000" , X: 2 , Y: 2 , W: Gui1.W - 4 , H: Gui1.H - 4 , Round: 10 } , 1 )

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

;#############################################
;>>>>>     New Icon Button Prototype
;#############################################
/*
;~ Bob := New IconButtons( { Alpha: 		200 
						;~ , PulseLength: 	5 
						;~ , PulseRate: 	1 
						;~ , Animate:		"Pulse" 
						;~ , X: 			125 
						;~ , Y: 			150 
						;~ , W: 			Icon1.W 
						;~ , H: 			Icon1.H 
						;~ , pBitmap: 		Icon1.pBitmap
						;~ , Parent: 		Gui1.Hwnd } )
*/
;#############################################
;#############################################
;*******************************************************************************************************************************************************************************************************
;*******************************************************************************************************************************************************************************************************

;Base64 string for the play button image
PlayButton120x120 := "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"

;Convert the string to a pBitmap that can get drawn to a layered window.
PlayButtonBitmap := Bitmap.BitmapFromBase64( PlayButton120x120 )

;Setup a new button object ( See Prototype )
PlayButton := 	{ X: 50  
				, Y: 50 
				, W: 120 
				, H: 120 
				, pBitmap: PlayButtonBitmap.pBitmap
				, Parent: Gui1.Hwnd 
				, Animate: "Pulse" }

;Create a New Icon Button					
PlayButton := New IconButtons( PlayButton )

;*******************************************************************************************************************************************************************************************************
;*******************************************************************************************************************************************************************************************************
;#############################################
;#############################################
;Base64 string for the pause button image
PauseButton120x120 := "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"
;Convert the string to a pBitmap that can get drawn to a layered window.
PauseButtonBitmap := Bitmap.BitmapFromBase64( PauseButton120x120 )
;Setup a new button object ( See Prototype )
PauseButton := 	{ X: 220  
				, Y: 50 
				, W: 120 
				, H: 120 
				, pBitmap: PauseButtonBitmap.pBitmap
				, Parent: Gui1.Hwnd 
				, Animate: "Pulse" }
;Create a New Icon Button					
PauseButton := New IconButtons( PauseButton )
;*******************************************************************************************************************************************************************************************************
;*******************************************************************************************************************************************************************************************************
;<<<<<--  Gui example
index := 0 , size := 80
Gui, 1:+AlwaysOnTop +HwndGuiHwnd
Gui, 1:Color, 72767a
Gui, 1:Margin, % mx := 10 , % my := 10 
Gui, 1:Add, ListBox, xm ym w250 r5 , % "Item: " ++Index "|" "Item: " ++Index "|" "Item: " ++Index "|" "Item: " ++Index "|" "Item: " ++Index "|" "Item: " ++Index "|" "Item: " ++Index "|" "Item: " ++Index "|" "Item: " ++Index "|" "Item: " ++Index "|" "Item: " ++Index "|" "Item: " ++Index "|" "Item: " ++Index "|" "Item: " ++Index "|" "Item: " ++Index "|" 
Gui, 1:Add, Button, xm y+20 w150, % "Do Nothing"
GuiPlayButton := New IconButtons( { X: 250 + 2 * mx , Y: my , W: size , H: size , pBitmap: PlayButtonBitmap.pBitmap , Parent: GuiHwnd , Animate: "Pulse" } )
GuiPauseButton := New IconButtons( { X: 250 + size + 3 * mx  , Y: my , W: size , H: size , pBitmap: PauseButtonBitmap.pBitmap , Parent: GuiHwnd , Animate: "Pulse" } )
Gui, 1:Show, % "w" 250 + 2 * size + 4 * mx
;*******************************************************************************************************************************************************************************************************
;*******************************************************************************************************************************************************************************************************
return
GuiClose:
GuiContextMenu:
*ESC::ExitApp

RALT::PopUpWindow.Helper()

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



Return to “Gaming Help (v1)”

Who is online

Users browsing this forum: Google [Bot] and 30 guests