Seite 2 von 2

Re: Hintergrundfarbe aller Gadgets im Container ändern

Verfasst: 22.02.2014 15:23
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.

Re: Hintergrundfarbe aller Gadgets im Container ändern

Verfasst: 22.02.2014 16:29
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.

Re: Hintergrundfarbe aller Gadgets im Container ändern

Verfasst: 02.02.2026 14:46
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()

Re: Hintergrundfarbe aller Gadgets im Container ändern

Verfasst: 02.02.2026 17:15
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

Re: Hintergrundfarbe aller Gadgets im Container ändern

Verfasst: 02.02.2026 18:12
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...

Re: Hintergrundfarbe aller Gadgets im Container ändern

Verfasst: 03.02.2026 13:19
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()

Re: Hintergrundfarbe aller Gadgets im Container ändern

Verfasst: 03.02.2026 20:07
von HeX0R
Zapman hat da auch was cooles gebastelt.