示例一:
Step1: 创建对话框工程。
Step2: 添加要自绘的按钮,为每个按钮添加一个位图
Step3: 添加WM_DRAWITEM 消息的响应函数OnDrawItem实现具体的自绘,详细实现方式参考函数实现代码
Step4: 本示例是根据ODS_FOCUS状态进行定制。还可以进行其他状态的绘制。控件自绘只需要记住一点:随时访问MEASUREITEMSTRUCT数据结构的数据成员是进行自绘的关
//通过消息WM_DRAWITEM自绘按纽
void CMyBtnDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
// TODO: Add your message handler code here and/or call default
::CDC BtnDC;
::CBitmap bitmapTrans;
::BITMAP bmp;
::CDC mem;
::CRect rc;
//得到用于绘制按钮的DC(从HDC得到一个CDC)
BtnDC.Attach(lpDrawItemStruct->hDC);
//准备用于向按钮区域传输位图
mem.CreateCompatibleDC(&BtnDC);
//获取按钮所占的矩形大小
rc = lpDrawItemStruct->rcItem;
//获取按钮目前所处的状态,根据不同状态绘制不同的按钮
UINT uState = lpDrawItemStruct->itemState;
//如果是按钮已经得到焦点,绘制选中状态下的按钮
if(uState & ODS_FOCUS)
{
//该函数从模块的可执行文件中加载指定的位图资源
bitmapTrans.LoadBitmap(IDB_GETFOCUS);//切记是位图ID
//本函数用于查看CBitmap对象的信息。返回的信息存放
//在pBitMap指向的BITMAP结构中。
bitmapTrans.GetBitmap(&bmp);
//该函数选择一对象到指定的设备上下文环境中,该新对象替换先前的相同类型的对象。
::CBitmap *old = mem.SelectObject(&bitmapTrans);
//向按钮所在位置传输位图
//使用StretchBlt的目的是为了让位图随按钮大小而改变
BtnDC.StretchBlt(rc.left,rc.top,rc.right,rc.bottom,&mem,0,0,
bmp.bmWidth,bmp.bmHeight,SRCCOPY);
mem.SelectObject(old);
bitmapTrans.DeleteObject();
//设置文字背景为透明
BtnDC.SetBkMode(TRANSPARENT);
//绘制按钮标题
BtnDC.DrawText("已选中", &rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}
else
{
bitmapTrans.LoadBitmap(IDB_LOSTFOCUS);
bitmapTrans.GetBitmap(&bmp);
::CBitmap *old2 = mem.SelectObject(&bitmapTrans);
// ::CBitmap *old = mem.SelectObject(&bitmapTrans);
//向按钮所在位置传输位图
//使用StretchBlt的目的是为了让位图随按钮大小而改变
BtnDC.StretchBlt(rc.left,rc.top,rc.right,rc.bottom,&mem,0,0,
bmp.bmWidth,bmp.bmHeight,SRCCOPY);
//设置文字背景为透明
BtnDC.SetBkMode(TRANSPARENT);
//绘制按钮标题
BtnDC.DrawText("未选中",&rc,DT_CENTER | DT_VCENTER | DT_SINGLELINE);
mem.SelectObject(old2);
bitmapTrans.DeleteObject();
}
CDialog::OnDrawItem(nIDCtl, lpDrawItemStruct);
}