

只今 Borland C コンパイラ 5.5.1 においてプログラムを書いているのですが、(C言語)
仕様なのかどうなのか、ある処理でウィンドウのサイズを
ぐりぐり動かしつづけるとリソースが減っていって
フリーズしていしまいます。使用しているWindowsは98SEです。
そのプログラムは、ウィンドウプロシージャにおいて、
case WM_PAINT:
hdc = BeginPaint(hWnd,&ps);
hPen = CreatePen(PS_SOLID, 0, RGB(255,0,0));
hOldPen = (HPEN)SelectObject(hdc, hPen);
hBrush = CreateSolidBrush(RGB(0,255,0));
Rectangle(hdc, 10,10,100,100);
DeleteObject(hPen);
SelectObject(hdc, hOldPen);
DeleteObject(hBrush);
DeleteObject(hOldPen);
EndPaint(hWnd,&ps);
break;
という風に、Rectangle関数で画面に四角形を描画しているのですが、どうも上記の処理を何度も行うことにより
リソースが解放されずに大量に消費されてしまいます。
C言語においてはまだ少しわかるほどのレベルで、
殆どの関数の意味を今だに理解していなくプログラムの
文法になにかしらの間違いがあるかもしれませんが、
ご指摘いただければ幸いです。
No.1ベストアンサー
- 回答日時:
原因が分かりました、というわけではないのですが、気になるところを2点。
(1) hPenがまだselectされている状態でDeleteObjectしています。hPenのselectを解除してから(hOldPenをselectしてから)DeleteObjectしましょう。もしかしたらselectされている状態でDeleteObjectできず、そのせいでリソースが消費されているのかもしれません。
(2) hBrushがどこにも使われていません。SelectObjectし忘れでしょうか。(使用しないことによる問題はありません。)
すいません、
すぐに回答いただいてそのあとすぐにお礼を言おうとしたのですが、どうやらエラーが起きたようで
ちゃんと投稿されなかったようです。
hPenがselectされている状態ではDeleteOBjectにて削除することはできなかったんですね。
言われたとおりhPenをhOldPenに変えてから削除したところ
リソースは消費されることはなくなりました。
それと、hBrushは確かにいらなかったですね^^;
どうもありがとう御座いました。
No.5
- 回答日時:
case WM_CREATE:
hPen = CreatePen(PS_SOLID, 0, RGB(255,0,0));
hBrush = CreateSolidBrush(RGB(0,255,0));
break;
case WM_PAINT:
hdc = BeginPaint(hWnd,&ps);
SelectObject(hdc, hPen);
Rectangle(hdc, 10,10,100,100);
EndPaint(hWnd,&ps);
break;
case WM_DESTROY:
DeleteObject(hBrush);
DeleteObject(hPen);
break;
といった感じでどうですか?
この場合は hPenとhBrushの値が初期化されないように、
hPen と hBrush を staticで定義しておかないと
ダメみたいですが、その手もありですね。
最初から最後までずっとhPenを登録してる方法なので、
少しだけでも動作は速くなると思うので、
やってみます。^^
回答有難う御座いました。
No.4
- 回答日時:
1の方のいうとおりDCに選択された状態でDeleteObjectするとリソースリークします。
それと、描画系の処理をするときはSaveDC, RestoreDCを使用されることをオススメします。
現在の設定を保存して、あとで復元することができますので、いちいち以前設定されていたPenやBrushなどを覚えて復元する必要がなくなりミスが減ります。
上記コードですとこんな感じで使用します
int nSaveDC;
case WM_PAINT:
hdc = BeginPaint(hWnd,&ps);
nSaveDC = SaveDC(hdc); /* <-- 設定を保存 */
hPen = CreatePen(PS_SOLID, 0, RGB(255,0,0));
SelectObject(hdc, hPen);
hBrush = CreateSolidBrush(RGB(0,255,0));
Rectangle(hdc, 10,10,100,100);
RestoreDC( hdc, nSaveDC ); /* 復元 */
/* DCに選択されていない状態で削除*/
DeleteObject(hPen);
DeleteObject(hBrush);
EndPaint(hWnd,&ps);
break;
以前から参考書などにもsaveDCとRestoreDCとい関数
の説明が載っていましたが全くどう働くのかわからず
スルーしていたことがありましたが、こういうことだったんですね。
しかもいちいちもとのhdcの状態を保持し、
それを一括してもとにもどしてくれる関数があったとは、ほんとに脱帽物です。
回答ありがとうございました。
No.3
- 回答日時:
DeleteObject(hOldPen); ←これが余計な処理では?
これをコメントアウトして試してください。
システムのリソースをDeleteObjectしている気がします。
#2さんへ
「Borland C コンパイラ 5.5.1」 でVCL
は使えないんじゃ?
>>DeleteObject(hOldPen); ←これが余計な処理では?
確かに余計でした(汗)
SelectObjectによるハンドルとは明記されていたのですが、
これもリソースを消費するのでは?というような
妙な考えを持ってしまいつけていたようでした。
外して試したところリソースは消費されていなかったので、
外して処理致しました。
本当に取っていいのだろうかと心配してたので、
大丈夫だなんだとわかり有難うござした^^
No.2
- 回答日時:
質問とは直接関係ありませんが、お許し下さい。
このプログラムは演習用でしょうか?
デバイスコンテキスト関連のAPI関数を呼ばなくても
void __fastcall TForm1::FormPaint(TObject *Sender)
{
Form1->Canvas->Pen->Style = psSolid;
Form1->Canvas->Pen->Color = (TColor)RGB(255,0,0);
Form1->Canvas->Brush->Style = bsSolid;
Form1->Canvas->Brush->Color = (TColor)RGB(0,255,0);
Form1->Canvas->Rectangle(10,10,100,100);
}
で済んでしまうのですが…。
(使う場所によっては、Form1->CanvasのPenとBrushを保存しておいて元に戻す必要がありますが)
このようにしない理由があるのでしょうか?
すいません、C言語によるプログラムから始めたばかりで、
まだまだ分からない所も山ほどあるので、そういった方法は全く無知でした。
APIから少しでもソフトを作れるようになって、いろいろと
スキル向上を目指したいと思います。
一応今開発しているツールの一部で、HSPのような
プログラムの描き方にはなるんですが、背景用として
Rectangleをこの場合は利用しています。
画面のちらつきを防ぐため、WM_ERASEBKGNDを処理しているので、その背景の変わりに利用してます。
回答ありがとうございました。^
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) エクセルのマクロを使ってメールを送る方法について教えてください 2 2022/03/29 01:36
- Visual Basic(VBA) Vba LongPtrについて教えてください 2 2022/08/19 11:14
- Excel(エクセル) マクロで行を追加、削除すると行位置がずれますが、解決方法はありませんか?。 5 2022/05/28 16:03
- その他(プログラミング・Web制作) プログラムの勉強のおすすめは 7 2022/12/09 20:09
- その他(プログラミング・Web制作) pythonのmap、結果の利用は1度だけ? 5 2022/06/11 12:33
- MySQL 下の画像はSQLの4大命令の性質をまとめたものであるらしいです UPDATE INSERT DELE 1 2023/06/07 15:36
- Visual Basic(VBA) 【変更】ファイルを閉じてダイアログで保存した時、更新したシートだけの処理の実行をする 5 2022/03/26 18:31
- 英語 Osteogenesis in group B and C were significantly l 2 2022/03/24 05:27
- Visual Basic(VBA) 【追加】ファイルを閉じてダイアログで保存した時だけ処理の実行をする 3 2022/03/23 15:43
- Excel(エクセル) エクセル VBA実行中のApplication.ScreenUpdatingについて 3 2023/07/13 21:06
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBでデスクトップアクセサリを...
-
Rectangleで、リソースが解放さ...
-
ダブルバッファの作り方
-
コンテキスト依存とは?
-
エクセルで作った新しいウイン...
-
グラフの交点の求め方(Excel)
-
コントロールの書式設定で、“コ...
-
「アイテムは収集されました」...
-
皆さん、おはようございます♪ ...
-
ウィンドウのないActiveXコント...
-
別アプリの終了について
-
アクセスのセルの数え方。
-
有限要素法について教えてください
-
PanelとCanvasの違いについて
-
ラジオボタンの初期指定
-
有限要素法(FEM)について教え...
-
マインクラフト(pc版)で座標...
-
CodewarriorでOSX的なウィンド...
-
スピンボタンを右クリックして...
-
Alt+P,Alt+NをPostmessageで送...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
コンテキスト依存とは?
-
PlgBltでの透過
-
OpenGLでウィンドウハンドルの取得
-
メモリデバイスコンテキストを...
-
GetDC()とCreateCompatibleDC()
-
ちらつきについて
-
VBでFD、USBの有効・無効...
-
Active Basic デバイスコンテ...
-
ExtTextOut
-
デバイスコンテキストとデバイ...
-
VC++のTextOutの再描画の仕方
-
画面がチカチカする
-
ハードコピーをプログラムから...
-
メモリデバイスコンテキスト&...
-
C++でBMP解析
-
C 多角形を半透明に塗る方法
-
領域を塗りつぶしたい
-
コントロール内の文字の背景色
-
GetPixelに使うHDCの作り方
-
丸いボタンの表示でCPU100%
おすすめ情報