我发现无法在DC上重新选择原始位图的问题,导致内存泄漏。指向原始位图的指针在整个程序中保持不变,但数据(来自CBitmap :: GetBitmap)从单色变为其他。我不知道位图实际上何时发生变化,但是系统中的某些东西正在引起它。
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世界中的全局位图
答案 0 :(得分:-1)
让我们看看OP的代码。
mpOldBitmap = mCanvasDc.SelectObject(& mCanvasBmp);
因为mCanvasBmp是CBitmap对象(不是指向CBitmap的指针),所以首先称为HGDIOBJ运算符,然后是 CDC :: SelectObject(HGDIOBJ),它返回 HGDIOBJ 和不是 CBitmap * 。这应该给出转换编译器错误。如果将返回的值转换为CBitmap *也是错误的。
摆脱问题的正确方法是传递指针。
sizeof(T)
此案例将被称为 CDC :: SelectObject(CBitmap * pBitmap),它返回 CBitmap * 。
//我希望它非常清楚。 :)