Gadget Frame3D

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
MLD
Messages : 1124
Inscription : jeu. 05/févr./2009 17:58
Localisation : Bretagne

Re: Gadget Frame3D

Message par MLD »

Non pas de skin mais, mais un vrai gadget, qui je le répète permet de changer la couleur du titre, la couleur de fond du titre, la couleur des traits (du cadre),le déplacement du titre, le remplissage ou non du cadre. Un cadre avec bord arrondis ou pas,L'inclusion dans le cadre de n'importe quel autre gadget.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Gadget Frame3D

Message par Backup »

Je ne sait pas comment chez MS il ont fait pour le gadget en VB6, mais personne n'a encore trouvé la solution en PB.
Ce que tu décris là , tu peux le faire toi même ;)
avec ma méthode ..

d'ailleurs en VBx il n'y a pas de "Gadget" au sens Purebasic ...
ce langage utilise des objets "Control" (OCX ) (une librairie quoi )

donc ils ont refait un "control" (gadget) a base de lignes

a mon avis, tu ne trouvera pas d'autres solution car Window ne propose pas de Container coloré !
on peut par l'Api bidouiller le fond du titre , voir la couleur de son text , mais pas les lignes

a moins de faire comme je le fait ( en redessinant par dessus en temp reel)

tu peux aussi utiliser la Librairie COMatePLUS qui utilise les OCX en recupérant l'objet (le control) "Container" de VB
mais faudra le fournir avec le Prg ... ;)
Avatar de l’utilisateur
GallyHC
Messages : 1708
Inscription : lun. 17/déc./2007 12:44

Re: Gadget Frame3D

Message par GallyHC »

Bonjour,
a mon avis, tu ne trouvera pas d'autres solution car Window ne propose pas de Container coloré !
on peut par l'Api bidouiller le fond du titre , voir la couleur de son text , mais pas les lignes
En fait je ne suis pas complètement d'accord avec toi, car en VB6 tu as deux types d'objets permettant du graphique.

1. Les objets Image : un peu comme PB en fait.
2. Les objets Picturebox : un peu aussi comme PB, mais par contre il est aussi container.

J'espère avoir été clair dans mon explication.

Cordialement,
GallyHC
Configuration : Tower: Windows 10 (Processeur: i7 "x64") (Mémoire: 16Go) (GeForce GTX 760 - 2Go) - PureBasic 5.72 (x86 et x64)
Avatar de l’utilisateur
MLD
Messages : 1124
Inscription : jeu. 05/févr./2009 17:58
Localisation : Bretagne

Re: Gadget Frame3D

Message par MLD »

En fait j'ai trouvé les API pour tout sauf la coloration des traits du cadre.
Même si en VB6 c'est un OCX. c'est OCX a bien été programé, la couleur des traits est au choix de l'utilisateur. Donc c'est possible comment ??. Je me méfis de VB6 car il utilisent beaucoup de fonctions non documentés.Il ne faut pas oublier que comme Windows c'est made in M.S.
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Re: Gadget Frame3D

Message par nico »

Je vois pas où est le problème, les API pour dessiner des rectangles et des rectangles arrondis sont connus: c'est Rectangle_(...) et RoundRect_(...)

Voici un exemple avec RoundRect:
Image
Avatar de l’utilisateur
MLD
Messages : 1124
Inscription : jeu. 05/févr./2009 17:58
Localisation : Bretagne

Re: Gadget Frame3D

Message par MLD »

@ nico bonjour

Il y a déja bien longtemp j'avais tenté quelque chose avec RoundRectangle, mais je ne me rappel
plus quoi, mais quelque chose clochait. :?
Tu n'aurai pas un petit bout de code que je teste tes exemples :lol:
Merci
Mesa
Messages : 1126
Inscription : mer. 14/sept./2011 16:59

Re: Gadget Frame3D

Message par Mesa »

On dirait que ça tourne en rond...

Sous Linux ou OSX, je ne sais pas mais sous Windows, PB utilise la WINAPI et dans cette API, il n'est pas possible de changer simplement la couleur des bordures d'un frame3D (GroupBox sous WINAPI ?), ça n'a pas été prévu. Voir le dernier post de cette page http://social.msdn.microsoft.com/Forums ... 5cbfbd00d4
Pour y arriver, il faut overrider l'évènement Paint. Il faudra utiliser une fonction callback.

Sous VB il faut créer une nouvelle classe, ce que ne peut pas faire PB.

