#PB_Tree_AlwaysShowSelection Auswahl verdeutlichen

Windowsspezifisches Forum , API ,..
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
Benutzeravatar
HeX0R
Beiträge: 2954
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win10 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2
Kontaktdaten:

Re: #PB_Tree_AlwaysShowSelection Auswahl verdeutlichen

Beitrag von HeX0R »

So, nun die finale Version (Win only):

Code: Alles auswählen

Structure _TREE_DATA_
	*TreeCB
	GadgetID.i
	BackColor.i
	FrontColor.i
	Focused.b
	Item.i
EndStructure

Procedure TreeCallBack(hWnd, Message, wParam, lParam)
	Protected *TD._TREE_DATA_, Item, Result
	
	*TD = GetProp_(hwnd, "TREE_FOCUS")
	If *TD
		Select Message
			Case #WM_SETFOCUS
				*TD\Focused = #True
				Item = GetGadgetState(*TD\GadgetID)
				SetGadgetItemColor(*TD\GadgetID, Item, #PB_Gadget_BackColor, -1)
				SetGadgetItemColor(*TD\GadgetID, Item, #PB_Gadget_FrontColor, -1)
			Case #WM_KILLFOCUS
				*TD\Focused = #False
				Item = GetGadgetState(*TD\GadgetID)
				If Item > -1
					SetGadgetItemColor(*TD\GadgetID, Item, #PB_Gadget_BackColor, *TD\BackColor)
					SetGadgetItemColor(*TD\GadgetID, Item, #PB_Gadget_FrontColor, *TD\FrontColor)
					*TD\Item = Item
				EndIf
			Case #WM_DESTROY
			Case #WM_NCDESTROY
				Item = *TD\TreeCB
				FreeMemory(*TD)
				RemoveProp_(hwnd, "TREE_FOCUS")
				Result = CallWindowProc_(Item, hWnd, Message, wParam, lParam)
				ProcedureReturn Result
			Case #WM_PAINT
				Item = GetGadgetState(*TD\GadgetID)
				If Item <> *TD\Item And *TD\Item <> -1
					SetGadgetItemColor(*TD\GadgetID, *TD\Item, #PB_Gadget_BackColor, -1)
					SetGadgetItemColor(*TD\GadgetID, *TD\Item, #PB_Gadget_FrontColor, -1)
					If *TD\Focused = #False And Item > -1
						*TD\Item = Item
						SetGadgetItemColor(*TD\GadgetID, Item, #PB_Gadget_BackColor, *TD\BackColor)
						SetGadgetItemColor(*TD\GadgetID, Item, #PB_Gadget_FrontColor, *TD\FrontColor)
					Else
						*TD\Item = -1
					EndIf
				EndIf
		EndSelect

		Result = CallWindowProc_(*TD\TreeCB, hWnd, Message, wParam, lParam)
	EndIf
	
	ProcedureReturn Result
EndProcedure

Procedure DarkenColor(Color, Amount)
	Protected R, G, B
	
	R = (Color & $FF)             - Amount
	G = ((Color & $FF00) >> 8)    - Amount
	B = ((Color & $FF0000) >> 16) - Amount
	
	If R < 0 : R = 0 : EndIf
	If G < 0 : G = 0 : EndIf
	If B < 0 : B = 0 : EndIf
	
	Color = R | (G << 8) | (B << 16)
	
	ProcedureReturn Color
EndProcedure

Procedure TreeAddLostFocusColor(Gadget, BackColor.i = #PB_Default, FrontColor.i = #PB_Default)
	Protected *TD._TREE_DATA_
	
	If BackColor = #PB_Default
		BackColor = DarkenColor(GetSysColor_(#COLOR_HIGHLIGHT), 15)
	EndIf
	If FrontColor = #PB_Default
		FrontColor = DarkenColor(GetSysColor_(#COLOR_HIGHLIGHTTEXT), 15)
	EndIf
	
	*TD              = AllocateMemory(SizeOf(_TREE_DATA_))
	*TD\GadgetID     = Gadget
	*TD\BackColor    = BackColor
	*TD\FrontColor   = FrontColor
	*TD\Item         = -1
	*TD\TreeCB       = SetWindowLongPtr_(GadgetID(Gadget), #GWL_WNDPROC, @TreeCallBack())
	
	SetProp_(GadgetID(Gadget), "TREE_FOCUS", *TD)

EndProcedure

Procedure InitTree(Gadget)
	;Use this, to initialy set the colors correctly, especially when changing the state of the tree at the beginning
	Protected *TD._TREE_DATA_, Item
	
	*TD = GetProp_(GadgetID(Gadget), "TREE_FOCUS")
	If *TD
		Item = GetGadgetState(Gadget)
		If Item > -1
			Select *TD\Focused
				Case #True
					SetGadgetItemColor(Gadget, Item, #PB_Gadget_BackColor, -1)
					SetGadgetItemColor(Gadget, Item, #PB_Gadget_FrontColor, -1)
				Case #False
					SetGadgetItemColor(Gadget, Item, #PB_Gadget_BackColor, *TD\BackColor)
					SetGadgetItemColor(Gadget, Item, #PB_Gadget_FrontColor, *TD\FrontColor)
					*TD\Item = Item
			EndSelect
		EndIf
	EndIf
EndProcedure
	
CompilerIf #PB_Compiler_IsMainFile
	Define BackColor.i, FrontColor.i
	
	
	If OpenWindow(0, 0, 0, 355, 180, "TreeGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
		TreeGadget(0, 0, 10, 160, 160, #PB_Tree_NoButtons | #PB_Tree_NoLines)
		TreeAddLostFocusColor(0)
		StringGadget(1, 180, 10, 160, 24, "")
		ButtonGadget(2, 180, 40, 160, 24, "Unselect Tree")
		ButtonGadget(3, 180, 70, 160, 24, "Select Item 4")
		AddGadgetItem(0, -1, "Item 1")
		AddGadgetItem(0, -1, "Item 2")
		AddGadgetItem(0, -1, "Item 3")
		AddGadgetItem(0, -1, "Item 4")
		AddGadgetItem(0, -1, "Item 5")
		SetGadgetState(0, 0)
		SetActiveGadget(1)
		InitTree(0)
		Repeat
			Select WaitWindowEvent()
				Case #PB_Event_CloseWindow
					Break
				Case #PB_Event_Gadget
					Select EventGadget()
						Case 2
							SetGadgetState(0, -1)
						Case 3
							SetGadgetState(0, 3)
					EndSelect
			EndSelect
		ForEver
	EndIf
CompilerEndIf
Zuletzt geändert von HeX0R am 02.08.2019 08:33, insgesamt 5-mal geändert.
Benutzeravatar
Shardik
Beiträge: 738
Registriert: 25.01.2005 12:19

Re: #PB_Tree_AlwaysShowSelection Auswahl verdeutlichen

Beitrag von Shardik »

Du solltest in der "finalen" Version unbedingt hinter

Code: Alles auswählen

            Case #PB_Event_CloseWindow
noch

Code: Alles auswählen

               SetWindowLongPtr_(GadgetID(0), #GWL_WNDPROC, 0)
einbauen, da man sonst bei Beenden des Programms oft einen Absturz oder die Fehlermeldung "Zeile 27 - Ungültiger Speicherzugriff. (Schreibfehler an der Adresse 2)" bekommt... :wink:
Benutzeravatar
HeX0R
Beiträge: 2954
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win10 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2
Kontaktdaten:

Re: #PB_Tree_AlwaysShowSelection Auswahl verdeutlichen

Beitrag von HeX0R »

Den Fehler habe ich nie gesehen, wie kann man den denn reproduzieren?
Weil hinter Close-Window ist mal wieder Quatsch, weil wie gesagt: MEHRERE Trees!
Ich könnte es beim #WM_DESTROY reinbasteln, bin mir aber nicht sicher, ob das so funktioniert.
Benutzeravatar
Shardik
Beiträge: 738
Registriert: 25.01.2005 12:19

Re: #PB_Tree_AlwaysShowSelection Auswahl verdeutlichen

Beitrag von Shardik »

HeX0R hat geschrieben:Den Fehler habe ich nie gesehen, wie kann man den denn reproduzieren?
Ich habe unter Windows 10 x64 V1809 getestet mit PB 5.70 x86 und x64. Nach jedem Start und sofortigen Klick auf das Schließen-Symbol "x" erhalte ich (ohne die von mir hinzugefügte Zeile) die beschriebene Fehlermeldung.
Benutzeravatar
HeX0R
Beiträge: 2954
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win10 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2
Kontaktdaten:

Re: #PB_Tree_AlwaysShowSelection Auswahl verdeutlichen

Beitrag von HeX0R »

o.k., dann teste ich das daheim, muss hier im G'schäft mit Win7 vorlieb nehmen :)
Benutzeravatar
Shardik
Beiträge: 738
Registriert: 25.01.2005 12:19

Re: #PB_Tree_AlwaysShowSelection Auswahl verdeutlichen

Beitrag von Shardik »

Ich habe Dein finales Beispiel jetzt auch einmal unter Windows 7 SP1 x64 mit PB 5.70 x86 und x64 getestet und in der Tat bei jeweils 10 Versuchen keinen einzigen Fehler beim Beenden gehabt, während unter Windows 10 jedes Beenden mit dem beschriebenen Fehler oder sogar manchmal mit einem Absturz endete ("PureBasic executable ended unexpectedly...").

In jedem Fall ist es aber immer eine gute Idee, das Subclassing eines Gadgets vor Schließen eines Fensters zu beenden. Ich hatte unter Windows und MacOS damit schon öfter die beschriebenen Probleme, die dann auch nicht immer und schwer reproduzierbar (in x von y Fällen) auftraten, nach Beenden des Subclassing aber nie...
Benutzeravatar
HeX0R
Beiträge: 2954
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win10 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2
Kontaktdaten:

Re: #PB_Tree_AlwaysShowSelection Auswahl verdeutlichen

Beitrag von HeX0R »

Naja, in der ersten finalen Version hatte ich in der Tat einen doofen Fehler, eigentlich habe ich das mittlerweile auch beseitigt, aber eben ein anderes Problem festgestellt.
Wenn ich den Focus NICHT abgebe, aber auf ein anderes Item klicke, bleibt das erste markiert.
Sieht man natürlich nicht, wenn man sich so ein blödes Beispiel mit nur einem Item einfallen lässt ;)

Also nix mit finaler Version.

Das Hauptproblem in der ersten Fassung war übrigens, dass ich bei #WM_DESTROY schon alles freigegeben habe, und dann festgestellt habe, dass danach noch ein #WM_NCDESTROY kommt. Dann hat's natürlich geknallt.

[Edit]
Neue Version, kannst Du das mal testen?
Ich habe die Property einfach entfernt (hätte ich eh machen sollen), dann macht der Callback auch keinen Ärger mehr.
Benutzeravatar
HeX0R
Beiträge: 2954
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win10 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2
Kontaktdaten:

Re: #PB_Tree_AlwaysShowSelection Auswahl verdeutlichen

Beitrag von HeX0R »

Ich muss sagen, das Ganze ist doch nicht so einfach, wie ich dachte.
Nächstes Problem:
Sobald ich programmiertechnisch eine andere Zeile auswähle, oder aber die Auswahl beende, hat mein Callback davon natürlich nichts mitbekommen und die Zeile immer noch markiert.
Habe mich jetzt an den #WM_PAINT gehängt, der kommt immer, wenn sich im Tree was verändert hat.
Scheint auch nun zu funktionieren.

Im Nachhinein, hötte ich vielleicht tatsächlich nur SetSysColor verwenden sollen :mrgreen:
Benutzeravatar
Shardik
Beiträge: 738
Registriert: 25.01.2005 12:19

Re: #PB_Tree_AlwaysShowSelection Auswahl verdeutlichen

Beitrag von Shardik »

HeX0R hat geschrieben:[Edit]
Neue Version, kannst Du das mal testen?
Ich habe die Property einfach entfernt (hätte ich eh machen sollen), dann macht der Callback auch keinen Ärger mehr.
Ich habe Dein Beispiel nach der 4.Änderung (also nicht die aktuelle Version) mit PureBasic 5.70 x86 und x64 unter folgenden Windows-Versionen erfolgreich getestet gehabt:
- Windows 7 SP1 x64 (virtualisiert)
- Windows 8.1 x64 (virtualisiert)
- Windows 10 x64 V1809 (nativ)
Antworten