在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代码:
#pragma once
// CImgButton
class CImgButton : public CBitmapButton
{
DECLARE_DYNAMIC(CImgButton)
public:
CImgButton();
virtual ~CImgButton();
protected:
DECLARE_MESSAGE_MAP()
public:
public:
COLORREF TextColor;
void SetTextColor(COLORREF crColor);
virtualvoid DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
};
// ImgButton.cpp : implementation file
//
#include "stdafx.h"
#include "win32Test.h"
#include "ImgButton.h"
// CImgButton
IMPLEMENT_DYNAMIC(CImgButton, CBitmapButton)
CImgButton::CImgButton()
{
}
CImgButton::~CImgButton()
{
}
BEGIN_MESSAGE_MAP(CImgButton, CBitmapButton)
END_MESSAGE_MAP()
void CImgButton::SetTextColor(COLORREF crColor)
{
TextColor = crColor;
}
void CImgButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
// TODO: Add your code to draw the specified item
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);
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);
}
else
{
pDC->DrawState(pt, szExtent, strText, DSS_NORMAL, TRUE, 0, (HBRUSH)NULL);
}
pDC->SelectObject(hOldFont);
pDC->SetBkMode(nMode);
}
pDC->RestoreDC(nSaveDC);
}