CButtonEx的實現

來源:互聯網
上載者:User

標籤:

要想修改CButton類按鈕背景顏色和文字顏色,必須利用自繪方法對按鈕進行重新繪製。這可以通過定義一個以CButton為基類的新按鈕類來實現。以下為具體的實現方法:

方法一:

加入一個新類,類名:CButtonEx,基類:CButton。
在標頭檔 CButtonEx.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(COLORREFcolor); //設定文本顏色

void SetBkColor(COLORREFcolor); //設定背景顏色

void SetTextFont(int FontHight,LPCTSTRFontName); //設定字型 
在 CButtonEx.cpp 的建構函式中初始設定變數:
CButtonEx::CButtonEx()

{

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 CButtonEx::PreSubclassWindow()

{

ModifyStyle( 0, BS_OWNERDRAW); //設定按鈕屬性為自畫式



CButton::PreSubclassWindow();


PreSubclassWindow()在按鈕建立前自動執行,所以我們可以在其中做一些初始工作。這裡我只做了一項工作,就是為按鈕設定屬性為“自繪”式,這樣,使用者在添加按鈕後,就不需設定“Owner draw”屬性了。
void CButtonEx::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 CButtonEx::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 CButtonEx::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 CButtonEx::OnLButtonDown(UINT nFlags, CPoint point)

{

m_Style = 2;

Invalidate(); //重繪按鈕



CButton::OnLButtonDown(nFlags, point);


OnLButtonDown()函數是單擊滑鼠左鍵時的訊息函數。這裡只是重新繪製按鈕,具體的單擊響應應該在擁有按鈕的對話方塊或視圖中進行。
void CButtonEx::OnLButtonUp(UINT nFlags, CPoint point)

{

m_Style = 1;

Invalidate(); //重繪按鈕



CButton::OnLButtonUp(nFlags, point);


OnLButtonUp()函數是單擊滑鼠左鍵後彈起時的訊息函數。這裡也只是重繪按鈕,這樣能使按鈕在按下和彈起時有所不同,使按鈕看上去有動態效果。
介面函數是用 CButtonEx類 定義的按鈕修改顏色、字型和按鈕文字的介面,由以下函數組成:
//設定按鈕文本

void CButtonEx::SetText(CString str)

{

m_strText = _T("");

SetWindowText(str);


//設定文本顏色

void CButtonEx::SetForeColor(COLORREF color)

{

m_ForeColor = color;

Invalidate();


//設定背景顏色

void CButtonEx::SetBkColor(COLORREF color)

{

m_BackColor = color;

Invalidate();


//設定字型(字型高度、字型名)

void CButtonEx::SetTextFont(int FontHight,LPCTSTR FontName)

{

if ( p_Font ) 
deletep_Font; //刪除舊字型

p_Font = new CFont;

p_Font->CreatePointFont( FontHight, FontName); //建立新字型

SetFont( p_Font); //設定字型


由於新字型由 new 產生,必須顯式回收,這項工作可以在 CButtonEx類 的解構函式中進行:
CButtonEx::~CButtonEx()

{

if ( p_Font ) 
deletep_Font; //刪除字型


這樣一個可設定顏色、字型的按鈕類就做好了。使用時,先在對話方塊中放置好按鈕,再用 ClassWizard 為按鈕添加控制變數,並且將變數的類型設定為 CButtonEx。之後,可以用該變數調用介面函數設定按鈕顏色和字型。

以上測試過,太複雜。又生一類。
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
方法二:
添加dlg類的WM_DRAWITEM訊息處理函數
void CBtncolorDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCTlpDrawItemStruct)

{

// TODO: Add your message handler code here and/or call default

if(nIDCtl==IDC_BUTTON1) //checking for the button

{

CDC dc;

RECT rect;

dc.Attach(lpDrawItemStruct ->hDC); // Get theButton DC to CDC



rect = lpDrawItemStruct->rcItem; //Store the Button rect to our local rect.



dc.Draw3dRect(&rect,RGB(255,255,255),RGB(0,0,0));
dc.FillSolidRect(&rect,RGB(100,100,255));//Here youcan define the required color to appear on the Button.
UINT state=lpDrawItemStruct->itemState; //Thisdefines the state of the Push button either pressed or not.
if((state & ODS_SELECTED))

{

dc.DrawEdge(&rect,EDGE_SUNKEN,BF_RECT);
}

else

{

dc.DrawEdge(&rect,EDGE_RAISED,BF_RECT);

}
dc.SetBkColor(RGB(100,100,255)); //Settingthe Text Background color

dc.SetTextColor(RGB(255,0,0)); //Setting the Text Color

TCHARbuffer[MAX_PATH]; //To store the Caption of the button.

ZeroMemory(buffer,MAX_PATH ); //Intializing the buffer to zero

::GetWindowText(lpDrawItemStruct->hwndItem,buffer,MAX_PATH); //Get theCaption of Button Window



dc.DrawText(buffer,&rect,DT_CENTER|DT_VCENTER|DT_SINGLELINE);//Redrawthe Caption of Button Window



dc.Detach(); // Detach the Button DC



CDialog::OnDrawItem(nIDCtl, lpDrawItemStruct);
}

http://www.lai18.com/content/931475.html

CButtonEx的實現

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.