2009-10-28 74 views

回答

29

您可以在您的對話框類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變量來過濾你想要的控件。

+0

你說得對。這是另一種方式。 我剛纔提到了我認爲更好的方式。在第二種情況下,您必須將代碼添加到每個想要以其他顏色顯示標籤的對話框中。 – 2009-10-29 13:54:20

+1

是的,我同意,在這種情況下,你的方式是更好的方法。如果有人想在整個對話框(或應用程序)中進行重大修改,我可以使用我的方式。 – djeidot 2009-10-29 19:07:37

+2

返回(HBRUSH)GetStockObject(NULL_BRUSH);會導致繪畫問題(或時髦的透明背景'功能')。您可能想要返回(HBRUSH)GetStockObject(WHITE_BRUSH); – 2010-05-28 17:45:59

7

不幸的是,你不會找到在靜態控件類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))。

問候。

+1

感謝您的解決方案。它有一些意想不到的副作用。現在我的靜態控件從我的主視圖中有不同的控件背景顏色,並且文本背景也是白色的。 – Sheen 2010-12-24 10:55:25

6

只是跟進的塗裝問題(透明背景),這引起*回報(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; 

希望這幫助。

2

從這裏和其他地方給出的答案,如何創建派生類來代替處理着色本身的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 
} 
1

非常有幫助。

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;