Code : Tout sélectionner

============CODE VB avec override de OnPaint==============

Public Class myGroupBox
    Inherits GroupBox
    
    Private borderColor As Color
    
    Public Sub New()
        MyBase.New
        Me.borderColor = Color.Black
    End Sub
    
    Public Property BorderColor As Color
        Get
            Return Me.borderColor
        End Get
        Set
            Me.borderColor = value
        End Set
    End Property
    
    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
        Dim tSize As Size = TextRenderer.MeasureText(Me.Text, Me.Font)
        Dim borderRect As Rectangle = e.ClipRectangle
        borderRect.Y = (borderRect.Y  _
                    + (tSize.Height / 2))
        borderRect.Height = (borderRect.Height  _
                    - (tSize.Height / 2))
        ControlPaint.DrawBorder(e.Graphics, borderRect, Me.borderColor, ButtonBorderStyle.Solid)
        Dim textRect As Rectangle = e.ClipRectangle
        textRect.X = (textRect.X + 6)
        textRect.Width = tSize.Width
        textRect.Height = tSize.Height
        e.Graphics.FillRectangle(New SolidBrush(Me.BackColor), textRect)
        e.Graphics.DrawString(Me.Text, Me.Font, New SolidBrush(Me.ForeColor), textRect)
    End Sub
End Class

Sachant qu'un frame3D SANS OPTION est considéré comme un bouton, peut-être qu'il est possible de s'en sortir avec ce code:
http://www.purearea.net/pb/CodeArchiv_v ... lements.pb en l'adaptant pour le frame3D mais ça sera compliqué !

Si les versions récentes de VB peuvent colorer la bordure d'un GroupBox, c'est parce qu'elles utilisent une autre API, le framework .NET, voir http://msdn.microsoft.com/fr-fr/library ... 80%29.aspx
dans ce cas, on peut tout faire même recueillir un évènement onclick.


Franchement, il est plus simple de créer son propre Frame3D, par exemple avec le code du Soldat Inconnu
http://forums.purebasic.fr/french/viewt ... f=6&t=9791
L'utilisation d'un Canvas pourrait être une bonne idée.

Mesa.
Avatar de l’utilisateur
graph100
Messages : 1318
Inscription : sam. 21/mai/2005 17:50

Re: Gadget Frame3D

Message par graph100 »

Attendez un moment, que je mette en forme le code sur lequel je bosse :mrgreen: :mrgreen: :mrgreen: :mrgreen:

J'ai trouvé un truc assez énorme !!! Pour ne pas dire extra giga, super chouette :lol: Excusez, pardonnez mon enthousiasme, mais là, franchement, en terme de skin de gadget, et d’événement de gadget, c'est un truc juste trop pratique !...

Je remercie à l'avance Kwai chang caine pour avoir poster un code de Srod sur le fofo fr :mrgreen:
LSI pour sa super vieille, mais très efficace procedure Skinwindow() (la 1ere du nom)
et Fred, pour son CanvasGadget() si pratique, mais qui viens encore de prendre du galon cette fois :mrgreen:

J'espère ne pas m'être excité pour rien :oops:
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))
Avatar de l’utilisateur
Ar-S
Messages : 9540
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Gadget Frame3D

Message par Ar-S »

Petit coquin qui nous fait baver :mrgreen:
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
graph100
Messages : 1318
Inscription : sam. 21/mai/2005 17:50

Re: Gadget Frame3D

Message par graph100 »

:oops: Busted ! Mais c'est parce qu'une fois que j'ai réussi à faire ce que je voulais, j'étais un peu excité :roll:

Maintenant voila le code, qu'en pensez-vous ?!

Code : Tout sélectionner

;{######################################
; Programme : 		CustomFrame3D
#VERSION = "1.00"
;	
; Description : 		- Ajoute un nouveau "gadget" personnalisé, imitant le Frame3DGadget(), avec le choix de la couleur / rayon des angles / largeur de ligne en plus
;									
; Détails & TODOs réalisés:
;										- Création d'un cadre surmonté d'un texte, caractéristiques personnalisables.
;									
;									
; Auteur : 					- graph100
; 
; Remerciements : 	- Kwai chang caine	-> Pour avoir posté un code de Srod sur le fofo FR
;										- Srod 							-> Code avec des bouton rond, qui m'a orienté sur la solution utilisée dans ce code
;										- LSI								-> Pour sa procedure SkinWindow() adaptée en ShapeObjectFromBitmap()
;										- Fred							-> Parce qu'on ne le remercie jamais assez :)
;}######################################



;{ Procedure/structure pour gérer le CustomFram3D

ProcedureDLL.l ShapeObjectFromBitmap(ObjectID, ImageID, Couleur) ; transforme la fenetre avec la forme de l'image avec comme couleur transparente couleur (appelée SkinWinfow() avant)
	Protected bmi.BITMAPINFO, bm.BITMAP
	Protected hdc, Region_Totale, Region_Temp, *Mem, Hauteur, Largeur, Y1, X1, X2, *Point
	
	GetObject_(ImageID, SizeOf(BITMAP), @bm.BITMAP) 
	
	bmi\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER) 
	bmi\bmiHeader\biWidth = bm\bmWidth 
	bmi\bmiHeader\biHeight = bm\bmHeight 
	bmi\bmiHeader\biPlanes = 1 
	bmi\bmiHeader\biBitCount = 32 
	bmi\bmiHeader\biCompression = #BI_RGB 
	
	Couleur = ((Couleur & $0000FF) << 16) | (Couleur & $00FF00) | ((Couleur & $FF0000) >> 16) 
	
	Region_Totale = CreateRectRgn_(0, 0, bm\bmWidth, bm\bmHeight) 
	
	*Mem = AllocateMemory(bm\bmWidth * bm\bmHeight * 4) 
	If *Mem 
		
		hdc = CreateCompatibleDC_(GetDC_(ImageID)) 
		If hdc 
			GetDIBits_(hdc, ImageID, 0, bm\bmHeight, *Mem, @bmi, #DIB_RGB_COLORS) ; on envoie la liste dans l'image 
			DeleteDC_(hdc) 
		EndIf 
		
		; On convertit la liste dans le bon format
		Largeur = bm\bmWidth - 1 
		Hauteur = bm\bmHeight - 1 
		*Point = *Mem 
		For Y1 = 0 To Hauteur 
			For X1 = 0 To Largeur 
				If PeekL(*Point) = Couleur 
					X2 = X1 
					While X2 < Largeur And PeekL(*Point + 4) = Couleur 
						X2 + 1 
						*Point + 4 
					Wend 
					Region_Temp = CreateRectRgn_(X1, Hauteur - Y1, X2 + 1, Hauteur - Y1 + 1) ; On retire le point de la region 
					CombineRgn_(Region_Totale, Region_Totale, Region_Temp, #RGN_DIFF) 
					DeleteObject_(Region_Temp) 
					X1 = X2 
				EndIf 
				*Point + 4 
			Next 
		Next 
		
		FreeMemory(*Mem) 
	EndIf 
	
	SetWindowRgn_(ObjectID, Region_Totale, 1) ; On applique la region 
	DeleteObject_(Region_Totale) ; On efface la region 
EndProcedure

Structure ICG_CustomFrame3D
	Color.l
	Title.s
	Font.l
	TextBackColor.l
	
	rayon.l
	largeur.l
	
	zz_Is_FontDefault.b
EndStructure

; Pour redessiner / changer le titre, la couleur...
Procedure RedrawFrame3D(Gadget.l, new_color.l = #PB_Ignore, new_title.s = #CR$, new_rayon = #PB_Ignore, new_largeur = #PB_Ignore, new_Text_BackColor.l = #PB_Ignore, new_x = #PB_Ignore, new_y = #PB_Ignore, new_width = #PB_Ignore, new_height = #PB_Ignore, new_Font.l = #PB_Ignore)
	#PB_CustomFrame3D_Round = 1
	Protected *mem.ICG_CustomFrame3D = GetGadgetData(Gadget)
	Protected color_trans, th, tw
	
	;{ changement des paramètres
	If new_color <> #PB_Ignore
		*mem\Color = new_color
	EndIf
	
	If new_Text_BackColor <> #PB_Ignore
		*mem\TextBackColor = new_Text_BackColor
	EndIf
	
	If new_rayon <> #PB_Ignore
		*mem\rayon = new_rayon
	EndIf
	
	If new_largeur <> #PB_Ignore
		*mem\largeur = new_largeur
	EndIf
	
	If new_Font <> #PB_Ignore
		If *mem\zz_Is_FontDefault And IsFont(*mem\Font)
			FreeFont(*mem\Font)
			*mem\zz_Is_FontDefault = #False
		EndIf
		
		*mem\Font = new_Font
	EndIf
	
	If new_title <> #CR$
		*mem\Title = new_title
	EndIf
	
	If new_x <> #PB_Ignore Or new_y <> #PB_Ignore Or new_height <> #PB_Ignore Or new_width <> #PB_Ignore
		ResizeGadget(Gadget, new_x, new_y, new_width, new_height)
	EndIf
	
	Protected w = GadgetWidth(Gadget), h = GadgetHeight(Gadget)
	Protected img = CreateImage(#PB_Any, w, h)
	
	If *mem\Font = #PB_Ignore Or IsFont(*mem\Font) = 0
		*mem\Font = LoadFont(#PB_Any, "Segoe UI", 8.5)
		*mem\zz_Is_FontDefault = #True
	EndIf
	;}
	
	; on calcule une autre couleur toujours valide pour la couleur transparente
	color_trans = RGB(Mod(Red(*mem\Color) + 50, 256), Mod(Green(*mem\Color) + 50, 256), Mod(Blue(*mem\Color) + 50, 256))
	
	If StartDrawing(ImageOutput(img))
		Box(0, 0, w, h, color_trans)
		
		If *mem\Title <> ""
			th = TextHeight(" " + *mem\Title) / 2 - 2
			tw = TextWidth(" " + *mem\Title + " ")
		EndIf
		
		RoundBox(0, th, w, h - th, *mem\rayon, *mem\rayon, *mem\Color)
		RoundBox(*mem\largeur, th + *mem\largeur, w - 2 * *mem\largeur, h - th - 2 * *mem\largeur, *mem\rayon, *mem\rayon, color_trans)
		
		If *mem\Title <> ""
			DrawingFont(FontID(*mem\Font))
			DrawText(7 + *mem\rayon, -1, " " + *mem\Title + " ", *mem\Color, *mem\TextBackColor)
		EndIf
		
		StopDrawing()
	EndIf
	
	
	ShapeObjectFromBitmap(GadgetID(Gadget), ImageID(img), color_trans)
	SetGadgetAttribute(Gadget, #PB_Canvas_Image, ImageID(img))
	
	FreeImage(img)
	
EndProcedure

; Pour la création du gadget
Procedure CustomFrame3D(Gadget, x.l, y.l, w.l, h.l, Title.s, color.l, rayon = 0, largeur = 1, Font = -1, Text_BackColor.l = 15790320)
	If Gadget = #PB_Any
		Gadget = CanvasGadget(#PB_Any, x, y, w, h);, #WS_CLIPSIBLINGS|#WS_CLIPCHILDREN)
	Else
		CanvasGadget(Gadget, x, y, w, h);, #WS_CLIPSIBLINGS|#WS_CLIPCHILDREN)
	EndIf
	
	Protected *mem.ICG_CustomFrame3D = AllocateMemory(SizeOf(ICG_CustomFrame3D))
	SetGadgetData(Gadget, *mem)
	
	RedrawFrame3D(Gadget, color, Title, rayon, largeur, Text_BackColor, #PB_Ignore, #PB_Ignore, #PB_Ignore, #PB_Ignore, Font)
	
	ProcedureReturn Gadget
EndProcedure

;}

;{ Chargement de la fenêtre

If OpenWindow(0, 0, 0, 320, 670, "Frame3D en folie !", #PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_SizeGadget)
	
	Frame3DGadget(0, 10, 10, 300, 100, "Cadre en relief standard de PureBasic")
	
	CustomFrame3D(1, 10, 120, 300, 100, "Cadre en relief standard rouge", #Red)
	ButtonGadget(2, 20, 135, 100, 20, "Couleur aléatoire")
	
	CustomFrame3D(3, 10, 230, 300, 100, "Cadre en relief standard de couleur changeante", #Red)
	AddWindowTimer(0, 0, 100) : compteur.d = 0
	
	CustomFrame3D(4, 10, 340, 300, 100, "Cadre en relief arrondis (rayon = 10), Bleu", #Blue, 7)
	
	CustomFrame3D(5, 10, 450, 300, 100, "Cadre en relief épais (rayon = 0, largeur = 3), Vert", #Green, 0, 3)
	
	CustomFrame3D(6, 10, 560, 300, 100, "Cadre en relief changeant (gros mix :)", #Black)
EndIf

;}


;{ Boucle principale

Repeat
	event = WaitWindowEvent()
	
	Select event
		Case #PB_Event_Gadget
			
			Select EventGadget()
				Case 2
					RedrawFrame3D(1, Random(#White), "Cadre en relief standard de couleur aléatoire")
					
			EndSelect
			
			
		Case #PB_Event_Timer
			If EventTimer() = 0
				compteur + #PI / 100
				
				RedrawFrame3D(3, RGB(255 * Abs(Sin(compteur)), 255 * Abs(Sin(compteur * 2)), 255 * Abs(Cos(compteur))))
				RedrawFrame3D(6, RGB(255 * Abs(Cos(compteur)), 255 * Abs(Cos(compteur * 2)), 255 * Abs(Sin(compteur))), #CR$, 15 * Abs(Cos(compteur * 1.5)), 5 * Abs(Sin(compteur * 0.5)))
			EndIf
			
			
	EndSelect
	
Until event = #PB_Event_CloseWindow

;}

End
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))
Avatar de l’utilisateur
Ar-S
Messages : 9540
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Gadget Frame3D

Message par Ar-S »

C'est fonctionnel ;)
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
graph100
Messages : 1318
Inscription : sam. 21/mai/2005 17:50

Re: Gadget Frame3D

Message par graph100 »

Tu as fait exprès d'être succinct non ? :lol:
Parce que je ne sais pas si le code est tellement opaque, mais ça veux dire qu'on peut "modeler" un canvasgadget() pour qu'il ai la forme voulue
Et donc faire un vrai gadget customisé 8)

Je ne crois pas avoir vu un code de ce type jusqu'à présent. (après tout c'est vrai qu'on perd la portabilité Linux / Mac, but, who care :twisted: )

@Nico : Pour obtenir ton screenshot, tu as fais une fenêtre et tu as dessiné avec un WindowOutput() ?? Ou bien c'étais une autre solution ?
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Gadget Frame3D

Message par Backup »

graph100 a écrit :Parce que je ne sais pas si le code est tellement opaque, mais ça veux dire qu'on peut "modeler" un canvasgadget() pour qu'il ai la forme voulue
Et donc faire un vrai gadget customisé 8)

Je ne crois pas avoir vu un code de ce type jusqu'à présent.
si si ! le changement de forme des Gadgets a deja été abordé ;)
ici :
http://www.purebasic.fr/french/viewtopi ... gle#p59200

de plus j'ai meme donné un code qui permettait de faire un Screen Rond ! (piqué aussi (en partie) sur la routine de découpe..trou du Soldat)

(recherche Horloge Fun ) ;)
ici :
http://www.purebasic.fr/french/viewtopi ... ic#p107915

ce qui est nouveau c'est de l'avoir appliqué sur un Canvas .... mais normal , le Canvas est nouveau aussi :mrgreen:

bon mis a part ça , c'est un tres bon code , meme si perso je ne l'utiliserais pas ( un peu trop "lourd") :)
Avatar de l’utilisateur
graph100
Messages : 1318
Inscription : sam. 21/mai/2005 17:50

Re: Gadget Frame3D

Message par graph100 »

Dobro a écrit :ce qui est nouveau c'est de l'avoir appliqué sur un Canvas .... mais normal , le Canvas est nouveau aussi :mrgreen:

bon mis a part ça , c'est un tres bon code , meme si perso je ne l'utiliserais pas ( un peu trop "lourd") :)
Oui, pour le code je parlais de l'application à un canvas, ce qui rend l'affaire géniale c'est qu'on gérer tout les évènement du canvas, et dessiner dessus ce qu'on veux.
Et pour le 1er lien, c'est de celui-ci que je parlais :P , mais en revanche la procedure finale du skinwindow vient d'encore avant, de mon tas de code mis de coté depuis quelques années :D

Après, les affaires de lourditudes ça dépend de ce qu'on cherche :wink: , moi je privilégie le résultat, et si je veux un code propre, je ferai un include (quoique avec les ;{ ;} le code reste très propre !
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Re: Gadget Frame3D

Message par nico »

Super le résultat, le code parait bien complexe et assez lourd quand même.
@Nico : Pour obtenir ton screenshot, tu as fais une fenêtre et tu as dessiné avec un WindowOutput() ?? Ou bien c'étais une autre solution ?
Non c'est un code de Christian Kemna, j'ai juste rajouté les api pour dessiner le rectangle arrondi
http://www.purebasic.fr/english/viewtop ... tian+Kemna
Répondre