1、起因

本来是想用gdi绘图的,但是一想到用gdi+libpng,还要自己处理一些比如alpha的效果之类的巨麻烦(而且涉及到处理每一个像素点的计算,一般都很耗时),我对自己处理像素点的能力一直持有怀疑态度。。so,先用cximage将就着,不知道是否可以跨平台。。

2、用cximage绘制png到屏幕上面确实很容易,简单的就几行代码

参考:http://blog.csdn.net/zengraoli/article/details/8635225

3、但是简单的在WM_PAINT消息进行重绘的时候,加入缓冲绘图,会发现背后出现黑色的区域-------------因为是在内存中使用了HBITMAP造成的,实例代码:


  1. case WM_PAINT:
  2. hdc = BeginPaint(hWnd, &ps);
  3. // TODO: 在此添加任意绘图代码...
  4. /*      hdc= GetDC(hWnd);*/
  5. hMemDC  = CreateCompatibleDC(hdc);
  6. hbitmap = CreateCompatibleBitmap(hdc, m_pCxImage->GetWidth(), m_pCxImage->GetHeight());
  7. oldBmp = (HBITMAP)SelectObject(hMemDC, hbitmap);
  8. m_pCxImage->Draw(hMemDC, 0, 0);
  9. BitBlt(hdc, 0, 0, m_pCxImage->GetWidth(), m_pCxImage->GetHeight(), hMemDC, 0, 0, SRCCOPY);
  10. ReleaseDC(NULL,hdc);
  11. EndPaint(hWnd, &ps);
  12. break;

4、其实去除背后的黑色区域很简单

可以先把没绘制时候的空白,先拷贝一份在兼容DC(hdcBk)中,在绘制png的时候,先在内存DC(hMemDC)中绘制hdcBk,在用cximage绘制png到hMemDC中,那么背后就是白色的了,就这么简单

主要代码:

  1. void GetBackImage(HWND hWnd, HDC &hdcBk, int iWidth, int iHeight)
  2. {
  3. HDC hdcParent/*, hdcBk*/;
  4. HBITMAP hbitmap;
  5. hdcParent = GetDC(hWnd);
  6. hdcBk = CreateCompatibleDC(hdcParent);
  7. hbitmap = CreateCompatibleBitmap(hdcParent, iWidth, iHeight);
  8. SelectObject(hdcBk, hbitmap);
  9. BitBlt(hdcBk, 0, 0, iWidth, iHeight, hdcParent, 0, 0, SRCCOPY);
  10. ReleaseDC(hWnd, hdcParent);
  11. }

在消息处理的时候:

  1. case WM_PAINT:
  2. hdc = BeginPaint(hWnd, &ps);
  3. // TODO: 在此添加任意绘图代码...
  4. /*      hdc= GetDC(hWnd);*/
  5. hMemDC  = CreateCompatibleDC(hdc);
  6. hbitmap = CreateCompatibleBitmap(hdc, m_pCxImage->GetWidth(), m_pCxImage->GetHeight());
  7. oldBmp = (HBITMAP)SelectObject(hMemDC, hbitmap);
  8. if (hdcBk == 0)
  9. {
  10. GetBackImage(hWnd, hdcBk, m_pCxImage->GetWidth(), m_pCxImage->GetHeight());
  11. }
  12. BitBlt(hMemDC, 0, 0, m_pCxImage->GetWidth(), m_pCxImage->GetHeight(), hdcBk, 0, 0, SRCCOPY);
  13. m_pCxImage->Draw(hMemDC, 0, 0);
  14. BitBlt(hdc, 0, 0, m_pCxImage->GetWidth(), m_pCxImage->GetHeight(), hMemDC, 0, 0, SRCCOPY);
  15. DeleteObject(SelectObject(hMemDC, oldBmp));
  16. DeleteDC(hMemDC);
  17. ReleaseDC(NULL,hdc);
  18. EndPaint(hWnd, &ps);
  19. break;
	 

得到的效果:

