Laufband in einem "static control"



  • Hallo,
    ich möchte (mehr oder weniger aus Spaß) eine Art Laufband (also einen sich bewegenden Text) in einem "static" Steuerlement unterbringen. Der Text soll ganz rechts auftauchen und sich dann immer weiter nach links fortbewegen, bis er einmal komplett durchgelaufen ist.

    Dazu wollte ich eine einfache statische Variable mit der aktuellen x-Position verwenden, die dann bei WM_TIMER" bis zu einem gewissen Punkt immer dekrementiert wird. Mein Problem ist, wo ich den eigentlichen Text (mit TextOut) ausgeben soll. Normalerweise würde ich ja an WM_PAINT denken, aber da muss ich mir erstmal den Gerätekontext des statischen Steuerelements besorgen. In der Nachricht WM_CTLCOLORSTATIC hingegen wird über wParam gleich ein HDC mitgeliefert, der auch schon die Schriftart usw. hat, die ich für das Steuerelement definiert habe.

    Allerdings müsste ich ja dann bei WM_TIMER immer WM_CTLCOLORSTATIC senden, damit der Text auch ständig an seiner neuen Position gezeichnet wird. Was soll ich aber dann als wParam übergeben? 😕

    Mein Problem ist also, wo ich den Zeichenvorgang einbauen soll. Es wäre nett, wenn ihr mir da ein paar Tipps geben könntet 🙂

    ph4nt0m



  • SetWindowText(hWndStatic, "Schweine im Weltall"); /* und dann */
    SetWindowText(hWndStatic, "l Schweine im Weltal"); /* und so weiter */
    

    Möglicherweise geht auch was mit Subclassing (Nachrichten an das Control senden und dann abfangen und bearbeiten), aber da kenne ich mich nicht so gut aus.


  • Mod

    WM_PAINT ist korrekt.
    Wieso musst Du Dir einen Gerätekontext besorgen? WM_PAINT liefert Dir doch mit BeginPaint den entsprechenden DC.



  • @keksekekse
    Erstmal danke für deine Hilfe. Mit SetWindowText wollte ich es aber eigentlich nicht machen, denn dann kann ich ja pro WM_TIMER immer nur einen ganzen Buchstaben mehr ausgeben. Ich glaube, dass die Bewegung dann nicht sehr weich wäre 😞
    Mit TextOut kann man ja Pixelgenau zeichnen, deshalb wollte ich diese Funktion an dieser Stelle eigentlich verwenden... 🙂

    @Martin Richter
    Wenn ich einen DC mit BeginPaint hole, bezieht sich der doch auf das gesamte Fenster bzw. in meinem Fall auf den ganzen Dialog. Dann müsste ich erstmal die richtig Position meines Steuerelements "suchen". Außerdem wird es dann auch schwer, den Text wirklich nur im Steuerelement zu halten und nicht über die Ränder hinaus zu zeichnen.

    Der DC von WM_CTLCOLORSTATIC war genau richtig "justiert" 😋, weil der Nullpunkt hier genau in der oberen Ecke des Steuerelements liegt...

    ph4nt0m

    UPDATE: Ich hab jetzt trotzdem die Zeichenaktion in die WM_CTLCOLORSTATIC gepackt. Es klappt alles soweit "perfekt", jedenfalls stimmt die von mir definierte Schriftart und -größe, und die Koordinaten bei TextOut beziehen sich auf das Steuerelement und nicht auf den ganzen Dialog. Wenn ich bei TextOut für x etwas negatives einsetze, wird der Text links abgeschnitten und nicht über das Steuerelement hinaus gezeichnet. Also genau das, was ich wollte.

    Allerdings wird das Steuerelement vor jeden neuzeichnen nicht gelöscht, wodurch der Text immer über den alten gezeichnet wird. Welche Funktion sollte ich bei WM_TIMER aufrufen, damit das Steuerelement gelöscht und neugezeichnet wird?



  • Hmm deine Frage kann ich dir leider nicht ganz beantworten aber wie wäre es wenn du ein back color angibst dann wird doch alles übermalt.

    MfG schirrmie


  • Mod

    Das ist Qurak. Du musst ein eigenes CStatic Control ableiten dort OnPaint überschreiben. Dann bekommst Du in diesem OnPaint auch den DC des Static Controls. Mit einem DC des Dialoges kann man nicht in den Bereich des CStatic schreiben.

    Und den Weg in CTLCOLOR handler zu Zeichnen kan ich nur ablehnen.



  • Das hört sich für mich sehr nach MFC an!? Damit kenne ich mich leider nicht aus, ich wollte eigentlich reine WinAPI verwenden 😞

    ph4nt0m



  • Subclassing ist das Stichwort...



  • OK,
    ich habe jetzt eine eigene Fensterprozedur für mein static-control erstellt, wie es hier beschrieben ist: http://www.winapi.net/index.php?inhalt=s27

    Allerdings passiert nichts, wenn ich als Reaktion auf WM_PAINT in dieser neuen Prozedur etwas in das Steuerelement zeichnen möchte. Bei z.B. WM_LBUTTONDOWN funktioniert es hingegen wie geschwünscht. Auch ein Aufruf von InvalidateRect bei WM_LBUTTONDOWN scheint nicht dafür zu sorgen, dass WM_PAINT gesendet wird. Woran kann das nun wieder liegen? 🙄

    ph4nt0m



  • Hmm wenn du eh WinAPI nutzt, registrierst du dir einfach eine eigene Fensterklasse die du dann als WM_CHILD erstellst und in deren WindowProc reagierst du dann auf WM_PAINT ...



  • Naja, eigentlich wollte ich das vermeiden, weshalb ich auch meinen Dialog und die ganzen Steuerelemente in einem Ressourcenskript untergebracht habe, anstatt sie alle "manuell" zu erstellen. Ich werds aber wohl mal so probieren. Vielen Dank erstmal 🙂

    ph4nt0m


  • Mod

    Na und? Dann plazierst Du ein User Defined Control in Deinem Dialog in den Ressourcen. Dann brauchst Du nicht mal Subclassing. Du musst nur die Klasse vorher registriert haben.



  • Tut mir leid, falls es nervt. Ich hab zwar ein benutzerdefiniertest Steuerelement erstellt, aber was genau meinst du mit

    Du musst nur die Klasse vorher registriert haben.

    😕


  • Mod

    RegisterClass/RegisterClassEx!

    Ich empfehle Dir ein Windows-Tutorial zu lesen!
    Den Namen gibst Du dann in Deinem Dialog-Template an.


Anmelden zum Antworten