4 Stimmen

Die MFC-gezeichneten Elemente ändern sich nach 30-60 Minuten.

Ich habe eine Anwendung mit einer vollständig benutzerdefinierten UI (dh nur eine Reihe gefüllter Kästchen mit Text). Nach etwa 30-60 Minuten Laufzeit ändern sich die UI-Elemente spontan. Beispielsweise verschwinden die weißen Linien (Kanten der Kästchen), der Text ändert seine Größe, usw.

Ich habe einige Vorher-Nachher-Bilder eines der Bildschirme verlinkt. Dieses zeigt, dass alle weißen Linien verschwunden sind. Andere Bildschirme zeigen signifikante Änderungen in der Textgröße.

VORHER: http://s21.postimg.org/cogqodson/BEFORE.png

NACHHER: http://s24.postimg.org/7skx21sid/AFTER.png

Dieses Projekt ist in MS Visual C++ 2010 mit MFC geschrieben und läuft auf Windows 7 Pro.

Hier ist mein OnPaint() Code:

void CMainWindow::OnPaint()
{
    CPaintDC dcScreen( this );
    CBitmap bitmap;
    bitmap.CreateCompatibleBitmap( &dcScreen, m_rect.Width(), m_rect.Height() );

    CDC dc;
    dc.CreateCompatibleDC( &dcScreen );
    CBitmap* pOldBitMap = dc.SelectObject( &bitmap );

    dc.FillRect(m_rect, &BGBRUSH);
    int bkmode = dc.SetBkMode(TRANSPARENT);
    dc.SelectObject(&BGBRUSH);

    CPen brightwhitepen(PS_SOLID, 5, RGB(255,255,255));
    CPen* pOldPen = dc.SelectObject(&brightwhitepen);

    // draw some stuff:
    // dc.Rectangle, dc.DrawText, etc.
    // ...

    // Blit the memory device context to the screen device context
    dcScreen.BitBlt
        (
        0, 
        0, 
        m_rect.Width(), 
        m_rect.Height(),
        &dc, 
        0, 
        0, 
        SRCCOPY
        );

    dc.SetBkMode( bkmode );     // Alten Hintergrundmodus wiederherstellen
    dc.SelectObject( pOldPen ); // alten Stift erneut auswählen
    dc.SelectObject( pOldBitMap ); // Alte Bitmap wiederherstellen
}

Hat jemand schon einmal ein seltsames Verhalten wie dieses gesehen? Irgendwelche Tipps, wo ich nachforschen kann?

Vielen Dank!

2voto

user244795 Punkte 678

Ich habe ein Problem wie dieses schon einmal gelöst, als ich vergessen hatte, den Zustand eines der GDI-Handles wiederherzustellen. Die Lösung bestand darin, SaveDC und RestoreDC zu verwenden, was bedeutet, dass Sie nach Abschluss der Arbeit mit ihnen keine der Objekte im DC wiederherstellen müssen. Sie können hier eine wirklich praktische RAII-Klasse herunterladen, die die gesamte Arbeit für Sie erledigt.

Ein sekundärer Vorschlag besteht darin, die Standardobjekte und die integrierten DC-Handles zu verwenden, anstatt Ihre eigenen zu erstellen. Ersetzen Sie also Ihren Code für brightwhitepen wie folgt:

dc.SetDCPenColor(RGB(255,255,255));
CPen* pBrightwhitepen = CPen::FromHandle((HPEN)GetStockObject(DC_PEN));

dc.SetDCBrushColor(RGB(0,0,255));
CBrush* pBgBrush = CBrush::FromHandle((HBRUSH)GetStockObject(DC_BRUSH));

Verwenden Sie nun diese beiden Zeiger, um Ihre Sachen zu zeichnen. Der Vorteil ist, dass Sie nichts allokiert haben, also nichts undicht werden kann, und die Aufrufe können nicht fehlschlagen, da die Standardobjekte immer existieren.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X