• 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格式即可获得

    Keep it simple!
    作者:N3verL4nd
    知识共享,欢迎转载。
  • 相关阅读:
    零元尝鲜|阿里云 Grafana 商业化服务正式发布
    报名进入尾声,赶快申请加入 sealer 开源之夏吧!
    阿里巴巴在 Envoy Gateway 的演进历程浅析
    Nacos 开源之夏 2022 来了
    从“预见”到“遇见” | SAE 引领应用步入 Serverless 全托管新时代
    OpenClusterManagement 开源之夏 2022 来了
    阿里云“大算力”支持嬴彻自动驾驶仿真提速 20 倍
    开源夜聊栏目开播:聊聊新晋 CNCF 项目 sealer 背后的故事
    最佳实践|从Producer 到 Consumer,如何有效监控 Kafka
    阿里云性能测试 PTS 4 月新功能
  • 原文地址:https://www.cnblogs.com/lgh1992314/p/6616340.html
Copyright © 2020-2023  润新知