Je vois un problème où je ne peux pas sélectionner à nouveau le bitmap d'origine sur un contrôleur de domaine, provoquant une fuite de mémoire. Le pointeur sur le bitmap d'origine est resté le même tout au long du programme, mais les données (de CBitmap :: GetBitmap) passent de monochrome à autre chose. Je ne sais pas quand le bitmap change réellement, mais quelque chose dans le système le cause.GDI: les modifications de bitmap DC d'origine ne peuvent pas être restaurées
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);
}
- Tous les scénarios connus où cela peut se produire?
- Des conseils de débogage à interrompre lorsque les données bitmap changent?
Remarque: Dans le code, j'ai mentionné "cela échoue". Je supprime le assert sur les valeurs retournées pour rendre le code lisible.
Edit: La solution que j'utilise pour le fixer est d'utiliser CDC: SaveDC et CDC :: RestoreDC au lieu de stashing le pointeur. La fuite de mémoire a disparu, et chaque appel GDI est passé. Mais je suis toujours curieux de savoir pourquoi le code original a fui. Le pointeur vers le bitmap par défaut, autant que je sache, devrait être un bitmap monochrome par défaut qui est probablement global dans le monde GDI
[mcve] requis. – IInspectable
Je pense que votre problème est que vous ne pouvez pas manipuler (recréer) une variable d'instance comme celle-ci. Vous avez besoin d'un pointeur vers CBitmap, c'est-à-dire CBitmap * mCanvasBmp et le "supprimer" et le recréer comme mCanvasBmp = new CBitmap à chaque fois. – VuVirt