1、继承自CDoubleBufferImpl

template <class T>
class CDoubleBufferImpl
{
public:
// Overrideables
void DoPaint(CDCHandle /*dc*/)
{
// must be implemented in a derived class
ATLASSERT(FALSE);
} // Message map and handlers
BEGIN_MSG_MAP(CDoubleBufferImpl)
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
MESSAGE_HANDLER(WM_PAINT, OnPaint)
#ifndef _WIN32_WCE
MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
#endif // !_WIN32_WCE
END_MSG_MAP() LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
return 1; // no background painting needed
} LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd)); if(wParam != NULL)
{
RECT rect = { 0 };
pT->GetClientRect(&rect);
CMemoryDC dcMem((HDC)wParam, rect);
pT->DoPaint(dcMem.m_hDC);
}
else
{
CPaintDC dc(pT->m_hWnd);
CMemoryDC dcMem(dc.m_hDC, dc.m_ps.rcPaint);
pT->DoPaint(dcMem.m_hDC);
} return 0;
}
};

2、添加消息映射

CHAIN_MSG_MAP(CDoubleBufferImpl<CMainDlg>)

3、增加DoPaint函数void DoPaint(CDCHandle dc);

4、将OnPaint的代码应用于DoPaint即可

完整代码:

MainDlg.h

// MainDlg.h : interface of the CMainDlg class
//
///////////////////////////////////////////////////////////////////////////// #pragma once class CMainDlg : public CDialogImpl<CMainDlg>, public CDoubleBufferImpl<CMainDlg>
{
public:
enum { IDD = IDD_MAINDLG }; BEGIN_MSG_MAP(CMainDlg)
CHAIN_MSG_MAP(CDoubleBufferImpl<CMainDlg>)
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
MESSAGE_HANDLER(WM_SIZE, OnSize)
//MESSAGE_HANDLER(WM_PAINT, OnPaint)
COMMAND_ID_HANDLER(IDCANCEL, OnCancel)
END_MSG_MAP() // Handler prototypes (uncomment arguments if needed):
// LRESULT MessageHandler(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
// LRESULT CommandHandler(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
// LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/) LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
LRESULT OnCancel(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
//LRESULT OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
void DoPaint(CDCHandle dc);
};

MainDlg.cpp

// MainDlg.cpp : implementation of the CMainDlg class
//
///////////////////////////////////////////////////////////////////////////// #include "stdafx.h"
#include "resource.h"
#include "MainDlg.h"
#include <atlimage.h>
#include <time.h>
#include <gdiplus.h>
#pragma comment (lib,"Gdiplus.lib")
using namespace Gdiplus;
ULONG_PTR gdiplusToken; LRESULT CMainDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
// center the dialog on the screen
CenterWindow(); // set icons
HICON hIcon = AtlLoadIconImage(IDR_MAINFRAME, LR_DEFAULTCOLOR, ::GetSystemMetrics(SM_CXICON), ::GetSystemMetrics(SM_CYICON));
SetIcon(hIcon, TRUE);
HICON hIconSmall = AtlLoadIconImage(IDR_MAINFRAME, LR_DEFAULTCOLOR, ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON));
SetIcon(hIconSmall, FALSE); GdiplusStartupInput gdiplusStartupInput;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); return TRUE;
} LRESULT CMainDlg::OnCancel(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
EndDialog(wID);
GdiplusShutdown(gdiplusToken);
return 0;
} //LRESULT CMainDlg::OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
//{
/*
srand((unsigned)time(NULL));
CPaintDC dc(this->m_hWnd);
CBrush brush;
CRect rect;
GetClientRect(&rect);
InvalidateRect(&rect, FALSE);
brush.CreateSolidBrush(RGB(rand() % 255, rand() % 255, rand() % 255));
dc.FillRect(&rect, brush);
*/ //RECT rect;
//获得客户区坐标
//GetClientRect(&rect);
//Graphics作图对象
//Graphics g(m_hWnd); //画线
/*
Pen pen(Color(255, 0, 0, 0), 15);
g.DrawLine(&pen, rect.left, rect.top, rect.right, rect.bottom);
g.DrawLine(&pen, rect.left, rect.bottom, rect.right, rect.top);
*/ //画字符串
/*
SolidBrush brush(Color(255, 0, 0, 255));
FontFamily fontFamily(TEXT("Times New Roman"));
Font font(&fontFamily, 24, FontStyleRegular, UnitPixel);
PointF pt(10.0f, 10.0f);
g.DrawString(L"Hello World", -1, &font, pt, &brush);
*/ //画矩形
/*
Pen pen(Color(255, 0, 255, 0));
while (rect.left < rect.right && rect.top < rect.bottom)
{
g.DrawRectangle(&pen, rect.left, rect.top, rect.right, rect.bottom);
rect.left += 5;
rect.top += 5;
rect.right -= 10;
rect.bottom -= 10;
}
*/ //填充矩形
/*
SolidBrush brush(Color(255, 0, 255, 0));
brush.SetColor(Color(255, 0, 0, 255));
g.FillRectangle(&brush, rect.left, rect.top, rect.right, rect.bottom);
*/
//Image img(L"ing.png");
//g.DrawImage(&img, rect.left, rect.top, rect.right, rect.bottom); //return TRUE;
//} void CMainDlg::DoPaint(CDCHandle dc)
{
RECT rect;
GetClientRect(&rect);
//Graphics g(m_hWnd);
//Graphics g(dc.m_hDC);
Graphics g(dc); Image img(L"forever.bmp");
g.DrawImage(&img, rect.left, rect.top, rect.right, rect.bottom);
} LRESULT CMainDlg::OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
RedrawWindow();
return TRUE;
}

copy /b src.png + src.rar dest.png

完整代码将上面图片保存本地,改为rar格式即可获得

WTL使用双缓冲避免重绘闪烁的更多相关文章

  1. [转载] MFC绘制动态曲线,用双缓冲绘图技术防闪烁

    转载的原文地址 先上效果图 随着时间的推移,曲线向右平移,同时X轴的时间坐标跟着更新. 一.如何绘制动态曲线 所谓动画,都是一帧一帧的图像连续呈现在用户面前形成的.所以如果你掌握了如何绘制静态曲线,那 ...

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

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

  3. MFC双缓冲解决图象闪烁[转]

    转载网上找到的一篇双缓冲的文章,很好用.http://www.cnblogs.com/piggger/archive/2009/05/02/1447917.html__________________ ...

  4. Duilib的双缓冲实现,附带GDI、WTL的双缓冲实现

    前言: 闪烁问题,之前的经验是使用双缓冲,借此机会,把双缓冲的研究心得总结下. 双缓冲的含义: 缓冲这个词,相信大家都不陌生,Cache.主要是为了解决上下游(或者模块.或者系统)等性能不匹配问题.如 ...

  5. (Winform)控件中添加GIF图片以及运用双缓冲使其不闪烁以及背景是gif时使控件(如panel)变透明

    Image img = Image.FromFile(@"C:\Users\joeymary\Desktop\3.gif"); pictureBox1.Image =img.Clo ...

  6. Winfrom 减少控件重绘闪烁的方法

    Winform控件的双缓冲.控件的双缓冲属性是隐藏的,可以通过反射改变其属性值. lv.GetType().GetProperty("DoubleBuffered", Bindin ...

  7. Winform解决界面重绘闪烁的问题

    在窗体或用户控件中重写CreateParams protected override CreateParams CreateParams { get { CreateParams cp = base. ...

  8. 强制设置双缓冲DoubleBuffered 解决tableLayoutPanel 闪烁

    tableLayoutPanel.GetType().GetProperty("DoubleBuffered", System.Reflection.BindingFlags.In ...

  9. VC使用双缓冲避免绘图闪烁的正确使用方法【转】

    使用内存DC绘图,然后实现双缓冲,避免绘图闪烁,这个小技术简单但很有效.但是仍然有很多人说使用了双缓冲,图片却仍然有闪烁,分析了几个这样的例子,发现 其实不是双缓冲的技术问题,而是使用者没有正确理解和 ...

随机推荐

  1. Django 链接MySQL及数据操作

    Django 链接MySQL Django创建的项目自带的数据库是SQLite3,我们想要链接MySQL的话,需要更改settings.py中的配置 1.在MySQL中创建好数据库,Django项目不 ...

  2. 1037 在霍格沃茨找零钱 (20 分)C语言

    题目描述 如果你是哈利·波特迷,你会知道魔法世界有它自己的货币系统 -- 就如海格告诉哈利的:"十七个银西可(Sickle)兑一个加隆(Galleon),二 十九个纳特(Knut)兑一个西可 ...

  3. 2019 年百度之星 初赛一 1002 Game

    传送门 Problem Description 度度熊在玩一个好玩的游戏.游戏的主人公站在一根数轴上,他可以在数轴上任意移动,对于每次移动,他可以选择往左或往右走一格或两格.现在他要依次完成 n 个任 ...

  4. 视频分片上传+C#后端合并

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. “云”端的语雀:用 JavaScript 全栈打造商业级应用

    作者|  不四(死马)蚂蚁金服 语雀产品技术负责人 语雀是什么? 语雀是一个专业的云端知识库,面向个人和团队,提供与众不同的知识管理,打造轻松流畅的工作协同,它提供各种格式的在线文档(富文本.表格.设 ...

  6. JVM性能优化系列-(2) 垃圾收集器与内存分配策略

    2. 垃圾收集器与内存分配策略 垃圾收集(Garbage Collection, GC)是JVM实现里非常重要的一环,JVM成熟的内存动态分配与回收技术使Java(当然还有其他运行在JVM上的语言,如 ...

  7. BigDecimal的加减乘除,比较,小数保留

    关于BigDecimal的一些常用基本操作记录 1        BigDecimal b1 = new BigDecimal("1.124"); 2        BigDeci ...

  8. Vue 例子

    一.简单音乐播放器 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  9. 缓存读写策略 - Cache Aside.md

    场景描述 比如一条数据同时存在数据库.缓存,现在你要更新此数据,你会怎么更新? 先更新数据库?还是先更新缓存? 其实这两种方式都有问题. (1)先更新数据库,后更新缓存 这样会造成数据不一致. A 先 ...

  10. Redis(四):del/unlink 命令源码解析

    上一篇文章从根本上理解了set/get的处理过程,相当于理解了 增.改.查的过程,现在就差一个删了.本篇我们来看一下删除过程. 对于客户端来说,删除操作无需区分何种数据类型,只管进行 del 操作即可 ...