www.pudn.com > virtualListview_demo.zip > MyListCtrl.cpp
// MyListCtrl.cpp : implementation file
//
#include "stdafx.h"
#include "listview_example.h"
#include "MyListCtrl.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CMyListCtrl
int column_sort = 0;
BOOL bSortAscending = FALSE;
CMyListCtrl::CMyListCtrl()
{
array = NULL;
count = 0;
max_items = 0;
}
CMyListCtrl::~CMyListCtrl()
{
}
BEGIN_MESSAGE_MAP(CMyListCtrl, CListCtrl)
//{{AFX_MSG_MAP(CMyListCtrl)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnclick)
ON_NOTIFY_REFLECT(LVN_GETDISPINFO, OnGetdispinfo)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMyListCtrl message handlers
//add a single item into the array for viewing
void CMyListCtrl::AddItem(DATA *item)
{
if(item == NULL)
return;
if(count >= max_items) //time to realloc() some more
{
//we'll ask for another 500 spaces
//You can realloc() more or less if you want.
//The obvious tradeoff is speed versus memory requirements.
DATA **tempptr;
int newmax;
newmax = max_items + 500;
tempptr = (DATA**)realloc(array, ((sizeof(DATA*)*newmax)));
if(tempptr == NULL)
{
MessageBox("Running out of memory...");
return;
}
array = tempptr;
max_items = newmax;
}
array[count++] = item;
//force redraw
SetItemCount(count);
}
//add x number of items into view
void CMyListCtrl::AddItem(DATA *front, int numToInsert)
{
if(front == NULL || numToInsert <= 0)
return;
int freespace = max_items - count;
//realloc() more if needed.
if(freespace < numToInsert)
{
int newmax = max_items + (numToInsert - freespace);
DATA **tempptr;
tempptr = (DATA**)realloc(array, ((sizeof(DATA*)*newmax)));
if(tempptr == NULL)
{
MessageBox("Running out of memory...");
return;
}
array = tempptr;
max_items = newmax;
}
int i;
DATA *tempptr = front;
//fill in array. if we made it this far, we have enough room in the array.
for(i = 0; i < numToInsert; i++)
{
array[count++] = tempptr;
tempptr = tempptr->next;
}
//force redraw
SetItemCount(count);
}
int CMyListCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CListCtrl::OnCreate(lpCreateStruct) == -1)
return -1;
//start off with enough room to hold 500 items. We will realloc() more room later as needed.
//for better performance gains (but more required memory) start off with a larger limit.
array = (DATA**)malloc(sizeof(DATA*) * 500);
if(array)
ZeroMemory(array, (sizeof(DATA*) * 500));
else
return -1;
max_items = 500;
return 0;
}
void CMyListCtrl::OnDestroy()
{
CListCtrl::OnDestroy();
if(array)
free(array);
}
//comparison function
int SortFunc(const void *v1, const void *v2)
{
DATA **nn1, **nn2, *n1, *n2;
int equal = 0;
nn1 = (DATA **)v1;
nn2 = (DATA **)v2;
n1 = (DATA*)*nn1;
n2 = (DATA*)*nn2;
if(n1 == NULL || n2 == NULL)
return 0;
switch(column_sort)
{
case 0:
equal = strcmp(n1->field1, n2->field1);
break;
case 1:
equal = strcmp(n1->field2, n2->field2);
break;
case 2:
equal = strcmp(n1->field3, n2->field3);
break;
}
if(bSortAscending == FALSE)
equal *= -1;
return equal;
}
//user clicked a column. sort by header in ascending or descending order
void CMyListCtrl::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
int clicked = pNMListView->iSubItem;
if(column_sort == clicked)
bSortAscending = !bSortAscending;
else
{
column_sort = clicked;
bSortAscending = TRUE;
}
qsort(array, count, sizeof(DATA*), SortFunc);
SetItemCount(count); //force redraw
*pResult = 0;
}
//Windows is asking for the text to display, at item(iItemIndex), subitem(pItem->iSubItem)
void CMyListCtrl::OnGetdispinfo(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
LV_ITEM* pItem= &(pDispInfo)->item;
int iItemIndex= pItem->iItem;
DATA *ptr = array[iItemIndex];
if(pItem->mask & LVIF_TEXT)
{
if(pItem->iSubItem == 0) //field 1
lstrcpyn(pItem->pszText, ptr->field1, pItem->cchTextMax);
else
if(pItem->iSubItem == 1) //field 2
lstrcpyn(pItem->pszText, ptr->field2, pItem->cchTextMax);
else
if(pItem->iSubItem == 2) //field 3
lstrcpyn(pItem->pszText, ptr->field3, pItem->cchTextMax);
}
*pResult = 0;
}