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

2023-05-16

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);
    }
这样就避免了重绘按钮的闪屏,希望闪屏以后不要再来!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • MFC:如何减少OnInitialUpdate()滚动的时间成本?

    我需要打印多行数据 每行都可以进行文本换行 因此高度会有所不同 要进行滚动 我需要导出总高度 由于每条线可能有不同的高度 我只能遍历每条线来累加高度 如下所示 void CMyScrollView OnInitialUpdate for a
  • MFC:如何捕获Web浏览器控件中的链接单击事件?

    我有一个带有 Web 控件的 MFC 应用程序 单击可单击链接时 它将使用 IE 打开 而不是默认浏览器 问题 有没有办法强制使用默认浏览器打开它 如果没有 我如何捕获链接单击事件 以便稍后可以操纵单击事件 谢谢 不 据我所知还没有 查看有
  • 基于 C# .NET 文档的应用程序操作图

    我想开发一个新的应用程序 用户可以在其中创建描述流程的图表 我认为在这种情况下 基于文档的应用程序是我唯一的选择 我熟悉C net C MFC 和J2EE 根据您的经验 实现这一目标的最佳方法是什么 我应该关注哪个平台 图表必须由方框和箭头
  • MFC:如何在一个函数中捕获对话框每个控件的设置焦点

    我有 n 个对话框 它们具有相同的基本对话框 每个对话框都有自己的控件 编辑框 组合框 列表控件 etc 在基本对话框中 如何设置每个控件的焦点消息 例如 给出一个消息框 text Hello I got focus my ID is d
  • 如何通过单击 MainFrame 内的按钮来更改 MFC 视图

    我想通过单击窗口内的按钮来更改呈现的视图像这样 https i stack imgur com 3IA2o png 我的项目设置 我制作了一个没有文档 视图支持的 MFC 项目 SDI 我在设计器中又创建了两个视图并向它们添加了类 新的视图
  • 如何在VC++/MFC中替换字符串中两个子字符串之间的字符串?

    假设我有一个 CString 对象 strMain AAAABBCCCCCCDDBBCCCCCCCCDDDAA 我还有两个较小的字符串 例如 strSmall1 BB strSmall2 DD 现在 我想替换 strMain 中 strSm
  • 您可以将 CMFCVisualManager 与基于对话框的应用程序一起使用吗?

    您可以将 CMFCVisualManager 与基于对话框的应用程序一起使用来更改应用程序的外观吗 如果是这样 它是如何完成的 这个想法是使用随 MSVC 2008 发布的 MFC 功能包来更改控件 例如按钮 的形状 颜色等 不 不能这样做
  • 如何在 MFC 中调整对话框大小时移动控件?

    我已经在 MFC 中创建了对话框视图 从下图中可以清楚地看到 如滑块控件和编辑框等 当我调整对话框大小时 这些控件不会移动 在此输入图像描述 https i stack imgur com 7OxAK jpg 我想移动控件以适应对话框 但不
  • 从模态 MFC 表单获取输入信息

    我已经创建了表格CPreparationDlg具有Edit Control 然后我创建了创建模态表单的应用程序 在按 确定 后 我需要将编辑控件中输入的文本读入主程序的变量中 最好的方法是什么 class CPreparationApp p
  • 为什么我的单选按钮不起作用?

    我正在 Visual C 2005 中开发 MFC 对话框应用程序 我的单选按钮是 m Small m Medium 和 m Large 它们都没有在我的 m Summary 编辑框中显示应有的内容 可能出什么问题了 这是我的代码 Pizz
  • 更改 GLUT 调用以与 MFC/C++ 一起使用

    我有一个使用 GLUT 进行 OpenGL 渲染的程序 现在我需要它位于 MFC 项目内部 以便它可以与另一个程序组件一起使用 我已经按照这个教程进行操作 http www codeguru com cpp g m opengl openf
  • MFC CList 支持复制分配吗?

    我在 MSVC 中查找了 CList 定义afxtempl h http www cppdoc com example mfc classdoc MFC AFXTEMPL H html并记录在MSDN http msdn microsoft
  • C++ 中的转换错误

    有人可以帮我解决这个错误吗 我是 C 新手 看来错误就发生在一堆宏中 我能做什么来解决它 或者我怎样才能追踪到它的源头 我真的不明白这个错误 这是否意味着编译器尝试转换该方法void ReadCPUparameter to a LRESUL
  • 如何中止使用 wininet 发送的请求?

    我有一个 MFC 应用程序 用于向相应的服务器发送 post 请求 这是一个http请求 用于上传文件 但有要求中止发送的请求 就像用户正在发送一个大文件一样 用户应该能够在请求完成之前取消请求 我正在使用 wininet api Http
  • 通过 MFC 对话框中的代码更改 Tab 顺序

    我在 OnInitDialog 中通过代码创建了一个控件 但我找不到任何方法通过代码更改对话框的选项卡顺序 有人知道如何做到这一点吗 First Option use ctrl d on resource view in visual st
  • MFC:如何设置CEdit框的焦点?

    我正在开发我的第一个简单的 MFC 项目 但我正在努力解决一个问题 想要设置所有的焦点CEdit其中一个对话框中的框 我的想法是 当打开对话框时 焦点位于第一个编辑框上 然后使用 选项卡 在它们之间交换 我看到了方法SetFocus 但我无
  • 如何获取通过网络驱动器访问的文件的 UNC 路径?

    我正在 VC 中开发一个应用程序 其中网络驱动器用于访问文件 驱动器由用户手动分配 然后在应用程序中选择驱动器 这会导致驱动器并不总是映射到相同的服务器 我该如何获取此类文件的 UNC 路径 这主要是为了识别目的 这是我用来将普通路径转换为
  • 支持 ARM 上的 Windows 10 桌面应用程序 - MFC 和 COM 以及 OPOS 可以工作吗?

    我试图了解将在 x86 Windows 10 上运行的 C MFC 应用程序移植到具有 Qualcomm Snapdragon 处理器的 ARM Windows 10 设备的障碍 32位应用程序具有以下特点 MFC 与 C 用于用户界面 C
  • 使用什么 API 在现有 MFC 应用程序中添加 HTTP 客户端支持?

    我最近接到一项任务 要添加与以下内容交互的能力网络地图服务 http en wikipedia org wiki Web Map Service到现有的 MFC 应用程序 我需要客户端 HTTP API 根据我的研究 领先的候选人似乎是CA
  • 混合 MFC 和 WPF:模态对话框

    我使用 C CLI 界面层将 C WPF 对话框添加到现有的 C MFC 应用程序 我一切正常 只是我遇到了形式问题 例如 MFC 应用程序使用 ShowDialog 显示 WPF 对话框 按预期工作 该 WPF 对话框显示使用 DoMod

