Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

Owner Drawn ListViews In WTL

, 26 Jun 2004
An overview of handling owner drawn listview controls in WTL.
// (C) 2004 - Mark Petrik Sosa

#pragma once
#include "stdafx.h"

template <class TBase>
class COwnerDrawnListViewCtrl : public CWindowImpl<TBase, CListViewCtrl>,
								public COwnerDraw<TBase>
{
public:
	BEGIN_MSG_MAP(COwnerDrawnListViewCtrl)
		CHAIN_MSG_MAP_ALT(COwnerDraw<TBase>, 1)
		DEFAULT_REFLECTION_HANDLER()
	END_MSG_MAP()

	// If this control was .SubclassWindowed instead of .Create(Xe)d, then it 
	// will not receive a WM_MEASUREITEM since this message occurs before 
	// WM_INITDIALOG. By moving the window we can get windows to generate
	// another one for us.
	// ---------------------------------------------------------------------
	void ForceMeasureItemMessage()
	{
		// I just want to nudge it up a little.
		CRect window_rect;
		GetWindowRect(&window_rect);
		CPoint pt = window_rect.TopLeft();
		::ScreenToClient(GetParent(), &pt);
		window_rect.right = pt.x + window_rect.Width();
		window_rect.left = pt.x;
		window_rect.bottom = pt.y + window_rect.Height();
		window_rect.top = pt.y + 1;
		MoveWindow(window_rect);

		// Alright now move it back.
		window_rect.top = pt.y;
		MoveWindow(window_rect);
	}

	// We are required to have this empty DeleteItem to avoid ambiguity issues
	// with COwnderDraw::DeleteItem and CListViewCtrl::DeleteItem.
	// ---------------------------------------------------------------------
	void DeleteItem(LPDELETEITEMSTRUCT /*lpDeleteItemStruct*/) {};

	void GetCellRect(int header_column, const CRect& item_rect, CRect& cell_rect)
	{
		CHeaderCtrl header = GetHeader();
		CRect header_rect;
		header.GetItemRect(header_column, &header_rect);

		// If we don't do this, when we scroll to the right, we will be 
		// drawing as if we weren't and your cells won't line up with the
		// columns.
		int x_offset = -GetScrollPos(SB_HORZ);

		cell_rect.left = x_offset + header_rect.left;
		cell_rect.right = x_offset + header_rect.right;
		cell_rect.top = item_rect.top;
		cell_rect.bottom = item_rect.bottom;
	}

	// These are the functions you can overload in your class for Owner Drawing.
	// You will need to at least handle DrawItem().
	// If your going to use MeasureItem, make sure you call 
	// ForceMeasureItemMessage if you didn't create it yourself
	// ---------------------------------------------------------------------
	//void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/)
	//void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
	//int CompareItem(LPCOMPAREITEMSTRUCT /*lpCompareItemStruct*/)
	//void DeleteItem(LPDELETEITEMSTRUCT /*lpDeleteItemStruct*/)
};

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Mark Petrik

United States United States
No Biography provided

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.141223.1 | Last Updated 27 Jun 2004
Article Copyright 2004 by Mark Petrik
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid