MFC中的窗体绘制事件函数:OnCtlColor、OnPaint、OnNcPaint、OnDrawItem、OnEraseBkgnd、OnDraw

这篇具有很好参考价值的文章主要介绍了MFC中的窗体绘制事件函数:OnCtlColor、OnPaint、OnNcPaint、OnDrawItem、OnEraseBkgnd、OnDraw。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

参考:https://learn.microsoft.com/

CWnd::OnCtlColor

即将绘制子控件时,框架会调用此成员函数。

afx_msg HBRUSH OnCtlColor(
    CDC* pDC,
    CWnd* pWnd,
    UINT nCtlColor);

参数
pDC
包含指向子窗口的显示上下文的指针。 可能是暂时性指针。

pWnd
包含指向请求颜色的控件的指针。 可能是暂时性指针。

nCtlColor
包含以下用于指定控件类型的值之一:

CTLCOLOR_BTN 按钮控件

CTLCOLOR_DLG 对话框

CTLCOLOR_EDIT 编辑控件

CTLCOLOR_LISTBOX 列表框控件

CTLCOLOR_MSGBOX 消息框

CTLCOLOR_SCROLLBAR 滚动条控件

CTLCOLOR_STATIC 静态控件

返回值
OnCtlColor 必须返回用于绘制控件背景的画笔的句柄。

注解
大多数控件将此消息发送到其父级(通常是一个对话框),以准备 pDC 来使用正确的颜色绘制控件。

若要更改文本颜色,请使用所需的红绿蓝 (RGB) 值调用 SetTextColor 成员函数。

若要更改单行编辑控件的背景色,请在 CTLCOLOR_EDIT 和 CTLCOLOR_MSGBOX 消息代码中设置画笔句柄,并调用 CDC::SetBkColor 函数来响应 CTLCOLOR_EDIT 代码。

不会对下拉组合框的列表框调用 OnCtlColor,因为下拉列表框实际上是组合框的子级,而不是窗口的子级。 若要更改下拉列表框的颜色,请在 nCtlColor 参数中创建一个 CComboBox,并在其中包含一个用于检查 CTLCOLOR_LISTBOX 的 OnCtlColor 重写。 在此处理程序中,必须使用 SetBkColor 成员函数来设置文本的背景色。

备注

框架调用此成员函数来支持你的应用程序处理 Windows 消息。 传递到函数的参数反映了收到消息时框架所接收的参数。 如果调用此函数的基类实现,该实现将使用最初随消息传递的参数,而不是你提供给该函数的参数。 若要将以下方法添加到对话框类,请使用 Visual Studio 属性窗格添加 WM_CTLCOLOR 的消息处理程序。 或者,可以手动将 ON_WM_CTLCOLOR() 条目添加到消息映射。

示例

// This OnCtlColor handler will change the color of a static control
// with the ID of IDC_MYSTATIC. The code assumes that the CPenWidthsDlg
// class has an initialized and created CBrush member named m_brush.
// The control will be painted with red text and a background
// color of m_brush.
HBRUSH CPenWidthsDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
   // Call the base class implementation first! Otherwise, it may
   // undo what we're trying to accomplish here.
   HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

   // Are we painting the IDC_MYSTATIC control? We can use
   // CWnd::GetDlgCtrlID() to perform the most efficient test.
   if (pWnd->GetDlgCtrlID() == IDC_MYSTATIC)
   {
      // Set the text color to red
      pDC->SetTextColor(RGB(255, 0, 0));

      // Set the background mode for text to transparent 
      // so background will show thru.
      pDC->SetBkMode(TRANSPARENT);

      // Return handle to our CBrush object
      hbr = m_brush;
   }

   return hbr;
}

CWnd::OnPaint

当 Windows 或应用程序请求重绘应用程序窗口的一部分时,框架会调用此成员函数。

afx_msg void OnPaint();

注解
在调用 UpdateWindow 或 RedrawWindow 成员函数时发送 WM_PAINT 消息。

由于在设置了 RDW_INTERNALPAINT 标志的情况下调用了 RedrawWindow 成员函数,窗口可能会收到内部绘制消息。 在这种情况下,窗口可能不包含更新区域。 应用程序应调用 GetUpdateRect 成员函数来确定窗口是否包含更新区域。 如果 GetUpdateRect 返回 0,则应用程序不应调用 BeginPaint 和 EndPaint 成员函数。

应用程序需负责通过在其内部数据结构中查找每个 WM_PAINT 消息来检查任何必要的内部重绘或更新,因为 WM_PAINT 消息可能是由无效区域以及在设置了 RDW_INTERNALPAINT 标志的情况下调用 RedrawWindow 成员函数而导致的。

Windows 仅发送内部 WM_PAINT 消息一次。 在 UpdateWindow 成员函数将内部 WM_PAINT 消息发送到某个窗口后,在该窗口失效或者在设置了 RDW_INTERNALPAINT 标志的情况下再次调用 RedrawWindow 成员函数之前,不会发送或发布更多的 WM_PAINT 消息。

CWnd::OnNcPaint

需要绘制非工作区时,框架会调用此成员函数。

afx_msg void OnNcPaint();

注解
默认实现绘制窗口框架。

应用程序可以重写此调用并绘制其自身的自定义窗口框架。 剪切区域始终是矩形,即使框架的形状已更改。

CWnd::OnDrawItem

当控件或菜单的视觉方面发生更改时,框架将对所有者绘制按钮控件、组合框控件、列表框控件或菜单的所有者调用此成员函数。

afx_msg void OnDrawItem(
    int nIDCtl,
    LPDRAWITEMSTRUCT lpDrawItemStruct);

参数
nIDCtl
包含发送了 WM_DRAWITEM 消息的控件的标识符。 如果菜单发送了消息,则 nIDCtl 包含 0。

lpDrawItemStruct
指定指向 DRAWITEMSTRUCT 数据结构的长指针,该结构包含有关要绘制的项和所需绘制类型的信息。
注解
DRAWITEMSTRUCT 结构的 itemAction 成员定义要执行的绘制操作。 此成员中的数据允许控件所有者确定所需的绘制操作。

在处理此消息后返回之前,应用程序应确保 DRAWITEMSTRUCT 结构的 hDC 成员所标识的设备上下文已还原到默认状态。

如果 hwndItem 成员属于 CButton、CMenu、CListBox 或 CComboBox 对象,则调用相应类的 DrawItem 虚拟函数。 重写相应控件类的 DrawItem 成员函数可绘制项。

备注

框架调用此成员函数来支持你的应用程序处理 Windows 消息。 传递到函数的参数反映了收到消息时框架所接收的参数。 如果调用此函数的基类实现,该实现将使用最初随消息传递的参数,而不是你提供给该函数的参数。

CWnd::OnEraseBkgnd

当 CWnd 对象背景需要擦除时(例如,调整大小时),框架会调用此成员函数。

afx_msg BOOL OnEraseBkgnd(CDC* pDC);

参数
pDC
指定设备上下文对象。

返回值
如果擦除背景,则返回非零值;否则返回 0。

注解
调用它来准备一个用于绘制的失效区域。

默认实现使用窗口类结构的 hbrBackground 成员指定的窗口类背景画笔来擦除背景。

如果 hbrBackground 成员为 NULL,则 OnEraseBkgnd 的重写版本应擦除背景色。 该版本还应通过首先对画笔调用 UnrealizeObject,然后选择画笔,将所需画笔的原点与 CWnd 坐标对齐。

如果重写的 OnEraseBkgnd 处理消息并擦除背景,则它应返回非零值以响应 WM_ERASEBKGND;这表示不需要进一步擦除。 如果它返回 0,则窗口将仍旧标记为需要擦除。 (通常,这意味着 PAINTSTRUCT 结构的 fErase 成员将是 TRUE。)

Windows 假设使用 MM_TEXT 映射模式来计算背景。 如果设备上下文使用任何其他映射模式,则擦除的区域可能不在工作区的可见部分内。

