無効のエディットボックスの文字色の変更 – プログラミング – Home

無効のエディットボックスの文字色の変更
 
通知
すべてクリア

[解決済] 無効のエディットボックスの文字色の変更


花乃
 花乃
(@花乃)
ゲスト
結合: 16年前
投稿: 6
Topic starter  

早速質問させていただきます。

OS:Windows2000 XP
VC6でダイアログベースです。

HBRUSH CColorEdit::CtlColor(CDC* pDC, UINT nCtlColor)
{
// TODO: この位置で DC のアトリビュートを変更してください
pDC->SetTextColor( m_colText );
pDC->SetBkColor( m_colBack );
return m_brush;

}

//-----------------------------------------------------------------------------
// 文字色の変更
// ret : なし
// arg1 : (IN) colBack 文字色
//-----------------------------------------------------------------------------
void CColorEdit::SetTextColor( COLORREF colText )
{
m_colText = colText;
}

//-----------------------------------------------------------------------------
// 背景色の変更
// ret : なし
// arg1 : (IN) colBack 背景色
//-----------------------------------------------------------------------------
void CColorEdit::SetBackColor( COLORREF colBack )
{
m_colBack = colBack;
m_brush.DeleteObject();
m_brush.CreateSolidBrush( m_colBack );
if( NULL != m_hWnd )
{
RedrawWindow( NULL, NULL, RDW_FRAME | RDW_INVALIDATE |
RDW_UPDATENOW );
}
}


引用未解決
トピックタグ
花乃
 花乃
(@花乃)
ゲスト
結合: 16年前
投稿: 6
Topic starter  

すみません。途中で送信してしまいました。
上記のように、CEditの派生クラスを作って、
色を変えているのですが、
リソースの設定で「無効」にした場合に、
文字色が変わりません。

ReadOnly(TRUE)にして、TabStopを設定しないというのも
試したのですが、エディットボックス内にカーソルが出てしまいます。
カーソルは出したくないのです。
スタティックテキストにするしか無いのでしょうか?
この場合、入力したくなると困るので、
何か良い方法があればと思い書き込みさせていただきました。
よろしくお願い致します。


返信引用
どとう
 どとう
(@どとう)
ゲスト
結合: 21年前
投稿: 7
 

私はよく、エディットコントロールのEN_SETFOCUSのイベントハンドラで
別のコントロールにフォーカスを移すようにしています。

void CXXXXDlg::OnEnSetfocusEdit1()
{
  //最初のコントロールにフォーカスを移動
CWnd *pWnd=GetWindow( GW_CHILD );
if( pWnd ) pWnd->SetFocus();
}


返信引用
花乃
 花乃
(@花乃)
ゲスト
結合: 16年前
投稿: 6
Topic starter  

どとう様、ありがとうございます。

この場合、一つ一つのコントロールのフォーカスを、
移動させなくてはならないのですよね?
今回、この色設定をするエディットボックスが50個くらいあるので、
この対応はかなり厳しそうですが、今後の参考になりました。


返信引用
subaru
 subaru
(@subaru)
ゲスト
結合: 18年前
投稿: 381
 

カーソル移動させたくないだけなら、
CEditの派生クラスの方にOnLButtonDownとOnContextMenuの
ハンドラを追加してその実装を空にするだけでも
できそうですがどうでしょうか。


返信引用
Hazard52
 Hazard52
(@Hazard52)
ゲスト
結合: 19年前
投稿: 9
 

かなり前の記憶ですが、EDITを無効化した場合は、
STATICと同じく、WM_CTLCOLORSTATICが送られてきて、
こちらで処理しないといけなかった様な気がします。


返信引用
どとう
 どとう
(@どとう)
ゲスト
結合: 21年前
投稿: 7
 

よく考えたら、CEditの派生クラスのOnSetFocus()で
前のフォーカスに戻せば良いのではないでしょうか?

void CXXXEdit::OnSetFocus(CWnd* pOldWnd)
{
  //CEdit::OnSetFocus(pOldWnd);
  //前のフォーカスに戻す
if( pOldWnd ) pOldWnd->SetFocus();
}

カーソルは出なくなりますが、入力もできなくなり
ただのスタティックテキストのようになります。
それで良いのですよね?

Tabで移動できなくなるので、TabStop=FALSEが必要。


返信引用
花乃
 花乃
(@花乃)
ゲスト
結合: 16年前
投稿: 6
Topic starter  

subaru様 Hazard52様
ありがとうございます。

subaru様
> カーソル移動させたくないだけなら、
> CEditの派生クラスの方にOnLButtonDownとOnContextMenuの
> ハンドラを追加してその実装を空にするだけでも
> できそうですがどうでしょうか。

この場合、無効にしているエディットボックスは、
理想的な動きをしてくれたのですが、
色を変更したいだけの、有効なエディットボックスも
入力が出来なくなってしまったので、

void CColorEdit::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: この位置にメッセージ ハンドラ用のコードを追加するかまたはデフォル
トの処理を呼び出してください
if( !( GetStyle() & ES_READONLY ))
{
CEdit::OnLButtonDown(nFlags, point);
}
}

こんな感じで、回避してみたのですが、
OnContextMenuの方の対応策が思いつきません。
何か良い方法ありますでしょうか?

--------------------------------------------------------------------

Hazard52様
> かなり前の記憶ですが、EDITを無効化した場合は、
> STATICと同じく、WM_CTLCOLORSTATICが送られてきて、
> こちらで処理しないといけなかった様な気がします。

クラスウィザードを使っているのですが、
WM_CTLCOLORSTATICが見当たりません。
自分で、書かないとダメですか?

よろしくお願い致します。


返信引用
gak
 gak
(@gak)
ゲスト
結合: 21年前
投稿: 132
 

> ReadOnly(TRUE)にして、TabStopを設定しないというのも
> 試したのですが、エディットボックス内にカーソルが出てしまいます。
> この場合、入力したくなると困るので
文字を範囲選択して Ctrl+C とかされても問題は無いのだけど、カーソルに点滅されると
入力可と誤解されるかもしれないので嫌だ!って可能性もあるのかな。

void CColorEdit::OnSetfocus() {
::DestroyCaret();
}

仮にそうならば上記コードでカーソルを消す事は可能なハズ。
だが、内部的にはカーソルは生きているので Shift + 十字キーとかマウスとかで文字の
範囲選択はできちゃうけどね。

> WM_CTLCOLORSTATICが見当たりません。
MFC では WM_CTLCOLORxxxx 系メッセージは WM_CTLCOLOR に纏めて送られてくる。
で、実際にどの WM_CTLCOLORxxxx が送られてきたか判断するには OnCtlColor() の
nCtlColor を見て判断する仕様になってる。
ぶっちゃけると、花乃さんのコードで WM_CTLCOLORSTATIC で送られてきた時の処理はで
きている。(EDIT にくる WM_CTLCOLORxxxx 系メッセージ全てで同じ処理をしているので
結果的に、と言った方が正しいだろうけど)


返信引用
subaru
 subaru
(@subaru)
ゲスト
結合: 18年前
投稿: 381
 

>こんな感じで、回避してみたのですが、
>OnContextMenuの方の対応策が思いつきません。
OnLButtonDownと同様
CEdit::OnContextMenu(...);
で既定の処理が行われます。

>クラスウィザードを使っているのですが、
>WM_CTLCOLORSTATICが見当たりません。
>自分で、書かないとダメですか?
MFCの場合はOnCtlColorの引数で判断すること
になるのですがこれは通常ダイアログ側の実装のはず。
#CEditの派生クラスの方に書いてるみたいだけどメッセージくるのかな?


返信引用
Hazard52
 Hazard52
(@Hazard52)
ゲスト
結合: 19年前
投稿: 9
 

gak様、subaru様、ありがとうございます。
MFCの場合は、OnCtlColor()に纏められて送られて来るですね。
確かに以前作った時は、APIで作ってました。

で終わってしまうのも中途半端なので、CEditの派生クラスで作ってみました。
CEditの派生クラスにOnPaint()を追加して、その中で色付けをすると
無効にしても同じく設定できましたが、いかがでしょうか?


返信引用
花乃
 花乃
(@花乃)
ゲスト
結合: 16年前
投稿: 6
Topic starter  

どとう様 gak様 subaru様 Hazard52様
何度も書き込みしてくださってありがとうございます。

どとう様
> よく考えたら、CEditの派生クラスのOnSetFocus()で
> 前のフォーカスに戻せば良いのではないでしょうか?

void CColorEdit::OnSetFocus(CWnd* pOldWnd)
{
if(( GetStyle() & ES_READONLY ))
{
// 前のフォーカスに戻す
if( pOldWnd )
{
pOldWnd->SetFocus();
}
}
else
{
CEdit::OnSetFocus( pOldWnd );
}
}

これで、うまくいきました。
SetReadOnly( TRUE );
設定をした、エディットボックスはカーソルが付かず、
それ以外は普通に入力も出来ました。
勿論、色も変わりました。
ありがとうございます。

--------------------------------------------------------------------

gak様
色々と解説ありがとうございます。
まだまだ、勉強不足でカーソルを消すなんて
思いついても無かったです。
参考になりました。

--------------------------------------------------------------------

subaru様
> OnLButtonDownと同様
> CEdit::OnContextMenu(...);
> で既定の処理が行われます。

void CColorEdit::OnContextMenu(CWnd* pWnd, CPoint point)
{
// TODO: この位置にメッセージ ハンドラ用のコードを追加してください
if( !( GetStyle() & ES_READONLY ))
{
CEdit::OnContextMenu( pWnd, point );
}
}

こちらもうまくいきました。
クラスウィザードで関数を作成したとき、
OnLButtonDownは
CEdit::OnLButtonDown(nFlags, point);
↑この、規定クラスを呼ぶコードが勝手に付いてきたのですが、
OnContextMenuには無かったので、
どうしたものかと、考えてしまいました。
無事に解決しました。
ありがとうございます。

--------------------------------------------------------------------

Hazard52様
> で終わってしまうのも中途半端なので、CEditの派生クラスで作ってみました。
> CEditの派生クラスにOnPaint()を追加して、その中で色付けをすると
> 無効にしても同じく設定できましたが、いかがでしょうか?

ありがとうございます。
こちらの案も試してみたくて、
OnPaint()の追加をして、CtlColorのように色をセットしてみたのですが、
文字が出なくなってしまいました。
この場合、CtlColorは標準に戻すのでしょうか?
それと、OnPaint()関数では、色設定のほかに何をすればよいのでしょうか?
何度もすみませんが教えていただければと思います。
よろしくお願い致します。


返信引用
Hazard52
 Hazard52
(@Hazard52)
ゲスト
結合: 19年前
投稿: 9
 

OnPaint()は、下記の様に記述しました。
OnChildNotify()が無いと、入力した時に一部しか再描画されません。
ヘッダファイルには、publicで、下の一文を追加して下さい。
virtual BOOL OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam,
LRESULT* pLResult);

void CColorEdit::OnPaint()
{
UINT nFormat = DT_SINGLELINE;
COLORREF OldColText;
COLORREF OldColBack;
CString sTitle;
CRect cr1, cr2;
CPen cPen;
CPen* cPenOld;

CPaintDC dc(this); // 描画用のデバイス コンテキスト

// 描画ペン生成
LOGBRUSH logBrush;
logBrush.lbStyle = BS_SOLID;
logBrush.lbColor = RGB(0, 0, 0);
cPen.CreatePen(PS_SOLID | PS_GEOMETRIC, 1, &logBrush);
cPenOld = dc.SelectObject(&cPen);
// 描画文字列取得
GetWindowText(sTitle);
// クライアント矩形描画領域取得
GetClientRect(&cr1);

cr2.left = cr1.left + 1;
cr2.top = cr1.top + 1;
cr2.right = cr1.right - 1;
cr2.bottom = cr1.bottom - 1;
dc.FillSolidRect(cr2, m_ColBack);

OldColText = dc.SetTextColor(m_ColText);
OldColBack = dc.SetBkColor(m_ColBack);
dc.DrawText(sTitle, &cr2, nFormat);

// 変更した属性を戻す
dc.SetTextColor(OldColText);
dc.SetBkColor(OldColBack);
dc.SelectObject(cPenOld);
}

BOOL CColorEdit::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam,
LRESULT* pLResult)
{
Invalidate();
return CEdit::OnChildNotify(message, wParam, lParam, pLResult);
}


返信引用
Hazard52
 Hazard52
(@Hazard52)
ゲスト
結合: 19年前
投稿: 9
 

あっ。すいません。
CtlColor()は、使用してませんでした。


返信引用
花乃
 花乃
(@花乃)
ゲスト
結合: 16年前
投稿: 6
Topic starter  

Hazard52様
親切にしてくださって、ありがとうございます。

教えてくださった方法でも、
希望通りの動作が出来ました。
OnPaint関数では、自分で描画しないといけなかったのですね。
OnChildNotifyの存在も知らなかったので、
本当に勉強になりました。感動です。
ありがとうございました。

一つの事を実現するのに、色々な方法があるのですね。
今回は、OnSetFocusで、前のフォーカスに戻すことに
致しました。
教えてくださった皆さん、ありがとうございました。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました