在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.
3.
4.// CImgButton
5.
6.class CImgButton : public CBitmapButton
7.{
- DECLARE_DYNAMIC(CImgButton)
9.
10.public:
- CImgButton();
12.virtual ~CImgButton();
13.
14.protected:
- DECLARE_MESSAGE_MAP()
16.public:
17.
18.public:
19.COLORREF TextColor;
20.void SetTextColor(COLORREF crColor);
21.
22.virtualvoid DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
23.};
24.
25.
26.
27.
28.// ImgButton.cpp : implementation file
29.//
30.
31.#include “stdafx.h”
32.#include “win32Test.h”
33.#include “ImgButton.h”
34.
35.
36.// CImgButton
37.
38.IMPLEMENT_DYNAMIC(CImgButton, CBitmapButton)
39.
40.CImgButton::CImgButton()
41.{
42.
43.}
44.
45.CImgButton::~CImgButton()
46.{
47.}
48.
49.
50.BEGIN_MESSAGE_MAP(CImgButton, CBitmapButton)
51.END_MESSAGE_MAP()
52.
53.
54.void CImgButton::SetTextColor(COLORREF crColor)
55.{
- TextColor = crColor;
57.}
58.
59.void CImgButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
60.{
61.
62.// TODO: Add your code to draw the specified item
CRect rect = lpDrawItemStruct->rcItem;
CDC *pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
65.int nSaveDC = pDC->SaveDC();
66.UINT state = lpDrawItemStruct->itemState;
67.TCHAR strText[MAX_PATH + 1];
- ::GetWindowText(m_hWnd, strText, MAX_PATH);
69.
- CBitmapButton::DrawItem(lpDrawItemStruct);
71.
- pDC->SetTextColor(TextColor);
73.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);
79.if (state & ODS_SELECTED)
{
pt.Offset(1, 1);
}
83.int nMode = pDC->SetBkMode(TRANSPARENT);
84.if (state & ODS_DISABLED)
{
pDC->DrawState(pt, szExtent, strText, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL);
}
88.else
{
pDC->DrawState(pt, szExtent, strText, DSS_NORMAL, TRUE, 0, (HBRUSH)NULL);
}
pDC->SelectObject(hOldFont);
pDC->SetBkMode(nMode);
}
95.
- pDC->RestoreDC(nSaveDC);
97.}