备注

框架调用此成员函数来支持你的应用程序处理 Windows 消息。 传递到函数的参数反映了收到消息时框架所接收的参数。 如果调用此函数的基类实现,该实现将使用最初随消息传递的参数,而不是你提供给该函数的参数。

CWnd::InvalidateRect

通过将给定矩形添加到 CWnd 更新区域,使给定矩形中的工作区失效。

void InvalidateRect(
    LPCRECT lpRect,
    BOOL bErase = TRUE);

参数
lpRect
指向包含要添加到更新区域的矩形(以客户端坐标表示)的 CRect 对象或 RECT 结构。 如果 lpRect 为 NULL,则将整个工作区添加到该区域。

bErase
指定是否要擦除更新区域中的背景。

注解
在发送下一条 WM_PAINT 消息时,会将失效矩形连同更新区域中的所有其他区域一起标记为可绘制。 失效区域在更新区域中累积到在下一次发生 WM_PAINT 调用时处理该区域,或者该区域被 ValidateRect 或 ValidateRgn 成员函数验证为止。

bErase 参数指定在处理更新区域时是否要擦除更新区域中的背景。 如果 bErase 为 TRUE,则在调用 BeginPaint 成员函数时擦除背景;如果 bErase 为 FALSE,则背景将保持不变。 对于更新区域的任何部分,如果 bErase 为 TRUE,则会擦除整个区域(而不仅仅是给定部分)中的背景。

每当 CWnd 更新区域不为空并且该窗口的应用程序队列中没有其他消息时,Windows 就会发送一条 WM_PAINT 消息。

类似的函数
MFC中的CWnd::Invalidate、CWnd::InvalidateRgn

void Invalidate(BOOL bErase = TRUE);
void InvalidateRect(LPCRECT lpRect, BOOL bErase = TRUE);

WIN32API中的InvalidateRect

BOOL InvalidateRect(
  [in] HWND       hWnd,
  [in] const RECT *lpRect,
  [in] BOOL       bErase
);

CView::OnDraw

由框架调用以呈现文档的图像。

virtual void OnDraw(CDC* pDC) = 0;

参数
pDC
指向用于呈现文档图像的设备上下文。

注解
框架调用此函数以执行屏幕显示、打印和打印预览,并在每种情况下传递不同的设备上下文。 没有默认实现。

必须重写此函数才能显示文档的视图。 可以使用 pDC 参数所指向的 CDC 对象发出图形设备接口 (GDI) 调用。 可以在绘图前在设备上下文中选择 GDI 资源(例如笔或字体),之后将取消选择它们。 通常,绘图代码可以与设备无关;也就是说,不需要有关哪种类型的设备显示图像的信息。

若要优化绘图,请调用设备上下文的 RectVisible 成员函数,以确定是否绘制给定的矩形。 如果需要区分普通屏幕显示和打印,请调用设备上下文的 IsPrinting 成员函数。文章来源地址https://www.toymoban.com/news/detail-655992.html

