コントロール等の描画処理について

[戻る]
whitecof [E-Mail] 2004/09/22(水) 17:01:11
whitcofと申します。
よろしくお願いします。

Win2000、VC++6.0、MFCの環境で、あるアプリケーションを作っています。

不明な異常があるため、情報を得たいと思い投稿しました。

ダイアログベースのアプリケーションにスタティックテキストコントロール
を配置して、あるデータを参照して、表示文字、表示色の変更を行なっています。
これは、WM_CTLCOLORを追加して、処理しています。

このアプリケーションが動作中におかしな状態になる時があります。
例えば、「アプリケーションの右下の方にあるコントロールが、
画面の左上の方に描画され、アプリケーション自体も動作不良になる。」
などです。

この他、別ダイアログを表示して、上記と同様の処理+CDCオブジェクトを
使って図形を描いている部分があるのですが、
クライアント領域を、黒で塗り潰しているのに、
突然、白で塗り潰されて、画面の解像度が変わったりして、動作不良状態になる。
などもあります。

これらの症状について、何かわかることがあれば、教えていただきたいと思います。
よろしくお願いします。

PATIO 2004/09/22(水) 17:54:45
書き込まれている内容だけからでは決定的な事はいえませんけれど、
解像度が変わってしまうくらいの挙動があるなら
グラフィックボードのドライバを疑いますね。
但し、よっぽど自分が書いたコードに自信が無いとそこまでは考えません。
まずは自分のコードに不具合があるのではないかと考えます。
何処まで異常な状況が起こるかはわかりませんけれど、
アプリケーション内でメモリの不正アクセスが行われると
状況によってはどんな異常な動作も起こりうると私は考えています。
ですから、まずは自分のソフトにメモリリークとか不正アクセスが
無いかどうかを調べます。
簡単なメモリリークならデバッグビルドしてデバッガーで動かし、
普通に終了すれば、アウトプットウインドウにメモリリークの表示が出ます。
また、本格的に調べたいのであれば、バウンダリチェッカとかピューリファイと
いった高価なソフトを使う手もあります。
不正アクセスについては、地道に追っかけるしかないですね。
不正アクセス即怪しい動作とはならない事もありますし。
怪しい動作が後になって現れるパターンもあります。
不正アクセスは前出のソフトでチェックする事も出来たと思います。

whitecof 2004/09/23(木) 09:52:29
PATIOさん回答ありがとうございます。

メモリリークとかだけでなく、グラフィックボードのドライバってのもあるんですね。

コントロールの色の変更については、ある参考書のサンプルを元に、少々手を加えて、以下の様な
コードを書いています。

void *******::○○○○○() //描画判断
{
 ー 途中省略 ー

  if(*******)
    m_bDrive = TRUE;   ←データをチェックして、描画状態のフラグを立ててます。
  else
    m_bDrive = FALSE;

  m_cDrive.RedrawWindow(NULL,NULL,RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);

 − 省略 −
}

HBRUSH ******::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
  HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
 − 途中省略 −

    if(pWnd == &m_cDrive)        //運転状態コントロール
    {
     if(m_bDrive==TRUE && m_bStop==FALSE)
     {
        pDC->SetTextColor(RGB(255,0,0));
        m_cDrive.SetWindowText("運転中");
        return ::CreateSolidBrush(RGB(0,255,0));
     }
     else if(m_bDrive==FALSE && m_bStop==TRUE)
     {
        pDC->SetTextColor(RGB(0,0,0));
        m_cDrive.SetWindowText("停止中");
        return ::CreateSolidBrush(RGB(192,192,192));        
        
     }
    }
}


参考書の内容を完全に信じきってやるのもいけないのかもしれませんが、
ぱっと見た感じ、おかしなところがあれば、ご指摘願います。

REE 2004/09/23(木) 11:29:40
OnCtlColorの中で、SetWindowTextを行うのはどうかと・・

しかし、それよりも悪いのは、
関数が呼ばれるたびに、CreateSolidBrushでブラシを作っているにも関わらず、
そのブラシを削除していないことでしょう。
確実にリソースリークになります。

whitecof 2004/09/23(木) 18:19:50
PATIOさん回答ありがとうございます。

過去レスを探してみたら、PATIOさんの指摘同様に
「return::CreateSolidBrush(***);はリソース不足になるのでしない方が良い。」
との記述がありました。

そこで、HBRUSH型の変数、例えば、”m_RED”を予め作っておいて、
「return m_RED;」
の様に変更しようと思います。

文字の変更の方も修正して、連続動作させてみようと思います。

whitecof 2004/09/27(月) 21:46:25
[[解決]]
通常より負荷をかけて連続動作させていますが、
動作不良も起こさなくなりました。

以前の状態だとタスクマネージャーのプロセスタブでメモリ使用量を見ていると
どんどん増加していくのが見られましたが、

全く変動しなくなりました。

アドバイスどうもありがとうございました。

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