VC 绘图,使用双缓冲技术实现

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

*******************************************************************例子*******************************************************************

   ********************所有的GDI绘图函数使用的都是逻辑坐标(逻辑范围)*******************
*******************系统默认情况下 物理范围和逻辑范围 是1:1 的对应关系*******************
1. 首先定义类成员:

   CDC *m_pDC;
   CDC MemDC;
   CBitmap MemBitmap;
   CBitmap *pOldbitmap;

   LONG xRange;   // 逻辑范围,x方向宽度
   LONG yRange;   // 逻辑范围,y方向高度
   LONG nWidht;   // 物理范围,x方向宽度
   LONG nHeight;  // 物理范围,y方向高度

2. 在类初始化函数中:

  m_pDC = this->GetDC();                 // 获取设备上下文句柄 

  CWnd *wnd = GetDlgItem(IDC_SHOWGRAPH);     // 获取界面上显示图形的ID控件的句柄
  wnd->GetWindowRect(&rect);             // 获取显示/画图区域大小(物理范围)
  ScreenToClient(&rect);                 // 转换为客户区坐标

  nWidth = rect.Width();                 // 显示/画图区域x方向物理宽度
  nHeight = rect.Height();               // 显示/画图区域y方向物理高度

3. 在自定义函数中,设置视口与窗口的比例关系
 
  m_pDC->SetMapMode(MM_ANISOTROPIC);     // 注意MM_ANISOTROPIC和MM_ISOTROPIC的区别

  m_pDC->SetWindowExt(XRange,-yRange);   // 设定窗口尺寸范围,画图使用的逻辑范围,实现放大或是缩小,坐标方向↑和→为正向

  m_pDC->SetViewportExt(nWidth,nHeight); // 设定视口尺寸范围,客户区实际图形显示的区域范围,大小固定

  m_pDC->SetViewportOrg(rect.left,rect.bottom);  //设定画图的逻辑原点坐标(0,0)在物理坐标的(rect.left,rect.bottom)点上

 4. 在自定义函数中,双缓冲技术的使用

  MemDC.CreateCompatibleDC(m_pDC);                          // 创建内存兼容设备上下文
  MemBitmap.CreateCompatibleBitmap(m_pDC,xRange,yRange);    // 创建内存兼容画布,大小由逻辑范围决定
  pOldbitmap = MemDC.SelectObject(&MemBitmap);              // 将画布选入内存设备上下文

  MemDC.FillSolidRect(0,0,xRange,yRange,RGB(123,213,132)); // 对内存中的画布填充背景颜色,否则是默认的黑色

  // 画图操作,如画一条对角直线
  MemDC.MoveTo(0,0);
  MemDC.LineTo(xRange*0.9,yRange*0.9);

  // 将内存中的画图区域拷贝到界面的控件区域上去
  // 第1和第2个参数若是0时,则从物理坐标的(rect.left,rect.bottom)点上开始按上述指定的方向贴图
  m_pDC->BitBlt(0,0,xRange,yRange,&MemDC,0,0,SRCCOPY);

5. 在类的析构函数中:

  MemDC.SelectObject(pOldbitmap);
  bitmap.DeleteObject();

  this->ReleaseDC(m_pDC);

6. 至此,就完成了双缓冲坐标缩放绘图的功能

*********************************************************************************************************************************************

用VC做的画图程序,当所画的图形大于屏幕时,在拖动滚动条时屏幕就会出现严重的闪烁,为了解决这一问题,就得使用双缓冲来解决。程序产生严重的闪烁问题是因为画图过程中前后两次的画面反差很大造成的人的视觉的闪烁。因为在VC中每次在调用OnDraw时系统都是先用背景画刷将画布清除再执行画图命令,这样在你每次移动滚动条时每执行一次OnDraw就会有一个空白页,这样和你的最终结果图象之间有一个很大的反差,因而看起来闪烁,而且滚动条滚动越快闪烁越严重。当然,你可以将背景画刷设为NULL,这样可以解决闪烁问题,但是不能将先前的图象擦除,这样整个屏幕就显得很乱。

下面将利用双缓冲来解决这一问题的思路给大家作一下简单的介绍。

我先来解释一下在MFC里面很关键的设备环境描述符,也就是所谓的 DC(device context)。

在dos时代,我们如果要绘图,必须通过一系列系统函数来启动图形环境(用过turbo pascal或者turbo c的人该还有印象吧),这之间对各种硬件的初始化参数都不相同,非常的烦人,常常还要查阅硬件手册,那时的程序智能针对最流行的硬件来编写,对不流行的就没有办法了。windows操作系统为了屏蔽不同的硬件环境,让编程时候不考虑具体的硬件差别,采取了一系列办法,设备环境描述符就是这样产生的。简单地说,设备描述符抽象了不同的硬件环境为标准环境,用户编写时使用的是这个虚拟的标准环境,而不是真实的硬件,与真实硬件打交道的工作一般交给系统和驱动程序去完成(这同样解释了为什么我们需要经常更新驱动程序的问题)。使用在windows图形系统(gdi,而不包括direct x)上面,就体现在一系列的图形DC上面,我们如果要在gdi上面绘图,就必须先得到图形DC的句柄(handle),然后在指定句柄的基础上进行图形操作。

那么我们怎么在sdk环境下面绘图的呢,我想这个大家都不太清楚,但是确实很基础。在windows的sdk环境下面,我们用传统的c编写程序,在需要的绘图地方(比如响应WM_PAINT消息的分支)这样做:

hdc = GetDC( hwnd );
oldGdiObject = SelectObject( hdc,newGdiObject );
...绘图操作...
SelectObject( hdc,oldGdiObject );
DeleteObject( newGdiObject );
ReleaseDC( hdc);

或者这样

BeginPaint( hwnd,&ps );  //PAINTSTRUCT ps -- ps is a paint struct
...绘图操作...
EndPaint( hwnd )

这就是大概的过程,我们看到了hdc(图形DC句柄)的应用。在绘图

VC6对话框双缓冲加载图片 用应用程序向导生成一个基于对话框的应用程序 把对话框Styles里的Border设置为Resizing,并把Minimize box跟Maximize box复选按钮都勾上 现在我们为资源导入一张位图然后我们为程序添加四个私有变量private: int height; int width; CBitmap myBitmap; BITMAP bm; 然后用类向导添加WM SIZE消息输入下列代码: width = cx; height = cy; Invali... 阅读详情

相关推荐

利用双缓冲技术来显示动画

现在,你已经能够对主表面的内容做直接修改了(就是锁住主表面然后绘制像素),也就是通过视频控制器直接将每一帧都光栅化。   什么是光栅化???? http://blog.sina.com.cn/s/blog_61ac952e0100fs84.html 什么是帧???? 答:一帧就是一副静止的画面,连续的帧就形成动画,如电视图象等。   我们通常说帧数,简单地说,就是在1秒钟时间里传输的

假装狠牛逼 5327

MFC双缓冲+提升绘图效率方法(号称三缓冲):自定义静态背景不频繁擦除(★firecat推荐★)

应用场景是:绘制一个运动小球,在大屏幕滚动,屏幕背景图也是一个自定义绘制的(填充色,线条和文字等组成)。如图所示。红色是小球,在大背景里动态移动,而背景是静态的,静止不动。 1、MFC克服C++窗体重绘时的闪烁问题,用到的技巧是双缓冲双缓冲原理网上的文章好多,这里不赘述。 //---------------------------------MFC双缓冲//--------------...

$firecat利白的代码足迹$ 3957

MFC高效绘图:优化双缓冲绘图机制

然而,在频繁重绘的情况下,直接在屏幕上进行绘制可能会导致闪烁和性能问题。无论是在处理大量绘图操作的复杂场景中,还是在需要频繁更新绘图内容的实时应用中,双缓冲绘图都是一个非常实用的技术双缓冲绘图是一种通过在内存中创建一个缓冲区进行绘图,然后将其一次性绘制到屏幕上的技术。接下来,在缓冲DC上进行绘图操作,可以使用各种GDI(Graphics Device Interface)函数进行绘制,例如。最后,在清理资源时,我们需要还原原始的位图对象,并删除缓冲位图和内存DC,以防止内存泄漏。完成绘制后,我们使用

JfBackend的博客 482

双缓冲技术绘图原理及简单的VC实现

1、Windows 绘图原理  我们在 Windows 环境下看到各种元素,如菜单、按钮、窗口、图像,从根本上说,都是“画”出来的。这时的屏幕,就相当于一块黑板,而 Windows 下的各种 GDI 要素,如画笔、画刷等,就相当于彩色粉笔了。我们在黑板上手工画图时,是一笔一划的,电脑亦然。只不过电脑的速度比手工快的太多,所以在我们看起来好像所有的图形文字都是同时出现的。  2、普通绘图方式的局

小龙王2010 1237

linux上c语言hdc句柄,VC 绘图使用双缓冲技术实现

CDC *m_pDC;CDC MemDC;CBitmap MemBitmap;CBitmap*pOldbitmap;LONG xRange; // 逻辑范围,x方向宽度LONG yRange; // 逻辑范围,y方向高度LONGnWidht; // 物理范围,x方向宽度LONG nHeight; // 物理范围,y方向高度2. 在类初始化函数中:m_pDC = this->Get...

weixin_35645701的博客 962

【转】VC 绘图使用双缓冲技术实现

********************所有的GDI绘图函数使用的都是逻辑坐标(逻辑范围)******************* *******************系统默认情况下 物理范围和逻辑范围 是1:1 的对应关系******************* 1. 首先定义类成员: CDC *m_pDC; CDC MemDC; CBitmap MemBitm...

weixin_30799995的博客 168

VC 绘图使用双缓冲技术实现 2012-02-06 16:47:07 分类: C/C++

*******所有的GDI绘图函数使用的都是逻辑坐标(逻辑范围)******************* *******************系统默认情况下 物理范围和逻辑范围 是1:1 的对应关系******************* 1. 首先定义类成员: CDC *m_pDC; CDC MemDC; CBitmap MemBitmap; CBitmap *pO

C++ 1884

VC双缓冲绘图

最早在vchelp上发表过的一篇文章,VChelp已经上不了了,又有好多人问人关于VC双缓冲绘图方面的问题,下面我将这篇文章再重新发出来,供大家学习一下:   用vc做的画图程序,当所画的图形大于屏幕时,当拖动滚动条时屏幕就会出现严重的闪烁情况,为了解决这一问题就得使用双缓冲来解决这一问题,程序产生严重的闪烁问题是因为画图过程中前后两次的画面反差很大造成的人的视觉的闪烁。因为在VC中每次在

相生昌专栏 1万+
上一篇: 一个串口编程实例
下一篇: evc vc字符串转换处理一:(绝对精华,收集所有的例子)
scollins
博客等级 码龄19年 70粉丝 172原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值