スタティックテキストの色変更

[戻る]
PING 2002/10/22(火) 13:53:29
1秒ごとにスタティックテキストの背景色等を変更するプログラムを
作っているのですが、約1時間半ぐらいで、スタティックテキスト部分が白くなり
ダイアログが崩れていってしまいます。
下記の通り書いてるのですが不具合箇所がどなたかお分かりでしょうか?
よろしくお願いします。
1秒を10msでやると50秒ほどで白くなり色が付かなくなります。
Invalidate()をやりすぎるといけないのでしょうか?

HBRUSH CSrvMonitorDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
  HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
  // TODO :  ここで DC の属性を変更してください。
  if(nCtlColor==CTLCOLOR_STATIC){
    if(pWnd->GetDlgCtrlID() == IDC_STATIC1){
       pDC->SetBkMode(TRANSPARENT);//背景色を見せる
       pDC->SetTextColor(RGB(f_aka,f_green,f_blue));//文字色      
       return ::CreateSolidBrush(RGB(b_aka,b_green,b_blue));//背景色
    }
  }
  // TODO :  既定値を使用したくない場合は別のブラシを返します。
  return hbr;
}


//色を変える部分★★ここを1秒ごと呼んでます。
void CSrvMonitorDlg::ColorChange()
{
  CStatic *static1=(CStatic*)GetDlgItem(IDC_STATIC1);
  static1->SetFocus();
  static1->Invalidate(TRUE);
}

くたくた 2002/10/22(火) 14:15:50
「CreateSolidBrush()に対するDeleteObject()が無い」のが原因ではないでしょうか。

アイススケーター 2002/10/22(火) 14:22:52
リソースの問題では・・・
CreateSolidBrushの後で、DeleteObjectが必要です。(HELPを見てね)

[E-Mail] 2002/10/22(火) 15:26:27
::CreateSolidBrush() じゃーなくて CBrush を使ったほうが
簡単ではないでしょうか。
私はそうしてますんで。

PING 2002/10/22(火) 18:51:46
DeleteObjectを追加したら時間的に長くなったので一部解決しました。
大変助かりました。ありがとうございます。

がしかし、まだ同様な不具合が発生するので当方で確認したところ、
スレッドでSrvCheck()が1秒ごとに呼ばれ、
SetDlgItemText(IDC_STATIC1,"実行中");//状態表示

上記のようにスタティックテキストに書いているのですが、
これをコメントアウトすると継続的に動作し、正常に動いているみたいなのですが、
このSetDlgItemText()でのスタティックへの書き方は悪いのでしょうか?
他に良い方法はありますでしょうか?




void CSrvMonitorDlg::ColorChange()
{
  CStatic *static1=(CStatic*)GetDlgItem(IDC_STATIC1);
  static1->SetFocus();
  static1->Invalidate(TRUE);
    DeleteObject(hBrush);<<追加したらOKになりました。ありがとうございました。
}

//スレッドで呼ばれるところ
void CTestColorDlg::SrvCheck()
{
    SetDlgItemText(IDC_STATIC1,"実行中");//情報を表示
    
    f_aka=f_green=f_blue=255;        //フォント色:白
    b_aka=0;b_green=128;b_blue=255;    //背景色:青
    ColorChange();

}

アイススケーター 2002/10/22(火) 20:25:20
文章を読んでいて、どういう現象になってどういう異常になったのかが
解らないんですが・・・

後、CreateとDeleteはなるべく同じサブルーチン内で行ったほうが
バグにならないと思うのですが。

kazuma 2002/10/22(火) 23:24:36
OnCtlColorは再描画が必要になるたびに呼ばれますから、
CSrvMonitorDlg::ColorChange
でDeleteObjectしても、CreateSolidBrushとDeleteObjectとが1対1に対応しません。

解決策は、
1.CSrvMonitorDlgに、CBrush型のメンバ変数を追加します。
2.CSrvMonitorDlg::OnInitDialogで一度だけCreateSolidBrushを呼びます。
3.CSrvMonitorDlg::OnCtlColorではそのブラシのハンドルを返すだけでいいです。

kazuma 2002/10/22(火) 23:59:26
あ、途中で色が変わるんですね。

その場合は先に挙げた1.〜3.に加えて、
4.色を変えたいところ(CTestColorDlg::SrvCheckなど)で、DeleteObjectして、  
  CreateSolidBrushしなおします。

PING 2002/10/23(水) 08:54:09
[[解決]]
みなさん回答ありがとうございました。
おかげさまで、問題解決致しました。大変助かりました。

みなさんの意見を参考にCreateとDeleteを同じところで
やりましたら、うまくいきました。文字の書き込みをしても
色が抜けたり、画面が崩壊しなくなりました。

一部理解できない表現がありましたところは、お詫び致します。
ありがとうございました。

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