2016-05-10 7 views
0

MFCを使用して単純なゲームを実装しました。画像と書式付きテキストが含まれています。テスト中、問題なく約7分間プログラムを実行した後、画像が消えてテキストフォーマットがリセットされることがわかりました。問題を特定するために、書式付きテキストのみを表示する非常に基本的なバージョンを書き直しました。しかし、問題はまだ続き、私は1日のためにグーグルではありますが、問題はまだ同じです。ここに私のOnPaintメソッドがありますWin32 C++のDrawTextでメモリ使用量が増加する

CPaintDC dc(this); 

    CRect clientRect; 
    GetClientRect(&clientRect); 

    CDC bitmapDC; 
    bitmapDC.CreateCompatibleDC(&dc); 

    CBitmap bitmap; 
    bitmap.CreateCompatibleBitmap(&dc, clientRect.Width(), clientRect.Height()); 
    bitmapDC.SelectObject(&bitmap); 

    CBrush backgroundBrush; 
    backgroundBrush.CreateSolidBrush(RGB(0xf8, 0xf8, 0xf8)); 
    bitmapDC.FillRect(&clientRect, &backgroundBrush); 

    int SavedDc = bitmapDC.SaveDC(); 

    long nHeight = -MulDiv(20, GetDeviceCaps(bitmapDC, LOGPIXELSY), 72); 
    HFONT myfont = CreateFont(nHeight, 0, 0, 0, FW_ULTRALIGHT, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS, 
     CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, VARIABLE_PITCH, TEXT("Arial")); 

    bitmapDC.SelectObject(myfont); 
    SetBkMode(bitmapDC, TRANSPARENT); 

    bitmapDC.DrawText(L"This shouldn't happen", &clientRect, DT_SINGLELINE | DT_CENTER | DT_VCENTER); 

    dc.BitBlt(0, 0, clientRect.Width(), clientRect.Height(), &bitmapDC, 0, 0, SRCCOPY); 

    bitmapDC.RestoreDC(SavedDc); 
    backgroundBrush.DeleteObject(); 
    bitmap.DeleteObject(); 
    bitmapDC.DeleteDC(); 

Visual Studioでメモリ使用量が徐々に増えているのがわかります。私がDrawTextの部分をコメントアウトすると、それ以上は増加しません。私は何か間違っているのですか?どのようにDrawTextメソッドをメモリ使用量の増加から保護することができますか?私も画像でテストしましたが、それは同じ問題です。私は何とかDrawTextをリリースするか、削除する必要がありますか?どんな助けでも大歓迎です。

+4

あなたはmyfontを削除していません。 –

+0

@JonathanPotterあなたは、増加を止めたのは正しいです。私は画像を描画したい場合は、CImageオブジェクトを削除するだけで十分ですか?私はちょうどそれをテストし、単純にCImageを削除しても増加は止まらない。手伝ってくれてどうもありがとう。 – Revangelis

+1

どこでもCImageは表示されません。 –

答えて

3

消えるイメージとフォントは、メモリではなく、漏れたGDIリソースの兆候です。

メモリをリークするのはかなり難しいですが、リソースがかなり限られているため、リークするのは悪いことです。ゲームのタスクマネージャでGDI Objects列を観察してください。カウンターが10,000に達すると、あなたは完了です。

GDIリソースを保持するMFCオブジェクトを削除するだけでは十分ではありません。まず、DCからそれらのオブジェクトを選択解除する必要があります(現在選択されているオブジェクトは解放できません)。

+2

ツールと戦略の詳細については、[GDIリソースリークのデバッグ](https://blogs.msdn.microsoft.com/dsui_team/2013/04/23/debugging-a-gdi-resource-leak/)を参照してください。 – IInspectable

+0

これは非常に役に立ちます。ありがとうございます。しかし1つの質問:どのように私は選択を解除するのですか?あなたの最後の文章から理解しているところから、ReleaseDCはそのトリックをやりませんよね? – Revangelis

+0

@Revangelis - 'CDC :: SelectObject()'は、以前に選択されたタイプのオブジェクトへのポインタを返します。それを保存してそのDCに戻すだけで済みます。しかし、これは 'SaveDC()'/'RestoreDC()'呼び出しによってコード内ですでに行われている可能性があります。 –

-1

DCに選択したオブジェクトを削除できない場合は、 厳密に処理しないのはなぜですか?

bitmapDC.SelectObject(&bitmap); 
 ↓ 
CBitmap* pbmold = bitmapDC.SelectObject(&bitmap); 

(omission) 

bitmapDC.SelectObject(pbmold); // addition 
bitmap.DeleteObject(); 
bitmapDC.DeleteDC(); 

フォントも同じである...

+0

すみません。あなたはそれをセーブしました。 – nariuji

関連する問題