⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 listviewnoflicker.h

📁 These listed libraries are written in WTL. But it s really hard to mix both MFC & WTL together. Obvi
💻 H
字号:

#ifndef __LIST_VIEW_NO_FLICKER_H__
#define __LIST_VIEW_NO_FLICKER_H__

// CListViewNoFlickerT is meant as a mix-in class to
//  help reduce flicker of a SysListView32.
//
// You can use CListViewNoFlickerT for a class that is
//  superclassing or subclassing a SysListView32.
//
// You can use CListViewNoFlicker as-is if you don't
//  need to specialize the list view

// If you can require Windows XP at a minimum, you should
//  use the extended style LVS_EX_DOUBLEBUFFER instead.
//  LVS_EX_DOUBLEBUFFER will also give you an alpha-blended
//  drag selection like windows explorer has in its file list views.

#ifndef __ATLAPP_H__
  #error ListViewNoFlicker.h requires atlapp.h to be included first
#endif

#ifndef __ATLGDIX_H__
  #error ListViewNoFlicker.h requires atlgdix.h to be included first
#endif

template <class T>
class CListViewNoFlickerT
{
protected:
	typedef CListViewNoFlickerT<T> thisClass;

protected:
	ATL::CWindow m_headerCtrl;

public:
	CListViewNoFlickerT() : m_headerCtrl(NULL)
	{
	}

	// We don't have a virtual destructor because this is a mix-in class
	~CListViewNoFlickerT()
	{
	}

public:
	// Call in WM_CREATE handler or SubclassWindow
	void Initialize(HWND hWndHeaderCtrl)
	{
		m_headerCtrl = hWndHeaderCtrl;
	}

	// Call in WM_DESTROY handler or UnsubclassWindow
	void Uninitialize(void)
	{
		m_headerCtrl = NULL;
	}

public:
	BEGIN_MSG_MAP(thisClass)
	ALT_MSG_MAP(1)
		MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
		MESSAGE_HANDLER(WM_PAINT, OnPaint)
		MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
	END_MSG_MAP()

	LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		// Erase the background in OnPaint.
		// This is part of the key to flicker free drawing.
		return 1;
	}

	LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		T* pT = static_cast<T*>(this);
		if( wParam != NULL )
		{
			WTL::CMemDC memdc((HDC)wParam, NULL);
			pT->DoPaint(memdc.m_hDC, memdc.m_rc);
		}
		else
		{
			WTL::CPaintDC dc(pT->m_hWnd);
			WTL::CMemDC memdc(dc.m_hDC, &dc.m_ps.rcPaint);
			pT->DoPaint(memdc.m_hDC, dc.m_ps.rcPaint);
		}
		return 0;
	}

	inline void DoPaint(WTL::CDCHandle dc, RECT& rcClip)
	{
		T* pT = static_cast<T*>(this);

		if(m_headerCtrl.IsWindow())
		{
			// Draw the header first
			m_headerCtrl.SendMessage(WM_ERASEBKGND, (WPARAM)(HDC)dc, 0);
			m_headerCtrl.SendMessage(WM_PAINT, (WPARAM)(HDC)dc, 0);
			m_headerCtrl.ValidateRect(&rcClip);

			// Prevent the header being drawn over
			CRect rcHeader;
			m_headerCtrl.GetClientRect(&rcHeader);
			dc.ExcludeClipRect(&rcHeader);
		}

		// Now draw the listview
		pT->DefWindowProc(WM_ERASEBKGND, (WPARAM)(HDC)dc, 0);
		pT->DefWindowProc(WM_PAINT, (WPARAM)(HDC)dc, 0);
	}

};

typedef CWinTraits<
			WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
			LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS,
			WS_EX_CLIENTEDGE> CListViewNoFlickerWinTraits;

class CListViewNoFlicker :
	public CWindowImpl<CListViewNoFlicker, CListViewCtrl, CListViewNoFlickerWinTraits>,
	public CListViewNoFlickerT<CListViewNoFlicker>
{
protected:
	typedef CListViewNoFlicker thisClass;
	typedef CWindowImpl<CListViewNoFlicker, CListViewCtrl, CListViewNoFlickerWinTraits> baseClass;
	typedef CListViewNoFlickerT<CListViewNoFlicker> noFlickerClass;

// Constructors
public:
	CListViewNoFlicker() { }

// Base Class overrides
public:
	BOOL SubclassWindow(HWND hWnd)
	{
		BOOL bRet = baseClass::SubclassWindow(hWnd);
		if(bRet)
		{
			noFlickerClass::Initialize(this->GetHeader());
		}
		return bRet;
	}

	HWND UnsubclassWindow(BOOL bForce = FALSE)
	{
		noFlickerClass::Uninitialize();

		return baseClass::UnsubclassWindow(bForce);
	}

// Message Handling
public:
	BEGIN_MSG_MAP(thisClass)
		MESSAGE_HANDLER(WM_CREATE, OnCreate)
		MESSAGE_HANDLER(WM_DESTROY, OnDestroy)

		CHAIN_MSG_MAP_ALT(noFlickerClass, 1)
		DEFAULT_REFLECTION_HANDLER()  // Just in case
	END_MSG_MAP()

	LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		LRESULT lRet = DefWindowProc(uMsg, wParam, lParam);

		noFlickerClass::Initialize(this->GetHeader());

		// We've already called DefWindowProc
		bHandled = TRUE;

		return lRet;
	}

	LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
		noFlickerClass::Uninitialize();

		// Let anyone else (including DefWindowProc) see the message
		bHandled = FALSE;
		return 0;
	}
};

#endif //__LIST_VIEW_NO_FLICKER_H__

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -