ContainerGadget avec fond transparent

Programmation d'applications complexes
Anonyme

Re: ContainerGadget avec fond transparent

Message par Anonyme »

Container , à la poubelle :D , c'est fin , je sais...

pour me faire pardonner voila ma petite idée en gros :

Code : Tout sélectionner

Structure GadgetGroup
 GadgetID.i
 Group.i
EndStructure

Global NewList GadgetGroup.GadgetGroup()



Procedure.i TextGadgetEX(Gadget,x,y,Width,Height,Text$,GroupID,Flag=#Null)
GadgetID = TextGadget(Gadget,x,y,Width,Height,Text$,Flag)
    AddElement(GadgetGroup())
    GadgetGroup()\GadgetID = Gadget
    GadgetGroup()\Group    = GroupID
ProcedureReturn GadgetID
EndProcedure


Procedure HideGadgetGroup(Group,State)
ForEach GadgetGroup()
  If GadgetGroup()\Group = Group
    HideGadget(GadgetGroup()\GadgetID,State)
  EndIf 
Next 
EndProcedure
@+
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Re: ContainerGadget avec fond transparent

Message par nico »

En rajoutant le message #WM_ERASEBKGND, ça marche!

Code : Tout sélectionner

Global NewMap ContainerGadgetTransparent.l()
Procedure ContainerGadgetCallBack(hwnd, uMsg, wParam, lParam)

		If uMsg = #WM_ERASEBKGND
				ProcedureReturn 1
		EndIf

    ;ici pas nécessaire
		If uMsg = #WM_NCPAINT
				ProcedureReturn 0
		EndIf
		
		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)
				SetContainerGadgetTransparent(1)		
				
				ButtonGadget(5, 10, 10, 64, 32, "Test")
				TextGadget(6, 50, 50, 64, 16, "Texte")
				
		CloseGadgetList()

		
		
		; 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
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: ContainerGadget avec fond transparent

Message par Le Soldat Inconnu »

Joli ! Merci Nico

C'est presque bon, parce que quand je sors la fenêtre de l'écran puis je reviens, c'est tout rose (j'ai remis le panel gadget), il dois manquer un petit truc

Code : Tout sélectionner

Global NewMap ContainerGadgetTransparent.l()
Procedure ContainerGadgetCallBack(hwnd, uMsg, wParam, lParam)
	Select uMsg 
		Case #WM_ERASEBKGND
			ProcedureReturn 1
		Case #WM_NCPAINT
			ProcedureReturn 0
		Case #WM_PAINT
			hdc = BeginPaint_(hwnd, @ps.PAINTSTRUCT)
			If hdc
				EndPaint_(hwnd, ps)
			EndIf
			ProcedureReturn 0
		Default
			ProcedureReturn CallWindowProc_(ContainerGadgetTransparent(Str(hwnd)), hwnd, uMsg, wParam, lParam)
	EndSelect
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, 600, 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)
		SetContainerGadgetTransparent(1)      
		
		ButtonGadget(5, 10, 10, 64, 32, "Test")
		TextGadget(6, 50, 50, 64, 16, "Texte")
		
	CloseGadgetList()
	
	
	
	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()


