ブラシの削除だ

[戻る]
歯磨き 2002/02/22(金) 15:41:14
HDC hDC;
HBRUSH hBrush, hBrushOld;

hDC = GetDC(hWnd);
hBrush = CreateSolidBrush(123);        //新ブラシ作成
hBrushOld = SelectObject(hDC, hBurush);    //新ブラシ適用
使い終わる
SelectObject(hDC, hBrushOld);        //旧ブラシに戻す
DeleteObject(hBrush);            //ブラシ削除
ReleaseDC(hWnd, hDC);

これは

HDC hDC;
HBRUSH hBrush;

hDC = GetDC(hWnd);
hBrush = CreateSolidBrush(123);        //新ブラシ作成
SelectObject(hDC, hBurush);            //新ブラシ適用
使い終わる
ReleaseDC(hWnd, hDC);            //先にHDCを消す
DeleteObject(hBrush);            //ブラシ削除

としてもいいですか?

不良PG 2002/02/22(金) 15:57:09
そこまで突っ込む理由が解りませんが・・
とりあえず、駄目です

メモリリークしますね

>ReleaseDC(hWnd, hDC); //ここでhBrushが解放されます

そして、デバイスコンテキストが最初から持っていたブラシが解放されずに残ります

不良PG 2002/02/22(金) 16:05:35
・・違ったかな(^^;

不良PG 2002/02/22(金) 16:13:07
しかも、

誤)メモリーリーク
正)リソースリーク

不良PG 2002/02/22(金) 16:17:41
というよりもこれ以上は、自分で考えましょう(^^;

EIJI 2002/02/22(金) 16:46:52
ほんとに問題が起こるかは実際に試してみないとわかりませんね。
Windows9x系で100万回くらい描画してみてリソース残量を確認してみると
いいのでは。
NT系だと問題が発覚しにくいので9x系で。

不良PG 2002/02/22(金) 16:52:19
>ほんとに問題が起こるかは実際に試してみないとわかりませんね。
>Windows9x系で100万回くらい描画してみてリソース残量を確認してみると
>いいのでは。
>NT系だと問題が発覚しにくいので9x系で。

9x系とNT系では、GDIの挙動が異なる為、
9x系で大丈夫だからと言ってNT系で大丈夫と一概には、言えませんよ

歯磨き 2002/02/22(金) 17:23:25
EIJIさんの考えでは、下のソースで問題なさそう
といことですか?

EIJI 2002/02/22(金) 17:28:22
>9x系で大丈夫だからと言ってNT系で大丈夫と一概には、言えませんよ

そうですね。両方で試したほうがよいでしょうね。
ただ、ブラシの開放忘れが起きて問題になるのなら、
9x系のほうがすぐわかるだろうと思います。
この手のバグはNT系だと発覚しにくいです。

EIJI 2002/02/22(金) 17:33:13
実際にやってみるのが一番だと思いますけど、
個人的には後者のような書き方はしません。
問題があるかどうかは別に、前者のように書くべきだと思いますよ。

歯磨き 2002/02/22(金) 18:08:22
実験して不具合が発生しても、僕に分かるのは下のソースはだめだと
いうことだけで、僕にはそのだめな原因が分からないと思うんです。
僕にはソースのどこにエラーがあるのか分かりません。
どこがいけないのか、このままだとどうなってしまう
可能性があるのか教えてください。

不良PG 2002/02/22(金) 18:26:09
うーん

>実験して不具合が発生しても、僕に分かるのは下のソースはだめだと
>いうことだけで、僕にはそのだめな原因が分からないと思うんです。

だめだと分かったら前者のような書き方をしましょう

>僕にはソースのどこにエラーがあるのか分かりません。

自分で分かるまで自分でWebや本で勉強して下さい

>どこがいけないのか、このままだとどうなってしまう
>可能性があるのか教えてください。

アプリかOSが落ちる可能性がある


ところで、原因を調べてどうするつもりですか?

不良PG 2002/02/22(金) 18:34:13
納得いくかどうかは、分かりませんが・・

前者にする理由は、OS(API)の仕様だからです

以下は、MSDNの API SelectObject の解説です

この関数は、指定されたのと同じタイプで、それまで選択されていたオブジェクトを返します。
アプリケーションは新しいオブジェクトを使い終えたら、必ず元の(既定)オブジェクトに置き
換えるべきです。

いもちぃ 2002/02/26(火) 11:11:17
えと、問題は確実に起こりませんか・・?
後者だと、hBrushは、最後にDeleteしますよね?つまりhBrushによって
指し示されたBrushの実体はメモリ上から(論理的に)なくなり、そのメモリは
フリーになるわけです。
でも、hDCは存在しつづけますし、Brushを使う必要が出たら、hBrushを
使おうとするわけです。でも実際にはもう存在しないと。
かなり簡単に問題が発覚しそうな気が・・・。

彦滝 2002/02/27(水) 20:13:00
後者でも問題無ありません。
以下で証明されます。

int i;
bool b;
char buf[10];

i = ReleaseDC(hWnd, hDC);
b = DeleteObject(hBrush);

wsprintf(buf, "%d, %d", i, (int)b);
MessageBox(hWnd, buf, "ReleaseDC, DeleteObject", MB_OK);

不良PG 2002/02/27(水) 20:46:25
>後者でも問題無ありません。
>以下で証明されます。
>
>int i;
>bool b;
>char buf[10];
>
>i = ReleaseDC(hWnd, hDC);
>b = DeleteObject(hBrush);
>
>wsprintf(buf, "%d, %d", i, (int)b);
>MessageBox(hWnd, buf, "ReleaseDC, DeleteObject", MB_OK);

あの・・、これのどの辺りが証明になるのでしょう。

確かに後者のコード内の関数は、成功します
・ReleaseDCはデバイスコンテキストが解放された場合に、成功します
・DeleteObjectは、GDIオブジェクトが削除できれば、成功します

しかし、解放されたデバイスコンテキストは、ブラシが削除された(参照するブラシがない)
状態で存在することになります。
これは、問題ないのですか?

古いスレッドには追加発言できません。