Hintergrundfarbe aller Gadgets im Container ändern

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Hintergrundfarbe aller Gadgets im Container ändern

Beitrag von ts-soft »

WIN 32 Programmierung - API Bible (Win95 / NT) aus dem SAMS Verlag finde ich da
wesentlich übersichtlicher. Nicht soviel langweiliges blabla, sondern die Infos, die man
sucht. Aber eben auch schon veraltet.

Mit Büchern aus dem Microsoft Press Verlag habe ich sowieso meine Probleme, die
darf man wohl nur im engl. Original lesen :mrgreen: , da reichen meine Englisch-
Kenntnisse aber nicht.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
SBond
Beiträge: 266
Registriert: 22.05.2013 20:35

Re: Hintergrundfarbe aller Gadgets im Container ändern

Beitrag von SBond »

ich sehe schon... jeder hat seine WinAPI-Bibel zu Hause und abends wird den Kindern immer eine spannende Geschichte daraus vorgelesen :mrgreen:
Ich wusste schon immer, dass mir im Leben etwas entscheidendes gefehlt hat ;). ...aber als Student sind 60€ schon eine Ansage.
41 6c 73 6f 20 77 65 6e 6e 20 64 75 20 73 6f 20 76 69 65 6c 20 4c 61 6e 67 65 77 65 69 6c 65 20 68 61 73 74 2c 20 64 61 6e 6e 20 6b 61 6e 6e 73 74 20 64 75 20 61 75 63 68 20 67 6c 65 69 63 68 20 7a 75 20 6d 69 72 20 6b 6f 6d 6d 65 6e 20 75 6e 64 20 61 62 77 61 73 63 68 65 6e 2e

:D
Michael Vogel
Beiträge: 74
Registriert: 16.03.2006 11:20

Re: Hintergrundfarbe aller Gadgets im Container ändern

Beitrag von Michael Vogel »

Hey, das ist ein guter Weg, mit relativ wenig Aufwand den Hintergrund von Gadgets anzupassen (auch mit PB6.xx)...
...ich habe ein paar weitere Gadgets zum Testen hinzugefügt, beim TrackGadget muss man scheinbar etwas nachhelfen, damit die Farbe automatisch aktualisiert wird (siehe Prozedur 'UpdateColors').

Es stellt sich die Frage, ob man - ohne großem Mehraufwand - auch die Textfarben leicht anpassen könnte. Der nächste Schritt ist dann Text und Hintergrund von Stringelementen und Comboboxen (insidetext,insidebackground), aber eins nach dem anderen ;)

Code: Alles auswählen


