MFC 6.0 VC++で処理が重くなる原因と対策

このQ&Aのポイント
  • MFC 6.0 VC++で処理が重くなる問題について説明します。
  • 処理が重くなる原因として、画面の再描画と描画処理に必要な計算が挙げられます。
  • また、仮想ウィンドウに描画してBitBlt()を実行する方法も試しましたが、処理が重くなってしまいました。
回答を見る
  • ベストアンサー

MFC 6.0 VC++ で、処理が重くなります。

MFC 6.0 VC++ で、処理が重くなります。 上記の環境でダイアログベースで処理を作成しています。 画面の再描画を繰り返すと、同じ処理をしていても処理が重くなります。 OnPainメッセージを受け取ったあとに、描画処理を行っているのですが、画面に表示に必要な計算も描画時に行っています。 仮想ウィンドウに描画してBitBlt()を実行する方法も試しましたが、ちらつかなくなった代わりに余計に処理が重くなりました。 描画のやり方が問題なのか、内部の処理が問題なのか良く分からないのですが、何か良い方法が無いでしょうか? タスクマネージャーを見るとコミットチャージが増えているようです。 このコミットチャージもどう対処してよいのか良く分からないのですが、これが関係しているでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

使用したスレッドやクラス、メモリの開放は行われていますか? タスクマネージャーは「コミットチャージ」ではなく「プロセス」で、 該当アプリの「メモリ使用量」「ハンドルの数」「スレッドの数」も確認してください。

TonoATS
質問者

お礼

解決しました。 メモリーが増えている部分を追跡したところ・・・ Rgn.CreateRectRgn(SelScreen.left,SelScreen.top,SelScreen.right,SelScreen.bottom); が2行重複して定義されている部分がありました。 これを削除したところ、現象を回避することができました。 どうやら、私のポカミスだったようです。 ありがとうございました。

TonoATS
質問者

補足

ありがとうございます。 ダイアログの初期化の際にInitDialogからcallocを使用して確保したメモリはOnDestroy内で開放していますが、この部分ではない気がします。 確認してみたところ、ハンドル数とスレッド数は変化ありませんが、メモリー使用量が増えています。 再描画するたびに増えているので、描画関連の処理の中で何かが起きている気がします。 描画は描画用のクラスを作成して、内部にCDC m_dcを設けて、m_dc.Attach(*dc)の後に描画処理をおこない、終了後にm_dc.Detach()を実行しています。 BOOL CGraphics::MyCreate(CDC *dc) { BOOL flg = m_dc.Attach(*dc); m_dc.SetBkMode(TRANSPARENT); return flg; } HDC CGraphics::MyDetach() { return m_dc.Detach(); } /////////////////////////////////////////////////////////////////////////////////// // 線を引く /////////////////////////////////////////////////////////////////////////////////// void CGraphics::line(int x1, int y1, int x2, int y2, int width, COLORREF color) { CPen pen; pen.CreatePen(PS_SOLID,width,color); m_dc.SelectObject(&pen); m_dc.MoveTo(x1,y1); m_dc.LineTo(x2,y2); pen.DeleteObject(); } ・・・というような基本構成になっています。 呼び出す側は・・・ ヘッダーの中で CGraphic m_Gr;をダイアログのメンバシップ変数として定義しています。 void CMyDialog::OnPaint() { CPaintDC dc(this); // 描画用のデバイス コンテキスト MyViewMain(&dc); } // 描画のメイン void CMyDialog::MyViewMain(CDC *dc) { ViewGrid(dc,View.GridLink[START],0); ViewGrid(dc,View.GridLink[END],1); dc->SelectClipRgn(NULL); } void CMyDialog::ViewGrid(CDC *dc, int grid, int sid) { CRgn Rgn; m_Gr.MyCreate(dc); Rgn.CreateRectRgn(SelScreen.left,SelScreen.top,SelScreen.right,SelScreen.bottom); m_Gr.m_dc.SelectClipRgn(&Rgn); //このあたりにforループなどで制御された描画命令が書かれる Rgn.DeleteObject(); m_Gr.MyDetach(); } ・・・っといった構成になっています。

その他の回答 (1)

  • koi1234
  • ベストアンサー率53% (1866/3459)
回答No.2

計算内容にもよりますが計算してからOnPaint行うのが一般的な考え方ではないでしょうか 時間経つごとに計算量が増えるようなロジックであれば 当然遅くなるということはありえると思います ちょっと気になりましたが 処理が重いというのはOS全体のレスポンスが悪くなる ということでしょうか それともアプリケーションの表示(更新・その他)が遅くなるということでしょうか? >タスクマネージャーを見るとコミットチャージが増えているようです。 #1さん書かれてますがどこかでリークしてるような気がします アプリケーション終了時にVC上に一杯エラー表示されませんか?

TonoATS
質問者

お礼

解決しました。 ありがとうございます。 エラーは表示されていませんでしたが、表示部でリージョンを2重に定義している部分がありました。 重複している部分を削除したら、現象が収まりました。

TonoATS
質問者

補足

ありがとうございます。 計算というより、計算結果をforループなので座標を出しながら表示していくもので、時間と共に内容が変わるものではありません。 ちゃんと測定したわけではありませんが、重くなっているのはアプリケーションのみだと思います。 特にエラーは表示されません。重くなっているのを我慢すれば使用し続けられます。

