在按钮控件上加载位图,形成位图按钮

1、建立基于对话框的MFC,工程名为test,在对话框添加button控件,并将button控件的Owner Draw的属性改为true;

2、添加一个子类CMyButton继承于CButton类;

3、在CtestDlg类中添加成员变量CMyButton m_MyButton,并在OnInitDialog中添加:

  m_MyButton.SubclassDlgItem(IDC_BUTTON1,this);  //这是将成员变量与具体控件相关联,并将CMyButton类的消息加入CtestDlg类的消息路由中

4、并在CMyButton中添加虚函数void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);

5、详细的程序代码:

  1 //控件重绘
  2 void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
  3 {
  4     // TODO:  添加您的代码以绘制指定项
  5     CBitmap bitmap1,bitmap2;
  6     bitmap1.LoadBitmapW(IDB_BITMAP2);  //将位图对象和资源ID相关联
  7     bitmap2.LoadBitmapW(IDB_BITMAP3);  //将位图对象和资源ID相关联
  8     UINT CtlID=lpDrawItemStruct->CtlID; //得到ID号
  9 
 10     //创建画笔,用来画按钮控件矩形
 11     //CPen pen;
 12     //pen.CreatePen(PS_SOLID,1,RGB(255,0,0));
 13     //CPen* pOldPen=(CPen*)pDC->SelectObject(pen);
 14     //pDC->Rectangle(rect);
 15 
 16     if(CtlID==IDC_BIGCIRCLEBTN)
 17     {
 18         CDC* dc=CDC::FromHandle(lpDrawItemStruct->hDC);
 19         CRect rect=lpDrawItemStruct->rcItem;   //控件的大小
 20         UINT state=lpDrawItemStruct->itemState;  //控件的状态,是否按下
 21         if (state&ODS_SELECTED)  
 22             dc->DrawFrameControl(&rect,DFC_BUTTON,DFCS_BUTTONPUSH|DFCS_PUSHED);
 23         else
 24             dc->DrawFrameControl(&rect,DFC_BUTTON,DFCS_BUTTONPUSH);
 25         Refresh(bitmap1,dc,rect);    
 26 
 27         CString str;
 28         GetWindowText(str);  //得到按钮控件上caption
 29         if (!str.IsEmpty())
 30         {
 31             CSize size=dc->GetTextExtent(str);    //使用当前的字体来确定一行字符串的宽度和高度
 32             CPoint central=CPoint(rect.Width()/2-size.cx/2,rect.Height()/2-size.cy/2);  //确定文本输出的起始位置
 33             dc->SetTextColor(RGB(255,0,0));  //设置输出文本的字体颜色
 34             /*
 35             TRANSPARENT表示字体的背景不会擦除,意思是说可以透过字体与字体或者字体本身的缝隙可以看到背景
 36             OPAQUE则刚好相反
 37             */
 38             //dc->SetBkColor(RGB(0,0,255));   设置文字显示区域背景颜色
 39             dc->SetBkMode(TRANSPARENT);  //默认形式是OPAQUE   
 40             if(state&ODS_SELECTED) central.Offset(1,1);  
 41             if (state&ODS_DISABLED)
 42                     dc->DrawState(central,size,NULL,ODS_DISABLED,TRUE,0,(HBRUSH)NULL);
 43             else
 44                 dc->TextOut(central.x,central.y,str);
 45             dc->SetBkMode(OPAQUE);
 46         }
 47     }
 48     if(CtlID==IDC_SMALLCIRCLEBTN)
 49     {
 50         CDC* dc=CDC::FromHandle(lpDrawItemStruct->hDC);
 51         CRect rect=lpDrawItemStruct->rcItem;
 52         UINT state=lpDrawItemStruct->itemState;
 53         if (state&ODS_SELECTED)  
 54             dc->DrawFrameControl(&rect,DFC_BUTTON,DFCS_BUTTONPUSH|DFCS_PUSHED);
 55         else
 56             dc->DrawFrameControl(&rect,DFC_BUTTON,DFCS_BUTTONPUSH);
 57         Refresh(bitmap2,dc,rect);
 58         CString str;
 59         GetWindowText(str);  //得到按钮控件上caption
 60         if (!str.IsEmpty())
 61         {
 62             CSize size=dc->GetTextExtent(str);    //使用当前的字体来确定一行字符串的宽度和高度
 63             CPoint central=CPoint(rect.Width()/2-size.cx/2,rect.Height()/2-size.cy/2);  //确定文本输出的起始位置
 64             dc->SetTextColor(RGB(255,0,255));  //设置输出文本的字体颜色
 65             /*
 66             TRANSPARENT表示字体的背景不会擦除,意思是说可以透过字体与字体或者字体本身的缝隙可以看到背景
 67             OPAQUE则刚好相反
 68             */
 69             dc->SetBkMode(TRANSPARENT);  //默认形式是OPAQUE   
 70             if(state&ODS_SELECTED) central.Offset(1,1);  
 71             if (state&ODS_DISABLED)
 72                     dc->DrawState(central,size,NULL,ODS_DISABLED,TRUE,0,(HBRUSH)NULL);
 73             else
 74                 dc->TextOut(central.x,central.y,str);
 75             dc->SetBkMode(OPAQUE);
 76         }
 77     }
 78 }
 79 
 80 // DDB双缓冲法(适用于设备相关图)
 81 //bitmap是指导入的DDB的位图,CDC相关控件的相关描述表,rect是指控件的尺寸
 82 /************************************************************************/
 83 /*注意这里的函数说明,如果CBitmap不加引用的话,会出现,只有指针才能调用
 84  error C2248: “CObject::CObject”: 无法访问 private 成员(在“CObject”类中声明)
 85 */
 86 /************************************************************************/
 87 void CMyButton::Refresh(CBitmap& bitmap, CDC* dc, CRect rect)
 88 {
 89     CDC MemDC,mdc;  //声明内存描述表,创建一个会在内存只中画画的画家
 90     mdc.CreateCompatibleDC(dc);  //与显示器兼容的设备描述表
 91     MemDC.CreateCompatibleDC(dc);  //与显示器兼容的设备描述表
 92     BITMAP bitmapdate;     //位图的数据
 93     bitmap.GetBitmap(&bitmapdate);  //从位图对象中获取数据
 94     /************************************************************************/
 95     /* 
 96     因为CreateCompatibleBitmap初始化了一个与pDC指定的设备上下文兼容的位图,
 97     位图与指定的设备上下文具有相同的颜色位面数或相同的每个像素的位数。
 98     你可以试一试,如果此处传入&MemDC,完啦完啦,画家怎么画,图上都是灰色的线条,郁闷死啦。
 99     */
100     /************************************************************************/
101     mdc.SelectObject(&bitmap);    //把要导入位图选入,相当于把画好的图放入内存中
102     CBitmap MemBitmap;   //定义内存画布
103     MemBitmap.CreateCompatibleBitmap(dc,rect.Width(),rect.Height()); //确定画布的大小,要与显示控件相兼容的描述表
104     //画家选择画布
105     MemDC.SelectObject(&MemBitmap);
106     MemDC.FillSolidRect(rect,RGB(0,0,0));  //系统默认就是黑色
107     //MemDC.Rectangle(rect);   //这是矩形区域覆盖意思,画边框直线不能用这个
108     //将mdc的画布复制到MemDC中
109     //StretchBlt带有一定的拉伸和缩短变换
110     MemDC.StretchBlt(0,0,rect.Width(),rect.Height(),&mdc,0,0,bitmapdate.bmWidth,bitmapdate.bmHeight,SRCCOPY);
111     //将MemDC中画好的画布复制到控件的画布上,这个函数按照1:1比例进行复制
112     dc->BitBlt(0,0,rect.Width(),rect.Height(),&MemDC,0,0,SRCCOPY);
113     //绘图完成后的清理
114     MemBitmap.DeleteObject();
115     MemDC.DeleteDC();
116     mdc.DeleteDC();
117 }

6、结果示意图:

 

转载于:https://www.cnblogs.com/gzy-zju-edu/articles/4177165.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值