給mfc中按鈕設置背景顏色

給對話框上的按鈕添加背景顏色,這個是我在網上找的一個方法。我實現了,但是感覺還是有一點小問題,就是按鈕不是一運行的時候就出現設置後的顏色,得點擊一下才會出現顏色。不知道這是怎麼回事,希望看到的人如果結局了這個問題給我留個言。下面就貼出步驟:
第一步:加入一個新類,類名:CMyButton,基類:CButton。
 
在頭文件 MyButton.h 中加入以下變量和函數定義:
 
private:
int         m_Style;    //按鈕形狀(0-正常,1-當前,2-按下,3-鎖定)
BOOL        b_InRect;           //鼠標進入標誌
CString     m_strText;          //按鈕文字
COLORREF    m_ForeColor;        //文本顏色
COLORREF    m_BackColor;        //背景色
COLORREF    m_LockForeColor;    //鎖定按鈕的文字顏色
CRect       m_ButRect;          //按鈕尺寸
CFont*      p_Font;             //字體
 
void  DrawButton(CDC *pDC);     //畫正常的按鈕
 
// 接口函數
public:
void SetText(CString str);
void SetForeColor(COLORREF color);      //設置文本顏色
void SetBkColor(COLORREF color);        //設置背景顏色
void SetTextFont(int FontHight,LPCTSTR FontName);   //設置字體
第二步:在 MyButton.cpp 的構造函數中初始化變量:
 
CMyButton::CMyButton()
{
m_Style = 0;               //按鈕形狀風格
b_InRect = false;          //鼠標進入標誌
m_strText = _T("");        //按鈕文字(使用默認文字)
m_ForeColor = RGB(0,0,0);            //文字顏色(黑色)
m_BackColor = RGB(243,243,243);      //背景色(灰白色)
m_LockForeColor = GetSysColor(COLOR_GRAYTEXT);    //鎖定按鈕的文字顏色
p_Font = NULL;                       //字體指針
}
 
用ClassWizard添加下列消息函數:
 
PreSubclassWindow();
DrawItem();
onMouseMove();
OnLButtonDown();
OnLButtonUp();
 
在各函數內加入代碼:
 
void CMyButton::PreSubclassWindow()
{
ModifyStyle( 0, BS_OWNERDRAW );        //設置按鈕屬性爲自畫式
 
CButton::PreSubclassWindow();
}
 
PreSubclassWindow()在按鈕創建前自動執行,所以我們可以在其中做一些初始工作。這裏我只做了一項工作,就是爲按鈕設置屬性爲“自繪”式,這樣,用戶在添加按鈕後,就不需設置“Owner draw”屬性了。
 
void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDC *pDC = CDC::FromHandle( lpDrawItemStruct->hDC );
m_ButRect = lpDrawItemStruct->rcItem;    //獲取按鈕尺寸
 
if( m_strText.IsEmpty() )
GetWindowText( m_strText );          //獲取按鈕文本
 
int nSavedDC = pDC->SaveDC();
VERIFY( pDC );
DrawButton( pDC );                //繪製按鈕
pDC->RestoreDC( nSavedDC );
}
 
DrawItem()函數是一個關鍵函數,按鈕的繪製工作就在這裏進行,它的作用相當於對話框中的OnPaint()函數和視圖中的OnDraw()函數。
 
這裏我做了三項工作:獲取按鈕尺寸、獲取按鈕文本、繪製按鈕。其中繪製工作在自定義函數DrawButton()中完成。以下就是繪製過程:
 
void CMyButton::DrawButton(CDC *pDC)
{
//調整狀態
if( m_Style==3 ) m_Style = 0;
if( GetStyle() & WS_DISABLED )
m_Style = 3;    //禁止狀態
//根據狀態調整邊框顏色和文字顏色
COLORREF bColor, fColor;    //bColor爲邊框顏色,fColor爲文字顏色
switch( m_Style )
{
case 0: bColor = RGB(192,192,192); fColor = m_ForeColor; break;  //正常按鈕
case 1: bColor = RGB(255,255,255); fColor = m_ForeColor; break;  //鼠標進入時按鈕
case 2: bColor = RGB(192,192,192); fColor = m_ForeColor; break;  //按下的按鈕
case 3: bColor = m_BackColor; fColor = m_LockForeColor; break;   //鎖定的按鈕
}
//繪製按鈕背景
CBrush Brush;
Brush.CreateSolidBrush( m_BackColor );    //背景刷
pDC->SelectObject( &Brush );
CPen Pen;
Pen.CreatePen(PS_SOLID, 1, bColor );
pDC->SelectObject( &Pen );
pDC->RoundRect(&m_ButRect,CPoint(5,5));   //畫圓角矩形
//繪製按鈕按下時的邊框
if( m_Style!=2 )
{
CRect Rect;
Rect.SetRect( m_ButRect.left+2, m_ButRect.top+1, m_ButRect.right, m_ButRect.bottom );
pDC->DrawEdge( &Rect, BDR_RAISEDINNER, BF_RECT );    //畫邊框
}
//繪製按鈕文字
pDC->SetTextColor( fColor );        //畫文字
pDC->SetBkMode( TRANSPARENT );
pDC->DrawText( m_strText, &m_ButRect, DT_SINGLELINE | DT_CENTER
DT_VCENTER | DT_END_ELLIPSIS);
//繪製擁有焦點按鈕的虛線框
if( GetFocus()==this )
{
CRect Rect;
Rect.SetRect( m_ButRect.left+3, m_ButRect.top+2, m_ButRect.right-3, m_ButRect.bottom-2 );
pDC->DrawFocusRect( &Rect );    //畫擁有焦點的虛線框
}
}
 
