4

我有一个具有完全自定义绘制的 UI 的应用程序(即只是一堆带有文本的填充框)。运行大约 30-60 分钟后,UI 元素会自发变化。例如,白线(框边框)消失,文本调整大小等。

我已经链接到其中一个屏幕的前后图像。这表明所有的白线都消失了。其他屏幕显示文本大小的显着变化。

之前:http ://s21.postimg.org/cogqodson/BEFORE.png

之后:http ://s24.postimg.org/7skx21sid/AFTER.png

该项目使用 MFC 用 MS Visual C++ 2010 编写,并在 Windows 7 Pro 上运行。

这是我的 OnPaint() 代码:

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 );     // Restore old background mode
    dc.SelectObject( pOldPen ); // reselect old pen
    dc.SelectObject( pOldBitMap ); // Restore old bitmap
}

有没有人见过这样奇怪的行为?关于在哪里调查的任何提示?

谢谢!

4

1 回答 1

2

当我忘记恢复其中一个 GDI 句柄的状态时,我曾经解决过这样的问题。解决方案是使用SaveDCand RestoreDC,这意味着您在使用完之后不必恢复 DC 中的任何对象。你可以在这里下载一个非常方便的 RAII 类,它可以为你完成所有的工作。

第二个建议是使用库存对象和内置 DC 句柄,而不是创建自己的。因此,像这样替换您的brightwhitepen代码:

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));

现在使用这两个指针来绘制你的东西。优点是你没有分配任何东西,所以你不能泄漏任何东西,并且调用不会失败,因为股票对象总是存在的。

于 2013-04-09T20:19:17.923 回答