Absturz bei SetWindowText



  • Hallo,

    ich habe folgendes mysteriöses Problem. Ich habe einen Dialog mit
    dynamisch erzeugten CEdit Feldern. Mit SetWindowText setze ich nun die
    anzuzeigenden Werte.
    Dieser Wert wird alle 100ms aktuallisiert. Das funktioniert soweit ganz gut,
    das Problem ist nun, nach ca. 10000 Zyklen (der Wert variiert) wird der Dialog
    nicht mehr richtig angezeigt. Verschiedene Steuerelemente werden ins linke obere
    Eck verschoben, die MessageBox Texte werden in neuem Font angezeigt und das
    Programm reagiert nur noch stark verzögert auf Benutzereingaben.

    Ich hoffe mir kann jemand weiterhelfen, oder zumindest Tipps zur Fehlersuche geben.
    Ich bin hier schon am verzweifeln.

    Gruss Charlie



  • Zeig mal etwas Code dazu.



  • Die CEdit Felder werden wie folgt erzeugt und in einem Container gespeichert

    CEdit *Anzeige;
    Anzeige = new CEdit();
    Anzeige->Create(
    	WS_CHILD | WS_VISIBLE,
    	CRect(aktPosX, m_uiTextDlgPos, aktPosX + 220, m_uiTextDlgPos + 15),  
    	this, 	
    	m_uiNextEditIDC++);
    Anzeige->SetReadOnly();
    m_EditVec.push_back(Anzeige);
    

    Der Dialog ist in einem Beobachter-Container angemeldet und wir alle 100ms vom Subjekt aufgefordert die Anzeigen zu aktualisieren.

    void CStatusAnzeigeDlg::Refresh(HardwareSettings* newSubjekt)
    {
    	for(vector<CEdit*>::iterator i = m_EditVec.begin(); 
                         i < m_EditVec.end(); 
                         i++)
    	{
    		CEdit* ed = *i;
    		ed->SetWindowText("Test"); //Nur zu Testzwecken, normalerweise werden hier Variablen aus dem Subjekt angezeigt.
    	}
    }
    


  • Wieviele Editfelder sind das?



  • Bisher nur 6.
    Wie ist das mit der Control-ID bei Create.
    Ich habe da einen unter Ressourcesymbolen nicht belegten Wertebereich (1400-1500)
    benutzt. Könnte das eine Fehlerquelle sein?



  • Nein, kann es nicht.
    Führst du im Originalquelltext in der Refreshmethode möglicherweise Berechnungen aus, die länger als 100 ms dauern könnten?



  • Nein, das ist eher unwahrscheinlich. Aber auch mit der Refresh Methode wie ich sie hier beschrieben habe tritt dieses Problem auf.



  • Ein Tipp:
    Wenn der Font in den Fenstern sich plötzlich ändert, kann das daran liegen, dass Windows keine GDI-Objekte mehr anlegen kann. Dann wird nämlich der Standard-Systemfont verwendet.
    Vielleicht machst du ja in deiner Schleife ein CDC::SelectObject und nicht das passende SelectObject(<oldobject>) bevor das Objekt aus dem Scope verschwindet.



  • Abgesehen davon sollltes du mal dein Design ändern. Man sollte in einer Oberfläche nur was Anzeigen wenn sich was ändert.



  • Das ist mir auch klar, die Beobachter werden von Subjekt ja auch nur aufgerufen wenn sich was ändert. Das is nunmal alle 100ms.



  • Ich denke ich habe den Fehler gefunden. Ich hatte, um in Edit Feldern einen farbigen Hintergrund zu bekommen, die OnCtlColor Funktion überschrieben.
    Habe diese jetzt wieder auskommentiert und das Programm läuft. Kann mir jemand weiterhelfen wo da der Fehler liegen kann.
    Hab die Funktion so im Forum gefunden und übernommen.

    HBRUSH CStatusAnzeigeDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
    {
        HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
    	UINT ctrlID;
    	if(nCtlColor==CTLCOLOR_STATIC) 
    	{
    		ctrlID=pWnd->GetDlgCtrlID(); 
    		if((ctrlID >= 1400) && (ctrlID < m_uiNextEditIDC)) //Handelt es sich um das richtige Edit Feld
    		{
    			pDC->SetTextColor(RGB(0,0,0));	
    			pDC->SetBkMode(TRANSPARENT);
    			HBRUSH B = CreateSolidBrush(RGB(100,149,237)); //Hintergrundfarbe
    			return (HBRUSH) B; 
    		}
    
    	}
    }
    


  • Du Schreibst Dir mit :

    HBRUSH B = CreateSolidBrush(RGB(100,149,237)); //Hintergrundfarbe
    

    den Speicher voll.

    Erstelle die Variable B nur einmal beim Konstruktor und lösche Sie beim Dekonstruktor.

    DeleteObject(B)
    

    Das müßte Dein Problem in der Funktion OnCtlColor beheben.

    Oli



  • Vielen Dank für die schnelle Hilfe. Das war der Fehler, jetzt funktioniert es einwandfrei.


Anmelden zum Antworten