none
エディットコントロールの文字に色を付ける方法について教えてください。 RRS feed

  • 質問

  • ダイアログに、エディットコントロールを2つと、コンボボックスを
    1つ貼り付け、OnCtlColorで、エディットコントロールの文字色を
    変えるテストプログラムを作成したのですが、コンボボックスの
    色まで変わってしまいます。(下記テスト方法参照)

    私の調べたところ、
    コンボボックスのエディットボックスのIDが、1001で、
    コンボボックスのプルダウンリストのIDが、1000で送られてきている為、
    エディットコントロールとだぶってしまっているようです。

    Resource.h の
    #define IDC_EDIT1                       1000
    #define IDC_EDIT2                       1001

    の値を、1100番代辺りに変えるとエディットコントロールだけ色を変える
    ことができるようになりますが、そんなことをせず、OnCtlColor内部で
    エディットコントロールだけ色を変えるにはどうすればいいのでしょうか?
    よろしくお願い致します。


    ■テスト方法
    ① ダイアログに、エディットコントロールを2つ貼り付け、最後にコンボ
      ボックスを1つ貼り付けます。
    ② OnCtlColorを、下記のコードを書き加えます。
    ③ プログラムを実行し、文字色が分かるよう各コントロールに文字を入力
       します。

    HBRUSH Ctest4Dlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
    {
    HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

        // TODO :  ここで DC の属性を変更してください。
        int id;

        if (nCtlColor != CTLCOLOR_EDIT)
            return hbr;

        id = pWnd->GetDlgCtrlID();
        if (id == IDC_EDIT1) {
            pDC->SetBkMode(TRANSPARENT);
            pDC->SetTextColor(RGB(0, 0x777, 0));
        }
        if (id == IDC_EDIT2) {
            pDC->SetBkMode(TRANSPARENT);
            pDC->SetTextColor(RGB(0xFF, 0, 0));
        }

        // TODO :  既定値を使用したくない場合は別のブラシを返します。
        return hbr;
    }

    2006年10月14日 2:51

すべての返信

  • 確かに IDC_EDIT2 の 1001 の値が ComboBox の EditBox の ID と重なってしまっているようですね。

    次のようなチェックコードを入れてみるというのは如何でしょうか? かなり ad hoc ですが…

        if (id == IDC_EDIT2 && pWnd->GetOwner ()->GetSafeHwnd () == GetSafeHwnd ()) {
            pDC->SetBkMode(TRANSPARENT);
            pDC->SetTextColor(RGB(0xFF, 0, 0));
        }

    GetParent で Parent Window を確認していても足りるようですが…。

    # IDC_EDIT1 が重なる可能性も考えると、先頭で Owner や Parent の check をした方が良いのかもしれませんね。

     

    2006年10月14日 8:03
  • Takashi SAKAMOTO様、レスありがとうございます。

    OnCtlColorの引数 CWnd* pWnd の親で判別するようにしました。
    akashi SAKAMOTO様と考え方は同じですね(^^
    ダイアログに貼り付けたエディットコントロールの親はダイアログで、
    コンボボックスのエディットコントロールの親はコンボボックスなので、

        if (nCtlColor != CTLCOLOR_EDIT)
            return hbr;

        if (pWnd->GetParent() != this)    // 追加コード // コントロールの親がダイアログ
            return hbr;                                  // 追加コード // でなければ抜ける。

        id = pWnd->GetDlgCtrlID();

    というコードを入れることにより解決しました。
    これにより、期待通りの動きをしていますが、これは正しい方法でしょうか?

    因みに、コンボボックスのエディットコントロールに送られてくる親を、
    pWnd->GetParent()で調べてみたところ、確かに、コンボボックスのCWnd*
    を指していました。

    2006年10月14日 8:50
  • Parent Window で判断するという方法は問題ないと思います。

    気がかりがあるとすれば、OnCtlColor の引数の pWnd と this で Window Handle が同じなのに違う場所を指す可能性ですが…

    CWnd::OnWndMsg の AfxSig_CTLCOLOR の扱いを見る限り、引数の pWnd は CWnd::FromHandlePermanent で作られていますから、this と比較するのは問題なさそうです。

    # 私の書いた ad hoc コードは、そのあたりを心配して(プラスきちんと確認していなくて) Window Handle で比較しようとしていました。

     

    2006年10月14日 19:21
  • Takashi SAKAMOTO 様

    > CWnd::OnWndMsg の AfxSig_CTLCOLOR の扱いを見る限り・・・
    わざわざ調べて頂いたんですね。ありがとうございます。
    Ctest4Dlgは、←CDialog←CWndと派生したクラスですから、確かに
    thisと、CWndを安直に比較するのは、危ないかも知れませんね。

    > # 私の書いた ad hoc コードは、そのあたりを心配して(プラスきちんと確認していなくて) Window Handle で比較しようとしていました。
    なるほど!そういうことだったんですか。
    この度は、本当にありがとうございました。

    2006年10月15日 16:27
  • 整理したテストプログラムををアップします。
    今回、コントロールの背景色はいじっていないので、
    pDC->SetBkMode(TRANSPARENT);
    は削除しました。

    ■内容
    エディットコントロール、コンボボックスに色をつける。
    (他のコントロールにも同じ様に使用できると思います)

    ■作成、テスト方法(MFC 使用)
     ① ダイアログに、エディットコントロールを2つ貼り付け、最後にコンボ
       ボックスを1つ貼り付けます。
     ② OnCtlColorを、下記のコードを書き加えます。
     ③ プログラムを実行し、文字色が分かるよう各コントロールに文字を入力
        します。

    ■ソースコード
    #define COMBOBOX_EDIT_ID    1001

    HBRUSH Ctest4Dlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
    {
        HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

        // TODO :  ここで DC の属性を変更してください。
        int id;

        if (nCtlColor == CTLCOLOR_EDIT) {
            if (pWnd->GetParent() == this) {                        // エディットコントロールに色をつける
                id = pWnd->GetDlgCtrlID();
                if (id == IDC_EDIT1)
                     pDC->SetTextColor(RGB(0, 0x777, 0));
     
                if (id == IDC_EDIT2)
                    pDC->SetTextColor(RGB(0xFF, 0, 0));
            }
            if (pWnd->GetParent() == GetDlgItem(IDC_COMBO1)) {      // コンボボックスに色をつける
                id = pWnd->GetDlgCtrlID();
                if (id == COMBOBOX_EDIT_ID)                         // #define COMBOBOX_EDIT_ID    1001
                    pDC->SetTextColor(RGB(0, 0, 0xFF));
            }
        }

        // TODO :  既定値を使用したくない場合は別のブラシを返します。
        return hbr;
    }

    以上です。

    レスを頂いたTakashi SAKAMOTO様、このスレを見て頂いた沢山の方々ありがとうございました。

    2006年10月16日 9:36