1:第一次尝试

设置    IDC_BUTTON3按钮风格的bitmap为true

在OnInitialDilog中:

CButton* cbpTest = NULL;

HINSTANCE hInstance=AfxGetResourceHandle();
HBITMAP    m_hBmp4=(HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_BITMAP1), IMAGE_BITMAP, 0, 0, 0);
    cbpTest = (CButton*)GetDlgItem(IDC_BUTTON3);

::PostMessage(cbpTest->GetSafeHwnd(), BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)m_hBmp4);

覆盖掉了文字,并且也有闪屏

2:第二次尝试:https://wenku.baidu.com/view/95f2be7a1711cc7931b716e2.html

2.1建立基于对话框的MFC,并且将 IDC_BUTTON3按钮风格的ower-draw打钩:

2.2 声明CBitamapButton m_btnBMP;

2.3 在对话框类CtestDlg的构造函数中m_btnBMP.loadbitmaps(IDB_BITMAP1,IDB_BITMAP2,IDB_BITMAP3,IDB_BITMAP4);

2.4 然后在OnInitialDilog中:m_btnBMP.SubClassDlgItem(IDC_BUTTON3,this);m_btnBMP.SizeToContent();

缺点:覆盖掉了文字,并且也有闪屏

位图按钮

由于MFC提供的按钮外观不是很漂亮(其实是很丑),所以使用按钮的时候往往要自己重新绘制,最多的就是添加自己的漂亮图片。
1.CButton中提供了SetBitmap函数,可以给按钮设置位图,使用方法如下:
CButton button;
button.Create(_T("My button"), WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, CRect(10,10,100,30),this, 1);
CBitmap bmp;
bmp.LoadBitmap(IDB_BMP);
button.SetBitmap(bmp);
优点:使用方法简单
缺点:位图单一,不能显示区分按钮各种状态,有闪屏情况
2.使用MS做好的CBitmapButton类:
CBitmapButton是MS封装好的位图按钮类,从CButton类继承而来,提供两种使用方法,但使用前要创建一个CButton对象与其关联,另外,CBitmapButton类必须具有BS_OWNERDRAW属性:
<1> 使用LoadBitmaps方法:
CBitmapButton bmpButton;
bmpButton.Create(NULL, WS_CHILD | WS_VISIBLE | BS_OWNERDRAW, CRect(10, 10, 100, 100), this, BTN_ID);
bmpButton.LoadBitmaps(IDB_UP, IDB_DOWN, IDB_FOCUS, IDB_DISABLE);

<2>使用AutoLoad方法:
创建一个按钮资源ID为IDC_MYBUTTON并且具有BS_OWNERDRAW属性,设定Caption为:MYBUTTON,插入四张资源位图ID为"MYBUTTONU","MYBUTTOND","MYBUTTONF","MYBUTTONX",分别表示按钮的”弹起“,”按下“,”焦点“,”禁用“状态。最后调用AutoLoad函数就可以自动加载了:
CBitmapButton bmpButton;
bmpButton.AutoLoad(IDC_MYBUTTON, this);

以上两种用法
优点:使用简单,很好的用位图表示了按钮的各种状态,丰富了按钮的外观
缺点:有闪屏情况

MS真让人受伤啊,提供了位图按钮的使用,但就是不能用,都有闪屏。所以只有自己重新绘制了:

3.添加自定义类,从CButton继承,在类向导中添加虚函数DrawItem,然后重画:
    //从lpDrawItemStruct获取控件的相关信息
    CRect rect = lpDrawItemStruct->rcItem;
    CDC *pDC=CDC::FromHandle(lpDrawItemStruct->hDC);
    int nSaveDC=pDC->SaveDC();
    UINT state = lpDrawItemStruct->itemState;
    if(state & ODS_SELECTED)
    {
       // 画按钮按下状态的时候需要显示的位图
        DrawBmpState(pDC, m_bmpResDown);
    }
    else
    {
       // 画按钮其他状态的时候需要显示的位图
        DrawBmpState(pDC, m_bmpResUp);
    }
    
    // 恢复DC
    pDC->RestoreDC(nSaveDC);

