Frage zu UpdateAllViews



  • Hallo zusammen,

    habe eine Frage zu UpdateAllViews. Habe eine MFC-SDI Anwendung.
    Ich möchte nun zwei Kreise zeichnen, und zwar den ersten vor dem zweiten.
    Den Zeitverschub zwischen den beiden Zeichnungen habe ich durch eine einfache Schleife realisiert.

    Der Code sieht in dem Dokument nun folgermaßen aus:

    CPoint pPoint,pPoint2;
        pPoint.x = tester;
        pPoint.y = tester1;
        double i,j,k = 0;
        m_oaPoints.Add(pPoint);
        UpdateAllViews(NULL);
        for(i=0; i<200000000.; i++)
        {
        }
        pPoint2.x = tester+100;
        pPoint2.y = tester1+100;
        m_oaPoints.Add(pPoint2);
        UpdateAllViews(NULL);
    

    Die Befehle zum zeichnen sind in der View in der Funktion OnPaint geschrieben.

    for(int i = 0; i<pDoc->m_oaPoints.GetCount();i++)
        {
            CPoint pPoint = pDoc->m_oaPoints[i];
            Ellipse(dc,pPoint.x+100, pPoint.y+100, pPoint.x+200, pPoint.y+200);
        }
    

    Nun sehe ich aber auf dem Bildschirm immer nur beide Kreise gleichzeitig. Wenn ich nur den Code

    CPoint pPoint,pPoint2;
        pPoint.x = tester;
        pPoint.y = tester1;
        double i,j,k = 0;
        m_oaPoints.Add(pPoint);
        UpdateAllViews(NULL);
    

    zeichnet das Programm mir relativ schnell nur einen Kreis.
    Sobald ich die Schleife aber integriere, braucht der PC einige Zeit wegen der Schleife und spuckt mir erst dann beide Kreise aus obwohl ich erwarten würde, dass er den ersten Kreis vor der Schleife schreibt.

    Das ist ein nur ein Testprogramm aber wichtig für mich für eine spätere Anwendung.
    Vielen Dank schonmal..



  • Also wenn du dich mit dem nachrichtensystem etwas auskennen würdest, währst du von selbst drauf gekommen, das es mit einer for-schleife bei windows nie geht, da erzeugst du die tollsten effekte die du nicht haben willst. Entweder du packst alles in einen thread und sendest von da aus die message zum zeichnen oder du schaust dir das mal an

    http://www.mpdvc.de/html.htm#Q75

    gruß Matthias



  • hi habe mir den beitrag angeschaut und weiss jetzt dass ich PumpMessage verwenden muss. Jedoch ist die Erklärung viel zu kurz.

    Wie kann ich es denn nun machen dass ich praktisch in der Doc was berechne und von Zeit zu zeit was in der View aktualisiere?

    Habe auch schon gegoogelt aber scheint nicht was für anfänger zu sein.

    gruß



  • Du könntest in deinem Doc nen Pointer auf die View-Klasse halten und dann darüber die Aktualisierung durchführen lassen, bzw. ne Wrapperfunktion im View aufrufen.

    Nächste Möglichkeit wäre folgende:
    Du kannst doch ne eigene Message definieren und dann deinem View per Sendmessage mitteilen, dass es sich aktualisieren soll.

    Also z.B. in deiner App-Klasse:

    #define WM_MY_MSG WM_APP+1
    

    Dann in deiner View:
    In der Messagemap:

    ON_MESSAGE(WM_MY_MSG, OnMyMsg)
    

    Und dann die Funktion an sich in deiner View:

    // Deklaration
    LRESULT OnMyMsg(WPARAM wParam, LPARAM lParam);
    ...
    // Definition
    LRESULT C...View::OnMyMsg(WPARAM wParam, LPARAM lParam)
    {
        tu was...
    }
    

    Und im Doc dann Sendmessage:

    SendMessage(m_pView->m_hWnd, WM_MY_MSG, 0, (LPARAM)irgendwas);
    

    Noch ne Möglichkeit:
    Je nachdem wwas für Daten du verarbeitest kannst du auch die Daten in der in z.B. ne CList, std::vector... schreiben und in der View in nem bestimmten Zeitintervall (Timer) die neuesten Daten holen.

    So habe ich das gemacht, habe in der Anwendung aber nen Thread, der mir Daten von der RS232 holt, dann mir ne Message schickt, wenn er neue hat und die werden im Doc in ne CList eingetragen.

    Es wird noch einige weitere Möglichkeiten geben, aber die hier sind mir auf die schnelle eingefallen !
    Hoffe, habe sonst nix vergessen zu erwähnen 👍


  • Mod

    UpdateAllViews alleine löst nur ein Invalidate des entsprechenden Fensters aus. Um ein Fenster aber sofort zu aktualisieren müsstest Du auch einen UpdateWindow ausführen.

    Ein Invalidate alleine wie Du es hier machst würde aber ein Neuzeichnen erst beiu Ausführung der nächsten Nachrichtenschleife auslösen. Du hast eine permanente Blockierung Deines Threads (ohne Messageloop) in Deinem Code), das kann so also dann nicht gehen.

    Du kannst jetzt selber OnUpdate überschreiben und Dir entsprechenden passenden Code (mit UpdateWindow/RedrawWindow) einbauen.

    Beschäftige Dich mal etwas wie Windows zeichnet.



  • Hi R3dNeXX und martin,

    vielen Dank für eure nützliche Hilfe. Wäre toll, wenn man hier im Forum öfters so hilfreiche Ratschläge bekommt die einem direkt weiterhelfen.meistens kriegt man ja die Antwort: "guck dir das mal an oder jenes" was einen noch weiter verwirrt.

    Kriege es jetzt hin, dass er die Kreise richtig zeichnet. Werde erstmal selber versuchen hinzukriegen, dass das Programm alte Kreise löscht und sich immer aktualisierte Koordinaten holt.

    Vielen Dank euch beiden (besonders R3dNeXX) 🙂



  • Hey,
    einwas ist mir noch eingefallen:
    Solltest etwas aufpassen mit dem Sendmessage aus dem Thread heraus ! ⚠

    Diese kehrt ja erst zurück, wenn die Nachricht abgearbeitet wurde.
    Das kann entweder deinen Thread ausbremsen bzw. kann es vielleicht auch zu Problemen führen wenn er der Thread mal nicht ordnungsgemäß beendet wird. Kann dann passieren, dass er noch in der Message-Qeue hängt wenn das Programm oder der Thread selber beendet wird und dann knallts!

    Oder du verwendest PostMessage, da musst du aber wiederum aufpassen, dass deine View nicht zu sehr belastet wird wenn dein Thread dauernd ne Message schickt.

    Man muss da aber je nach Anwendungsfall aufpassen und entscheiden, welche Möglichkeit man nun nutzt.
    Um allen Problemen aus dem Weg zu gehen, habe ich, was ich in meinem letzten Post erwähnt habe, in meinem Beispiel die Daten immer wieder in eine CList geschrieben und in der View wieder herausgeholt und bearbeitet, so habe ich eine schnelle Ausführung und mein Thread ist gekapselt, da er nix in meiner View verloren hat. 👍

    Aber probieren geht über studieren... 🙂


Anmelden zum Antworten