博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CDC,CPaintDC,CClientDC,CWindowDC
阅读量:6916 次
发布时间:2019-06-27

本文共 2071 字,大约阅读时间需要 6 分钟。

在使用任何绘图函数之前必须建立一个设备环境对象。

 

CDC是Windows绘图设备的基类

CDC的使用:

OnDraw(CDC* pDC),因此OnDraw中可以直接使用CDC类编写代码。

其他函数中要使用CDC类,需使用GetDC函数和ReleaseDC函数,实现申请CDC类得指针和释放CDC类的指针。

 

CPaintDC使用示例:

在视图类中使用CPaintDC进行窗口的重绘

当用户区内容需要被刷新时,系统向应用程序消息队列发WM_PAINT消息,调用OnPaint函数进行处理。

如果视图类中没有OnPaint函数,窗口重绘时调用MFC底层代码里的OnPaint函数来调用OnDraw函数。

如果有OnPaint函数,且OnPaint函数中没有调用OnDraw函数,那么视图类中的OnDraw函数永远得不到调用。

下面用一些简单的代码看看如果使用这些类

1、使用HDC

HDC hdc;//声明一HDC

    hdc = ::GetDC(m_hWnd);

//用全局函数HDC GetDC(HWND hWnd),来获取设备句柄。全局函数前面加::既可

    MoveToEx(hdc,m_ptOrigin.x, m_ptOrigin.y,NULL);

    LineTo(hdc,point.x,point.y);

    ::ReleaseDC(m_hWnd,hdc);

可以看到HDC的使用较麻烦, 而且如果::GetDC和::ReleaseDC不配对的话,会造成错误

2、

CDC* pDC = GetDC();

    pDC->MoveTo(m_ptOrigin);

    pDC->LineTo(point);

    ReleaseDC(pDC);

3、

    CClientDC dc(this);

    dc.MoveTo(m_ptOrigin);

    dc.LineTo(point);

4、

CWindowDC dc(this);

//CWindowDC dc(GetParent());

//CWindowDC dc(GetDesktopWindow());

    dc.MoveTo(m_ptOrigin);

    dc.LineTo(point);

      

相关:

CPaintDC:

(1)用于响应窗口重绘消息(WM_PAINT)。
(2)CPaintDC在构造函数中调用BeginPaint()取得设备上下文,在析构函数中调用EndPaint()释放设备上下文。EndPaint()除了释放设备上下文外,还负责从消息队列中清除WM_PAINT消息。因此,在处理窗口重画时,必须使用CPaintDC,否则WM_PAINT消息无法从消息队列中清除,将引起不断的窗口重画。
(3)CPaintDC也只能用在WM_PAINT消息处理之中。

关于 WM_PAINT 事件

系统会在多个不同的时机发送WM_PAINT消息:当第一次创建一个窗口时,当改变窗口的大小时,当把窗口从另一个窗口背后移出时,当最大化或最小化窗口时,等等,这些动作都是由系统管理的,应用只是被动地接收该消息,在消息处理函数中进行绘制操作;大多数的时候应用也需要能够主动引发窗口中的绘制操作,比如当窗口显示的数据改变的时候,这一般是通过InvalidateRect和InvalidateRgn函数来完成的。InvalidateRect和 InvalidateRgn把指定的区域加到窗口的Update Region中,当应用的消息队列没有其他消息时,如果窗口的Update Region不为空时,系统就会自动产生WM_PAINT消息。

 

系统为什么不在调用Invalidate时发送 WM_PAINT消息呢?又为什么非要等应用消息队列为空时才发送WM_PAINT消息呢?这是因为系统把在窗口中的绘制操作当作一种低优先级的操作,于是尽可能地推后做。不过这样也有利于提高绘制的效率:两个WM_PAINT消息之间通过InvalidateRect和InvaliateRgn使之失效的区域就会被累加起来,然后在一个WM_PAINT消息中一次得到更新,不仅能避免多次重复地更新同一区域,也优化了应用的更新操作。像这种通过 InvalidateRect和InvalidateRgn来使窗口区域无效,依赖于系统在合适的时机发送WM_PAINT消息的机制实际上是一种异步工作方式,也就是说,在无效化窗口区域和发送WM_PAINT消息之间是有延迟的;有时候这种延迟并不是我们希望的,这时我们当然可以在无效化窗口区域后利用SendMessage 发送一条WM_PAINT消息来强制立即重画,但不如使用Windows GDI为我们提供的更方便和强大的函数:UpdateWindow和RedrawWindow。UpdateWindow会检查窗口的Update Region,当其不为空时才发送WM_PAINT消息;RedrawWindow则给我们更多的控制:是否重画非客户区和背景,是否总是发送 WM_PAINT消息而不管Update Region是否为空等。

转载地址:http://nixcl.baihongyu.com/

你可能感兴趣的文章
Gradle 1.12用户指南翻译——第三十六章. Sonar Runner 插件
查看>>
基于HTTP 协议认证介绍与实现
查看>>
(原創) 如何寫一個加法器? (C/C++) (SystemC) (IC Design)
查看>>
Npoi导入导出Excel操作
查看>>
说说接口封装
查看>>
TCP/IP建立连接与终止连接
查看>>
asp.net 中页面缓存 ,数据源缓存,自定义缓存
查看>>
[九度][何海涛] 翻转单词顺序
查看>>
微信相关的应用
查看>>
将数组适配到ListView
查看>>
Olivia Palermo & Johannes Huebl 模范情侣
查看>>
[geeksforgeeks] Convert a given Binary Tree to Doubly Linked List
查看>>
android mk详解
查看>>
程序员与禅的对话录
查看>>
【mysql】执行mysql脚本
查看>>
ASP.NET 时间方法大全
查看>>
git 查看远程分支、本地分支、创建分支、把分支推到远程repository、删除本地分支...
查看>>
scp 使用
查看>>
Shell命令_awk命令
查看>>
获取某行某列的值
查看>>