人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

開発環境:C++ Builder 2009(WinXPPro)

別スレッドから、一定時間毎にフォーム上に配置したTImageの内容を
書き換える処理を行っているのですが、たまに、EOutOfResourcesエラーが発生します。

TImageのハンドルが取得できなくなっているのではないか、と思うのですが、
どのように対処すればいいのかわかりません。

・別スレッドで行っているのは、下記のような内容です。
Graphics::TBitmap bmpBuffer;
//---------------------------------------------------------------------------
void __fastcall thread_proc::Execute()
{
bmpBuffer = new Graphics::TBitmap();
bmpBuffer->HandleType = bmDIB;
bmpBuffer->PixelFormat = pf1bit;
bmpBuffer->SetSize(100, 300);

while(true) {
// bmpBuffer->Canvasを使用した描画処理

Synchronize(&ImgUpdate);

i++;
Sleep(100);
}

delete bmpBuffer;
}
//---------------------------------------------------------------------------
void __fastcall thread_proc::ImgUpdate()
{
Form1->ImgPrev->Picture->Bitmap->Assign(bmpBuffer);
}

わかる方がいらっしゃいましたら、ご教授いただければと思います。
よろしくお願いします。


●質問者: madapaja
●カテゴリ:コンピュータ
✍キーワード:Builder C++ Canvas DELETE void
○ 状態 :終了
└ 回答数 : 7/7件

▽最新の回答へ

[1]と思うという、想像ではなく tdoi

まずは、EOutOfResourcesの例外が投げられる場所を特定してはどうですか?

対処法の前に、原因を確定させないと難しいでしょう。


[2]リソースリーク? cx20

C++ Builder は使ったことはありませんが、以下が原因ではないでしょうか?


Windows の仕様で「プロセス毎の GDI オブジェクト数」の制限(Windows 2000/XP の既定値:10,000個)というのがあります。

通常、使用した GDI オブジェクトを正しく開放していれば、問題ありませんが、取得して開放しなかったりすると、だんだんリークしていって、リソースが足りなくなります。


GDI オブジェクト数は、タスクマネージャで確認することができます。

該当プロセスの GDI オブジェクト数が 9,999 個に達していないか確認してみてください。

<GDI オブジェクト数の確認方法>
1. [Ctrl] + [Shift] + [ESC] にて「タスクマネージャ」を起動します。
2. [表示] - [列の選択] メニューを選択します。
3. 「列の選択」ダイアログにて [GDI オブジェクト] にチェックを入れ [OK] ボタンを押下します。
<参考情報>
■ Windows XP または Windows 2000 でプロセスが GDI オブジェクト クォータを超えた場合、
デスクトップのアプリケーション メニューが正しく表示されない
http://support.microsoft.com/kb/838283/ja
■ はてブ閲覧時のリソース不足
http://q.hatena.ne.jp/1227957618

[3]>2 回答ありがとうございます ja9

いただいた方法を元に、全GDI数を計算した所、2000強でした。

また、作成したアプリケーションのみのGDI数は55程度で、GDI数に引っかかっているようではありませんでした。

引き続き、原因を調査したいと思います。

ご回答いただき、ありがとうございました!


[4]>1 ご回答ありがとうございます。 ja9

知識不足でEOutOfResources例外が投げられる場所を特定する方法がわかりませんでした。。。

いただいた内容(推測ではなく原因を調査する必要があるという点)はごもっともだと思いますので、

何とか例外がおきている箇所を特定する方法を模索したいと思います。

ご回答いただき、ありがとうございました!


[5]>4 例外なら・・・ tdoi

Borland提供のAPIは詳しくないので、はずしていたら申し訳ないですが、

あやしいところをtry/catchで囲めばいいのでは?

try {

bmpBuffer = new Graphics::TBitmap();

} catch (EOutOfResources e) {

//エラーメッセージ

}

これで、エラーメッセージがでれば、TBitmapのコンストラクタが例外を投げていると分かるでしょう。

明らかにあやしい処理があれば、こんな感じでピンポイントでチェックして、それで見つからなければ、try/catchの範囲を色々変えてみればいかがですか?

何かの参考になれば。


[6]>5 CopyRect時にEOutOfResources例外 ja9

回答ありがとうございます。

try/catchを使って、例外が発生する箇所の特定を試みたところ、

// bmpBuffer->Canvasを使用した描画処理

部分で行っているCopyRectにて、EOutOfResources例外が発生しているようでした。

//該当部分のソース

TRect SrcRect, DstRect;

SrcRect = Rect(0, 0, 100, 300 - 8);

DstRect = Rect(0, 8, 100, 300);

try {

bmpBuffer->Canvas->CopyRect(DstRect, bmpBuffer->Canvas, SrcRect);

} catch (EOutOfResources &e) {

ShowMessage("EOutOfResources at CopyRect");

}

なぜ、このようになるのかわからないのですが、引き続き調査したいと思います。


[7]>6 アニメーション? tdoi

ソースから判断すると、左下に動いていくようなアニメーションを表示したいのですか?

元の描画がどのように行っているのかわからないですが、

CopyRectを呼び出すインスタンスと、CopyRectの第2引数のインスタンスが同一でもいいのでしょうか?

これがAPIでサポートされているかは分かりますか?


これで解決するかどうかも分かりませんが、オリジナルの絵を持ったTBitmapオブジェクトを作成しておいて、この処理を通るたびに、SrcRectの値と、DstRectの値を変えて、そのオリジナルのTBitmapのTCanvasから、上記のソース中のbmpBufferのTBitmapの持つTCanvasにコピーするようにしたらどうでしょうか?


全体が見えないので、原因も明確に見えないので、はずしている可能性は大ですが。

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