Draw with Buffer stürzt nach 80 sec ab



  • Hallo,
    ich möchte eine Anzeige erstellen, welche abgerufene Werte in ein Diagramm aufzeichnet, ähnlich einem Osziloskop. Das funktioniert wunderbar, aber nur 80 sec. Dann hängt sich das komplette Fenster auf.

    Ich sitzt jetzt schon den 3. Tag an diesem Problem und komm einfach nicht weiter. 😞
    Kann mir jemand sagen, woran das liegen kann??? Vielleicht am Buffer??

    Hier hab ich mal den Code von der Problem-Funktion, die mit einem Timer alle 20ms aufgerufen wird.

    void Draw_With_Buffering()
    {
    	int i;
    	SelectObject(biop->Get_DC_Buffer(0),background_brush);
    
    	//FillRect fills the  buffer DC with the colour white
    	FillRect(biop->Get_DC_Buffer(0),&rect1,background_brush);
    
    	// Gitter grau, gestrichelt zeichnen
    	hAufnahmePen = CreatePen(PS_DASH, 1, RGB(150, 150, 150));
    	hPenOld = (HPEN)SelectObject(biop->Get_DC_Buffer(0), hAufnahmePen);
    	// horizontal:
    	for (i=1; i<5; i++){
    		MoveToEx(biop->Get_DC_Buffer(0), 100, 500-i*100, NULL);
    		LineTo(biop->Get_DC_Buffer(0), 600, 500-i*100);
    	}
    	// vertikal:
    	for (i=1; i<8;i++){
    		MoveToEx(biop->Get_DC_Buffer(0), static_cast<int>(100+i*62.5+0.5), 100, NULL);
    		LineTo(biop->Get_DC_Buffer(0), static_cast<int>(100+i*62.5+0.5), 500);
    	}
    	// Rahmen zeichnen:
    	hAufnahmePen = CreatePen(PS_DASH, 2, RGB(0, 0, 0));
    	hPenOld = (HPEN)SelectObject(biop->Get_DC_Buffer(0), hAufnahmePen);
    	MoveToEx(biop->Get_DC_Buffer(0), 100, 500, NULL);
    	LineTo(biop->Get_DC_Buffer(0), 600, 500);
    	LineTo(biop->Get_DC_Buffer(0), 600, 100);
    	LineTo(biop->Get_DC_Buffer(0), 100, 100);
    	LineTo(biop->Get_DC_Buffer(0), 100, 500);
    
    	// Kritisches-Limit zeichnen:
    	hAufnahmePen = CreatePen(PS_SOLID, 3, LimColor1);
    	hPenOld = (HPEN)SelectObject(biop->Get_DC_Buffer(0), hAufnahmePen);
    	MoveToEx(biop->Get_DC_Buffer(0), 100, Limit1, NULL);
    	LineTo(biop->Get_DC_Buffer(0), 600, Limit1;
    	// Warnungs-Limit zeichnen:
    	hAufnahmePen = CreatePen(PS_SOLID, 3, LimColor2);
    	hPenOld = (HPEN)SelectObject(biop->Get_DC_Buffer(0), hAufnahmePen);
    	MoveToEx(biop->Get_DC_Buffer(0), 100, Limit2 , NULL);
    	LineTo(biop->Get_DC_Buffer(0), 600, Limit2);
    	// Unteres Limit zeichnen:
    	hAufnahmePen = CreatePen(PS_SOLID, 3, LimColor3);
    	hPenOld = (HPEN)SelectObject(biop->Get_DC_Buffer(0), hAufnahmePen);
    	MoveToEx(biop->Get_DC_Buffer(0), 100, Limit3, NULL);
    	LineTo(biop->Get_DC_Buffer(0), 600, Limit3);
    
    	// Kurve zeichnen:
    	hAufnahmePen = CreatePen(PS_SOLID, 3, DrehmomentColor);
    	hPenOld = (HPEN)SelectObject(biop->Get_DC_Buffer(0), hAufnahmePen);
    	if (!ArrayVoll){	// -beim Starten der Aufzeichnung (bis WerteFeld gefüllt ist
    		MoveToEx(biop->Get_DC_Buffer(0), WerteFeld[0][1], WerteFeld[0][0], NULL);
    		for (i=1;i<Durchgang;i++){
    			LineTo(biop->Get_DC_Buffer(0), WerteFeld[i][1], WerteFeld[i][0]);
    		}
    	}
    	else {		// -wenn WerteFeld voll ist
    		MoveToEx(biop->Get_DC_Buffer(0), WerteFeld[0][1], WerteFeld[Durchgang][0], NULL);
    		for (i=1; i<(MAX - Durchgang); i++){
    			LineTo(biop->Get_DC_Buffer(0), WerteFeld[i+1][1], WerteFeld[Durchgang +i][0]);
    		};
    		for (i=0; i< (Durchgang-1); i++){
    			LineTo(biop->Get_DC_Buffer(0), WerteFeld[MAX- Durchgang+1 +i][1], WerteFeld[i][0]);
    		}
    	}
    
    	SelectObject(biop->Get_DC_Buffer(0), hPenOld);
    
    	biop->Copy_to_Screen(0);
    	//realease memory of the brushes
    }
    

    Dabei soll mit der Klasse Bitmap_Operations der Buffer realisiert werden

    // in WM_CREATE:
    biop = new Bitmap_Operations();
    
    // Buffer erstellen in diese Klasse:
    void Bitmap_Operations::Create_Buffer( int which)
    {	GetClientRect(my_handle,&dc_rect[which]);
    	my_DC = GetDC(my_handle);
    	my_DC_Buffer[which] = CreateCompatibleDC(my_DC);
    	hbm_Buffer[which] = CreateCompatibleBitmap(my_DC,dc_rect[which].right ,
    		dc_rect[which].bottom );
    	hbm_oldBuffer[which] = (HBITMAP) SelectObject(my_DC_Buffer[which],
    		hbm_Buffer[which]);
    }
    

    Ohne die Draw_with_Buffer() - Funktion läuft das Programm, doch auch mit Unterbrechungen, sobald diese Funktion insgesammt länger als 80sec ausgeführt wird, hängt sich das Fenster auf. Wenn mir jemand helfen kann wäre das echt super!!


  • Mod

    Das Ding leaked ohne Ende, dass funktioniert NIE 😉
    1. Alle Deine Pen's die Du erzeugst werden nicht gelöscht.
    2. Du solltest nur beim ersten SelectObject den Pen merken und zurückladen.



  • Vielen Dank Martin Richter,
    ja, ich muss zugeben, das ich mit der Win API-Programmierung noch ziemlich Anfänger bin.
    Hab jetzt die ganzen erzeugten Pen's gelöscht, und tataaaaaa, es läuft. 😃
    Vielen Dank!!!! Du warst meine Rettung nach 2 ruhelosen Nächten. 👍

    Allerdings hab ich deinen 2. Punkt nicht ganz verstanden, wenn ich nur mit der Zeile 11 den Pen merke und zurücklade, wird alles mit dem Pen in Zeile 10 gezeichnet. Wie mache ich das dann am besten?


  • Mod

    Du musst schon die Pens mit SelectObject selektieren, die Du möchtest.

    Nur:
    1. Darf ein Objekt, dass Du erzeugt hast nicht im weiter DC selektiert sein, wenn dieses entsorgt wird. Sonst entsteht ein Leak. Das Objekt wird nicht gelöscht.
    2. Ein DC wird immer mit einem "defualt" Objekt erzeugt. Beim ersten SelectObject eines Pens merkst Du dir diesen "deafult"-Pen. Und am Ende der ganzen Operationen selektierst Du diesen alten Pen zurück. Dann kannst Du sicher sein, dass keines Deiner Objekte im DC verbleibt.

    Lies mal ein paar Grundlagen, über GDI... (Petzold)


Anmelden zum Antworten