関連するQ&A

  • MFC 6.0 VC++ で、処理が重くなります。

    MFC 6.0 VC++ で、処理が重くなります。 上記の環境でダイアログベースで処理を作成しています。 画面の再描画を繰り返すと、同じ処理をしていても処理が重くなります。 OnPainメッセージを受け取ったあとに、描画処理を行っているのですが、画面に表示に必要な計算も描画時に行っています。 仮想ウィンドウに描画してBitBlt()を実行する方法も試しましたが、ちらつかなくなった代わりに余計に処理が重くなりました。 描画のやり方が問題なのか、内部の処理が問題なのか良く分からないのですが、何か良い方法が無いでしょうか? そもそもダイアログベースで画像処理をしているのが間違いな気もするのですが・・・。

  • MFCでOnPaintのタイミング

    Visual Studio 2008のMFCでOnPaint()が呼ばれるタイミングですが、 非表示の時など再描画が不要と思われるところで立て続けに 呼ばれているのが気になりました。 そのタイミングはどういう時でしょうか? といいますのも、ダイアログベースで OnPaint()の中でダブルッファリングを使用していくつかの処理をまとめて描画をしているのですが、 起動後数分後にCResourceExceptionで落ちてしまっていまして、 最小限の描画回数に済ませればそのようにはならないかと考えた次第です。 ※メンバにデバイスコンテキストとCBITAMAPを定義して使用しています。 BitBltするごとにDeleteObjectはしていますが・・・

  • 再描画について。

    VC++のMFC、ダイアログベースで画像処理のソフトを作っている者 ウィンドウを動かしたり他のウィンドウを重ねたりすると描画した画像が消えてしまうので、 再描画をしたいのですが、方法が分かりません。 分かる方がいらっしゃいましたらよろしくお願いいたします。

  • VC++でタスクバーに表示させない方法。(非MFC)

    VC++6.0 で常駐アプリの開発をしているのですが、 MFCを使わずにダイアログを作成し、 タスクトレイにアイコンを表示するのはできたのですが、タスクバーには表示が残ってしまいます。 タスクバーに表示させない方法を教えてください。 よろしくお願いします。

  • VC++2010 描画処理について

    VC++2010 描画処理について質問なんですが、 再描画するさい、前の描画した画像(自分が今作成しているプロジェクトでいうと前、描画した点が消えてしまってあらたに点が描画されるんですが)その前、描画された点を消すことなく新たに点が描画される方法が分からないので質問させていただきました。このままだったら直線にならない、そして点がただ動くだけのプロジェクトになります。点がただ動くだけのじゃない、線が描画される方法をよろしくお願いします。 ではよろしくお願いします。

  • MFCでデータベースを

    はじめまして。 VC++の初心者なのですが、MFCで開発を行おうとしております。そこで、MFCでのデータベースの扱い方をおしえていただきたいのです。 MFCのダイアログベースで開発をしているのですが、そこからデータベースを読みに行ったりは可能なのでしょうか。 よいサイト等あれば教えていただけないでしょうか。よろしくお願いいたします。

  • VC++2008にて、画面の動的変更処理について

    現在VC++2008のMFCにて開発を行っております。 ダイアログのテキストボックスAの値を変更し、 カーソルが移動した際に 他のテキストボックスBの値を、Aの値により処理がかかる のような処理は無理なのでしょうか? やはり、ボタン押下でしか画面の更新は無理なのでしょうか? ご教授頂ければ幸いです。

  • 「VC++6」ウィンドウの再描画

    VC++6を使って簡単なプログラムをダイアログベース作っています。 内容はリストを読み込み、1件ずつDBにSQLを発行して情報を取得していくという内容です。 画面には、プログレスバーも設置しており、普通に操作すると正常に、プログレスバーも動きます。しかし、いったん別のウィンドウをアクティブにして、作成した動作中のプログラムを再選択しても、画面は壊れたまま再描画されません。しばらくまって、リストのSQL発行が終わって、画面に結果が表示されたら、きちんと再描画されます。 そこまで処理が終わったら、他のウィンドウに切り替えて戻ってきても画面が壊れることはありません。 時間がかかるプログラムなので、動作中に別の仕事をするため、アクティブでなくても、きちんとウィンドウを更新したいのです。 ちなみに、ループ処理中にRedrawWindow();を入れてみましたがダメでした。 アドバイスよろしくお願いします。

  • MFC ダイアログ上のID取得について

    VC++6.0 MFC ダイアログベースで開発しています。 リソースエディタで配置したダイアログ上にある全てのコントロール(ボタン、テキスト等)IDを取得する方法はありませんか? よろしくお願いします。

  • ダイアログ画面全体をマウスで動かせるようにするには

    VC++、MFC、WindowsXPです。 現在の状況としてはは ダイアログベースによる作成。 ダイアログにオーナー描画でビットマップを貼り付けている。 という感じです。 普通ウィンドウのタイトルバーをマウスで押してウィンドウの位置を動かしますが、たまに画面のどこを押しても動かせるようなウィンドウがありますが、あれは一体どうやっているのでしょうか? よろしくお願いします。

専門家に質問してみよう