Click here to Skip to main content
15,886,067 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
When i draw listview i encountered a problem.

I have a class derived from wtl CListViewCtrl and I am doing all paint by myself.

when select item, the selected item's background Highlight and other normal.

All item is fine except the first item.

I find the problem is when mouse down on the first item, the first item's rect not int clipbox, so when mouse down, the first item not Invalidate();
but other is ok.
#ifndef _SKINX_LISTVIEW_H_
#define _SKINX_LISTVIEW_H_

#pragma	once

template< class T, class TBase = CListViewCtrl, class TWinTraits = ATL::CControlWinTraits >
class CSkinXListViewImpl : public CWindowImpl< T, TBase, TWinTraits >
{
public:

	void Initialize()
	{
		m_clrLine = RGB(238,238,238);
		m_clrBackGround = RGB(255,255,255);
		m_clrSelected = RGB(173,195,231);
	}

	BOOL SubclassWindow(HWND hWnd)
	{
		ATLASSERT(m_hWnd == NULL);
		ATLASSERT(::IsWindow(hWnd));

		BOOL bRet = CWindowImpl< T, TBase, TWinTraits >::SubclassWindow(hWnd);
		if( bRet ) Initialize();
		return bRet;
	}

	BEGIN_MSG_MAP(CSkinXListViewImpl)
		MESSAGE_HANDLER(WM_CREATE, OnCreate)
		MESSAGE_HANDLER(WM_PAINT, OnPaint)
		MESSAGE_HANDLER(WM_NCPAINT, OnNcPaint)
		MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
		MESSAGE_HANDLER(WM_WINDOWPOSCHANGED, OnNcCalcSize)
		MESSAGE_HANDLER(WM_NCCALCSIZE, OnNcCalcSize)
	END_MSG_MAP()

	LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		LRESULT lRes = DefWindowProc();
		Initialize();
		return lRes;
	}
	LRESULT OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled){
		CPaintDC dc(m_hWnd);
		RECT rcClient;
		GetClientRect(&rcClient);

		HBRUSH hBrushBackGround = CreateSolidBrush(m_clrBackGround);
		dc.FillRect(&rcClient, hBrushBackGround);
		DeleteObject(hBrushBackGround);

		int n = GetItemCount();
		for(int nItem = 0; nItem < n; nItem++){
			RECT rcItem;
			GetItemRect(nItem, &rcItem, LVIR_BOUNDS);

			if (GetItemState(nItem, LVIS_SELECTED)){
				HBRUSH hBrushItem = CreateSolidBrush(m_clrSelected);
				dc.FillRect(&rcItem, hBrushItem);
				DeleteObject(hBrushItem);
			}

			int nSubCount = GetColumnCount();
			for(int nSubItem = 0; nSubItem < nSubCount; nSubItem++){
				CString str;
				GetItemText(nItem, nSubItem, str);

				RECT rcSubColumn, rcSubItem;
				GetColumnItemRect(nSubItem, &rcSubColumn);
				rcSubItem = rcItem;
				rcSubItem.left = rcSubColumn.left;
				rcSubItem.right = rcSubColumn.right;

				dc.SetBkMode(TRANSPARENT);
				HFONT hOldFont = dc.SelectFont(GetCtrlFont());
				dc.DrawText( str, -1, &rcSubItem, DT_SINGLELINE | DT_VCENTER);
				dc.SelectFont(hOldFont);
			}

			RECT rcLine = { rcItem.left, rcItem.bottom - 1, rcItem.right, rcItem.bottom - 1 };

			HPEN hPen = CreatePen(PS_SOLID, 1, m_clrLine);
			HPEN hOldPen = dc.SelectPen(hPen);
			dc.MoveTo(rcLine.left, rcLine.top);
			dc.LineTo(rcLine.right, rcLine.bottom);
			dc.SelectPen(hOldPen);

			DeleteObject(hPen);
		}

		return 0;
	}
	LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		return 1; // handled; no need to erase background; do it in DoPaint();
	}
	LRESULT OnNcPaint(UINT uMsg, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		CWindowDC dc(m_hWnd);

		//DefWindowProc();

		RECT rcClient, rcWindow;
		GetWindowRect(&rcWindow);
		ScreenToClient(&rcWindow);

		GetClientRect(&rcClient);

		rcWindow.left += 3;
		rcWindow.top += 3;
		rcWindow.bottom += 1;
		rcWindow.right += 1;

		HPEN hPen = ::CreatePen(PS_SOLID, 1, RGB(255,0,0));
		HPEN hOldPen = dc.SelectPen(hPen);
		dc.Rectangle(&rcWindow);
		dc.SelectPen(hOldPen);
		DeleteObject(hPen);

		Invalidate();
		UpdateWindow();


		return 0;
	}
	LRESULT OnNcCalcSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/){
		UpdateWindow();
		DefWindowProc();
		return 0;
	}

	HFONT GetCtrlFont()
	{
		HFONT hFont;
		if ( (hFont = (HFONT)::SendMessage(m_hWnd,WM_GETFONT,0,0))==NULL)
			hFont = (HFONT)::GetStockObject(SYSTEM_FONT);

		return hFont;
	}
	int GetColumnCount()
	{
		CHeaderCtrl HeaderCtrl = GetHeader();
		return HeaderCtrl.GetItemCount();
	}
	BOOL GetColumnItemRect(int nIndex, LPRECT lpItemRect){
		CHeaderCtrl HeaderCtrl = GetHeader();
		return HeaderCtrl.GetItemRect(nIndex, lpItemRect);
	}
private:
	COLORREF			m_clrLine;
	COLORREF			m_clrBackGround;
	COLORREF			m_clrSelected;
};
class CListViewCtrlX : public CSkinXListViewImpl<CListViewCtrlX>
{
public:
	DECLARE_WND_SUPERCLASS(_T("WTL_CListViewCtrlX"), GetWndClassName())  
};
#endif //_SKINX_LISTVIEW_H_
Posted
Updated 26-Jun-10 2:08am
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900