2013-04-09 44 views
4

我有一個完全自定義繪製的UI(即只有一堆帶有文本的填充框)的應用程序。在大約30-60分鐘的運行時間之後,UI元素自發地改變。例如,白線(框邊框)消失,文本大小調整等。30-60分鐘後MFC繪製的元素髮生變化

我已經鏈接到某個屏幕前後的一些圖像。這表明所有的白線都消失了。其他屏幕顯示文字大小的重大變化。

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

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

該項目是用微軟的Visual C++ 2010中使用MFC,並在Windows 7專業版上運行。

這裏是我的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 
} 

有沒有人見過這種怪異的行爲?在哪裏進行調查的任何提示?

謝謝!

+7

我懷疑是不知何故,你沒有完全釋放你的資源,每次調用都會泄漏。在某個點之後,它剛剛開始無法分配新的筆,位圖等等......但我不確定如何使用所有MFC包裝類爲win32原始句柄。檢查頭釘管理器,看看你的過程在做什麼記憶明智。也許Process Explorer允許你查看打開的句柄的數量? – cppguy 2013-04-09 17:25:36

+0

這也是我最初的想法,但如果我看任務管理器,內存使用情況良好。事實上,在我最後的測試中,內存使用率在UI混亂前後完全相同。 – user2262676 2013-04-09 18:33:40

+3

消除繪圖代碼,直到問題消失,在taskmanager中查看gdi句柄count而不是內存使用情況 - 不確定該列的實際名稱可能不同 – marcinj 2013-04-09 18:38:49

回答

2

我已經解決了這個問題之前曾經忘記恢復其中一個GDI句柄的狀態。解決方案是使用SaveDCRestoreDC,這意味着在完成DC之後,您不必恢復DC中的任何對象。你可以在這裏下載一個really convenient RAII class,爲你做所有的工作。

第二個建議是使用庫存對象和內置的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)); 

現在使用這兩個指針來繪製你的東西。優點是你沒有分配任何東西,所以你不能泄漏任何東西,並且由於庫存對象總是存在,所以調用不會失敗。

相關問題