MFC自绘按钮的实现

自绘按钮的实现过程

  • 申明自绘属性
  • 进行VM_MESUREITEM事件响应,说明按钮的尺寸
  • 进行VM_DRAWITEM消息的重新响应,说明如何绘制按钮

首先在vc6中新建工程,选择MFC并且新建dialog工程

输入工程名,然后将生成的按钮等删除,重新添加两个按钮。

为按钮设置属性

选择自绘,就是自己向上贴图

在dlg类的对象上添加WM_DRAWITEM属性

在生成的OnDrawItem方法中添加如下代码

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
//添加绘图函数
void CMy40_mybuttonDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
    // TODO: Add your message handler code here and/or call default
    CDC ButtonDC;
    CBitmap bitmapTrans;
    BITMAP bmp;
    CDC mem;
    CRect rc;
    //得到用于绘制按钮的DC
    ButtonDC.Attach(lpDrawItemStruct->hDC);
    //准备用于向按钮区域传输位图
    mem.CreateCompatibleDC(&ButtonDC);
    //获取按钮所占的矩形大小
    rc=lpDrawItemStruct->rcItem;
    //获取按钮目前所处的状态,根据不同的状态绘制不同的按钮
    UINT state = lpDrawItemStruct->itemState;
    //如果按钮已经得到焦点,绘制选中状态下的按钮
    if(state&ODS_FOCUS)
    {
        bitmapTrans.LoadBitmap(IDB_BITMAP1);
        bitmapTrans.GetBitmap(&bmp);
        CBitmap *old=mem.SelectObject(&bitmapTrans);
        //向按钮所在位置传输位图
        //使用StretcnBlt的目的是为了让位图随按钮的大小而改变
        ButtonDC.StretchBlt(rc.left,rc.top,rc.right,rc.bottom,&mem,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);
        mem.SelectObject(old);
        bitmapTrans.DeleteObject();
        //设置文字背景为透明
        ButtonDC.SetBkMode(TRANSPARENT);
        ButtonDC.DrawText("已选中",&rc,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
    }
    else
    {
        bitmapTrans.LoadBitmap(IDB_BITMAP2);
        CBitmap *old2 = mem.SelectObject(&bitmapTrans);
        bitmapTrans.GetBitmap(&bmp);
        CBitmap *old=mem.SelectObject(&bitmapTrans);
        ButtonDC.StretchBlt(rc.left,rc.top,rc.right,rc.bottom,&mem,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);
        ButtonDC.SetBkMode(TRANSPARENT);
        ButtonDC.DrawText("未选中",&rc,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
        mem.SelectObject(old2);
        bitmapTrans.DeleteObject();
    }
 
    CDialog::OnDrawItem(nIDCtl, lpDrawItemStruct);
}

编译运行,运行后得到效果如果所示

 

posted @   skyme  阅读(22630)  评论(1编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示