スポンサーリンク

GetHBITMAPはDeleteObjectしないといけないらしい

アメリカ側の手続きが進んでいなくて先にアパートを追い出されたので☆の家に荷物共々転がり込んでいる。

☆もあまりいい顔をしていないが、震災に備えて貯めておいた無駄に高価な粉末青汁とか、真空パック玄米とか、比較的新しい洗濯機とかがただで手に入ったんでなんとか収まっている。賞味期限が切れていることはいわないでおいた方が良さそうである。

それはさておき、黒猫大和に問い合わせたら荷物30個をヤマト便で送ってくれるというので頼んだら、集配の人がものすごくいやな顔をしていた。というか梱包を自分でするなら引っ越し便使えないといったのはヤマト側なんだが、どうもそんなことはないらしい。受付と現場の認識の乖離が激しい。

 

さて、四月からの職場の上司との打ち合わせで、VC++2005を使っていることが発覚。でGDIで一生懸命図を書いていて、この人プログラマでもないのに凄いなと思ったんだが、アルファチャンネルをどんなに頑張っても加えられないと嘆いていたので、GDI+使うといいよと教えてあげたら喜んでた。

で、gdiplusを使うのはいいんだが、コントロール自作してたらDrawImageでちらつくことが発覚し、仕方が無いのでオフスクリーンレンダリングしてAlpaBlendしようと思った。

 

のだが、問題が発覚した。

OnPaintの中で以下のコードを走らせる。その際、OnSizingでInvalidateするようにして、マウスパッドを消しゴムで消すようにマウスで振り回しウィンドウサイズを変えていると、だいたい1~2分すると描画が一切されなくなる。

絶対メモリリーク的な何かがおこってると思ったが、案の定、それを指摘している人がいた。

 

CPaintDC dc(this); // 描画のデバイス コンテキスト
RECT rect;
rect.top = 20;
rect.left = 40;
rect.right = 200;
rect.bottom = 200;
Gdiplus::Bitmap backbuffer(rect.right, rect.bottom);
CDC memDC;
memDC.CreateCompatibleDC(&dc);
HBITMAP hbmp;
backbuffer.GetHBITMAP(Gdiplus::Color(0, 0, 0, 0), &hbmp);
HBITMAP oldbmp = (HBITMAP)memDC.SelectObject(hbmp);

Gdiplus::Graphics g(memDC);
for (size_t i = 0; i < 10; i++) {
	Gdiplus::Rect rct(0, i * 50, 50, 50);
	Gdiplus::SolidBrush brush(Gdiplus::Color(100, 255, 0, 0));
	g.FillRectangle(&brush, rct);
}
dc.BitBlt(0, 0, rect.right, rect.bottom, &memDC, 0, 0, SRCCOPY);

memDC.SelectObject(oldbmp);
//DeleteObject(hbmp);  ①

CDialogEx::OnPaint();

 

解決策は最後から三行目、①のコメントを外すこと。

というか

https://msdn.microsoft.com/ja-jp/library/windows/desktop/ms536295%28v=vs.85%29.aspx

説明読むと、

The Bitmap::GetHBITMAP method creates a Windows Graphics Device Interface (GDI) bitmap from this Bitmap object.

つまりGDI bitmapを作るっていう関数なので、作ったら破棄しなければいけないのは当たり前だ。

 

 

コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: