Dienstag, 15. Juni 2010

Marquee Texte schnell und einfach erzeugen / Creating marquee texts quick and easy

Wenn wir mit einfachen Mitteln einen Lauftext (Marquee) erzeugen bzw. darstellen wollen, dann ist alles, was wir benötigen eine Containerklasse mitsamt Label- und Timerobjekt. Dem Container verpassen wir noch einen Eigenschaft, mit welcher die Laufrichtung bzw. das Verhalten beim Verlassen des sichtbaren Bereiches gesteuert wird und fertig ist die Laube.

Der folgende Mustercode kann, wenn als PRG in Foxpro gestartet, über das Befehlsfenster direkt beeinflußt werden. Ausschlaggebend hierfür ist die Eigenschaft _screen.oMover._Mode. Sie verarbeitet die Werte 1 - 4 (Siehe Kommentare im Block Funktionstest des Codebeispiels). Defaultwert ist die 2 (Von rechts nach links bewegen).

* // Funktionstest -START-

_screen.AddObject([oMover],[cntMover])
_screen.oMover.Visible = .T.
* // kontinuierlich nach rechts scrollen        
* _screen.oMover._Mode = 1
* // kontinuierlich nach links scrollen    
* _screen.oMover._Mode = 2
* // JoJo-Effekt nach links initiieren        
* _screen.oMover._Mode = 3
* // JoJo-Effekt nach rechts initiieren        
* _screen.oMover._Mode = 4
* // Mover-Objekt entsorgen...                
*_screen.RemoveObject([oMover])



* // Funktionstest -ENDE-


DEFINE CLASS cntmover AS container

    Anchor = 14
    Width = 570
    Height = 20
    BackColor = RGB(128,128,128)
    Name = [cntmover]
    _Mode = 2

    ADD OBJECT lblmove AS label WITH ;
        AutoSize = .T., ;
        BackStyle = 0, ;
        Caption = [Timer basierender Marquee Text], ;
        Height = 17, ;
        Left = 1, ;
        Top = 3, ;
        Width = 280, ;
        ForeColor = RGB(255,255,255), ;
        Name = [lblMove]

    ADD OBJECT tmrmove AS timer WITH ;
        Top = 1, ;
        Left = 1, ;
        Height = 23, ;
        Width = 23, ;
        Interval = 20, ;
        Name = [tmrMove]

    PROCEDURE tmrmove.Timer
    
        WITH This.Parent

            DO CASE 
            CASE ._Mode = 1
            
                .lblMove.Left = .lblMove.Left - 1
                IF .lblMove.Left < .lblMove.Width * (-1)
                    .lblMove.Left = .Width
                ENDIF
                
            CASE ._Mode = 2
            
                .lblMove.Left = .lblMove.Left + 1
                IF .lblMove.Left > .Width
                    .lblMove.Left = .lblMove.Width * (-1)
                ENDIF
                
            CASE ._Mode = 3
            
                .lblMove.Left = .lblMove.Left - 1
                IF .lblMove.Left + .lblMove.Width < 1
                    ._Mode = 4
                ENDIF 
                
            CASE ._Mode = 4
            
                .lblMove.Left = .lblMove.Left + 1
                IF .lblMove.Left > .Width
                    ._Mode = 3
                ENDIF 
                
            ENDCASE 

        ENDWITH 
        
    ENDPROC

ENDDEFINE

2 Kommentare:

  1. Danke dafür, aber ist das ganze nicht Resourcenfressend? wenn alle 20 Millisekunden der Text Label neu gezeichnet werden muss...

    btw... du hast einen kleinen Fehler bei deinem Aufruf... man muss die "_MODE" Eigenschaft ändern und nicht die "_MOVE"

    gruß

    AntwortenLöschen
  2. Hallo Anonym,

    _Move ist korrigiert ;-)

    Ob das Ressourcen frist? Davon ist auszugehen, auch wenn es bei einem einfachen Label eher marginal sein dürfte. Die 20ms müssen aber sein, um eine fließende Bewegung des Labels zu erreichen. Alternativ kann man natürlich Consolas/Courier New als Schriftart auswählen, setzt den Time auf 500 oder sogar 1000 hoch und repositioniert das Label jeweils um einen kompletten Buchstaben. Dann ruckelt es zwar ein wenig, aber sollte ebenfalls lesbar sein.

    Ich habe allerdings nicht vor diesen Code in einer bestehenden App einzusetzen. Vielmehr werde ich diesen Code als Basis nehmen, um eine eigenständige App (bestehend nur aus einer rahmenlosen Form + Marquee-Container + Combobox, AlwaysOnTop und am oberen Bildschirmrand angedockt) zu erstellen. Aufgabe dieser App wir es sein, dem User wichtige Informationen ad hoc anzuzeigen und bei neuen Infos die vorherige in ein DropDown-Feld zu Übernehmen. In diesem Zusammenhang sehe ich da keine Latenzen auf mich zu kommen.

    AntwortenLöschen