OnPaint spinnt
-
Hallo,
ich habe ein eigenes Steuerelement geschrieben, dass von der Optik her an eine CListCtrl erinnert. Eigentlich läuft das Ding aber wenn ich das Programm mehrere Stunden laufen lasse, dann wird plötzlich die standard Schrift genommen und nicht meine eigene und außerdem wird keine der definieren Farben mehr benutzt um den Hintergrund zu zeichnen. Es ist also alles weiss, Schrift schwarz und Schrift standard Schrift.Hier mein Code:
void myListCtrl::OnPaint() { // Variablen CPaintDC paint_dc(this); CMemDC dc(&paint_dc); // Farben COLORREF m_backgroundColor = RGB(255, 255, 255); COLORREF m_systemGREY = RGB(236, 233, 216); COLORREF m_darkGREY = RGB(173, 170, 153); COLORREF m_lightGREEN = RGB(149, 255, 144); COLORREF m_darkGREEN = RGB( 9, 198, 0); // Textart HFONT m_Font = CreateFont(14,0, 0,0, FW_THIN, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_DONTCARE, "Arial"); // Bereiche CRect client_rect; CRect content_rect; // Bestimmen, wo gezeichnet werden soll GetClientRect(client_rect); content_rect = client_rect; content_rect.top+=1; content_rect.right-=2; content_rect.left+=1; dc.SetBkMode(TRANSPARENT); // Alle nicht bemalten Flächen sind durchsichtig dc.SelectObject(m_Font); // Schriftart laden dc.FillSolidRect( client_rect, m_backgroundColor ); // Hintergrund malen // Titelleiste zeichnen // // Hintergrund zeichnen HPEN border_pen = CreatePen( PS_SOLID,0,m_darkGREY ); SelectObject( dc, border_pen ); HBRUSH backg_fill = CreateSolidBrush( m_systemGREY ); SelectObject( dc, backg_fill); Rectangle( dc, content_rect.left, content_rect.top, content_rect.right, content_rect.top+row_height); // Spalten und Spaltenbeschriftung int x = content_rect.left; for( int i=0; i<myCols.size(); i++ ) { // Beschriftung dc.TextOut(x+5,content_rect.top+1,myCols[i].title); // Trennlinie x += myCols[i].width; dc.MoveTo( x, content_rect.top); dc.LineTo( x, content_rect.top+row_height ); } // Content // // Hintergrundfarbe wählen backg_fill = CreateSolidBrush( m_backgroundColor ); SelectObject( dc, backg_fill); int y = content_rect.top+row_height+2; // Rahmen für die Zeilen for( i=0; i<m_iVisibleLines; i++) { Rectangle( dc, content_rect.left, y, content_rect.right, y+row_height); y+=row_height-1; } // Rahmen für die Spalten border_pen = CreatePen( PS_SOLID,0,m_darkGREY ); SelectObject( dc, border_pen); x = content_rect.left; for( i=0; i<myCols.size()-1; i++ ) { x += myCols[i].width; dc.MoveTo( x, content_rect.top+row_height+4); dc.LineTo( x, y ); } // Content eintragen CString data; y = content_rect.top+row_height+2; for( i=m_iFirstLine; i<row_data_set.size(); i++) { x = content_rect.left; for( int j=0; j<3; j++ ) { if(j==0) data = row_data_set[i].data1; if(j==1) data = row_data_set[i].data2; if(j==2) data.Format("%.3f",row_data_set[i].data3); dc.TextOut(x+6,y+1,data); x += myCols[j].width; } y+=row_height-1; }
-
Das wundert mich nicht. Du erzeugst einen Font, selektierst diesen in den DC und dann wird dieser Font nicht wieder aus dem DC entfernt. Dadurch kann der Font auch nicht zerstört werden.
Also immer bei einem SelectObject, den Rückgabewert merken und später (vor dem Ende der OnPaint Routine) wieder den alten Wert selektieren.
Außerdem sehe ich nicht, dass der Font wieder zerstört wird.
Erzeuge den Font doch nur einmal.CFont *pOldFont = dc.SelectObject(&m_Font); ... dc.SelectObject(pOldFont);
-
Hallo Martin,
vielen Dank für deinen Beitrag.
Ich konnte das Problem gestern lösen und dein Beitrag ist Teil der Lösung.Was ich jetzt anders mache:
CPen *pen1 = new CPen; pen1->CreatePen( PS_SOLID,0,RGB(0,0,0) ); dc->SelectObject(pen1); [...] pen1->DeleteObject(); delete pen1;Das für alle CBrush, CPen & CFont.
Grüße,
Michael
-
1. Hast Du nicht gelesen wie es richtig geht. Denn auch in diesem Fall bleibt der CPen in dem DC selektiert.
2. Du brauchst die CPen Objekte nicht mit new erzeugen. Das kostet nur Zeit. Erzeuge sie wie bisher auf dem Stack...
3. Das explizite Aufrufen von DeleteObject ist nicht noitwendig, das besorgt der Destruktor.CPen pen1; pen1.CreatePen( PS_SOLID,0,RGB(0,0,0) ); CPen *pPenOld = dc->SelectObject(&pen1); [...] dc->SelectObject(pPenOld);