Page 1 sur 2
ContainerGadget avec fond transparent
Publié : dim. 04/oct./2009 17:51
par Le Soldat Inconnu
Salut,
je cherche à faire un ContainerGadget dont le fond est transparent.
pourquoi ?
Car si je mets mon containergadget dans une fenêtre, ou dans un panelgadget (fond de couleur différente de la fenêtre avec dégradé), je veux qu'il reste invisble.
Car j'utilise le ContainerGadet pour mettre des gadgets ensemble et pouvoir les cacher/montrer ou déplacer facilement, on jouant juste sur le containergadget
j'ai essayé de faire de l'ownerdraw, mais le résultat n'est pas bon
alors je veux bien un coup de main
Code : Tout sélectionner
; Auteur : Le Soldat Inconnu
; Version de PB : 4.40
;
; Explication du programme :
; Pour faire des programmes de test rapidement, il ne reste qu'a rajouter les gadgets et la gestion des évènements.
Procedure ContainerGadgetCallBack(hwnd, uMsg, wParam, lParam)
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
; Création de la fenêtre et de la GadgetList
If OpenWindow(0, 0, 0, 300, 300, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget) = 0
End
EndIf
SetWindowColor(0, $FF00FF)
PanelGadget(0, 0, 0, 300, 300)
AddGadgetItem(0, -1, "Tranparent")
ContainerGadget(1, 50, 50, 200, 200, #PB_Container_BorderLess)
ButtonGadget(5, 10, 10, 64, 32, "Test")
TextGadget(6, 50, 50, 64, 16, "Texte")
CloseGadgetList()
SetWindowLong_(GadgetID(1), #GWL_WNDPROC, @ContainerGadgetCallBack())
AddGadgetItem(0, -1, "Normal")
ContainerGadget(2, 50, 50, 200, 200, #PB_Container_BorderLess)
ButtonGadget(7, 10, 10, 64, 32, "Test")
TextGadget(8, 50, 50, 64, 16, "Texte")
CloseGadgetList()
CloseGadgetList()
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Menu
Select EventMenu() ; Menus
EndSelect
Case #PB_Event_Gadget
Select EventGadget() ; Gadgets
EndSelect
EndSelect
Until Event = #PB_Event_CloseWindow
Re: ContainerGadget avec fond tranparent
Publié : dim. 04/oct./2009 19:01
par Anonyme2
Le container est une fenêtre, peut-être que tu as essayé de donner un style BS_ownerdrawn ou autre.
Je poste juste un code qui colorie le container, tu mettras la transparence.
Code : Tout sélectionner
EnableExplicit
Global OldProc ;// mémorise l'adresse de la procedure standart MS de traitement des événements de la fenêtre
Procedure WinCallback(hWnd, uMsg, wParam, lParam)
Protected ps.PAINTSTRUCT
Protected hDC
Protected hdcMem
Protected hBmpTampon
Protected SavedDC
Protected brush
If uMsg = #WM_PAINT
hDC = BeginPaint_(hWnd, @ps)
If hDC
hdcMem = CreateCompatibleDC_(hDC)
hBmpTampon = CreateCompatibleBitmap_(hDC, ps\rcPaint\right, ps\rcPaint\bottom)
If hBmpTampon
If hdcMem
SavedDC = SaveDC_(hDC)
SelectObject_(hdcMem, hBmpTampon)
SetTextColor_(hdcMem, #Blue)
SetBkMode_(hdcMem, #OPAQUE)
brush = CreateSolidBrush_(#Red)
FillRect_(hdcMem, ps\rcPaint, brush)
DeleteObject_(brush)
; on écrit le texte
DrawTextEx_(hdcMem, "essai", -1, ps\rcPaint, #DT_LEFT | #DT_VCENTER, 0)
; on copie le hDC de la mémoire vers celui du container
BitBlt_(hDC, ps\rcPaint\left, ps\rcPaint\top, ps\rcPaint\right, ps\rcPaint\bottom, hdcMem, ps\rcPaint\left, ps\rcPaint\top, #SRCCOPY)
DeleteDC_(hdcMem)
EndIf
DeleteObject_(hBmpTampon)
EndIf
RestoreDC_(hDC, SavedDC)
EndPaint_(hWnd, ps)
ProcedureReturn 0
EndIf
EndIf
;// traitement par défaut
ProcedureReturn CallWindowProc_(OldProc, hWnd, uMsg, wParam, lParam)
EndProcedure
If OpenWindow(0, 0, 0, 320, 250, "Frame3DGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ContainerGadget(117, 10, 70, 300, 50, #PB_Container_Raised)
OldProc = SetWindowLongPtr_(GadgetID(117), #GWLP_WNDPROC, @WinCallback())
CloseGadgetList()
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
tu peux modifier SetBkMode_(hdcMem, #Transparent) pour voir la différence
Re: ContainerGadget avec fond tranparent
Publié : dim. 04/oct./2009 20:27
par nico
En mettant un procedurereturn 0 après un WM_PAINT, le container ne sera pas dessiné.
Re: ContainerGadget avec fond transparent
Publié : dim. 04/oct./2009 21:57
par Le Soldat Inconnu
oui, j'ai essayé, ça ne marche pas
Code : Tout sélectionner
; Auteur : Le Soldat Inconnu
; Version de PB : 4.40
;
; Explication du programme :
; Pour faire des programmes de test rapidement, il ne reste qu'a rajouter les gadgets et la gestion des évènements.
Global NewMap ContainerGadgetTransparent.l()
Procedure ContainerGadgetCallBack(hwnd, uMsg, wParam, lParam)
If uMsg = #WM_PAINT
hdc = BeginPaint_(hwnd, @ps.PAINTSTRUCT)
If hdc
EndPaint_(hwnd, ps)
EndIf
ProcedureReturn 0
Else
ProcedureReturn CallWindowProc_(ContainerGadgetTransparent(Str(hwnd)), hwnd, uMsg, wParam, lParam)
EndIf
EndProcedure
Procedure SetContainerGadgetTransparent(Gadget)
ContainerGadgetTransparent(Str(GadgetID(Gadget))) = SetWindowLongPtr_(GadgetID(Gadget), #GWLP_WNDPROC, @ContainerGadgetCallBack())
EndProcedure
; Création de la fenêtre et de la GadgetList
If OpenWindow(0, 0, 0, 300, 300, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget) = 0
End
EndIf
SetWindowColor(0, $FF00FF)
; PanelGadget(0, 0, 0, 300, 300)
; AddGadgetItem(0, -1, "Transparent")
ContainerGadget(1, 50, 50, 200, 200, #PB_Container_BorderLess)
ButtonGadget(5, 10, 10, 64, 32, "Test")
TextGadget(6, 50, 50, 64, 16, "Texte")
CloseGadgetList()
SetContainerGadgetTransparent(1)
; AddGadgetItem(0, -1, "Normal")
;
; ContainerGadget(2, 50, 50, 200, 200, #PB_Container_BorderLess)
;
; ButtonGadget(7, 10, 10, 64, 32, "Test")
; TextGadget(8, 50, 50, 64, 16, "Texte")
;
; CloseGadgetList()
;
; CloseGadgetList()
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Menu
Select EventMenu() ; Menus
EndSelect
Case #PB_Event_Gadget
Select EventGadget() ; Gadgets
EndSelect
EndSelect
Until Event = #PB_Event_CloseWindow
Re: ContainerGadget avec fond transparent
Publié : dim. 04/oct./2009 22:57
par Anonyme
Passe toi des containers si tu ne trouves pas.
Code : Tout sélectionner
Structure Gadget_Info
Gadget_id.i
Group.i
endstructure
global newlist MyAppGagdetList.Gadget_Info()
si tu veut cacher les gadgets d'un même groupe , tu parcours simplement la liste et tu appliques la fonction adéquate.
@+
Re: ContainerGadget avec fond transparent
Publié : lun. 05/oct./2009 7:17
par Anonyme2
Voilà ce que je t'ai fait, fait varier la constante #alpha entre 0 et 255 et regardes.
Le calcul de la couleur finale se fait hors la callback pour ne pas avoir un cumul des couleurs.
Pour un dégradé, une image, , tu devras calculer l'ensemble des points.
A+
Code : Tout sélectionner
; Auteur : Le Soldat Inconnu
; détourné par denis
; Version de PB : 4.40
;
; Explication du programme :
; Pour faire des programmes de test rapidement, il ne reste qu'a rajouter les gadgets et la gestion des évènements.
Global CouleurContainer, CouleurFenetre, NouvelleCouleurContainer
Global RougeAfficher, VertAfficher, BleuAfficher
#alpha = 100
Global NewMap ContainerGadgetTransparent.l()
Procedure ContainerGadgetCallBack(hwnd, uMsg, wParam, lParam)
If uMsg = #WM_PAINT
hdc = BeginPaint_(hwnd, @ps.PAINTSTRUCT)
If hdc
brush = CreateSolidBrush_(NouvelleCouleurContainer)
If brush
FillRect_(hdc, ps\rcPaint, brush)
DeleteObject_(brush)
EndIf
EndIf
EndPaint_(hwnd, ps)
ProcedureReturn 0
EndIf
ProcedureReturn CallWindowProc_(ContainerGadgetTransparent(Str(hwnd)), hwnd, uMsg, wParam, lParam)
EndProcedure
Procedure SetContainerGadgetTransparent(Gadget)
ContainerGadgetTransparent(Str(GadgetID(Gadget))) = SetWindowLongPtr_(GadgetID(Gadget), #GWLP_WNDPROC, @ContainerGadgetCallBack())
EndProcedure
; Création de la fenêtre et de la GadgetList
If OpenWindow(0, 0, 0, 300, 300, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget) = 0
End
EndIf
SetWindowColor(0, $FF00FF)
; PanelGadget(0, 0, 0, 300, 300)
; AddGadgetItem(0, -1, "Transparent")
ContainerGadget(1, 50, 50, 200, 200, #PB_Container_BorderLess)
ButtonGadget(5, 10, 10, 64, 32, "Test")
TextGadget(6, 50, 50, 64, 16, "Texte")
CloseGadgetList()
SetContainerGadgetTransparent(1)
CouleurContainer = GetGadgetColor(1, #PB_Gadget_BackColor)
If CouleurContainer = -1
;// la couleur d'origine de la fenêtre
CouleurContainer = GetSysColor_(#COLOR_WINDOW)
EndIf
CouleurFenetre = GetWindowColor(0)
If CouleurFenetre = -1
CouleurFenetre = GetSysColor_(#COLOR_WINDOW)
EndIf
;// on mélange chaque composante
RougeAfficher = (Red(CouleurContainer) * #alpha / 255) + Red(CouleurFenetre) * (255 - #alpha) / 255
VertAfficher = (Green(CouleurContainer) * #alpha / 255) + Green(CouleurFenetre) * (255 - #alpha) / 255
BleuAfficher = (Blue(CouleurContainer) * #alpha / 255) + Blue(CouleurFenetre) * (255 - #alpha) / 255
NouvelleCouleurContainer = RGB(RougeAfficher, VertAfficher, BleuAfficher)
; Debug GetParent_(GadgetID(1))
; Debug WindowID(0)
; AddGadgetItem(0, -1, "Normal")
;
; ContainerGadget(2, 50, 50, 200, 200, #PB_Container_BorderLess)
;
; ButtonGadget(7, 10, 10, 64, 32, "Test")
; TextGadget(8, 50, 50, 64, 16, "Texte")
;
; CloseGadgetList()
;
; CloseGadgetList()
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Menu
Select EventMenu() ; Menus
EndSelect
Case #PB_Event_Gadget
Select EventGadget() ; Gadgets
EndSelect
EndSelect
Until Event = #PB_Event_CloseWindow
Re: ContainerGadget avec fond transparent
Publié : lun. 05/oct./2009 14:10
par Anonyme2
Voilà un code avec une image
Il faut faire varier la constante #alpha entre 0 et 255
C'est pas du plus rapide, ça demande à être optimisé, c'est bien ce que tu cherches à faire ?
L'image est ici pour le test, donc modifier le chemin dans le code en datasection
Code : Tout sélectionner
; Auteur : Denis
; Version de PB : 4.40
;
; Explication du programme :
; application de la transparence à un containergadget
EnableExplicit
UseJPEGImageDecoder()
Global CouleurContainer, CouleurFenetre, NouvelleCouleurContainer
Global RougeAfficher, VertAfficher, BleuAfficher
Global brush1, Event
#alpha = 128
Global NewMap ContainerGadgetTransparent.l()
Procedure ContainerGadgetCallBack(hwnd, uMsg, wParam, lParam)
Protected ps.PAINTSTRUCT
Protected hDC, imageDC
Protected hdcMem
Protected hBmpTampon
Protected SavedDC
Protected brush
Protected x, y
Protected GadgetX, GadgetY, X_max, Y_Max
If uMsg = #WM_PAINT
Select hwnd
Case GadgetID(1)
If IsImage(0)
hDC = BeginPaint_(hwnd, @ps.PAINTSTRUCT)
If hDC
hdcMem = CreateCompatibleDC_(hDC)
hBmpTampon = CreateCompatibleBitmap_(hDC, ps\rcPaint\right, ps\rcPaint\bottom)
If hBmpTampon
If hdcMem
SavedDC = SaveDC_(hDC)
SelectObject_(hdcMem, hBmpTampon)
CouleurContainer = GetGadgetColor(1, #PB_Gadget_BackColor)
If CouleurContainer = -1
;// la couleur d'origine de la fenêtre
CouleurContainer = GetSysColor_(#COLOR_WINDOW)
EndIf
;// le container se trouve à la position x=50 et y = 50 sur la fenêtre
imageDC = StartDrawing(ImageOutput(0))
If imageDC
;// on copie point par point la zone de imageDC qui est recouverte par
;// le container, en faisant le mélange des couleur pour transparence
;// l'opération est faite sur le dc temporaire pour éviter le scintillement
GadgetX = GadgetX(1)
GadgetY = GadgetY(1)
X_max = GadgetWidth(1) + gadgetX - 1
Y_max = GadgetHeight(1) + GadgetY - 1
For x = GadgetX To X_max
For y = gadgetY To Y_max
;// on retrouve la couleur du point courant de l'image ou le container est superposé
CouleurFenetre = GetPixel_(imageDC, x, y)
;// on mélange chaque composante pour chaque pixel
RougeAfficher = (Red(CouleurContainer) * #alpha / 255) + Red(CouleurFenetre) * (255 - #alpha) / 255
VertAfficher = (Green(CouleurContainer) * #alpha / 255) + Green(CouleurFenetre) * (255 - #alpha) / 255
BleuAfficher = (Blue(CouleurContainer) * #alpha / 255) + Blue(CouleurFenetre) * (255 - #alpha) / 255
NouvelleCouleurContainer = RGB(RougeAfficher, VertAfficher, BleuAfficher)
;// on copie le point sur le dc temporaire
SetPixel_(hdcMem, x-GadgetX, y-GadgetY, NouvelleCouleurContainer)
Next y
Next x
StopDrawing()
EndIf
;// on copie le hDC de la mémoire vers celui du container
BitBlt_(hDC, ps\rcPaint\left, ps\rcPaint\top, ps\rcPaint\right, ps\rcPaint\bottom, hdcMem, ps\rcPaint\left, ps\rcPaint\top, #SRCCOPY)
DeleteDC_(hdcMem)
EndIf
DeleteObject_(hBmpTampon)
EndIf
RestoreDC_(hDC, SavedDC)
EndPaint_(hWnd, ps)
ProcedureReturn 0
EndIf
EndIf
EndSelect
ProcedureReturn 0
EndIf
ProcedureReturn CallWindowProc_(ContainerGadgetTransparent(Str(hwnd)), hwnd, uMsg, wParam, lParam)
EndProcedure
Procedure SetContainerGadgetTransparent(Gadget)
ContainerGadgetTransparent(Str(GadgetID(Gadget))) = SetWindowLongPtr_(GadgetID(Gadget), #GWLP_WNDPROC, @ContainerGadgetCallBack())
EndProcedure
; Création de la fenêtre et de la GadgetList
If OpenWindow(0, 0, 0, 450, 335, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget) = 0
End
EndIf
If CatchImage(0, ?img)
brush1 = CreatePatternBrush_(ImageID(0))
If brush1
SetClassLong_(WindowID(0),#GCL_HBRBACKGROUND, brush1)
EndIf
Else
End
EndIf
ContainerGadget(1, 50, 50, 200, 200, #PB_Container_BorderLess)
ButtonGadget(5, 10, 10, 64, 32, "Test")
TextGadget(6, 50, 50, 64, 16, "Texte")
CloseGadgetList()
SetContainerGadgetTransparent(1)
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Menu
Select EventMenu() ; Menus
EndSelect
Case #PB_Event_Gadget
Select EventGadget() ; Gadgets
EndSelect
EndSelect
Until Event = #PB_Event_CloseWindow
If brush1
DeleteObject_(brush1)
EndIf
DataSection
Img:
IncludeBinary("K:\Images\new_image111.jpg")
EndDataSection
Re: ContainerGadget avec fond transparent
Publié : lun. 05/oct./2009 14:16
par Anonyme2
Il faudrait voir aussi l'API AlphaBlend(), j'avais pondu un code il y a quelques temps déjà
http://msdn.microsoft.com/en-us/library ... 85%29.aspx
Re: ContainerGadget avec fond transparent
Publié : lun. 05/oct./2009 17:26
par Le Soldat Inconnu
Merci du coup de main, Denis.
Mais je crois que la seule solution valable est de créer des groupes via une List, comme CPL Bator l'a proposé
Sinon, c'est trop lourd à gérer et ça n'a pas d'intérêt.
Car à la base, je groupe mes gadgets dans un container pour aller plus vite après

Re: ContainerGadget avec fond transparent
Publié : lun. 05/oct./2009 17:53
par Anonyme2
Tu veux cacher aussi les gadgets qui sont dans le container ?
Si c'est le cas, je n'ai pas saisi ta question

Re: ContainerGadget avec fond transparent
Publié : lun. 05/oct./2009 18:44
par Le Soldat Inconnu
non, je groupe des gadget dans un container pour pouvoir les masquer facilement, ou tous les déplacer d'un coup.
Mais le problème du container, c'est que il se voit, notamment si il est dans un panelgadget
par exemple, sous XP avec le thème gris, le panelgadet est blanc et le fond de la fenêtre est gris. Donc le containergadget se voit
Re: ContainerGadget avec fond transparent
Publié : lun. 05/oct./2009 20:19
par Flype
J'ai déjà eu a réfléchir à ce problème, et à mon sens, je suis d'accord avec toi, le but
est de simplifier et s'il faut en passer par des callbacks pour si peu c'est pas 'rentable'.
Je pense que le meilleur moyen si on persiste à travailler avec les containergadget (et il y a pleins d'arguments) c'est de lui mettre la même couleur de fond que son gadget parent.
Du moins c'est une solution suffisamment élégante et 'standard'
car elle est elle même utilisée par le Visual Designer de Visual Studio.
Et purebasic propose la fonction qui va bien pour çà (et compatible avec les containergadget) :
SetGadgetColor(1, #PB_Gadget_BackColor, maCouleurDeFond)
Reste à récupérer la couleur de fond du gadget parent. Il y a plusieurs solutions pour çà.
NB:
Sous .NET chaque gadget créer dans un autre gadget parent, prend automatiquement la couleur de fond du gadget parent (et que la couleur du fond). C'est très pratique l'air de rien, et un mode du genre sous PB serait apprécié.
Re: ContainerGadget avec fond transparent
Publié : lun. 05/oct./2009 20:41
par Flype
nb: je viens de voir ton rapport de bug sur le forum anglais.
'arrive' en anglais c'est pas terrible.
'manage' pour 'réussir' c'est mieux.
If i manage to find reason

Re: ContainerGadget avec fond transparent
Publié : mar. 06/oct./2009 13:05
par Anonyme2
Salut Flype, le problème du soldat c'est :
"je cherche à faire un ContainerGadget dont le fond est transparent.
pourquoi ?
Car si je mets mon containergadget dans une fenêtre, ou dans un panelgadget (fond de couleur différente de la fenêtre avec dégradé), je veux qu'il reste invisble."
Si le fond est dégradée, la solution passe par le traitement de l'image, ou il existe une solution que je ne connais pas
Peut-être as-tu une solution plus simple
Re: ContainerGadget avec fond transparent
Publié : mar. 06/oct./2009 19:55
par Flype
oula autant pour moi.
non, je n'ai rien de simple à proposer dans ce cas précis.
si ce n'est de se faire un jeu de fonctions pour gérer une sorte de container,
en gérant une liste de gadgets avec leurs coordonnées ou un truc du genre (comme çà a été évoqué).