注:DrawBmpState用来画按钮的各种状态,采用双缓冲技术,在PC上测试运行正常,但是在手持设备运行有闪屏情况。闪屏发生在按其他按钮的时候,由于这个按钮要丢失焦点,状态转换太快,处理器速度跟不上的原因。(这只是我的个人猜测,高人知道的请赐教)。或者是其他的原因。总之闪屏就像一个甩不掉的魔鬼一样如影随形,最后只能自己重画了。

4.在OnPaint中彻底重画,定制自己的位图按钮:
添加CBmpButton类继承自CButton:
添加BOOL m_bDown;初始化为FALSE,用来标识按钮的按下状态,当按钮按下是置为TRUE,否则为FALSE,主要是为了避免当鼠标在其他地方按下后,然后在按钮上释放造成的按钮重绘。
添加WM_PAINT消息重绘:
    CPaintDC dc(this); // device context for painting
    if(m_bDown)
    {
        DrawBmpState(&dc, m_bmpResDown);
    }
    else
    {
        DrawBmpState(&dc, m_bmpResUp);
    }
DrawBmpState函数用来画按钮各个状态的位图,采用双缓冲技术避免了按钮重绘时的闪屏,这里只列出了两种:弹起和按下:
VOID CBmpButton::DrawBmpState(CDC *pDC, HBITMAP hBitmap)
{
    CRect rect;
    //GetWindowRect(&rect);
    GetClientRect(&rect);
    
    CDC MemDC,mdc;
    mdc.CreateCompatibleDC(NULL);
    MemDC.CreateCompatibleDC(NULL);
    
    CBitmap MemBitmap;
    MemBitmap.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());
    
    MemDC.SelectObject(&MemBitmap);
    MemDC.FillSolidRect(0,0,rect.Width(),rect.Height(),RGB(0,0,0));
    
    //b1.LoadBitmap(bmpID);
    //pb1 = CBitmap::FromHandle(hBitmap);
    mdc.SelectObject(hBitmap);
    MemDC.BitBlt(0,0,rect.Width(),rect.Height(),&mdc,0,0,SRCCOPY);
    
    pDC->BitBlt(0,0,rect.Width(),rect.Height(),&MemDC,0,0,SRCCOPY);
    //绘图完成后的清理
    MemBitmap.DeleteObject();
    MemDC.DeleteDC();
}
添加WM_LBUTTONDOWN事件:
    m_bDown = TRUE;
    InvalidateRect(NULL);
添加WM_LBUTTONUP事件:
    if(m_bDown)
    {
        m_bDown = FALSE;
        InvalidateRect(NULL);
    }
这样就避免了重绘按钮的闪屏,希望闪屏以后不要再来!