随机推荐

  • MFC 类库结构 总结

    MFC主要类库结构总结 MFC类主要分为应用程序结构类 窗口支持类 图书设备类 模版集合类 简单数据类型类以及全局AFX函数等6个类 1 应用程序结构类 应用程序结构类代表的是应用程序的基本元素 xff0c 主要包括了CcmdTarget类
  • MFC基本框架结构

    本文将剖析基于MFC的框架程序 xff0c 探讨MFC框架程序的内部组织结构 xff0c MFC是微软为了简化程序员的开发工作而设计的一套c 43 43 类集合 xff0c 利用这些类有 效地帮助程序员完成windows应用程序开发 代码结
  • mfc编程消息机制中消息汇总

    做VC开发必须熟悉消息机制 xff0c 笔试面试重点 xff0c 自己在这方面很欠缺 xff0c 搜集学习一下 WM CREATE CreateWindow 初始化工作 GetMessage 遇到WM QUIT 程序结束 DispatchM
  • c++中SetEvent和ResetEvent的使用

    关于事件 事件 Event 是WIN32提供的最灵活的线程间同步方式 xff0c 事件可以处于激发状态 signaled or true 或未激发状态 unsignal or false 根据状态变迁方式的不同 xff0c 事件可分为两类
  • MFC设置主界面背景图片、设置子窗体背景图片

    在Onpaint函数中加入如下代码 给窗口设置背景图片 CPaintDC dc this CRect myrect GetClientRect amp myrect CDC dcMem dcMem CreateCompatibleDC am
  • MFC——在视图窗口加载背景图片

    1 若是文档视图程序的话 xff0c 在视图类的OnDraw CDC pDC 函数中调用pDC gt TextOut 函数 xff0c 就像平常输出文字一样 若是嫌文字的背景颜色破坏了图像 xff0c 可以在输出文字之前调用pDC gt S
  • 如何修改MFC的图标

    更改IDR MainFrm指向的ico文件 xff0c 该图标有两种格式 xff0c 32 32和16 16 xff0c 这两种格式都要改 xff0c 还可以在主框架的OnCreate函数里指定使用哪个图标 xff1a HICON m hI
  • MFC改变控件位置和大小

    最近经常要用到改变控件在对话框上的位置和大小 xff0c 一直找不到有效的方法 xff0c 查看了很多资料 这篇博文还算靠谱 xff0c 转载到这里了 void CmyqeDlg OnSize UINT nType int cx int c
  • mfc控件位置调整和坐标确定 .

    在mfc工程中控件或者窗口位置的调整是经常遇到的 xff0c 特别是基于对话框的工程 位置的调整包括坐标 长度和宽度的变化 xff0c 一般在窗口类的OnSize函数中实现 控件位置的调整涉及的函数有 xff1a GetWindowRect
  • MFC笔记2(控件位置调整)

    1 根据计算 xff0c 使用GetClientRect amp 就可以调整好 2 遇到了OK和Cancel按钮通过GetDlgItem xff08 ID xff09 找不到id资源号的情况 xff0c 最后通过给控件绑定控件变量到类中就可
  • MFC控件随窗口大小变化原理及实现

    本文主要针对MFC的dialog xff0c 实现控件随窗口大小变化 原理 xff1a 首先获取dialog的初始大小 xff0c 当窗口发送变动时 xff0c 调用OnSize事件和方法 xff0c 计算缩放比例 xff0c 然后对界面中
  • MFC对话框中处理Enter或Esc按键事件方法

    建立好的MFC的对话框 xff0c 按下Enter或Esc时 xff0c 系统会调用 默认 事件处理函数 xff0c 也就是OnOK xff0c 倘若自己的CFormView子类或者CDialog子类没有重写OnOK 函数 xff0c 则会
  • VS2010 MFC中控件、对话框等背景颜色动态修改的方法

    通过类向导 xff0c 或者手动添加消息 xff1a WM CTLCOLOR xff0c 其消息响应函数为 xff1a afx msg HBRUSH OnCtlColor CDC pDC CWnd pWnd UINT nCtlColor 1
  • MFC窗口风格 WS_style/WS_EX_style

    窗口风格 Window style WS BORDER 有边框窗口 WS CAPTION 必须和WS BORDER风格配合 xff0c 但不能与WS DLGFRAME风格一起使用 指示窗口包含标题要部分 WS CHILD 说明窗口为子窗口
  • MFC 窗体样式修改

    窗体创建之后 xff0c 如何设置窗体的样式呢 xff1f 一般情况下使用GetWindowLongW与SetWindowLongW即可实现窗体样式的修改或者使用ModifyStyle 关于MFC存在GetWindowLongW和GetWi
  • 更改MFC生成的程序的默认exe图标

    一般更改打开程序时的左上角的程序图标使用如下方法 xff1a 对话框为例 xff0c 在对话框构造函数中m hIcon 61 AfxGetApp gt LoadIcon IDI ICON3 将最后的IDR MAINFRAME改为自己的图标即
  • C#与USB设备通信

    最近有一个项目 xff0c 也是我硕士大论文要写的东西 xff0c 就是从两个线阵相机上读取数据 gt 分析数据 gt 做到利用线阵相机检测接触线 铁路接触网 几何参数的功能 由于线阵相机是从武汉的一个创业公司买的 xff0c 实在是坑死个
  • C++常用类型转换

    char是C语言标准数据类型 xff0c 字符型 xff0c 至于由几个字节组成通常由编译器决定 xff0c 一般一个字节 Windows为了消除各编译器的差别 xff0c 重新定义了一些数据类型 CHAR为单字节字符 还有个WCHAR为U
  • C++在dll中获取自身路径(非exe调用路径)

    include 34 stdafx h 34 include lt fstream gt include lt iostream gt include lt windows h gt using namespace std HMODULE
  • MFC/VC++中怎样设置位图按钮并且位图不会覆盖文字——–位图按钮

    1 第一次尝试 设置 IDC BUTTON3按钮风格的bitmap为true 在OnInitialDilog中 xff1a CButton cbpTest 61 NULL HINSTANCE hInstance 61 AfxGetResou