MFC 对Button控件的重绘方法(多种)

EosPro MFC Button的绘制

 

自绘按钮

一、位图按钮的实现方法:首先,我们创建一个基于对话框的应用程序CmyDialogAMFCCBitmapButton类,这也是最简单的功能最强的位图按钮。

采取如下的步骤:1. 为按钮指定唯一的按钮标题(此例子为OK按钮,这里设置按钮标题为OK)并选中Ownerdraw属性,然后在项目中加一些位图资源,并用名字标示这些资源而不要用数字ID,其ID分别为OKUOKDOKFOKX(一定要加双引号),分别对应于按钮的松开(Up)按下(Down)获得输入焦点(focused)禁止(Disable)状态。2. 我们还要在对话框类中加入CBitmapButton m_aBmpBtn;数据成员。3. 在初始化中为这个成员调用:m_aBmpBtn. AutoLoad(IDOK,this);点击编译按钮,成功后运行程序,哈哈,看看效果,我们的位图按钮已经建立了。/*如果以上方法不行请检查你的BITMAP 资源,APPSTUDIO中,"OKU""OKD" 等的资源名称都是需要用引号引起来的, AutoLoad不成功,很可能就是由此产生的。 */改变CANCLE按钮的标题,可以设置其标题为ICON或者BITMAP :(这里演示bitmap的用法,Icon按钮读者可以按照下面的代码处理)

B使用图标制作按钮1. 打开ICON按钮的属性页,在Style中选中Icon2. 在对话框类的头文件中定义成员变量(使用ClassWizard加入这个成员变量)CButton m_ IconBtn//对应于图标按钮3. 创建相应的图标或者位图资源:图标资源:IDI_ICONBUTTON4.在初始化中加入如下代码://对应于图标按钮HICON hIcon=AfxGetApp()->LoadIcon(IDI_ ICONBUTTON);m_IconBtn.SetIcon(hIcon);重新编译运行程序,奇妙的图像按钮呈现在眼前了。C使用位图制作按钮1. 打开BITMAP按钮的属性页,在Style中选中Bitmap2. 对话框类的头文件中定义成员变量(使用ClassWizard加入这个成员变量)CButton m_BmpBtn3.创建位图资源:位图资源:IDB_BITMAPBUTTON4.在初始化中加入如下代码://对应于位图按钮HBITMAP hBmp=::LoadBitmap(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDB_ BITMAPBUTTON));m_BmpBtn.SetBitmap(hBmp);

 

二、

A只加载一张位图的方法:

1.装入bmp资源,idIDB_BMP,按钮的bitmap属性设为trueicon属性为false

2

CButton *pBtn = (CButton *)GetDlgItem(IDB_BMP);CBitmap bitMap;HBITMAP hBit ;if(bitMap.LoadBitmapW(IDB_NORMAL_BTN)){hBit = (HBITMAP)bitMap.Detach();pBtn->SetBitmap(hBit);}

缺点:图片不会自动拉伸。

B为按钮的不同状态加载不同的位图:(使用CBitmapButton类)这种方法还可以。1,按钮属性 Owner Draw选上,按钮ID: IDC_BUTTON1

IDC_BUTTON1添加CButton变量m_button,2,然后手动将CButton m_button改为CBitmapButton m_button;3,在初始化里边m_button.LoadBitmaps(IDB_BITMAP1, IDB_BITMAP2);//IDB_BITMAP1:平时;IDB_BITMAP2:按下m_button.SubclassDlgItem(IDC_BUTTON1, this);m_button.SizeToContent();

或者用另一种方式,不必为IDC_BUTTON1添加关联的变量。直接声明CBitmapButton m_button;,在初始化里边调用

m_BitmapBtn.AutoLoad(IDC_BUTTON1_AREA,this);//把按钮和变量联系起来

m_BitmapBtn.LoadBitmaps(IDB_BITMAP1, IDB_BITMAP2);

m_button.SizeToContent();

缺点:1,无法显示文字,需重载DrawItem函数。

2,无法去掉图片的背景色,即只能显示矩形按钮

// NOTE: CMyButton is a class derived from CButton. The CMyButton

// object was created as follows:

//CMyButton 类继承CButton

// CMyButton myButton;

// myButton.Create(_T("My button"),

//      WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON|BS_OWNERDRAW,

//      CRect(10,10,100,30), pParentWnd, 1);

//

// This example implements the DrawItem method for a CButton-derived

// class that draws the button's text using the color red.

//例子中实现了DrawItem方法以特定RGB颜色画文字

void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)

{

   UINT uStyle = DFCS_BUTTONPUSH;

   // This code only works with buttons.

   ASSERT(lpDrawItemStruct->CtlType == ODT_BUTTON);

   // If drawing selected, add the pushed style to DrawFrameControl.

   if (lpDrawItemStruct->itemState & ODS_SELECTED)

      uStyle |= DFCS_PUSHED;

   // Draw the button frame.

   ::DrawFrameControl(lpDrawItemStruct->hDC, &lpDrawItemStruct->rcItem,

      DFC_BUTTON, uStyle);

   // Get the button's text.

   CString strText;

   GetWindowText(strText);

   // Draw the button text using the text color red.

   COLORREF crOldColor = ::SetTextColor(lpDrawItemStruct->hDC, RGB(255,0,0));

   ::DrawText(lpDrawItemStruct->hDC, strText, strText.GetLength(),

      &lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER);

   ::SetTextColor(lpDrawItemStruct->hDC, crOldColor);

}

//继承CBitmapButton的例子

void MyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct){// TODO: Add your code to draw the specified item//lpDrawItemStruct获取控件的相关信息CRect rect=lpDrawItemStruct-> rcItem;CDC *pDC=CDC::FromHandle(lpDrawItemStruct-> hDC);int nSaveDC=pDC-> SaveDC();UINT state = lpDrawItemStruct-> itemState;TCHAR strText[MAX_PATH + 1];::GetWindowText(m_hWnd, strText, MAX_PATH);CBitmapButton::DrawItem(lpDrawItemStruct);CRect rect1=rect;rect.SetRect(rect1.left,rect1.top,rect1.left+75,rect1.top+24);//显示按钮的文本pDC-> SetTextColor(TextColor);if (strText!=NULL){CFont* hFont = GetFont();CFont* hOldFont = pDC-> SelectObject(hFont);CSize szExtent = pDC-> GetTextExtent(strText, lstrlen(strText));CPoint pt( rect.CenterPoint().x - szExtent.cx / 2, rect.CenterPoint().y - szExtent.cy / 2);if (state & ODS_SELECTED)pt.Offset(1, 1);int nMode = pDC-> SetBkMode(TRANSPARENT);if (state & ODS_DISABLED)pDC-> DrawState(pt, szExtent, strText, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL);elsepDC-> DrawState(pt, szExtent, strText, DSS_NORMAL, TRUE, 0, (HBRUSH)NULL);pDC-> SelectObject(hOldFont);pDC-> SetBkMode(nMode);}pDC-> RestoreDC(nSaveDC);}

 

C继承CButton类,重写OnPaint函数,为Button的不同状态画位图(BitBltTransparentBltStretchBltMaskBltPlgBlt)。

 

D可以采用CButtonST控件,挺好用的,比MFC的那些封装好用。假设按钮IDIDC_BUTTON11.添加成员变量CButtonST m_btn;2.添加位图资源,ID设为IDB_BITMAP13.OnInitDialog函数中初始化按钮m_btn.SubclassDlgItem(IDC_BUTTON1,this);m_btn.SetBitmaps(IDB_BITMAP1,RGB(0,0,0));m_btn.OffsetColor(CButtonST::BTNST_COLOR_BK_IN, 30);: 上面的SetBitmaps函数会将图片中颜色值为RGB(0,0,0)的点设为透明。

 

Ebutton按钮属性设置为ower draw然后映射onDrawItem消息ondraw函数内自己绘制就可以了void CUi6Dlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct){if(nIDCtl == IDC_HELLO_CFAN){//绘制按钮框架UINT uStyle = DFCS_BUTTONPUSH;//是否按下去了?if (lpDrawItemStruct->itemState & ODS_SELECTED)uStyle |= DFCS_PUSHED;CDC dc;dc.Attach(lpDrawItemStruct->hDC);dc.DrawFrameControl(&lpDrawItemStruct->rcItem, DFC_BUTTON, uStyle);//输出文字dc.SelectObject(&m_Font);dc.SetTextColor(RGB(0, 0, 255));dc.SetBkMode(TRANSPARENT);CString sText;m_HelloCFan.GetWindowText(sText);dc.TextOut(lpDrawItemStruct->rcItem.left + 20, lpDrawItemStruct->rcItem.top + 20, sText);//是否得到焦点if(lpDrawItemStruct->itemState & ODS_FOCUS){//画虚框CRect rtFocus = lpDrawItemStruct->rcItem;rtFocus.DeflateRect(3, 3);dc.DrawFocusRect(&rtFocus);}return;}CDialog::OnDrawItem(nIDCtl, lpDrawItemStruct);}

posted @ 2012-12-02 14:57  szwencan  阅读(3509)  评论(0编辑  收藏  举报