Montag, 23. Juli 2018

Tricksen mit dem Toolbarobjekt / fiddling with the toolbar object

Vor einiger Zeit arbeitete ich an einer Sidebar ähnlich der von Yousfi Benameur, nur mit VFP Bordmitteln. Hierbei stand ich vor dem Problem, dass das Toolbarobjekt nach dem Andocken nur im Rahmen seiner Größe basierend auf den darin befindlichen Objekten mit der von mir definierten Hintergrundfarbe versehen war. Der Rest wurde mit dem Standard-Grau für den Toolbarbereich gefüllt.
Vorsichtig ausgedrückt sah das ziemlich bescheiden aus, hatte es doch keinerlei Ähnlichkeit mit dem von mir gewünschten Effekt von einer einheitlichen Farbe für den gesamten Toolbarbereich.

Die von mir gefundene Lösung basiert darauf, dass beim Andocken der Toolbar zur Laufzeit ein Füllobjekt (ein simpler 'container') hinzugefügt wird und beim Lösen oder Repositionieren das Füllobjekt umgehend entsorgt und ggf. wieder erzeugt wird.

Problematisch hierbei war, dass sich VFP bei den diversen Tests regelmäßig verabschiedete. Sogar C0000005 Fehler traten hierbei auf.
Es stellte sich heraus, dass der Fuchs ziemlich verschnupft reagiert wenn zur Laufzeit eines der Toolbarobjekte (in diesem Fall das Füllobjekt) eine Größenänderung erhält. Zudem muss peinlich genau darauf geachtet werden wann ein Objekt entfernt und hinzugefügt wird, denn die Toolbar-Ereignisse BEFOREDOCK, UNDOCK, DOCKED und AFTERDOCK bekommen sich unter Umständen gar heftig in die Wolle.

Letztlich müssen nur zwei Toolbarmethoden mit Code gefüllt werden: UNDOCK und AFTERDOCK.

In UNDOCK versuchen wir ein evtl. vorhandenes Füllobjekt zu entfernen:

TRY 
    This.RemoveObject( [oFiller] )
CATCH
ENDTRY 

In AFTERDOCK erzeugen wir das Füllobjekt und definieren sein Aussehen, denn entweder ist es flach und breit oder schmal und hoch:

DO CASE 
CASE INLIST( This.DockPosition , 0 , 3 )    && TOP/BOTTOM

    This.AddObject( [oFiller] , [container] )
    
    This.oFiller.BorderWidth = 0
    This.oFiller.BackStyle   = 0

    This.oFiller.Height      = 22
    This.oFiller.Width       = SYSMETRIC( 1 )
    
    This.oFiller.Visible     = .T.

CASE INLIST( This.DockPosition , 1 , 2 )    && LEFT/RIGHT

    This.AddObject( [oFiller] , [container] )
    This.oFiller.BorderWidth = 0
    This.oFiller.BackStyle   = 0

    This.oFiller.Height      = SYSMETRIC( 2 )
    This.oFiller.Width       = 22
    
    This.oFiller.Visible     = .T.

ENDCASE 


Anschliessend hat man eine perfekt eingefärbte Toolbar :)

Wichtig bei o.a. Code ist, dass wir nicht die aktuelle Höhe und Breite vom _screen nehmen dürfen. Das Füllobjekt muss auf der maximalen Bildschirmhöhe bzw. -breite basieren, andernfalls hätte wir beim Wechseln in den Vollbildmodus wieder häßliche graue Flächen.



Wie an der o.a. Hardcopy gut zu erkennen ist, kann eine Toolbar nicht nur aus simplen Buttons bestehen. Im obigen Beispiel setzt sie sich vielmehr aus diversen spezialisierten Containerobjekten zusammen die tabellenbasierend zur Laufzeit erzeugt werden und als krönenden Abschluß das Füllobjekt untergeschoben bekommt.