【发布时间】:2010-12-10 19:56:57
【问题描述】:
如何更改 CStatic 文本控件的文本颜色?除了使用 CDC::SetTextColor 之外,还有其他简单的方法吗?
谢谢...
【问题讨论】:
标签: mfc visual-c++
如何更改 CStatic 文本控件的文本颜色?除了使用 CDC::SetTextColor 之外,还有其他简单的方法吗?
谢谢...
【问题讨论】:
标签: mfc visual-c++
您可以在对话框类中实现ON_WM_CTLCOLOR,而无需创建新的 CStatic 派生类:
BEGIN_MESSAGE_MAP(CMyDialog, CDialog)
//{{AFX_MSG_MAP(CMyDialog)
ON_WM_CTLCOLOR()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
HBRUSH CMyDialog::OnCtlColor(CDC* pDC, CWnd *pWnd, UINT nCtlColor)
{
switch (nCtlColor)
{
case CTLCOLOR_STATIC:
pDC->SetTextColor(RGB(255, 0, 0));
return (HBRUSH)GetStockObject(NULL_BRUSH);
default:
return CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
}
}
请注意,上面的代码设置对话框中所有静态控件的文本。但是您可以使用pWnd 变量来过滤您想要的控件。
【讨论】:
OnCtlColor() 的基类版本(无论如何)并将返回的HBRUSH 存储在一个变量中。接下来,如果合适,请致电pDC->SetTextColor()。最后,从第一步返回画笔。
很遗憾,您在 CStatic 类中找不到 SetTextColor 方法。如果要更改 CStatic 的文本颜色,则必须编写更多代码。
在我看来,最好的方法是创建您自己的 CStatic 派生类 (CMyStatic),然后在其中获取 ON_WM_CTLCOLOR_REFLECT 通知消息。
BEGIN_MESSAGE_MAP(CMyStatic, CStatic)
//{{AFX_MSG_MAP(CMyStatic)
ON_WM_CTLCOLOR_REFLECT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
HBRUSH CColorStatic::CtlColor(CDC* pDC, UINT nCtlColor)
{
pDC->SetTextColor(RGB(255,0,0));
return (HBRUSH)GetStockObject(NULL_BRUSH);
}
显然你可以使用成员变量和setter方法来替换红色(RGB(255,0,0))。
问候。
【讨论】:
只是对绘画问题(透明背景)的跟进,这是由 *return (HBRUSH)GetStockObject(NULL_BRUSH);* 引起的
简单的改变如下:
HBRUSH hBrush = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
if (nCtlColor == CTLCOLOR_STATIC &&
pWnd->GetSafeHwnd() == GetDlgItem(XXX)->GetSafeHwnd()
) pDC->SetTextColor(RGB(255, 0, 0));
return hBrush;
希望这会有所帮助。
【讨论】:
从这里和其他地方给出的答案来看,如何创建一个派生类来代替处理自身着色的 CStatic 并不明显。
以下是对我有用的方法,使用 MSVS 2013 版本 12.0.40629.00 更新 5。我可以在资源编辑器中放置一个“静态文本”控件,然后用 TColorText 替换成员变量的类型。
在 .h 文件中:
class TColorText : public CStatic
{
protected:
DECLARE_MESSAGE_MAP( )
public:
// make the background transparent (or if ATransparent == true, restore the previous background color)
void setTransparent( bool ATransparent = true );
// set background color and make the background opaque
void SetBackgroundColor( COLORREF );
void SetTextColor( COLORREF );
protected:
HBRUSH CtlColor( CDC* pDC, UINT nCtlColor );
private:
bool MTransparent = true;
COLORREF MBackgroundColor = RGB( 255, 255, 255 ); // default is white (in case someone sets opaque without setting a color)
COLORREF MTextColor = RGB( 0, 0, 0 ); // default is black. it would be more clean
// to not use the color before set with SetTextColor(..), but whatever...
};
在 .cpp 文件中:
void TColorText::setTransparent( bool ATransparent )
{
MTransparent = ATransparent;
Invalidate( );
}
void TColorText::SetBackgroundColor( COLORREF AColor )
{
MBackgroundColor = AColor;
MTransparent = false;
Invalidate( );
}
void TColorText::SetTextColor( COLORREF AColor )
{
MTextColor = AColor;
Invalidate( );
}
BEGIN_MESSAGE_MAP( TColorText, CStatic )
ON_WM_CTLCOLOR_REFLECT( )
END_MESSAGE_MAP( )
HBRUSH TColorText::CtlColor( CDC* pDC, UINT nCtlColor )
{
pDC->SetTextColor( MTextColor );
pDC->SetBkMode( TRANSPARENT ); // we do not want to draw background when drawing text.
// background color comes from drawing the control background.
if( MTransparent )
return nullptr; // return nullptr to indicate that the parent object
// should supply the brush. it has the appropriate background color.
else
return (HBRUSH) CreateSolidBrush( MBackgroundColor ); // color for the empty area of the control
}
【讨论】:
非常有帮助。
https://msdn.microsoft.com/de-de/library/0wwk06hc.aspx
类似
HBRUSH hBrush = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
if (nCtlColor == CTLCOLOR_STATIC &&
pWnd->GetSafeHwnd() == GetDlgItem(XXX)->GetSafeHwnd()
) pDC->SetTextColor(RGB(255, 0, 0));
return hBrush;
【讨论】: