我看到一個問題,我無法重新選擇DC上的原始位圖,導致內存泄漏。指向原始位圖的指針在整個程序中保持不變,但數據(來自CBitmap :: GetBitmap)從單色變爲其他。我不知道位圖實際更改的時間,但系統中的某些內容正在導致它。GDI:原始DC位圖發生變化,無法恢復
CBitmap* cMyClass::mpOldBitmap;
CDC cMyClass::mCanvasDc;
CBitmap cMyClass::mCanvasBmp;
void cMyClass::Init()
{
// One-time initialization
CDC* pDc = GetDC();
mCanvasDc.CreateCompatibleDC(pDc);
mCanvasBmp.CreateCompatibleBitmap(pDc, 10, 10);
mpOldBitmap = mCanvasDc.SelectObject(&mCanvasBmp);
ReleaseDC(pDc);
BITMAP bitmap;
mpOldBitmap->GetBitmap(&bitmap); // A monochrome bitmap, as expected.
}
void cMyClass::Recreate(int newW, int newH)
{
// 1. Delete existing bitmap:
if (mpOldBitmap)
{
BITMAP bitmap;
mpOldBitmap->GetBitmap(&bitmap); // This is no longer the monochrome bitmap. It is 8bpp, with random size.
CBitmap* pCurrBmp = mCanvasDc.SelectObject(mpOldBitmap); // This fails (NULL). I can't de-select my bitmap.
mCanvasBmp.DeleteObject(); // This fails too, causing memory leak. Actually, it fails in CE6, but not in Win32. Regardless, both platforms will have a memory leak.
}
// 2. Recreate the bitmap with new size:
{
CDC* pDc = GetDC();
mCanvasBmp.CreateCompatibleBitmap(pDc, newW, newH);
ReleaseDC(pDc);
}
// 3. Finalize
mpOldBitmap = mCanvasDc.SelectObject(&mCanvasBmp);
}
- 任何已知的場景中會發生這種情況?
- 任何調試提示在位圖數據更改時中斷?
注:在代碼中,我提到「這個失敗」。我刪除了返回值的斷言,以使代碼可讀。
編輯:我用來解決它的解決方案是使用CDC:SaveDC和CDC :: RestoreDC,而不是存儲指針。內存泄漏消失了,並且每個GDI調用都通過了。但我仍然很好奇爲什麼原始代碼泄漏。據我所知,指向默認位圖的指針應該是默認的單色位圖,可能是GDI世界中的全局位圖
[mcve]必需。 – IInspectable
我認爲你的問題是你不能像這樣操作(重新創建)一個實例變量。您需要一個指向CBitmap的指針,即CBitmap * mCanvasBmp並「刪除」它,並且每次重新創建它就像mCanvasBmp = new CBitmap。 – VuVirt