?
Ich habe noch ein kleines Problem. Ich zeichne nur in OnPaint. Wenn ich jetzt meinen Graphen etwas langsamer zeichnen lassen möchte (also z.B. mit Sleep(1); ) dann wird so lange der Graph gezeichnet wird nur der Graph selbst gezeichnet und der Rest des Fensters ist nicht sichtbar.
Sleep finktioniert normalerweise erst ab 10ms und aufwärts.
Wenn man einen niedrigeren Wert eingiebt, wird trotzdem 10ms gewartet.
Wenn das Zeichnen / die Animation länger dauert, würde ich mit Doppelpuffer oder mit einem seperaten "Arbeitsthread" arbeiten.
Ich denke das ist das Flickern von dem ihr immer sprecht, nur das es bei mir ziemlich lange dauert weil das Zeichnen des Graphen eben ein paar Sekunden dauert.
Das Flickern ist die Zeitdauer zwischen dem der Anzeigebereich gelöscht und neu gezeichnet wird.
Im Normalfall nimmt man dass als "Blinken" wahr.
Kann ich irgendwie sagen dass nur der Graph gezeichnet werden soll und der Rest einfach so bleibt wie er ist?
Schau dir mal http://msdn.microsoft.com/en-us/library/2f3csed3(VS.80).aspx an.
Du kannst aber auch in eine CImage Klasse malen und das Bild dann in ein CStatic Element kopieren.
Dass übernimmt dann die ganze Aktualisierungsarbeit in OnPaint.
(So mache ich dass meißtens)
Dass könnte so ausschaun:
//MyDlg.cpp
bool CMyDlg::ZeichneDasZeug()
{
CImage cDisplayImg;
// Bild neu erstellen
// X = 600 Pixel
// Y = 550 Pixel
// Farbtiefe = 24 Bit
if(!cDisplayImg.Create(600,550,24))
{
return false;
}
// DC zum malen holen.
CDC* dc = CDC::FromHandle(cDisplayImg.GetDC());
// Pinsel deffinieren
CBrush cBrush;
// Die Farbe Weiß wählen
cBrush.CreateSolidBrush(COLORREF(0xFFFFFF));
CBrush* cOldBrush = dc->SelectObject(&cBrush);
// Den DC-Bereich weiß malen, da sonst alles schwarz ist
dc->Rectangle(0,0,cDisplayImg.GetWidth(),cDisplayImg.GetHeight());
CPen Pen;
Pen.CreatePen(PS_SOLID,1,RGB(0,0,0));
CPen* ptrPen=dc->SelectObject(&Pen);
// dc->SetViewportOrg(180,-125);
// Hier wird lustig gemalt -> Aufpassen dass nicht außerhalb des
// Zeichenbereichs gemalt wird
dc->MoveTo(0,200);
dc->LineTo(0,300);
dc->MoveTo(0,300);
dc->LineTo(480,300);
int x= 0;
int y= 0;
for (int j = 0; j < 9; j++)
{
y = rand() %2;
x = j;
if(y == 0)
{
dc->LineTo((x*50),300);
dc->LineTo((x*50)+50,300);
}
else
{
dc->LineTo(x*50,250);
dc->LineTo((x*50)+50,250);
}
}
// Zum Schluss immer Aufräumen
dc->SelectObject(&cOldBrush);
dc->SelectObject(&cptrPen);
// DC der CImage Klasse freigeben, sonst kracht's
cDisplayImg.ReleaseDC();
//m_cStatic ist die Variable des Static Anzeigeelement's.
// Das Bild wird in das Anzeigeelement kopiert
m_cStatic.SetBitmap(cDisplayImg.Detach());
}
Ich hatte es mit OnEraseBkgnd() versucht, aber dann wird das Fenster immer durchsichtig und das dauerhaft, das möchte ich natürlich auch nicht.
Dass funktioniert nur, wenn man über den gesammten Bildbereich malt.
Wenn man OnEraseBkgnd abwürgt um das Flickern/Blinken zu verhindern, muss man sich selbst um das Malen des Hintergrunds kümmern.
@Martin Richter
"Live" zu berechnen und zeichnen funktioniert nur, wenn man nicht viel zeichnen muss und man genug Rechnerleistung zur Verfügung hat.
Ansonsten ist das Arbeiten mit Doppelpuffer bei denenen man das Bild "vorbereitet" und erst bei Bedarf auf den Bildbereich kopiert die bessere Lösung. Vorallem das Zoomen, Verschieben,... mit einem Doppelpuffer wesentlich einfacher.
Schiebe doch einfach einmal ein Programmfenster über den Anzeigebereich wenn eine Plod-Datei mit >1000 Zeilen angezeigt wird.
Einmal mit Doppelbuffer und einmal mit "Live" Zeichnen.