; Define

	#Container=	1; ein/aus

	EnableExplicit

	Enumeration
		#win
		CompilerIf #Container
			#cont
		CompilerEndIf
		#frame
		#check
		#radio1
		#radio2
		#string
		#combo
		#track
		#button
		#text
		#panel
	EndEnumeration

	#backcolor = $DFFFFF ;oder #white

	Global oldPanelWProc
	Global backColorBrush = CreateSolidBrush_(#backcolor)

; EndDefine

Procedure WindowCallback(hWnd, msg, wParam, lParam)

	Protected result = #PB_ProcessPureBasicEvents
	Protected *drawitem.DRAWITEMSTRUCT, paneltabtext.s

	Select msg
	Case #WM_CLOSE
		DeleteObject_(backColorBrush) ;Brush löschen bei Progende

	Case #WM_CTLCOLORSTATIC
		Select GetDlgCtrlID_(lparam)  ;holt Purebasic Gadgetnummer
		Case #frame, #text, #check, #radio1, #radio2, #track
			SetBkMode_(wParam, #TRANSPARENT) ;wParam ist das DC
			ProcedureReturn backColorBrush
		EndSelect

	Case #WM_DRAWITEM
		*drawitem.DRAWITEMSTRUCT = lParam
		With *drawitem
			If \CtlType = #ODT_TAB	   ;ist es ein Panelgadget ?
				If wParam = #panel      ;ist es das richtige Panel
					;hier wird jedes PanelTab eingefärbt und der Text geschrieben
					FillRect_(\hDC, \rcItem, backColorBrush)
					SetBkMode_(\hDC, #TRANSPARENT)
					paneltabtext = GetGadgetItemText(#panel, \itemID)
					\rcItem\top + 4
					\rcItem\left + 4
					TextOut_(\hDC, \rcItem\left, \rcItem\top, paneltabtext, Len(paneltabtext))
				EndIf
				ProcedureReturn #True
			EndIf
		EndWith

	EndSelect

	ProcedureReturn result
EndProcedure
Procedure PanelProc(hWnd, msg, wParam, lParam)
	;hier wird der Background des ganzen Panelgadgets eingefärbt
	Protected rect.Rect

	Select msg
	Case #WM_ERASEBKGND
		GetClientRect_(hWnd, rect)
		FillRect_(wParam, rect, backColorBrush)
		ProcedureReturn #True
	EndSelect

	ProcedureReturn CallWindowProc_(oldPanelWProc, hWnd, msg, wParam, lParam)
EndProcedure
Procedure UpdateColors(text,background,insidetext=#Black,insidebackground=#White)

	DeleteObject_(backColorBrush)

	CompilerIf #Container
		SetGadgetColor(#cont, #PB_Gadget_BackColor,background)
	CompilerElse
		SetWindowColor(#win,background)
	CompilerEndIf

	backColorBrush=CreateSolidBrush_(background)

	CompilerIf #Container
		InvalidateRect_(GadgetID(#cont),0,1)
	CompilerEndIf

	DisableGadget(#track,1)
	DisableGadget(#track,0)
	;RedrawWindow_(GadgetID(#track),0,0,#RDW_ERASENOW)
	;UpdateWindow_(GadgetID(#track))

EndProcedure

Procedure Main()

	Protected oldPanelStyle
	Protected quit

	OpenWindow(#win, 0, 0, 740, 260, "Gadget Colors", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

	CompilerIf #Container
		ContainerGadget(#cont, 20, 20, 700, 220, #PB_Container_Double)
	CompilerEndIf
	FrameGadget    (#frame, 10, 15, 400, 130, "Frame Test")
	CheckBoxGadget (#check,10,160,120,50,"Checkbox Test")
	OptionGadget   (#radio1,180,160,100,50,"Dark Mode")
	OptionGadget   (#radio2,310,160,100,50,"Light Mode")
	TrackBarGadget (#track,460,160,180,24,0,100)
	ButtonGadget   (#button, 20, 40, 120, 24, "Change Colors")
	TextGadget     (#text, 20, 80, 80, 18, "Static Text")
	StringGadget   (#string, 460, 20, 180, 28, "Editable Text")
	ComboBoxGadget (#combo, 460, 60, 180, 28,#PB_ComboBox_Editable)
	AddGadgetItem  (#combo, -1, "Entry 1")
	AddGadgetItem  (#combo, -1, "Entry 2")
	PanelGadget    (#panel, 180, 40, 200, 80)
	AddGadgetItem  (#panel, -1, "Test1 blabla")
	AddGadgetItem  (#panel, -1, "Test2")
	CloseGadgetList()
	CompilerIf #Container
		CloseGadgetList()
	CompilerEndIf


	CompilerIf #Container
		SetGadgetColor(#cont, #PB_Gadget_BackColor,#backcolor)
	CompilerElse
		SetWindowColor(#win,#backcolor)
	CompilerEndIf

	SetWindowCallback(@WindowCallback())

	;old Panel Proc + Style
	oldPanelWProc = GetWindowLongPtr_(GadgetID(#panel), #GWL_WNDPROC)
	oldPanelStyle = GetWindowLongPtr_(GadgetID(#panel), #GWL_STYLE)

	;new Panel Proc + Style
	SetWindowLongPtr_(GadgetID(#panel), #GWL_WNDPROC, @PanelProc())
	SetWindowLongPtr_(GadgetID(#panel), #GWL_STYLE, #TCS_OWNERDRAWFIXED | oldPanelStyle)


	Repeat
		Select WaitWindowEvent()
		Case #PB_Event_Gadget
			Select EventGadget()
			Case #button
				UpdateColors(#Black,Random(#White))
			Case #radio1
				UpdateColors(#White,$404040)
			Case #radio2
				UpdateColors(#Black,$FDFDF8)
			EndSelect
		Case #PB_Event_CloseWindow
			quit=1
		EndSelect
	Until quit

EndProcedure
Main()
SMaag
Beiträge: 187
Registriert: 08.05.2022 12:58

Re: Hintergrundfarbe aller Gadgets im Container ändern

Beitrag von SMaag »

ich muss jetzt mal nachfragen:

was spricht gegegen SetGadgetColor(#Gadget, #PB_Gadget_BackColor , Color)

zum Auflisten der Gadgetes kann man die PB SDK Funktionen benutzen.
Von mk-soft gibt es hierzu ein Beispiel.
viewtopic.php?f=8&t=31380
Benutzeravatar
Bisonte
Beiträge: 2476
Registriert: 01.04.2007 20:18

Re: Hintergrundfarbe aller Gadgets im Container ändern

Beitrag von Bisonte »

SMaag hat geschrieben: 02.02.2026 17:15 ich muss jetzt mal nachfragen:

was spricht gegegen SetGadgetColor(#Gadget, #PB_Gadget_BackColor , Color)
Es gibt unter Windows halt ein paar Gadgets die man damit nicht erreicht. ButtonGadget ist das Paradebeispiel dafür...
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
Michael Vogel
Beiträge: 74
Registriert: 16.03.2006 11:20

Re: Hintergrundfarbe aller Gadgets im Container ändern

Beitrag von Michael Vogel »

Leider kann die Farbe bei sehr vielen Gadgets nicht mit Purebasic-Befehlen geändert werden, das merkt man spätestens, wenn man einen Dark-Mode für ein Dialogfenster programmieren möchte...

Einige Gadget-Typen sind beispielsweise:
- Frame
- Option
- Checkbox
- Trackbar
- Combobox
- Button

Deshalb wäre eine möglichst einfache, universelle Lösung charmant... ;)


Im folgenden Code gibt es jetzt einen Mix und das TextGadget wird mit PureBasic-Befehlen eingefärbt. Je nach Hintergrund wird der Text nun weiß oder schwarz geschrieben. Das klappt jeoch, wie gesagt, nicht für die meisten anderen Gadgets, womit deren Texte bei dunklem Hintergrund nicht lesbar sind.

Code: Alles auswählen

; Define

	#Container=	1

	EnableExplicit

	Enumeration
		#win
		CompilerIf #Container
			#cont
		CompilerEndIf
		#frame
		#check
		#radio1
		#radio2
		#string
		#combo
		#track
		#button
		#text
		#panel
	EndEnumeration

	Global oldPanelWProc
	Global backcolor
	Global textcolor
	Global backColorBrush
	Global colorizing=		1
	Global wincolor=		GetSysColor_(#COLOR_3DFACE)
	Global darkbackground

	#Undefined=-1

; EndDefine

Procedure WindowCallback(hWnd, msg, wParam, lParam)

	Protected result = #PB_ProcessPureBasicEvents
	Protected *drawitem.DRAWITEMSTRUCT, paneltabtext.s

	If colorizing
		Select msg
		Case #WM_CLOSE
			DeleteObject_(backColorBrush) ;Brush löschen bei Progende

		Case #WM_CTLCOLORSTATIC
			Select GetDlgCtrlID_(lparam)  ;holt Purebasic Gadgetnummer
			Case #frame, #check, #radio1, #radio2, #track; #text wird mit 'normalen' SetGadgetColor-Befehlen eingefärbt
				SetBkMode_(wParam, #TRANSPARENT) ;wParam ist das DC
				ProcedureReturn backColorBrush
			EndSelect

		Case #WM_DRAWITEM
			*drawitem.DRAWITEMSTRUCT = lParam
			With *drawitem
				If \CtlType = #ODT_TAB	   ;ist es ein Panelgadget ?
					If wParam = #panel      ;ist es das richtige Panel
						;hier wird jedes PanelTab eingefärbt und der Text geschrieben
						FillRect_(\hDC, \rcItem, backColorBrush)
						SetBkMode_(\hDC, #TRANSPARENT)
						paneltabtext = GetGadgetItemText(#panel, \itemID)
						\rcItem\top + 4
						\rcItem\left + 4
						SetTextColor_(\hDC,textcolor)
						TextOut_(\hDC, \rcItem\left, \rcItem\top, paneltabtext, Len(paneltabtext))
					EndIf
					ProcedureReturn #True
				EndIf
			EndWith

		EndSelect

	EndIf

	ProcedureReturn result

EndProcedure
Procedure PanelProc(hWnd, msg, wParam, lParam)
	;hier wird der Background des ganzen Panelgadgets eingefärbt
	Protected rect.Rect

	Select msg
	Case #WM_ERASEBKGND
		GetClientRect_(hWnd, rect)
		FillRect_(wParam, rect, backColorBrush)
		ProcedureReturn #True
	EndSelect

	ProcedureReturn CallWindowProc_(oldPanelWProc, hWnd, msg, wParam, lParam)
EndProcedure
Procedure MixColors(ColorA,ColorB)

	ProcedureReturn (((ColorA&$FF0000)+ColorB&$FF0000)>>1)&$FF0000 + (((ColorA&$FF00)+ColorB&$FF00)>>1)&$FF00 + (((ColorA&$FF)+ColorB&$FF)>>1)
	ProcedureReturn (((ColorA&$FF0000)+ColorB&$FF0000*3)>>2)&$FF0000 + (((ColorA&$FF00)+ColorB&$FF00*3)>>2)&$FF00 + (((ColorA&$FF)+(ColorB&$FF)*3)>>2)

EndProcedure
Procedure UpdateColors(text,background,insidetext=#Black,insidebackground=#White)

	Protected color

	darkbackground=Bool((background&$FF + (background>>8)&$FF + (background>>16)&$FF)<256)*#White

	If text=#Undefined
		text=darkbackground
	EndIf

	If colorizing
		DeleteObject_(backColorBrush)

		textcolor=	text
		backcolor=	background
		color=		background
		backColorBrush=CreateSolidBrush_(background)

		SetGadgetColor(#string,#PB_Gadget_BackColor,MixColors(background,darkbackground!#White))
		SetGadgetColor(#string,#PB_Gadget_FrontColor,MixColors(text,darkbackground))

		SetGadgetColor(#text,#PB_Gadget_FrontColor,text)
		SetGadgetColor(#text,#PB_Gadget_BackColor,background)

	Else
		color=		wincolor
		text=		#Black

		SetGadgetColor(#string,#PB_Gadget_BackColor,#PB_Default)
		SetGadgetColor(#string,#PB_Gadget_FrontColor,#PB_Default)
		SetGadgetColor(#text,#PB_Gadget_BackColor,#PB_Default)
		SetGadgetColor(#text,#PB_Gadget_FrontColor,#PB_Default)

	EndIf

	CompilerIf #Container
		SetGadgetColor(#cont, #PB_Gadget_BackColor,color)
	CompilerElse
		SetWindowColor(#win,color)
	CompilerEndIf

	CompilerIf #Container
		InvalidateRect_(GadgetID(#cont),0,1)
	CompilerEndIf

	DisableGadget(#track,1)
	DisableGadget(#track,0)
	;RedrawWindow_(GadgetID(#track),0,0,#RDW_ERASENOW)
	;UpdateWindow_(GadgetID(#track))

EndProcedure

Procedure Main()

	Protected oldPanelStyle
	Protected color
	Protected quit

	OpenWindow(#win, 0, 0, 740, 260, "Gadget Colors", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

	CompilerIf #Container
		ContainerGadget(#cont, 20, 20, 700, 220, #PB_Container_Double)
	CompilerEndIf
	FrameGadget    (#frame, 10, 15, 400, 130, "Frame Test")
	CheckBoxGadget (#check,10,160,120,50,"Colorizing Off")
	OptionGadget   (#radio1,180,160,100,50,"Dark Mode")
	OptionGadget   (#radio2,310,160,100,50,"Light Mode")
	TrackBarGadget (#track,460,160,180,24,0,100)
	ButtonGadget   (#button, 20, 40, 120, 24, "Change Colors")
	TextGadget     (#text, 20, 80, 120, 18, "Static Text (B/W)")
	StringGadget   (#string, 460, 20, 180, 28, "Editable Text")
	ComboBoxGadget (#combo, 460, 60, 180, 28,#PB_ComboBox_Editable)
	AddGadgetItem  (#combo, -1, "Entry 1")
	AddGadgetItem  (#combo, -1, "Entry 2")
	PanelGadget    (#panel, 180, 40, 200, 80)
	AddGadgetItem  (#panel, -1, "Test1 blabla")
	AddGadgetItem  (#panel, -1, "Test2")
	CloseGadgetList()
	CompilerIf #Container
		CloseGadgetList()
	CompilerEndIf

	SetWindowCallback(@WindowCallback())

	;old Panel Proc + Style
	oldPanelWProc = GetWindowLongPtr_(GadgetID(#panel), #GWL_WNDPROC)
	oldPanelStyle = GetWindowLongPtr_(GadgetID(#panel), #GWL_STYLE)

	;new Panel Proc + Style
	SetWindowLongPtr_(GadgetID(#panel), #GWL_WNDPROC, @PanelProc())
	SetWindowLongPtr_(GadgetID(#panel), #GWL_STYLE, #TCS_OWNERDRAWFIXED | oldPanelStyle)

	UpdateColors(#Undefined,$FFE8CE)

	Repeat
		Select WaitWindowEvent()
		Case #PB_Event_Gadget
			Select EventGadget()
			Case #button
				UpdateColors(#Undefined,Random(#White))
			Case #radio1
				UpdateColors(#White,$404040)
			Case #radio2
				UpdateColors(#Black,$FDFDF8)
			Case #check
				colorizing=GetGadgetState(#check)!1
				UpdateColors(#Black,backcolor)
			EndSelect

		Case #PB_Event_CloseWindow
			quit=1

		EndSelect
	Until quit

EndProcedure
Main()
Benutzeravatar
HeX0R
Beiträge: 3060
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win11 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 + 3
Kontaktdaten:

Re: Hintergrundfarbe aller Gadgets im Container ändern

Beitrag von HeX0R »

Zapman hat da auch was cooles gebastelt.
Antworten