變量 m_Style 表徵當前按鈕狀態,它的取值爲:0-正常,1-當前,2-按下,3-鎖定。不同狀態下按鈕的邊框顏色和文字顏色有所不同。m_Style 的值在鼠標響應函數中進行修改。
 
繪製工作主要利用CDC類的繪圖函數完成,主要注意在 m_Style 不同取值下表現出來的差別。
 
void CMyButton::onMouseMove(UINT nFlags, CPoint point)
{
if( !b_InRect || GetCapture()!=this )    //鼠標進入按鈕
{
b_InRect = true;    //設置進入標誌
SetCapture();       //捕獲鼠標
m_Style = 1;        //設置按鈕狀態
Invalidate();       //重繪按鈕
}
else
{
if ( !m_ButRect.PtInRect(point) )    //鼠標離開按鈕
{
b_InRect = false;   //清除進入標誌
ReleaseCapture();   //釋放捕獲的鼠標
m_Style = 0;        //設置按鈕狀態
Invalidate();       //重繪按鈕
}
}
 
CButton::onMouseMove(nFlags, point);
}
 
onMouseMove()函數是鼠標移動消息函數,用於判定當前鼠標指針是否在按鈕上。b_InRect是個標誌,爲true表示鼠標指針進入了按鈕區域,此時要捕獲鼠標,讓鼠標命令傳送給按鈕。當鼠標指針離開按鈕時,要清除b_InRect標誌,並且釋放捕獲的鼠標,讓其它窗口可以接收鼠標命令。
 
Invalidate()函數用於更新按鈕,它會自動調用DrawItem()函數重新繪製按鈕。
 
設置條件的目的是僅在鼠標指針進入按鈕和離開按鈕時更新按鈕,這樣可以防止鼠標在按鈕上移動時發生閃爍。
 
void CMyButton::OnLButtonDown(UINT nFlags, CPoint point)
{
m_Style = 2;
Invalidate();        //重繪按鈕
 
CButton::OnLButtonDown(nFlags, point);
}
 
OnLButtonDown()函數是單擊鼠標左鍵時的消息函數。這裏只是重新繪製按鈕,具體的單擊響應應該在擁有按鈕的對話框或視圖中進行。
 
void CMyButton::OnLButtonUp(UINT nFlags, CPoint point)
{
m_Style = 1;
Invalidate();        //重繪按鈕
 
CButton::OnLButtonUp(nFlags, point);
}
 
OnLButtonUp()函數是單擊鼠標左鍵後彈起時的消息函數。這裏也只是重繪按鈕,這樣能使按鈕在按下和彈起時有所不同,使按鈕看上去有動態效果。
 
接口函數是用 CMyButton類 定義的按鈕修改顏色、字體和按鈕文字的接口,由以下函數組成:
 
//設置按鈕文本
void CMyButton::SetText(CString str)
{
m_strText = _T("");
SetWindowText(str);
}
 
//設置文本顏色
void CMyButton::SetForeColor(COLORREF color)
{
m_ForeColor = color;
Invalidate();
}
 
//設置背景顏色
void CMyButton::SetBkColor(COLORREF color)
{
m_BackColor = color;
Invalidate();
}
 
//設置字體(字體高度、字體名)
void CMyButton::SetTextFont(int FontHight,LPCTSTR FontName)
{
if ( p_Font )    delete p_Font;    //刪除舊字體
p_Font = new CFont;
p_Font->CreatePointFont( FontHight, FontName );    //創建新字體
SetFont( p_Font );                //設置字體
}
 
由於新字體由 new 生成,必須顯式回收,這項工作可以在 CMyButton類 的析構函數中進行:
 
CMyButton::~CMyButton()
{
if ( p_Font )    delete p_Font;        //刪除字體
}
 
第三步:使用時,先在對話框中放置好按鈕,再用 ClassWizard 爲按鈕添加控制變量,並且將變量的類型設置爲 CMyButton。之後,可以用該變量調用接口函數設置按鈕顏色和字體。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章