【问题标题】:MFC - change text color of a cstatic text controlMFC - 更改 cstatic 文本控件的文本颜色
【发布时间】:2010-12-10 19:56:57
【问题描述】:

如何更改 CStatic 文本控件的文本颜色?除了使用 CDC::SetTextColor 之外,还有其他简单的方法吗?

谢谢...

【问题讨论】:

    标签: mfc visual-c++


    【解决方案1】:

    您可以在对话框类中实现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 变量来过滤您想要的控件。

    【讨论】:

    • 你是对的。这是另一种方法。我只是提到了我认为更好的方式。在第二种情况下,您必须将代码添加到要以其他颜色显示标签的每个对话框中。
    • 是的,我同意,在这种情况下,您的方式是更好的方式。如果有人想对整个对话框(或应用程序)进行重大改造,可以使用我的方法。
    • 返回 (HBRUSH)GetStockObject(NULL_BRUSH);将导致绘画问题(或时髦的透明背景“功能”)。你可能想返回 (HBRUSH)GetStockObject(WHITE_BRUSH);
    • @Jack Bolding:感谢您的评论。你能分享一下为什么 WHITE_BRUSH 比 NULL_BRUSH 更受欢迎,还是只是任何非 NULL 画笔更受欢迎?再次感谢。
    • 按照这些说明加上@JackBolding 的建议在控件后面给了我一个白色背景。我解决了这个问题:首先,调用OnCtlColor() 的基类版本(无论如何)并将返回的HBRUSH 存储在一个变量中。接下来,如果合适,请致电pDC->SetTextColor()。最后,从第一步返回画笔。
    【解决方案2】:

    很遗憾,您在 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))。

    问候。

    【讨论】:

    • 感谢您的解决方案。它有一些意想不到的副作用。现在我的静态控件与我的主视图有不同的控件背景颜色,文本背景也是白色的。
    【解决方案3】:

    只是对绘画问题(透明背景)的跟进,这是由 *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;
    

    希望这会有所帮助。

    【讨论】:

      【解决方案4】:

      从这里和其他地方给出的答案来看,如何创建一个派生类来代替处理自身着色的 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
      }
      

      【讨论】:

        【解决方案5】:

        非常有帮助。

        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;
        

        【讨论】:

          猜你喜欢
          • 2015-07-29
          • 2021-02-18
          • 2017-11-02
          • 2016-10-09
          • 2011-11-22
          • 1970-01-01
          • 2014-09-04
          • 1970-01-01
          • 2016-03-04
          相关资源
          最近更新 更多