WTL使用双缓冲避免重绘闪烁
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使用双缓冲避免重绘闪烁的更多相关文章
- [转载] MFC绘制动态曲线,用双缓冲绘图技术防闪烁
转载的原文地址 先上效果图 随着时间的推移,曲线向右平移,同时X轴的时间坐标跟着更新. 一.如何绘制动态曲线 所谓动画,都是一帧一帧的图像连续呈现在用户面前形成的.所以如果你掌握了如何绘制静态曲线,那 ...
- 【MFC】MFC绘制动态曲线,用双缓冲绘图技术防闪烁
摘自:http://zhy1987819.blog.163.com/blog/static/841427882011614103454335/ MFC绘制动态曲线,用双缓冲绘图技术防闪烁 2011 ...
- MFC双缓冲解决图象闪烁[转]
转载网上找到的一篇双缓冲的文章,很好用.http://www.cnblogs.com/piggger/archive/2009/05/02/1447917.html__________________ ...
- Duilib的双缓冲实现,附带GDI、WTL的双缓冲实现
前言: 闪烁问题,之前的经验是使用双缓冲,借此机会,把双缓冲的研究心得总结下. 双缓冲的含义: 缓冲这个词,相信大家都不陌生,Cache.主要是为了解决上下游(或者模块.或者系统)等性能不匹配问题.如 ...
- (Winform)控件中添加GIF图片以及运用双缓冲使其不闪烁以及背景是gif时使控件(如panel)变透明
Image img = Image.FromFile(@"C:\Users\joeymary\Desktop\3.gif"); pictureBox1.Image =img.Clo ...
- Winfrom 减少控件重绘闪烁的方法
Winform控件的双缓冲.控件的双缓冲属性是隐藏的,可以通过反射改变其属性值. lv.GetType().GetProperty("DoubleBuffered", Bindin ...
- Winform解决界面重绘闪烁的问题
在窗体或用户控件中重写CreateParams protected override CreateParams CreateParams { get { CreateParams cp = base. ...
- 强制设置双缓冲DoubleBuffered 解决tableLayoutPanel 闪烁
tableLayoutPanel.GetType().GetProperty("DoubleBuffered", System.Reflection.BindingFlags.In ...
- VC使用双缓冲避免绘图闪烁的正确使用方法【转】
使用内存DC绘图,然后实现双缓冲,避免绘图闪烁,这个小技术简单但很有效.但是仍然有很多人说使用了双缓冲,图片却仍然有闪烁,分析了几个这样的例子,发现 其实不是双缓冲的技术问题,而是使用者没有正确理解和 ...
随机推荐
- Redo与Undo的理解
本文概要本文的原意是一篇个人学习笔记,为了避免成为草草记录一下的流水账,尝试从给人介绍的角度开写.但在整理的过程中,越来越感觉力不从心,一是细节太多了,原以为足够了解的一个小知识点下可能隐藏了很多细节 ...
- linux 双Redis + keepalived 主从复制+宕机自主切换
主要核心思想,如果master 和 salve 全部存活的情况,VIP就漂移到 master.读写都从master操作,如果master宕机,VIP就会漂移到salve,并将之前的salve切换为ma ...
- 开源工具abaplint的介绍
长期以来,SAP提供的标准ABAP开发工具是我们对代码进行检查的唯一方式.这意味着我们只能对ABAP服务器上的ABAP代码做出分析,而离线代码则成为了纯粹的文本,开发者无法对其进行检查.abaplin ...
- # "可插拔式"组件设计,领略组件开发的奥秘
从一个 Confirm 组件开始,一步步写一个可插拔式的组件. 处理一个正常的支付流程(比如支付宝购买基金) 点击购买按钮 如果风险等级不匹配则:弹确认框(Confirm) 用户确认风险后:弹出支付方 ...
- hutool BigExcelWriter 下的autoSizeColumnAll异常问题
autoSizeColumnAll java.lang.IllegalStateException: Could not auto-size column. Make sure the column ...
- Django之form组件自动校验数据
目录 一.form介绍 二.普通方式手写注册功能 views.py register.html 三.使用form组件实现注册功能 views.py register2.html 四.pycharm的专 ...
- JUnit 5和Selenium基础(二)
使用Selenium内置的PageFactory实现页面对象模式 在这一部分中,将通过Selenium的内置PageFactory支持类来介绍Page Object模式的实现.PageFactory提 ...
- Go 每日一库之 cobra
简介 cobra是一个命令行程序库,可以用来编写命令行程序.同时,它也提供了一个脚手架, 用于生成基于 cobra 的应用程序框架.非常多知名的开源项目使用了 cobra 库构建命令行,如Kubern ...
- 美团codem 数列互质 - 莫队
题目描述 给出一个长度为 nnn 的数列 a1,a2,a3,...,an{ a_1 , a_2 , a_3 , ... , a_n }a1,a2,a3,...,an,以及 mm ...
- NETCore下IConfiguration和IOptions的用法
NETCore下IConfiguration和IOptions的用法 https://www.cnblogs.com/RainingNight/p/strongly-typed-options-con ...