到了这里,关于MFC中的窗体绘制事件函数:OnCtlColor、OnPaint、OnNcPaint、OnDrawItem、OnEraseBkgnd、OnDraw的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C#之基于winform窗体绘制简单图形

    什么是窗体? 可以理解为是一个自定义的控制台应用程序。 假如需要仅仅是用vs制作游戏的话,那么vs中,我们平时所用到的控制台应用程序所呈现的窗口时远远不够用的。因此需要自定义窗体。 因此在新建项目时,我们不能再使用控制台应用程序,而是应该选择窗体: 之

    2023年04月16日
    浏览(42)
  • .net-----Windows 窗体应用程序包括控件,对话框,多重窗体,绘制图形,菜单和工具栏

    Windows窗体应用程序概述;  使用Visual Studio开发Windows窗体应用程序;  窗体和控件概述;  使用常用Windows窗体控件;  通用对话框;  菜单和工具栏;  多重窗体;  多文档界面;  绘制图形 Windows窗体应用程序是运行在用户计算机本地的基于Windows的应用程序,

    2024年02月04日
    浏览(65)
  • VB.NET—窗体引起的乌龙事件

    目录 前言: 过程: 总结: 升华:  分享一个VB.NET遇到的一个问题,开始一直没有解决,这个问题阻碍了很长时间,成功的变成我路上的绊脚石,千方百计的想要绕过去,但事与愿违怎么也绕不过去,因为运行不了窗体,程序就起不来,到后来废了九牛二虎之力终于找到的问题的

    2024年02月06日
    浏览(39)
  • 【C#进阶】C#中的委托、事件、回调函数、匿名函数和lambda表达式

    委托是一种类型,它可以存储对一个或多个方法的引用。它类似于C/C++中的函数指针,允许您将方法作为参数传递、存储和调用。 写法: delegate return_type delegate_name( ); return_type :表示委托所引用方法的返回类型。 delegate_name :表示委托的名称。 parameters :表示委托所引用方法

    2024年02月06日
    浏览(58)
  • 使用MFC绘制一些简单图形

    目录 一、画直线 更改画笔样式 二、使用画刷画一个矩形 透明矩形 自定义颜色填充矩形 自定义图形填充矩形 四、实现一个画笔 五、画扇形 六、画椭圆 七、画圆 八、输出文本     画一条直线需要一个起点和一个终点,当鼠标按下时记录为起点坐标,鼠标弹起时记录为终点

    2024年02月07日
    浏览(52)
  • 什么是Vue中的生命周期钩子函数?有哪些主要的生命周期钩子函数?如何监听DOM事件?

    Vue中的生命周期钩子函数是指在Vue实例创建、数据绑定、组件挂载等生命周期阶段中,可以执行一些特定操作的函数。这些函数在Vue实例的不同生命周期阶段被调用,可以帮助开发者更好地控制Vue实例的行为。 Vue的生命周期钩子函数包括: beforeCreate :在Vue实例创建之前调用

    2024年02月12日
    浏览(57)
  • C++MFC创建事件

    一、概念 创建事件: HANDLE CreateEvent( LPSECURITY_ATTRIBUTES lpEventAttributes, // SECURITY_ATTRIBUTES结构指针,可为NULL BOOL bManualReset, // 手动/自动 // TRUE:表示手动,在WaitForSingleObject后必须手动调用ResetEvent清除信号 // FALSE:表示自动,在WaitForSingleObject后,系统自动清除事件信号 BOOL bInit

    2024年02月13日
    浏览(33)
  • 基于MFC的键盘响应(热键触发事件)

    通过输入 CTRL + G 组合按键完成文件选择框弹出: 目标: 按下 CTRL + G ,弹出文件选择框 过程: 头文件添加消息申明 cpp文件添加消息映射 OnInitDialog添加全局热键注册 实现热键功能函数 MFC键盘宏定义: 功能键: VK_TAB : Tab键。 VK_SPACE : 空格键。 VK_BACK : 退格键(回退键)。

    2024年02月04日
    浏览(45)
  • MFC 子窗口利用双缓冲在指定控件中绘制椭圆

    想通过点击一个按钮,弹出一个对话框,在此对话框中绘制椭圆(对话框弹出时椭圆已绘制完毕,不需要点击按钮触发)。则需要在新建对话框的OnPaint()函数中绘制 1 建立模态对话框 1.1 插入一个新的对话框 1.2 修改对话框ID:选择对话框,Alt+Enter快捷键进入属性表 1.3 对话框关联

    2024年02月06日
    浏览(44)
  • MFC - 控件的消息和控件的事件(命令)有什么区别?

    MFC的控件都能添加事件处理程序( 类向导称事件为命令 ) 控件的 消息 和控件的**事件(命令)**有什么区别? 事件 可能由多个消息组成, 事件是消息的封装 。控件的事件也是通过消息机制来处理的,所以这两者在 本质上是一样的。函数本身没什么太大区别只不过函数的

    2023年04月13日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包