[转]cximage双缓冲绘图 .的更多相关文章

  1. MFC双缓冲绘图(2015.09.24)

    问题引入: 最近在尝试编写贪吃蛇游戏时遇到这么一个问题:当系统以较快频率向窗口发送WM_PAINT消息时,调用OnPaint()函数在窗口中绘制图形就会发生闪烁现象. 问题分析: 当我们把绘图过程放在 ...

  2. MFC双缓冲绘图实例

    本人之前一直了解双缓冲绘图的基本原理,但是在研究很久之后才大概知道具体的使用过程,本文将详细介绍本人在实际项目中使用双缓冲绘图的案例. 实现功能:主界面显示某张包含人脸的图片,通过dlib detec ...

  3. C#-gdi绘图,双缓冲绘图,Paint事件的触发

    一. 画面闪烁问题与双缓冲技术 1.1 导致画面闪烁的关键原因分析: 1  绘制窗口由于大小位置状态改变进行重绘操作时 绘图窗口内容或大小每改变一次,都要调用Paint事件进行重绘操作,该操作会使画面 ...

  4. 陈灯WGF双缓冲绘图框架

    “木丸子童屋”,专售各类儿童玩具,价格优惠,请大家多多支持:http://shop65552598.taobao.com/ WGF(windows graphic foundation)为window ...

  5. 双缓冲绘图和窗口控件的绘制——ATL ActiveX 窗口控件生成向导绘制代码OnDraw的一个错误 .

    双缓冲绘图和窗口控件的绘制 ---ATL ActiveX 窗口控件生成向导绘制代码OnDraw的一个错误 cheungmine 我们通常使用ATL COM组件,生成一个带窗口的ActiveX控件,然后 ...

  6. 简单的 "双缓冲" 绘图的例子(研究一下)

    所谓双缓冲就是先画到内存画布(如: TBitmap), 然后再转帖到目的地. 譬如下面小程序: procedure TForm1.FormCreate(Sender: TObject); begin ...

  7. mfc双缓冲绘图

    1.要求 在界面加载本地图片并显示,每过100ms改变一张图片显示 2.现象 通过定时器控制CImage,Load,Draw,Destroy,会非常的卡顿.因为Load图片时,会是非常大的数据[所有C ...

  8. 【MFC】MFC绘制动态曲线,用双缓冲绘图技术防闪烁

    摘自:http://zhy1987819.blog.163.com/blog/static/841427882011614103454335/ MFC绘制动态曲线,用双缓冲绘图技术防闪烁   2011 ...

  9. 简单的 "双缓冲" 绘图的例子

    http://www.cnblogs.com/del/archive/2010/04/19/1715779.html 所谓双缓冲就是先画到内存画布(如: TBitmap), 然后再转帖到目的地. 譬如 ...

随机推荐

  1. Ubuntu Server 命令行下的默认语言改为英语en_US.UTF-8

    源文链接:http://tonychiu.blog.51cto.com/656605/393131 如果Ubuntu Server在安装过程中,选择的是中文(很多新手都会在安装时选择中文,便于上手), ...

  2. TortoiseGit disconnected no supported authentication

    从远程服务器上获取到的工程,用Git没问题,而TortoiseGit报错: Disconnected: No supported authentication methods available(se ...

  3. 【ORA错误大全】 ORA-19527

    在做主备切换的时候,需要将备库的联机日志文件清除(clear online redo logfile),为了加快switchover的速度,Oracle10g在将备库置于manged standby状 ...

  4. poj1741(点分模板)

    #include<iostream> #include<cstring> #include<cmath> #include<cstdio> #inclu ...

  5. 周鸿祎与85后的座谈(一):人人需要Mentor,世界没有奇迹

    我们公司现在有将近 4000 人,我觉得里面肯定是卧虎藏龙.百里挑一的话,也有 40 个伟大的人才.但是,即使是天才,如果没有前辈的帮助,最后也会变成庸才,是做不出什么大事的.举例来说,每一个跳水冠军 ...

  6. hdu 4941 map的使用

    http://acm.hdu.edu.cn/showproblem.php?pid=4941 给定N,M和K,表示在一个N*M的棋盘上有K个棋子,给出K个棋子的位置和值,然后是Q次操作,对应的是: 1 ...

  7. SET FOREIGN_KEY_CHECKS=0;在Mysql中取消外键约束

      Mysql中如果表和表之间建立的外键约束,则无法删除表及修改表结构.   解决方法是在Mysql中取消外键约束:  SET FOREIGN_KEY_CHECKS=0;     然后将原来表的数据导 ...

  8. Python 高级编程——单例模式

    单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场. 在 Py ...

  9. WPF实现窗体中的悬浮按钮

    WPF实现窗体中的悬浮按钮,按钮可拖动,吸附停靠在窗体边缘. 控件XAML代码: <Button x:Class="SunCreate.Common.Controls.FloatBut ...

  10. 背水一战 Windows 10 (46) - 控件(ScrollViewer 基础): ScrollViewer, ScrollBar, ScrollContentPresenter

    [源码下载] 背水一战 Windows 10 (46) - 控件(ScrollViewer 基础): ScrollViewer, ScrollBar, ScrollContentPresenter 作 ...