Page 1 sur 1

Création de gadgets avec CanvasGadget() + VectorDrawing

Publié : dim. 11/janv./2026 22:59
par Jacobus
Salut :)
Aujourd'hui je vous propose la création simple de gadgets en utilisant Le CanvasGadget() comme support et les fonctions de VectorDrawing pour obtenir un joli rendu. C'est une manière simple de faire une interface d'application qui retient l'oeil et agréable à utiliser.
Vous pouvez très facilement modifier les fonctions créées pour vous les approprier et les ajuster à vos besoins, voire en créer de nouvelles. Tout est modifiable vu qu'au final ce n'est que du dessin.
Voici donc 5 fonctions sous forme de procédures et un exemple d'utilisation :
+ LargeGradientButton() = Créer de larges boutons avec images et textes aux couleurs en mode dégradées, option vertical ou horizontal pour le dégradé.
+ ButtonMovementEffect() = Donne un effet de mouvement aux boutons lors du survol de la souris
+ GradientTextArea() = Création d'une Zone de texte + image, en couleurs dégradées
+ GradientHeaderBar() = Créer une barre d'entête de fenêtre avec icone et textes de couleurs différentes
+ GradientExpanderBar() = Créer une barre de simulation de pliage de zone
+ NormalGradientButton() = Créer des boutons standards avec texte, image et gradient color

- Testé sur Windows 11 pro, 64 bits avec PB 6.30b7 32 et 64 bits.
- Les icônes et images utilisées sont chargées depuis le système (Shell32.dll)

Image

Corrections apportées le 12/01/2026
+ Désolé, oubli de la fonction SetGadgetCursor() nécessaire pour modifier le curseur :? Oubli corrigé :)
+ Ajout des tooltips sur les CanvasGadget()
+ 10h15 : Modification position du texte dans GradientTextArea() où il pouvait être tronqué.
: Optimisation de ButtonMovementEffect() x2 et y2 sont maintenant calculés automatiquement
+ 17h55 : Ajouté : NormalGradientButton() pour créer des boutons de taille normale, texte+image

Code : Tout sélectionner

;-ID PROGRAM
;==============================================================
; Library functions:      + LargeGradientButton()  = Créer de larges boutons avec images et textes aux couleurs en mode dégradées
;                         + ButtonMovementEffect() = Donne un effet de mouvement aux boutons lors du survol de la souris 
;                         + GradientTextArea()     = Création d'une Zone de texte + image, en couleurs dégradées
;                         + GradientHeaderBar()    = Créer une barre d'entête de fenêtre avec icone et textes de couleurs différentes
;                         + GradientExpanderBar()  = Créer une barre de simulation de pliage de zone
;                         + NormalGradientButton() = Créer des boutons standards avec texte, image et gradient color
;
; Version:.................1.0
; Author:..................Jacobus
; Date:....................11 janvier, 2026
; Target OS:...............Microsoft Windows 10 & 11 (All ??)
; Target Compiler:.........PureBasic 6.30 Beta 7
; License:.................Free, unrestricted, no warranty

;==============================================================

;- CONSTANTES
Enumeration Fenetres
  #MAIN_WINDOW 
EndEnumeration

Enumeration Gadgets
  #CANVAS_HEADER
  #TEXT_CANVAS
  #CANVAS_BTN_ONE
  #CANVAS_BTN_TWO
  #CANVAS_TEXTAREA
  #CANVAS_EXPAND
  #CONTAINER_EXPAND
  #EDITORNOTES
  #BTN_QUIT
  #BTN_ABOUT
  #BTN_OTHER
  #STATUS
EndEnumeration

;-DPI (prise en compte nécessaire pour les grands écrans)
CompilerIf #PB_Compiler_DPIAware = 1
  Global dpix.d = DesktopResolutionX()
  Global dpiy.d = DesktopResolutionY() 
CompilerElse 
  Global dpix.d = 1
  Global dpiy.d = 1 
CompilerEndIf

;==============================================================
;-SET GADGET CURSOR
;{
; Auteur :                     Le Soldat Inconnu
; Version de PB :              4.50
; Explication du programme :   Changer le curseur de la souris au survol d'un gadget
;==============================================================

Procedure SetGadgetCursor_SubClassProc(hwnd, msg, wparam, lparam) 
		Protected oldproc, Cursor
		oldproc = GetProp_(hwnd, "oldproc") 
		
		Select msg 
				Case #WM_NCDESTROY 
						RemoveProp_(hwnd, "oldproc") 
						RemoveProp_(hwnd, "cursor") 
						
				Case #WM_SETCURSOR
						Cursor = GetProp_(hwnd, "cursor") 
						SetCursor_(Cursor)
						ProcedureReturn 0 
						
		EndSelect    
		ProcedureReturn CallWindowProc_(oldproc, hwnd, msg, wparam, lparam) 
EndProcedure 
Procedure SetGadgetCursor(Gadget, Cursor) ; Change le curseur de la souris au dessus d'un Gadget
		If GetProp_(GadgetID(Gadget), "cursor")
				RemoveProp_(GadgetID(Gadget), "cursor") 
		EndIf
		SetProp_(GadgetID(Gadget), "cursor", Cursor)
		If GetProp_(GadgetID(Gadget), "oldproc") = 0
				SetProp_(GadgetID(Gadget), "oldproc", SetWindowLongPtr_(GadgetID(Gadget), #GWL_WNDPROC, @SetGadgetCursor_SubClassProc())) 
		EndIf
		SendMessage_(GadgetID(Gadget), #WM_SETCURSOR , 0, 0)
EndProcedure
; Valeurs possibles pour le curseur :
#IDC_ARROW        = 32512   ; la flèche (le curseur normal)
#IDC_IBEAM        = 32513   ; curseur sélection de texte
#IDC_WAIT         = 32514   ; curseur occupé (sablier)
#IDC_CROSS        = 32515   ; curseur précision de la sélection (croix)
#IDC_UPARROW      = 32516   ; flèche qui pointe vers le haut
#IDC_SIZENWSE     = 32642   ; curseur de dimensionnement, pointe le NordOuest et le SudEst
#IDC_SIZENESW     = 32643   ; curseur de dimensionnement, pointe le NE et le SO
#IDC_SIZEWE       = 32644   ; curseur de dimensionnement, pointe le E et le O
#IDC_SIZENS       = 32645   ; curseur de dimensionnement, pointe le N et le S
#IDC_SIZEALL      = 32646   ; curseur de déplacement, pointe le N, S, E et O
#IDC_NO           = 32648   ; curseur "interdit" (panneau d'interdiction)
#IDC_HAND         = 32649   ; curseur main
#IDC_APPSTARTING  = 32650   ; curseur attente (flèche + sablier)
#IDC_HELP         = 32651   ; curseur aide
                            ;}

;-FONTS
Global Font0 = LoadFont(0, "Bahnschrift Light SemiCondensed", 9, #PB_Font_Bold|#PB_Font_HighQuality)
Global Font1 = LoadFont(1, "Segoe UI Semibold", 10, #PB_Font_HighQuality|#PB_Font_Underline)
Global Font2 = LoadFont(2, "Segoe UI Semibold", 9, #PB_Font_HighQuality)
;-TEXT
Global TEXTAREA$ ; extrait de l'Apocalypse selon St Jean.
;{
TEXTAREA$ = "Chapitre 12"+#CRLF$
TEXTAREA$ + "La femme, le dragon et l'enfant"+#CRLF$
TEXTAREA$ + "1 Un grand signe parut dans le ciel: une femme enveloppée du soleil, la lune sous ses pieds, et une couronne de douze étoiles sur sa tête."+#CRLF$
TEXTAREA$ + "2 Elle était enceinte, et elle criait, étant en travail et dans les douleurs de l'enfantement."+#CRLF$ 
TEXTAREA$ + "3 Un autre signe parut encore dans le ciel; et voici, c'était un grand dragon rouge, ayant sept têtes et dix cornes, et sur ses têtes sept diadèmes."+#CRLF$ 
TEXTAREA$ + "4 Sa queue entraînait le tiers des étoiles du ciel, et les jetait sur la terre. Le dragon se tint devant la femme qui allait enfanter, afin de dévorer son enfant, lorsqu'elle aurait enfanté."+#CRLF$ 
TEXTAREA$ + "5 elle enfanta un fils, qui doit paître toutes les nations avec une verge de fer. Et son enfant fut enlevé vers Dieu et vers son trône."+#CRLF$ 
TEXTAREA$ + "6 et la femme s'enfuit dans le désert, où elle avait un lieu préparé par Dieu, afin qu'elle y fût nourrie pendant mille deux cent soixante jours."+#CRLF$ 
TEXTAREA$ + "7 et il y eut guerre dans le ciel. Michel et ses anges combattirent contre le dragon. Et le dragon et ses anges combattirent,"+#CRLF$ 
TEXTAREA$ + "8 mais ils ne furent pas les plus forts, et leur place ne fut plus trouvée dans le ciel."+#CRLF$ 
; TEXTAREA$ + "9 et il fut précipité, le grand dragon, le serpent ancien, appelé le diable et Satan, celui qui séduit toute la terre, il fut précipité sur la terre, et ses anges furent précipités avec lui."+#CRLF$ 
; TEXTAREA$ + "10 et j'entendis dans le ciel une voix forte qui disait: Maintenant le salut est arrivé, et la puissance, et le règne de notre Dieu, et l'autorité de son Christ; car il a été précipité, l'accusateur de nos frères, celui qui les accusait devant notre Dieu jour et nuit."+#CRLF$ 
; TEXTAREA$ + "11 ils l'ont vaincu à cause du sang de l'agneau et à cause de la parole de leur témoignage, et ils n'ont pas aimé leur vie jusqu'à craindre la mort."+#CRLF$ 
; TEXTAREA$ + "12 c'est pourquoi réjouissez-vous, cieux, et vous qui habitez dans les cieux. Malheur à la terre et à la mer! car le diable est descendu vers vous, animé d'une grande colère, sachant qu'il a peu de temps."+#CRLF$ 
; TEXTAREA$ + "13 quand le dragon vit qu'il avait été précipité sur la terre, il poursuivit la femme qui avait enfanté l'enfant mâle."+#CRLF$ 
; TEXTAREA$ + "14 et les deux ailes du grand aigle furent données à la femme, afin qu'elle s'envolât au désert, vers son lieu, où elle est nourrie un temps, des temps, et la moitié d'un temps, loin de la face du serpent."+#CRLF$ 
; TEXTAREA$ + "15 et, de sa bouche, le serpent lança de l'eau comme un fleuve derrière la femme, afin de l'entraîner par le fleuve."+#CRLF$ 
; TEXTAREA$ + "16 et la terre secourut la femme, et la terre ouvrit sa bouche et engloutit le fleuve que le dragon avait lancé de sa bouche."+#CRLF$ 
; TEXTAREA$ + "17 et le dragon fut irrité contre la femme, et il sen alla faire la guerre aux restes de sa postérité, à ceux qui gardent les commandements de Dieu et qui ont le témoignage de Jésus." 
;}

;-PROCEDURES
; Avec VectorDrawing, les couleurs sont de type RGBA (RGB + Canal Alpha) pour un meilleur rendu.
; ex: RGBA(125, 141, 172, 253) ou RGBA(213, 228, 223, 103)
Procedure GradientHeaderBar(canvasID, ColorZero, ColorOne, Title$, Text$, Enterprise$, ImageHeader, HV = 1)
  
  ; canvasID:...............N° ID du CanvasGadget() 
  ; ColorZero:..............Couleur du début du gradient, ex: RGBA(99, 184, 255, 255)
  ; ColorOne:...............Couleur de fin du gradient,   ex: RGBA(0, 0, 128, 255)
  ; Title$:.................Titre affiché en haut à gauche de la barre d'entête de fenêtre 
  ; Text$:..................Texte affiché en bas à gauche, sous le titre. 
  ; Enterprise$:............Texte ou nom qui sera affiché au milieu à droite de la barre d'entête de fenêtre  
  ; ImageHeader:............Image qui sera affichée à gauche de la barre d'entête de fenêtre
  ; HV:.....................Option: HV = 1 gradient vertical (par défaut) ou HV = 0 gradient horizontal
  
  Protected wc = GadgetWidth(canvasID)
  Protected hc = GadgetHeight(canvasID)
  Protected outputc = CanvasVectorOutput(canvasID, #PB_Unit_Pixel)
  
  If StartVectorDrawing(outputc)    
    ; Choix de l'orientation du dégradé de couleur
    If HV = 0  ; Fond gradient Horizontal (par défaut)
      VectorSourceLinearGradient(0, 0, w*dpix, h*dpiy)
      VectorSourceGradientColor(ColorZero, 0.0)
      VectorSourceGradientColor(ColorOne, 1.0)
    ElseIf HV = 1 ; Fond gradient vertical
      VectorSourceLinearGradient(1, hc*dpiy, 1, 1 )
      VectorSourceGradientColor(ColorZero, 0.0)
      VectorSourceGradientColor(ColorOne, 1.0)
    EndIf  
    FillVectorOutput() ; remplissage
    
    If ImageHeader <> 0
      MovePathCursor(10, 4)
      DrawVectorImage(ImageHeader, 255) 
    EndIf 
    
    If Title$ <> ""
      VectorFont(Font0, 20)
      VectorSourceColor(RGBA(231, 234, 238, 255)) ; gris clair 
      MovePathCursor(70, 5)   
      DrawVectorText(Title$)
    EndIf 
    
    If Text$ <> ""
      ;VectorFont(Font2)
      ;VectorSourceColor(RGBA(231, 234, 238, 255)) ; gris clair   
      MovePathCursor(70, 30)   
      DrawVectorText(Text$)
    EndIf 
    
    If Enterprise$ <> ""
      ; Modification de la couleur pour le texte Enterprise$
      VectorSourceColor(RGBA(145, 0, 0, 255)) ; rouge foncé
      MovePathCursor((wc*dpix)-(VectorTextWidth(Enterprise$)+30), 20)  ; positionnement à droite de la barre 
      DrawVectorText(Enterprise$)
    EndIf   
    
    StopVectorDrawing()
  EndIf   
EndProcedure

Procedure LargeGradientButton(canvasID, ColorZero, ColorOne, Title$, Text$, Image, PosImage = 0, HV = 1)
  
  ; canvasID:...............N° ID du CanvasGadget() 
  ; ColorZero:..............Couleur du début du gradient, ex: RGBA(105, 133, 187, 255)
  ; ColorOne:...............Couleur de fin du gradient,   ex: RGBA(213, 228, 223, 255)
  ; Title$:.................Titre affiché en haut à gauche du bouton et à droite de l'icône 
  ; Text$:..................Texte affiché en bas à gauche, sous le titre. 
  ; Image:..................Image qui sera affichée sur le bouton, à gauche du titre et du texte ou du côté droit du bouton
  ; PosImage:...............Option position de l'icône, 0 = à gauche, 1 = à droite
  ; HV:.....................Option: HV = 1 gradient horizontal (par défaut) ou HV = 0 gradient vertical
  
  Protected w = GadgetWidth(canvasID)
  Protected h = GadgetHeight(canvasID)
  Protected output = CanvasVectorOutput(canvasID, #PB_Unit_Pixel)
  
  If StartVectorDrawing(output) 
    
    ; Choix de l'orientation du dégradé de couleur
    If HV = 1  ; Fond gradient Horizontal (par défaut)
      VectorSourceLinearGradient(0, 0, w*dpix, h*dpiy)
      VectorSourceGradientColor(ColorZero, 0.0) ; 0,0 (le début du gradient)
      VectorSourceGradientColor(ColorOne, 1.0)  ; 1.0 (la fin du gradient). 
    ElseIf HV = 0 ; Fond gradient vertical
      VectorSourceLinearGradient(1, h*dpiy, 1, 1 )
      VectorSourceGradientColor(ColorOne, 1.0)
      VectorSourceGradientColor(ColorZero, 0.0)
    EndIf   
    FillVectorOutput()
    
    If PosImage = 0      ; l'image sera placée à gauche 
      MovePathCursor(10, 10)     
      DrawVectorImage(Image, 255) 
      
      VectorSourceColor(RGBA(0, 0, 0, 255)) ; noir   
      MovePathCursor(100, 40)   
      DrawVectorText(Text$)
      
      VectorFont(Font1, 20)
      VectorSourceColor(RGBA(28, 113, 218, 255)) ; bleu  
      MovePathCursor(100, 7)   
      DrawVectorText(Title$)
  
    ElseIf PosImage = 1  ; positionnement à droite
      MovePathCursor((w*dpix)-(48+10), 10) 
      DrawVectorImage(Image, 255)
      
      VectorSourceColor(RGBA(0, 0, 0, 255)) ; noir   
      MovePathCursor(10, 40)   
      DrawVectorText(Text$)
      
      VectorFont(Font1, 20)
      VectorSourceColor(RGBA(28, 113, 218, 255)) ; bleu  
      MovePathCursor(10, 7)   
      DrawVectorText(Title$)   
    EndIf 

    StopVectorDrawing()
  EndIf   
    
EndProcedure

Procedure NormalGradientButton(canvasID, ColorZero, ColorOne, Text$, ColorTxt, Image, OutlineColor, Outline = 0, PosImage = 0, HV = 1)
  
  ; canvasID:...............N° ID du CanvasGadget() 
  ; ColorZero:..............Couleur du début du gradient, ex: RGBA(105, 133, 187, 255)
  ; ColorOne:...............Couleur de fin du gradient,   ex: RGBA(213, 228, 223, 255)
  ; Text$:..................Texte affiché en bas à gauche, sous le titre.
  ; ColorTxt:...............Couleur du texte,   ex: RGBA(231, 234, 238, 255)
  ; Image:..................Image/icône 16x16 max (vous pouvez modifier cette limite) qui sera affichée sur le bouton, à gauche du titre et du texte ou du côté droit du bouton
  ; OutlineColor:...........Option choix de la couleur du contour
  ; Outline:................Option dessin d'un contour au bouton.
  ; PosImage:...............Option position de l'icône, 0 = à gauche, 1 = à droite
  ; HV:.....................Option: HV = 1 gradient horizontal (par défaut) ou HV = 0 gradient vertical
  
  Protected w = GadgetWidth(canvasID)
  Protected h = GadgetHeight(canvasID)
  Protected output = CanvasVectorOutput(canvasID, #PB_Unit_Pixel)

  If StartVectorDrawing(output)
    
    ; Choix de l'orientation du dégradé de couleur
    If HV = 1      ; Fond gradient Horizontal (par défaut)
      VectorSourceLinearGradient(0, 0, w*dpix, h*dpiy)
      VectorSourceGradientColor(ColorZero, 0.0) ; 0,0 (le début du gradient)
      VectorSourceGradientColor(ColorOne, 1.0)  ; 1.0 (la fin du gradient). 
    ElseIf HV = 0  ; Fond gradient vertical
      VectorSourceLinearGradient(1, h*dpiy, 1, 1 )
      VectorSourceGradientColor(ColorOne, 1.0)
      VectorSourceGradientColor(ColorZero, 0.0)
    EndIf   
    FillVectorOutput()
    
    ; image
    If Image <> 0
      If PosImage = 0      ; l'image sera placée à gauche 
        MovePathCursor(5, 5*dpiy)
        DrawVectorImage(Image, 255, 16*dpix, 16*dpiy)
      ElseIf PosImage = 1  ; positionnement à droite
        MovePathCursor((w*dpix)-(21*dpix), 5*dpiy)
        DrawVectorImage(Image, 255, 16*dpix, 16*dpiy)
      EndIf 
    EndIf 
    
    ; texte centré
    If Text$ <> ""
      Protected xt = (w*dpix/2)-(VectorTextWidth(Text$)/2)  ; pour centrer le texte horizontalement
      Protected yt = (h*dpiy/2)-(VectorTextHeight(Text$)/2) ; pour centrer le texte verticalement
      MovePathCursor(xt, yt) 
      VectorFont(Font0, 20)
      VectorSourceColor(ColorTxt)
      DrawVectorText(Text$)
    EndIf 
    
    ; pour marquer un contour (à faire en dernier pour ne pas qu'il soit recouvert)
    If Outline = 1
      MovePathCursor(0, 0)     
      AddPathBox(0, 0, w*dpix, h*dpiy)
      VectorSourceColor(OutlineColor)     
      StrokePath(3)   ; 3 pixels d'épaisseur
    EndIf 
    
    StopVectorDrawing()
  EndIf
  
EndProcedure

Procedure GradientTextArea(canvasID, ColorZero, ColorOne, Title$, Text$, Image, ImgWidth, ImgHeight, HV = 1)
   
  ; canvasID:...............N° ID du CanvasGadget() 
  ; ColorZero:..............Couleur du début du gradient, ex: RGBA(105, 133, 187, 255)
  ; ColorOne:...............Couleur de fin du gradient,   ex: RGBA(213, 228, 223, 255)
  ; Title$:.................Titre affiché en haut à gauche du bouton et à droite de l'icône 
  ; Text$:..................Texte affiché en bas à gauche, sous le titre. 
  ; Image:..................Image qui sera affichée 
  ; ImgWidth:...............Largeur de l'image
  ; ImgHeight:..............Hauteur de l'image
  ; HV:.....................Option: HV = 1 gradient horizontal (par défaut) ou HV = 0 gradient vertical
  
  Protected w = GadgetWidth(canvasID)
  Protected h = GadgetHeight(canvasID)
  Protected output = CanvasVectorOutput(canvasID, #PB_Unit_Pixel)
  
  If StartVectorDrawing(output)
    ; Chargement d'une police préalablement déclarée en Global
    VectorFont(Font0, 20)
    
    ; Choix de l'orientation du dégradé de couleur
    If HV = 1  ; Fond gradient Horizontal (par défaut)
      VectorSourceLinearGradient(0, 0, w*dpix, h*dpiy)
      VectorSourceGradientColor(ColorZero, 0.0) ; 0,0 (le début du gradient)
      VectorSourceGradientColor(ColorOne, 1.0)  ; 1.0 (la fin du gradient). 
    ElseIf HV = 0                               ; Fond gradient vertical
      VectorSourceLinearGradient(1, h*dpiy, 1, 1 )
      VectorSourceGradientColor(ColorOne, 1.0)
      VectorSourceGradientColor(ColorZero, 0.0)
    EndIf   
    FillVectorOutput()
    
    If Image <> 0
      If ImgWidth < 24 Or ImgHeight < 24
        ImgWidth = 24 : ImgHeight = 24 ; On donne une taille minimale de 24x24 à l'image
      ElseIf ImgWidth >= 24 And ImgHeight >= 24
        ImgWidth = ImgWidth : ImgHeight = ImgHeight
      EndIf 
      MovePathCursor(10, 10)
      DrawVectorImage(Image, 255, ImgWidth*dpix, ImgHeight*dpiy) 
    EndIf 
        
    If Title$ <> ""
      VectorFont(Font0, 20)
      VectorSourceColor(RGBA(255, 0, 0, 255)) ; rouge   
      MovePathCursor((ImgWidth*dpix)+30, 30)   
      DrawVectorText(Title$)
    EndIf  
    
    If Text$ <> ""
      VectorSourceColor(RGBA(0,0,0,255)) ; texte en noir    
      MovePathCursor(10, (ImgHeight*dpiy)+30)
      ; Le texte peut être long, il est placé dans un paragraphe avec retour à la ligne automatique
      DrawVectorParagraph(Text$, (w*dpix)-20, h*dpiy)
    EndIf 
    
    StopVectorDrawing()
  EndIf 
  
EndProcedure

Procedure GradientExpanderBar(canvasIDexp, ColorZero, ColorOne, Text$, ImageExp, HV = 1)
  
  ; canvasID:...............N° ID du CanvasGadget() 
  ; ColorZero:..............Couleur du début du gradient, ex: RGBA(99, 184, 255, 255)
  ; ColorOne:...............Couleur de fin du gradient,   ex: RGBA(0, 0, 128, 255)
  ; Title$:.................Titre affiché à gauche 
  ; Image:..................Image qui sera affichée du côté droit
  ; HV:.....................Option: HV = 1 gradient horizontal (par défaut) ou HV = 0 gradient vertical
  
  Protected wexp = GadgetWidth(canvasIDexp)
  Protected hexp = GadgetHeight(canvasIDexp)
  Protected outputexp = CanvasVectorOutput(canvasIDexp, #PB_Unit_Pixel)
  
  If StartVectorDrawing(outputexp)
    
    ; Choix de l'orientation du dégradé de couleur
    If HV = 1  ; Fond gradient Horizontal (par défaut)
      VectorSourceLinearGradient(0, 0, wexp*dpix, hcexp*dpiy)
      VectorSourceGradientColor(ColorZero, 0.0) ; 0,0 (le début du gradient)
      VectorSourceGradientColor(ColorOne, 1.0)  ; 1.0 (la fin du gradient). 
    ElseIf HV = 0 ; Fond gradient vertical
      VectorSourceLinearGradient(1, h*dpiy, 1, 1 )
      VectorSourceGradientColor(ColorOne, 1.0)
      VectorSourceGradientColor(ColorZero, 0.0)
    EndIf   
    FillVectorOutput()
    
    VectorFont(Font0, 20)
    VectorSourceColor(RGBA(117, 136, 157, 255)) ; gris clair   
    MovePathCursor(10, 5)   
    DrawVectorText(Text$)
    
    MovePathCursor((wexp-30)*dpix, 5)
    DrawVectorImage(ImageExp, 255, 24, 24) ; image redimensionnée en 24x24
    
    StopVectorDrawing()
  EndIf 

EndProcedure

Procedure ButtonMovementEffect(CanvasID, x1, y1)
  ; Lorsque la souris survole le bouton il est déplacé de x1 en x2 et de y1 en y2
  ; Lorsque la souris quitte le bouton il revient à sa place initiale
  ; donnant un effet de mouvement du gadget.
  
  Protected x2 = x1+2 
  Protected y2 = y1-2
  
  If EventType() = #PB_EventType_MouseEnter ;#CUSTOM_MSG_MOUSEENTER    
    ResizeGadget(CanvasID, x2, y2, #PB_Ignore, #PB_Ignore)    
  ElseIf EventType() = #PB_EventType_MouseLeave ;#CUSTOM_MSG_MOUSELEAVE    
    ResizeGadget(CanvasID, x1, y1, #PB_Ignore, #PB_Ignore)   
  EndIf
            
EndProcedure

Procedure Resize_MAIN_WINDOW()
  
  WinWidth  = WindowWidth(#MAIN_WINDOW,#PB_Window_InnerCoordinate)
  WinHeight = WindowHeight(#MAIN_WINDOW,#PB_Window_InnerCoordinate)
  
  ResizeGadget(#CANVAS_HEADER, #PB_Ignore, PB_Ignore, WinWidth, #PB_Ignore)
  GradientHeaderBar(#CANVAS_HEADER, RGBA(99, 184, 255, 255), RGBA(0, 0, 128, 255), "Fenêtre principale", "Création d'un bouton avec un Canvas. Lecteur de fichiers musicaux MP3 et WMA. (Ctrl+M)", "Jacobus Software", ExtractIcon_(GetModuleHandle_(#Null), "Shell32.dll",207))
  
  ResizeGadget(#CANVAS_TEXTAREA, #PB_Ignore, #PB_Ignore, WinWidth-524, WinHeight-110)
  GradientTextArea(#CANVAS_TEXTAREA, RGBA(125, 141, 172, 253), RGBA(213, 228, 223, 103)," --\\-- TEST IMAGE ET TEXTE --//--", TEXTAREA$, ExtractIcon_(GetModuleHandle_(#Null), "Shell32.dll",13), 64, 64)
  
  ResizeGadget(#BTN_QUIT, #PB_Ignore, WinHeight-52, #PB_Ignore, #PB_Ignore)
  ResizeGadget(#BTN_ABOUT, #PB_Ignore, WinHeight-52, #PB_Ignore, #PB_Ignore)
  ResizeGadget(#BTN_OTHER, #PB_Ignore, WinHeight-52, #PB_Ignore, #PB_Ignore)
  
EndProcedure

;- Interface graphique
If OpenWindow(#MAIN_WINDOW, 0, 0, 1024, 300, "Fenêtre principale", #PB_Window_SystemMenu | #PB_Window_ScreenCentered|#PB_Window_MaximizeGadget|#PB_Window_MinimizeGadget|#PB_Window_SizeGadget)
  WindowBounds(#MAIN_WINDOW, 1024, 300, 1280, 600)
  WidthWMain  = WindowWidth(#MAIN_WINDOW, #PB_Window_InnerCoordinate)
  HeightWMain = WindowHeight(#MAIN_WINDOW, #PB_Window_InnerCoordinate) 
  
  CanvasGadget(#CANVAS_HEADER, 0, 0, WidthWMain, 40)
  GradientHeaderBar(#CANVAS_HEADER, RGBA(99, 184, 255, 255), RGBA(0, 0, 128, 255), "Fenêtre principale", "Création d'un bouton avec un Canvas. Lecteur de fichiers musicaux MP3 et WMA. (Ctrl+M)", "WolfoRan Software", ExtractIcon_(GetModuleHandle_(#Null), "Shell32.dll",207))
  
  TextGadget(#TEXT_CANVAS, 10, 50, 500, 20, "Utilisation de CanvasGadget() pour la création de gadgets...")
  SetGadgetFont(#TEXT_CANVAS, FontID(0))
  
  CanvasGadget(#CANVAS_BTN_ONE, 10, 80, 500, 60)  : GadgetToolTip(#CANVAS_BTN_ONE,"Jacobus Mp3 Player")
  LargeGradientButton(#CANVAS_BTN_ONE, RGBA(213, 228, 223, 255), RGBA(105, 133, 187, 255),"Jacobus Mp3 Player", "Création d'un bouton avec un CanvasGadget()"+#CRLF$+"Ceci est peut-être un lecteur de fichiers MP3. (Ctrl+M)", ExtractIcon_(GetModuleHandle_(#Null), "Shell32.dll",13), 0, 0)
  
  CanvasGadget(#CANVAS_BTN_TWO, 10, 145, 500, 60, #PB_Canvas_Border)  : GadgetToolTip(#CANVAS_BTN_TWO,"Démarrer DirAnalyser")
  LargeGradientButton(#CANVAS_BTN_TWO, RGBA(125, 141, 172, 255), RGBA(213, 228, 223, 255), "Création d'un gros bouton long", "avec un CanvasGadget()"+#CRLF$+"Ceci est peut-être un lecteur de fichiers MP3, ou pas. (Ctrl+M)", ExtractIcon_(GetModuleHandle_(#Null), "Shell32.dll",80), 1, 1)
  
  CanvasGadget(#CANVAS_EXPAND, 10, 210, 500, 25, #PB_Canvas_DrawFocus)  : GadgetToolTip(#CANVAS_EXPAND,"Déplier la section d'édition")
  GradientExpanderBar(#CANVAS_EXPAND, RGBA(213, 228, 223, 255), RGBA(105, 133, 187, 255), "Ouvrir l'accès aux autres fonctions", ExtractIcon_(GetModuleHandle_(#Null), "Shell32.dll",247))
  ContainerGadget(#CONTAINER_EXPAND, 10, 235, 500, 300, #PB_Container_Single) ;{
  EditorGadget(#EDITORNOTES, 0, 0, 500, 300, #PB_Editor_WordWrap)
  SetGadgetColor(#EDITORNOTES, #PB_Gadget_BackColor, RGB(255, 250, 205))
  SetGadgetColor(#EDITORNOTES, #PB_Gadget_FrontColor, RGB(40, 56, 86))
  ;}
  CloseGadgetList()
  HideGadget(#CONTAINER_EXPAND, #True)
  
  CanvasGadget(#CANVAS_TEXTAREA, 520, 80, 500, HeightWMain-110, #PB_Canvas_Border|#PB_Canvas_DrawFocus)
  GradientTextArea(#CANVAS_TEXTAREA, RGBA(125, 141, 172, 253), RGBA(213, 228, 223, 103), "TEST IMAGE ET TEXTE", TEXTAREA$, ExtractIcon_(GetModuleHandle_(#Null), "Shell32.dll",13), 64, 64)
 
  ;ButtonGadget(#BTN_QUIT, 10, HeightWMain-50, 60, 25, "Quitter")  : GadgetToolTip(#BTN_QUIT,"Fermer la fenêtre")  
  CanvasGadget(#BTN_QUIT, 10, HeightWMain-52, 100, 25)  : GadgetToolTip(#BTN_QUIT,"Fermer la fenêtre")
  NormalGradientButton(#BTN_QUIT, RGBA(99, 184, 255, 255), RGBA(0, 0, 128, 255), "Quitter", RGBA(231, 234, 238, 255), ExtractIcon_(GetModuleHandle_(#Null), "Shell32.dll",27), RGBA(255, 0, 0, 255), 0, 0, 0)
  
  CanvasGadget(#BTN_ABOUT, 115, HeightWMain-52, 100, 25)  : GadgetToolTip(#BTN_ABOUT,"A propos de ces fonctions")
  NormalGradientButton(#BTN_ABOUT, RGBA(92, 113, 206, 255), RGBA(213, 228, 223, 255), "A propos", RGBA(44, 65, 97, 255), ExtractIcon_(GetModuleHandle_(#Null), "Shell32.dll",221), RGBA(255, 0, 0, 255), 0, 1, 0)
  
  CanvasGadget(#BTN_OTHER, 220, HeightWMain-52, 100, 25)  : GadgetToolTip(#BTN_OTHER,"A propos de ???")
  NormalGradientButton(#BTN_OTHER, RGBA(44, 218, 97, 255), RGBA(61, 128, 25, 255), "A propos ???", RGBA(44, 65, 97, 255), 0, RGBA(255, 0, 0, 255), 1, 0, 0)
  
  ;-Statusbar
  If CreateStatusBar(#STATUS, WindowID(#MAIN_WINDOW)) ;{
    AddStatusBarField(150)
    AddStatusBarField(#PB_Ignore)
    StatusBarText(#STATUS, 0, "Fenêtre principale", #PB_StatusBar_Center|#PB_StatusBar_Raised)
    StatusBarText(#STATUS, 1, "Information", #PB_StatusBar_Raised)    
    SendMessage_(StatusBarID(#STATUS),#WM_SETFONT,FontID(0),0) ; modifie la police de caractère de la statusbar
    ;}
  EndIf
  
  ;-Curseur
  Curseur = LoadCursor_(0, #IDC_HAND)       ; Charge le curseur main
  SetGadgetCursor(#CANVAS_BTN_ONE,  Curseur)  ; Applique le curseur aux gadgets voulus
  SetGadgetCursor(#CANVAS_BTN_TWO,  Curseur)
  SetGadgetCursor(#CANVAS_EXPAND,   Curseur)
  SetGadgetCursor(#BTN_QUIT,        Curseur)
  SetGadgetCursor(#BTN_ABOUT,       Curseur)
  SetGadgetCursor(#BTN_OTHER,       Curseur)
  
  ;Redimensionnement de la fenêtre et des gadgets
  BindEvent(#PB_Event_SizeWindow, @Resize_MAIN_WINDOW())

;- Boucle principale
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_Gadget
        Select EventGadget()
            
          Case #CANVAS_BTN_ONE ;{
            ButtonMovementEffect(#CANVAS_BTN_ONE, 10, 80)           
            If EventType() = #PB_EventType_MouseEnter ;#CUSTOM_MSG_MOUSEENTER
              StatusBarText(#STATUS, 1, "Démarrer l'application de lecture des mp3 et autres fichiers audio wma", #PB_StatusBar_Raised)
            ElseIf EventType() = #PB_EventType_MouseLeave ;#CUSTOM_MSG_MOUSELEAVE
              StatusBarText(#STATUS, 1, "Zone d'information", #PB_StatusBar_Raised)
            ElseIf EventType() = #PB_EventType_LeftClick
              AddGadgetItem(#EDITORNOTES, -1, "L'application de lecture des mp3 et autres fichiers audio wma a été lancée.")
            EndIf        
            ;} 
            
          Case #CANVAS_BTN_TWO ;{
            ButtonMovementEffect(#CANVAS_BTN_TWO, 10, 145)
            If EventType() = #PB_EventType_MouseEnter
              StatusBarText(#STATUS, 1, "Démarrer DirAnalyser qui fait l'invetaire des fichiers se trouvant sur votre PC.", #PB_StatusBar_Raised)
            ElseIf EventType() = #PB_EventType_MouseLeave
              StatusBarText(#STATUS, 1, "Zone d'information", #PB_StatusBar_Raised)
            ElseIf EventType() = #PB_EventType_LeftClick
              AddGadgetItem(#EDITORNOTES, -1, "DirAnalyser qui fait l'inventaire des fichiers se trouvant sur votre PC a été lancé.")
            EndIf        
            ;} 
            
          Case #CANVAS_EXPAND ;{
            If EventType() = #PB_EventType_MouseEnter
              StatusBarText(#STATUS, 1, "Extension de la fenêtre et affichage d'autres fonctions disponibles", #PB_StatusBar_Raised)
            ElseIf EventType() = #PB_EventType_MouseLeave
              StatusBarText(#STATUS, 1, "Zone d'information", #PB_StatusBar_Raised)
            ElseIf EventType() = #PB_EventType_LeftClick
              If WindowHeight(#MAIN_WINDOW) = 300 
                GradientExpanderBar(#CANVAS_EXPAND, RGBA(213, 228, 223, 255), RGBA(105, 133, 187, 255), "Refermer l'accès aux autres fonctions", ExtractIcon_(GetModuleHandle_(#Null), "Shell32.dll",246))
                ResizeWindow(#MAIN_WINDOW, #PB_Ignore, #PB_Ignore, #PB_Ignore, WindowHeight(#MAIN_WINDOW)+300)
                HideGadget(#CONTAINER_EXPAND, #False)
                AddGadgetItem(#EDITORNOTES, -1, "Ouverture de l'éditeur de texte.")
                GadgetToolTip(#CANVAS_EXPAND,"Replier la section d'édition")
              ElseIf WindowHeight(#MAIN_WINDOW) > 300 And WindowHeight(#MAIN_WINDOW) <= 600 
                GradientExpanderBar(#CANVAS_EXPAND, RGBA(213, 228, 223, 255), RGBA(105, 133, 187, 255), "Ouvrir l'accès aux autres fonctions", ExtractIcon_(GetModuleHandle_(#Null), "Shell32.dll",247))
                ResizeWindow(#MAIN_WINDOW, #PB_Ignore, #PB_Ignore, #PB_Ignore, 300)
                HideGadget(#CONTAINER_EXPAND, #True) 
                AddGadgetItem(#EDITORNOTES, -1, "Fermeture de l'éditeur de texte.")
                GadgetToolTip(#CANVAS_EXPAND,"Déplier la section d'édition")
              EndIf 
            EndIf        
            ;} 
            
          Case #BTN_QUIT ;{
            ButtonMovementEffect(#BTN_QUIT, 10, WindowHeight(#MAIN_WINDOW, #PB_Window_InnerCoordinate)-52)
            If EventType() = #PB_EventType_MouseEnter 
              StatusBarText(#STATUS, 1, "Quitter l'application maintenant", #PB_StatusBar_Raised)
            ElseIf EventType() = #PB_EventType_MouseLeave 
              StatusBarText(#STATUS, 1, "Zone d'information", #PB_StatusBar_Raised)
            ElseIf EventType() = #PB_EventType_LeftClick
              Break
            EndIf
            ;}  
            
          Case #BTN_ABOUT ;{
            ButtonMovementEffect(#BTN_ABOUT, 115, WindowHeight(#MAIN_WINDOW, #PB_Window_InnerCoordinate)-52)
            If EventType() = #PB_EventType_MouseEnter 
              StatusBarText(#STATUS, 1, "A propos de ces boutons", #PB_StatusBar_Raised)
            ElseIf EventType() = #PB_EventType_MouseLeave 
              StatusBarText(#STATUS, 1, "Zone d'information", #PB_StatusBar_Raised)
            ElseIf EventType() = #PB_EventType_LeftClick
              MessageRequester("Message", "C'est Cool!", #PB_MessageRequester_Ok|#PB_MessageRequester_Info)
            EndIf
            ;}
            
          Case #BTN_OTHER ;{
            ButtonMovementEffect(#BTN_OTHER, 220, WindowHeight(#MAIN_WINDOW, #PB_Window_InnerCoordinate)-52)
            If EventType() = #PB_EventType_MouseEnter 
              StatusBarText(#STATUS, 1, "A propos de ???", #PB_StatusBar_Raised)
            ElseIf EventType() = #PB_EventType_MouseLeave 
              StatusBarText(#STATUS, 1, "Zone d'information", #PB_StatusBar_Raised)
            ElseIf EventType() = #PB_EventType_LeftClick
              MessageRequester("Message", "C'est Cool aussi non ?", #PB_MessageRequester_Ok|#PB_MessageRequester_Info)
            EndIf
            ;}
            
        EndSelect
        
      Case #PB_Event_Menu  
        Select EventMenu()
            
        EndSelect
        
      Case #PB_Event_CloseWindow
        Break
        
    EndSelect
    
  ForEver
  
EndIf 

Re: Création de gadgets avec CanvasGadget() + VectorDrawing

Publié : lun. 12/janv./2026 7:56
par Micoute
Bonjour Jacobus, c'est vraiment de toute beauté ce modèle d'application dont tu as eus l'idée de réaliser, car PB est souvent plus puissant qu'on ne le croit.

Re: Création de gadgets avec CanvasGadget() + VectorDrawing

Publié : lun. 12/janv./2026 8:10
par Jacobus
Salut Micoute,
en effet PB offre plein de possibilités relativement simples à mettre en oeuvre et c'est ce qui est amusant :D

Re: Création de gadgets avec CanvasGadget() + VectorDrawing

Publié : lun. 12/janv./2026 17:34
par SPH
Merci Jacobus, ça pourra être utile. :idea: :arrow: :P

Re: Création de gadgets avec CanvasGadget() + VectorDrawing

Publié : lun. 12/janv./2026 18:03
par Jacobus
Hello SPH,
J'ai ajouté une fonction pour créer des petits boutons standards avec texte et image, contour et couleur dégradée biensûr.
Code et capture modifiés dans le premier post.
:)

Re: Création de gadgets avec CanvasGadget() + VectorDrawing

Publié : mar. 13/janv./2026 9:18
par Mesa
J'ai un problème de dpi, le texte n'est pas affiché en entier (et mon dpi=96ppp).

M.

Re: Création de gadgets avec CanvasGadget() + VectorDrawing

Publié : mar. 13/janv./2026 10:12
par Jacobus
A quel endroit le texte ne s'affiche pas ? as-tu bien activé le facteur DPI dans les options ?
Si c'est dans la zone de texte à droite, c'est normal, il faut déplier "Ouvrir l'accès aux autres fonctions" pour que tout s'affiche.
Sinon... :?:
tu peux aussi essayer de supprimer tous les *dpix et les *dpiy avec Chercher/remplacer pour voir ce que cela donne...
...
Je viens de tester et ça peut donner des résultats pas terrible en fonction des polices utilisées et de l'écran :?

Re: Création de gadgets avec CanvasGadget() + VectorDrawing

Publié : mar. 13/janv./2026 11:35
par SPH
A vrai dire, moi aussi, j'ai des problemes de textes non entierement affichés. J'ai pourtant un bureau de 100%

Toutes les "cases" ne sont pas entierement affichées :idea:

Re: Création de gadgets avec CanvasGadget() + VectorDrawing

Publié : mar. 13/janv./2026 11:45
par falsam
@SPH : J'ai eu un souci identique car je n'ai pas activé le facteur d'échelle d'affichage DPI.

■ Si vous êtes sous Windows :

1 - Menu compilateur puis Option du compilateur.
2 - Cocher la case Activer le facteur d'échelle d'affichage DPI(Windows)

Re: Création de gadgets avec CanvasGadget() + VectorDrawing

Publié : mar. 13/janv./2026 14:27
par SPH
Jacobus a écrit : mar. 13/janv./2026 10:12 A quel endroit le texte ne s'affiche pas ? as-tu bien activé le facteur DPI dans les options ?
http://xmas.free.fr/bug.bmp