在class view的工程目录下,添加类CImgButton,继承自CBitmapButton。选择CImgButton类的property,重载DrawItem(不是Message下的WM_DRAWITEM,其响应函数OnDrawItem不会被调用到。为什么?),实现在bitmap上写入文字的功能。使用时,1)在dialog中拖入一个button,设置ownerdraw。2)装载需要的位图资源。3)对话框头文件中 #include "ImgButton.h" CImgButton m_cImgBtn; 4)对话框cpp中 m_cImgBtn.SubclassDlgItem(IDC_BUTTON5, this);  m_cImgBtn.LoadBitmaps(IDB_BTNLONGU, IDB_BTNLONGD, IDB_BTNLONGU);  m_cImgBtn.SizeToContent();  m_cImgBtn.SetTextColor(RGB(0,0,0)); 完成。


按钮一般有四种状态:up/normal, down/select, focus(意为首选,可能为画面中只有一个按钮,或上次选择的就是此按钮。对于windows来说,就是button上有一个虚线框的情况), disable。第一种是必须有的,后三种可选。因此,至少需要准备button的一张图片。CBitmapButton的使用中,装载按钮图片有两种方法:AutoLoad()和LoadBitmaps()。

AutoLoad()法,该法将四种状态下的图片自动装载到BitmapButton中。1)在Dialog中拖入button控件,设置ownerdraw为true,caption为MYIMAGE(例),ID为IDC_MYIMAGE。2)将四张图片添加到bitmap资源,命名为"MYIMAGEU", "MYIMAGED", "MYIMAGEF", "MYIMAGEX",对应button四种状态,名称中需要加入分号。3)在头文件中手动添加对象CBitmapButton m_cBtn; 4)在对话框的OnInitDialog()中添加m_cBtn.AutoLoad(IDC_MYIMAGE, this);完成

LoadBitmaps()法。该法手动指定button每种状态的图片,优点是可以不提供不需要的状态,如focus,且多个button可以使用同样的图片,在资源中只需装载一次,节省空间。1)在Dialog中拖入button控件,设置ownerdraw为true,ID任意(例:IDC_BUTTNO4)。2)将所需图片添加到bitmap资源中,ID任意(例:IDB_BTNU,IDB_BTND)。3)在头文件中手动添加对象CBitmapButton m_cBtn; 4)在OnInitDialog()中添加 m_cBtn.SubclassDlgItem(IDC_BUTTON4, this); //关联按钮和对话框 m_cBtn.LoadBitmaps(IDB_BTNU, IDB_BTND); m_cBtn.SizeToContent();//调整大小. 完成

下一步就是继承CBitmapButton类,重载DrawItem实现文字写入。



CImgButton代码:


  1. #pragma once



  2. // CImgButton


  3. class CImgButton : public CBitmapButton  

  4. {  

  5.    DECLARE_DYNAMIC(CImgButton)  


  6. public:  

  7.    CImgButton();  

  8. virtual ~CImgButton();  


  9. protected:  

  10.    DECLARE_MESSAGE_MAP()  

  11. public:  


  12. public:  

  13. COLORREF TextColor;  

  14. void SetTextColor(COLORREF crColor);  


  15. virtualvoid DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);  

  16. };  





  17. // ImgButton.cpp : implementation file

  18. //


  19. #include "stdafx.h"

  20. #include "win32Test.h"

  21. #include "ImgButton.h"



  22. // CImgButton


  23. IMPLEMENT_DYNAMIC(CImgButton, CBitmapButton)  


  24. CImgButton::CImgButton()  

  25. {  


  26. }  


  27. CImgButton::~CImgButton()  

  28. {  

  29. }  



  30. BEGIN_MESSAGE_MAP(CImgButton, CBitmapButton)  

  31. END_MESSAGE_MAP()  



  32. void CImgButton::SetTextColor(COLORREF crColor)  

  33. {  

  34.    TextColor = crColor;  

  35. }  


  36. void CImgButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)  

  37. {  


  38. // TODO:  Add your code to draw the specified item

  39.    CRect rect = lpDrawItemStruct->rcItem;  

  40.    CDC *pDC = CDC::FromHandle(lpDrawItemStruct->hDC);  

  41. int nSaveDC = pDC->SaveDC();  

  42. UINT state = lpDrawItemStruct->itemState;  

  43. TCHAR strText[MAX_PATH + 1];  

  44.    ::GetWindowText(m_hWnd, strText, MAX_PATH);  


  45.    CBitmapButton::DrawItem(lpDrawItemStruct);  


  46.    pDC->SetTextColor(TextColor);  

  47. if (strText!=NULL)  

  48.    {  

  49.        CFont *hFont = GetFont();  

  50.        CFont *hOldFont = pDC->SelectObject(hFont);  

  51.        CSize szExtent = pDC->GetTextExtent(strText, lstrlen(strText));  

  52.        CPoint pt(rect.CenterPoint().x - szExtent.cx / 2, rect.CenterPoint().y - szExtent.cy / 2);  

  53. if (state & ODS_SELECTED)    

  54.        {  

  55.            pt.Offset(1, 1);  

  56.        }  

  57. int nMode = pDC->SetBkMode(TRANSPARENT);  

  58. if (state & ODS_DISABLED)  

  59.        {  

  60.            pDC->DrawState(pt, szExtent, strText, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL);  

  61.        }  

  62. else

  63.        {  

  64.            pDC->DrawState(pt, szExtent, strText, DSS_NORMAL, TRUE, 0, (HBRUSH)NULL);  

  65.        }  

  66.        pDC->SelectObject(hOldFont);  

  67.        pDC->SetBkMode(nMode);  

  68.    }  


  69.    pDC->RestoreDC(nSaveDC);  

  70. }