ContainerGadget(3, 350, 50, 200, 200, #PB_Container_BorderLess)
	SetContainerGadgetTransparent(3)      
	
	ButtonGadget(9, 10, 10, 64, 32, "Test")
	TextGadget(10, 50, 50, 64, 16, "Texte")
	
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
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Re: ContainerGadget avec fond transparent

Message par nico »

J'ai essayé de remplacer le container gadget par une fenêtre créer avec des API mais c'est pareil, y a rien à faire!
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Re: ContainerGadget avec fond transparent

Message par nico »

J'ai trouvé l'API qui va bien pour les thèmes, j'ai remarqué qu'un container sur un TabControl est toujours redessiné en entier même s'il n'est recouvert que partiellement (je ne sais pas si Fred pourra corriger cela), sinon ça marche très bien.

Un container sur un container sera lui aussi transparent!

Voici le code:

Code : Tout sélectionner

Structure Panel
	Region.l
	Parent.l
EndStructure

Procedure ChildWindows(hwnd.l,*Pointer.Panel)
	Protected RegionGadget.l,rect.rect
	
	If *Pointer\Region=0
		*Pointer\Region=CreateRectRgn_(0,0,0,0)
	EndIf 
	
	GetWindowRect_(hwnd,@rect.rect)
	ScreenToClient_(*Pointer\Parent,@rect)
 	ScreenToClient_(*Pointer\Parent,@rect+8)
	
	RegionGadget=CreateRectRgn_(rect\left,rect\top,rect\right,rect\bottom)
	CombineRgn_(*Pointer\Region,*Pointer\Region,RegionGadget,#RGN_OR)
	DeleteObject_(RegionGadget)
	
	ProcedureReturn 1
EndProcedure 

Procedure DrawBackGround(Gadget.l,hdc.l,*rc.RECT,hregion.l)
	Protected rect.Rect,Parent.l,Class.s,ID_Library
	Protected ThemePanel.l,hbrush.l,deleteBrush.l
	Protected HdcMem.l,hbitmap.l,Panel.Panel
	Protected HdcMem2.l,hbitmap2.l,rectParent.rect
	
	Parent=Gadget
	Repeat
		Parent=GetParent_(Parent)
		Class.s=Space(SizeOf(character)*255)
		GetClassName_(Parent,@Class,254)
	Until Class<>"PureContainer"
	
	If Class="Static"
		;-----------------------------------------------
		; Dans ce cas je construit une région en ôtant les fenêtres enfants
		; Car un ContainerGadget sur un Panel est toujours redessiné en entier!
		;-----------------------------------------------
		; d'où clignotement des fenêtres enfants
		;-----------------------------------------------
		Panel\Region=0
		Panel\Parent=Gadget
		EnumChildWindows_(Gadget,@ChildWindows(),@Panel)
		If Panel\Region
			CombineRgn_(hregion,hregion,Panel\Region,#RGN_DIFF)
			DeleteObject_(Panel\Region)
		EndIf
		
		; ------- Traitement si le Parent est un Panel ---------------
		If OSVersion()=>#PB_OS_Windows_XP And FindResource_(GetModuleHandle_(0),1,24)<>0
			ID_Library=OpenLibrary(#PB_Any,"UxTheme.dll")
			If ID_Library<>0
				If CallFunction(ID_Library,"IsThemeActive")=1 
					If CallFunction(ID_Library,"IsAppThemed")=1
						;Traitement si les thèmes sont activés 
						
						CopyMemory(*rc.RECT,rect.Rect,SizeOf(Rect))
						ClientToScreen_(Gadget,@rect)
						ClientToScreen_(Gadget,@rect+8)
						ScreenToClient_(Parent,@rect)
						ScreenToClient_(Parent,@rect+8)
						
						GetClientRect_(Parent,@rectParent.rect)
						HdcMem.l=CreateCompatibleDC_(hdc)
						hbitmap=CreateCompatibleBitmap_(hdc,rectParent\right,rectParent\bottom)
						SelectObject_(hdcmem,hbitmap)
						
						HdcMem2.l=CreateCompatibleDC_(hdc)
						hbitmap2=CreateCompatibleBitmap_(Hdc,*rc\right,*rc\bottom)
						SelectObject_(hdcmem2,hbitmap2)
						
						CallFunction(ID_Library,"DrawThemeParentBackground",Parent, HdcMem, rect) 
						
						BitBlt_(hdcMem2,0,0,*rc\right,*rc\bottom,HdcMem,rect\left,rect\top,#SRCCOPY)
						
						hbrush=CreatePatternBrush_(hbitmap2)
						FillRgn_(hdc,hregion,hbrush)    
						
						DeleteDC_(HdcMem)
						DeleteObject_(hbitmap)
						
						DeleteDC_(HdcMem2)
						DeleteObject_(hbitmap2)
						
						DeleteObject_(hbrush)
						
						ThemePanel=1
					EndIf
				EndIf 
				CloseLibrary(ID_Library)		
			EndIf
		EndIf 
		
		If ThemePanel
			ProcedureReturn 1
		Else
			;Traitement si les thèmes ne sont pas activés  
			hbrush=CreateSolidBrush_(GetSysColor_(#COLOR_BTNFACE))
			FillRgn_(hdc,hregion,hbrush)
			DeleteObject_(hbrush)
			ProcedureReturn 1
		EndIf 
	EndIf 
EndProcedure

Procedure.l ProcSkinGadget( hWnd, Msg,  wParam, lParam)
	Protected OriginProc.l,hrgn.l,rc.rect
	
	OriginProc= GetProp_(hWnd, "ProcSkinGadget")
	
	Select Msg
		Case #WM_ERASEBKGND
			ProcedureReturn 1
			
		Case #WM_PAINT
			GetClientRect_(hwnd,@rc)   
			
			hrgn=CreateRectRgn_(0,0,0,0)
			GetUpdateRgn_(hwnd,hrgn,0)
			
			HdcPaint=BeginPaint_(hWnd,@lpPaint.PAINTSTRUCT)   
			DrawBackGround(hwnd,HdcPaint,@rc,hrgn)
			EndPaint_(hWnd,@lpPaint)
			
			DeleteObject_(hrgn)
			ProcedureReturn 0
			
		Case #WM_THEMECHANGED,#WM_SYSCOLORCHANGE
  		    ; Pas nécessaire car le changement de thème ou de couleurs systèmes
  		    ; du Panel provoque un rafraichissement des fenêtres filles
  		    ;InvalidateRect_(hwnd,0,1) 
			
		Case #WM_NCDESTROY
			SetWindowLong_(hWnd, #GWL_WNDPROC, OriginProc)
			RemoveProp_(hWnd,"ProcSkinGadget")     
	EndSelect
	ProcedureReturn CallWindowProc_(OriginProc,hWnd,Msg,wParam,lParam)
EndProcedure


#Fenetre=0

If OpenWindow(#Fenetre, 0, 0, 600, 600, "PanelGadget", #PB_Window_SystemMenu | #PB_Window_SizeGadget| #PB_Window_ScreenCentered)
	
	PanelGadget(0, 8, 8, 400, 400)
		AddGadgetItem(0,-1, "Onglet 1")
		ContainerGadget(15,180,160,200,200);,#PB_Container_Flat)
			ContainerGadget(16,50,50,100,100);,#PB_Container_Flat)
				ButtonGadget(17,10,10,60,20,"ok")
			CloseGadgetList()
		CloseGadgetList()
	CloseGadgetList()
	
	
	OriginProc = SetWindowLong_(GadgetID(15), #GWL_WNDPROC, @ProcSkinGadget())
	SetProp_(GadgetID(15), "ProcSkinGadget", OriginProc)
	
	OriginProc = SetWindowLong_(GadgetID(16), #GWL_WNDPROC, @ProcSkinGadget())
	SetProp_(GadgetID(16), "ProcSkinGadget", OriginProc)
	
	
	SetWindowColor(#Fenetre,RGB(125,200,255))
	
	Repeat
		event=WaitWindowEvent()
		Select event
			Case #PB_Event_Gadget
				Select EventGadget()
					Case 17
						Debug "Cliqué"
						
				EndSelect
		EndSelect
	Until event=#PB_Event_CloseWindow
EndIf
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: ContainerGadget avec fond transparent

Message par Le Soldat Inconnu »

Je ne sais pas trop comment tu arrives a pondre ce genre de chose 8O

C'est presque bon, en fait, quand tu redessines le fond du gadget sous le container, il commencer à dessiner le fond à partir de la position rc.rect du gadget parent du container (au lieu du rc.rect du container).

Je chercherais comment faire plus tard, je vais me promener la :)
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Re: ContainerGadget avec fond transparent

Message par nico »

il commencer à dessiner le fond à partir de la position rc.rect du gadget parent du container (au lieu du rc.rect du container)
Tu veux dire que dans l'API DrawThemeParentBackground, le rect doit correspondre au parent et non au gadget lui même, je ne voyais pas ça comme ça, mais ça parait logique en même temps.

Quel thème tu utilises pour t'être rendu compte de ça, cela m'intéresse pour faire des essais!
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: ContainerGadget avec fond transparent

Message par Le Soldat Inconnu »

j'ai un thème perso et dans les panelgadget, le fond est avec un dégradé de couleur.
Donc le dégradé ne commençait pas au bon endroit dans le containergadget :)
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Re: ContainerGadget avec fond transparent

Message par nico »

Est ce que tu pourrais me filer ton thème?, j'en aurais besoin pour des essais.
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: ContainerGadget avec fond transparent

Message par Le Soldat Inconnu »

Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Re: ContainerGadget avec fond transparent

Message par nico »

Code précédent mis à jour, tu peux me confirmer que c'est bon. :)
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: ContainerGadget avec fond transparent

Message par Le Soldat Inconnu »

Super :)

La grande classe
Merci Nico
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: ContainerGadget avec fond transparent

Message par Backup »

je viens de tester le dernier code posté

j'ai une fenetre bleu clair et dessus un container gris et un onglet gris

est-ce normal ?

je ne vois pas de transparence la dedans.. :)

sur NC10; XP pack3 ;PB 4.40

Image
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: ContainerGadget avec fond transparent

Message par Le Soldat Inconnu »

le but es de ne pas voir le container gadget.

Je prend un exemple, l'onglet à un fond de couleur blanche (comme sous vista) et le containergadget à un fond gris comme les fenêtre.
Et bien si je place un container gadget dans un onglet, il est visible.

Avec le code de Nico, on ne voit pas le container gadget
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: ContainerGadget avec fond transparent

Message par Backup »

ha ! ok ok ! :)
Répondre