MFC/VC++中怎样设置位图按钮并且位图不会覆盖文字——–位图按钮相关推荐

  1. MFC/VC++中怎样将一个位图添加到数据库中并且将其读出来到指定的Picture控件上

    看这篇文章之前建议先看一下下面这篇文章: VC下显示位图的几种方法   http://blog.chinaunix.net/uid-607545-id-2088102.html或  http://bl ...

  2. VC中如何设置Socket的TCP/IP KeepAlive机制(MSDN)

    说明: A TCP keep-alive packet is simply an ACK with the sequence number set to one less than the curre ...

  3. VC中CListCtrl设置滚动条在最下边的方法(MSDN中的例子)

    当插入一条新的记录时同时设置: m_listReport.EnsureVisible(nColumn,FALSE);//设置滚动条到最下面 nColumn为当前记录条数 MSDN中: https:// ...

  4. MFC vc++ 中CTreeContrl如何自定义实现鼠标单击或双击响应事件 ,即重写类似于控件的响应事件或消息

    代码部分摘录自"天上的猩猩的专栏":https://blog.csdn.net/qq_23992597/article/details/51006920#commentsedit ...

  5. c 语言字体怎么改,VC++中的字体设置方法详解

    VC++中static text字体改变 窗口都有2个和字体有关的函数:CWnd::GetFont()和SetFont(CFont*, BOOL); 1)CFont* pFont = m_static ...

  6. 在VC中编程实现按钮的启用(enable)和禁用(disable)

    在VC中编程实现按钮的启用(enable)和禁用(disable)- - 方法总的说只有一个,就是调用CButton::EnableWindow()函数[毕竟CButton是从CWnd继承下来的] 具 ...

  7. php在dw中设置按钮圆角,Dreamweaver怎么用CSS制作圆角按钮?

    Dreamweaver想要制作一个网页中的圆角按钮,并添加鼠标经过时变色的效果,该怎么制作呢?下面我们就来看看详细的教程. 软件名称:Adobe Dreamweaver CC 2018 V18.0 中 ...

  8. VC++中操作XML(MFC、SDK)

    VC++中操作XML(MFC.SDK) XML在Win32程序方面应该没有在Web方面应用得多,很多Win32程序也只是用XML来存存配置信息而已,而且没有足够的好处的话还不如用ini.VC++里操作 ...

  9. java 按钮设置图片_Java中如何设置带图片按钮的大小

    在java部分需要用到图形界面编程的项目中,经常会使用图片设置对按钮进行美化,但是使用时会出现一个很麻烦的问题, 按照方法:JButton jb1 = new JButton(); jb1.setBo ...

最新文章

  1. android 开源Spanner,著名的分布式事务数据库谷歌Spanner设计有坑!
  2. 【Dual-Path-RNN-Pytorch源码分析】model的架构图
  3. 牛客网 二叉树的层序遍历
  4. 苹果面试8大难题及答案
  5. java float 高效加减_java Double 进行加减乘除
  6. html中设置边框形状为齿状,在CSS中制作锯齿状的三角形边框
  7. 函数或变量 rtenslearn_c 无法识别_深度学习的数学-卷积神经网络的结构和变量关系...
  8. SVN自助更新:运维利器Puppet实例讲解
  9. Python版点菜订单
  10. 向上造型和向下造型_动漫美少年漫画造型-仰视、俯视、情感表现
  11. Win10系统完全卸载52好压的方法
  12. 上海互盾信息科技有限公司:心之所向,行必能至
  13. 你的才艺怎样变现?--Rarible平台
  14. [BZOJ3503]-[CQOI2014]和谐矩阵-高斯消元
  15. 阴阳师服务器维护6,《阴阳师》手游6月24日维护更新公告
  16. java怎么给文件加密_java中如何给文件加密
  17. visual studio工程文件介绍
  18. 【天池竞赛】心跳数据挖掘
  19. 舞台灯光计算机控制,舞台灯光的操作
  20. 【PHP开发】Mac系统配置MAMP+Thinkphp框架环境 教程(一)

热门文章

  1. python写一个聊天程序_python实现一个简单的网络聊天程序
  2. 7-37 组个最小数 (20分)_波音737高度计上蹊跷的“8英尺”,09年土耳其航空1951号航班空难...
  3. 浏览器打开php显示空白,pc微信浏览器打开页面显示空白,其他浏览器正常
  4. python学习-综合练习五(五人分鱼(优化解)、顺向、反向推导)
  5. 函数式编程 lambda表达式
  6. 五个数字从小到大排序java,五个数冒泡排序 用c语言数组定义5个数使用冒泡排序 从小到大...
  7. Java十大排序算法总结,Java排序算法总结之冒泡排序
  8. 笨方法python3_“笨方法”学Python3,习题 34 。
  9. javaweb网关_Java网关服务-AIO(三)
  10. python字符串转化为long_Java带有运算符的字符串转换为Long型