給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。之後,可以用該變量調用接口函數設置按鈕顏色和字體。
第一步:加入一個新類,類名: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。之後,可以用該變量調用接口函數設置按鈕顏色和字體。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.