Wm_timer

Holla

Grünschnabel
Hallo zusammen,
ich habe ein Problem mit dem Timer.
Ich möchte/habe einen zellulären Automaten programmiert. Nun soll z.B. jede Sekunde ein neuer Evolutionsschritt dargestellt werden.
So habe ich es probiert:

Code:
const UINT idTimer = 1;
UINT nTimerDelay = 100;

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    
    switch (message)                  
    {
        case WM_CREATE:
            SetTimer(hwnd, idTimer, nTimerDelay, NULL );
            init();
            return 0;
        case WM_PAINT:
            OnDraw( hwnd );
            return 0;
        case WM_TIMER:
            Evolution();
            OnDraw( hwnd );
            return WM_PAINT;
        case WM_DESTROY:
            KillTimer(hwnd, idTimer);
            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
            break;
        default:                    
            return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}

Die Funktion init() initialisiert den Autometen, Evolution() berechnet die neuen Werte und die Funktion OnDraw gibt alles auf dem Bildschirm aus (sollte zumindest so sein).

Nun mein Problem:
Die Evolution wird brav berechnet, aber nicht beim Timer-Event neu dargestellt. Neue Bilder gibt es immer nur, wenn ich die Fenster-Größe ändere ( und eigentlich wollte ich nicht die ganze Zeit am Fenster wackeln, damit ich den neuen Zustand sehen kann).

Was mache ich nur falsch

Bitte helft mir...
 
Zuletzt bearbeitet:
Die Evolutionsschritte werden also berechnet; nur die Darstellung klappt nicht, oder? Ich vermute, es liegt daran, dass man OnDraw nicht so ohne weiteres aufrufen sollte. Hast du es mal stattdessen mit UpdateWindow() oder InvalidateRect() versucht?
 
Kachelator hat recht, das Fenster weiß nicht dass es neu gezeichnet werden muss , d.h. du musst sagen das sich was geändert hat
 
Wo wir gerade beim Thema sind, basd: Ich schmeisse UpdateWindow() und InvalidateRect() regelmässig durcheinander. Kannst du (oder sonstwer) ganz knapp die unterschiedliche Funktion der beiden erklären? Danke!
 
Hallo,

schon mal vielen Dank für Eure Antworten, auch wenn ich sie nicht umzusetzen wusste. Ich habe es mit beiden Funktionen an verschiedenen Stellen im Programm versucht, aber leider hat es nicht funktioniert.

Könntet ihr mir vielleicht noch mal genau sagen, an welcher Stelle ich diese Funktionen soll? Ich habe es einmal in switch-case WM_TIMER versucht (am Ende vor dem return) und einmal am Ende der Funktion OnDraw. Der Effekt war keiner, außer in einem (weiß schon nicht mehr welcher), da klappte dann auch die Berechnung der Evolution nicht mehr, d.h. auch eine Änderung der Fentstergröße brachte nichts mehr.

Für weiter Anleitung bin ich immer dankbar. Das ist nämlich mein erster Versuch einer Windows-Applikation und wäre doch schade, wenn das jetzt so völlig in die Hose gehen sollte. Und dazu habe ich ein Buch für Visual C++, nur habe ich keine Visual C++, sondern dev-c++. Und da gibt es nunmal kein MCF, da kann mir das Buch noch so oft schreiben: und im MCF-Assistenten drücke man dann diesen und dann jenen Knopf.... (ärger, ist zum Glück ein Buch aus der Bücherei und nicht gekauft)
 
Habe meinen Fehler doch noch selbst gefunden! Bin doch einfach zu blöde! Jetzt funktioniert es, und zwar so (falls es jemanden interessiert)

Code:
case WM_PAINT:
            hdc = BeginPaint( hwnd, &ps);
              OnDraw( hwnd, hdc );
              EndPaint( hwnd, &ps );
            return 0;
case WM_TIMER:
            HDC hdcWindow;
            hdcWindow = GetDC(hwnd);
                   
            Evolution();
            OnDraw( hwnd, hdcWindow );
           
            ReleaseDC(hwnd, hdcWindow);
            return WM_PAINT;

Ich Blödi hatte die Paintstruct mit in OnDraw gepackt! Jetzt ist sie im WM_PAINT und alles funktioniert!

Nochmal Danke für eure Mühe! Ich spiele jetzt noch ein wenig mit meinem Automaten!

Guts Nächtle, Holla
 
Ouch meine augen! das flackert doch irre wenn man das so macht!

Die einzige stelle wo man normal zeichnen sollte ist die WM_PAINT, und du zeichnest in WM_TIMER.

Versuchs mal lieber mit der netten funktion
RedrawWindow() ;-)
 
Und wo schreibt man das redraw hin?
Außerdem flackert es nicht, ich kann einfach jetzt nur, wie gewünscht, jeden Evolutions-Schritt sehen. Und etwas anderes will ich ja auch gar nicht.

Aber Kollegen hatten mir diesen Tip mit dem redraw auch gegeben, habe es aber nicht geschafft. Kann mich nicht mehr so genau erinnern, wie es war, es hat jedenfalls nicht funktioniert. So im Prinzip hätte ich aber schon gerne gewußt, wie es funktioniert. Gibt es da ein paar Tips?

Aber wie gesagt, mein Programm tut jetzt genau das, was es soll.

Gruß, Holla
 
Hola,

ich wollte mein Programm nicht ändern. Ich wollte es halt nur fürs Prinzip wissen. Ich hatte es nämlich mehrmals mit dem redraw versucht, aber das hatte nicht funktioniert, weil ich halt auch nicht genau wußte, wohin damit.

Trotzdem vielen Dank für eure Tips, Holla
 
Zurück