我有一个刷新列表的函数ShowAll():
void CListPaneView::ShowAll()
{
//////////////////////////////////////////////////////////////////////////
// Open recordset
int iNum = 0;
CListCtrl &List = GetListCtrl();
List.DeleteAllItems();
CMainFrame *pMainFrm = (CMainFrame*) AfxGetMainWnd();
CString strSQL = "select * from dms";
if (!OpenRecordSet(m_pRecordset, strSQL)) {
AfxMessageBox("无法打开数据库");
return;
}
m_pRecordset->MoveFirst();
while (!m_pRecordset->adoEOF) {
//////////////////////////////////////////////////////////////////////////
// prepare to input value to cellsCString strNumber, strName, strIDNumber, strGender, strAddress, strAge, strModifyTime;
COleDateTime oleBirthdate, oleModifyTime;
COleDateTime oleCurrentTime = COleDateTime::GetCurrentTime();
strName = pMainFrm->VariantToCString(m_pRecordset->GetCollect("姓名"));
strIDNumber = pMainFrm->VariantToCString(m_pRecordset->GetCollect("居民证号码"));
strAddress = pMainFrm->VariantToCString(m_pRecordset->GetCollect("常住地址"));
strGender =  pMainFrm->VariantToCString(m_pRecordset->GetCollect("性别"));
oleBirthdate = m_pRecordset->GetCollect("出生日期");
oleModifyTime = m_pRecordset->GetCollect("记录修改时间");
iNum++;
strNumber.Format("%d", iNum);
int iAge = oleCurrentTime.GetYear() - oleBirthdate.GetYear();
strAge.Format("%d", iAge);
strModifyTime.Format("%d年%d月%d日", oleModifyTime.GetYear(), oleModifyTime.GetMonth(), oleModifyTime.GetDay());
// start!
List.InsertItem(iNum, strNumber);  //序号
List.SetItemText(iNum, 1, strName); //姓名
List.SetItemText(iNum, 2, strAge); //年龄
List.SetItemText(iNum, 3, strGender); //性别
List.SetItemText(iNum, 4, strIDNumber); // 身份证号码
List.SetItemText(iNum, 5, strAddress); //地址
List.SetItemText(iNum, 6, strModifyTime); //最后修改时间
iNum++;
m_pRecordset->MoveNext();
}

这个函数用于刷新列表。对于排序的操作的代码,有两个函数OnColumnclk()和回调函数
ListViewCompareFunc():void CListPaneView::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult) 
{

// TODO: Add your control notification handler code here
static int ncurSortCol; // 保存当前的排序列。
// 一开始表示为-1,表示尚未按任何列排序。 NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
CListCtrl* lc = &GetListCtrl();
LONG ws = GetWindowLong(lc->m_hWnd, GWL_STYLE);
int nSortOrder; // 排序的方式

// 若点击列与当前排序列不同的列,则改变排序序,并将排序方式改为增序。
// 若当前排序列与点击列相同,则更改增、减序的排序方式
if (ncurSortCol == pNMListView->iSubItem)
{
if (ws & LVS_SORTASCENDING)
{
ws ^= LVS_SORTASCENDING;
nSortOrder = LVS_SORTDESCENDING;
}
else
{
ws ^= LVS_SORTDESCENDING;
nSortOrder = LVS_SORTASCENDING;
}
}
else
{
if (ws & LVS_SORTASCENDING)
ncurSortCol = pNMListView->iSubItem;
if (ws & LVS_SORTASCENDING)
nSortOrder = LVS_SORTASCENDING;
else
nSortOrder = LVS_SORTDESCENDING;
}
ncurSortCol = pNMListView->iSubItem;
// 将当前的排序信息保存在窗口Style中,供以后使用
ws |= nSortOrder;
SetWindowLong(lc->m_hWnd, GWL_STYLE, ws);

// 将各ITEM的LPARAM用新排序列的内容替换
LVITEM li;
li.mask = LVIF_PARAM|LVIF_TEXT|0x0200;
TCHAR szItemText[1024];
for (int i = 0; i < lc->GetItemCount(); i++)
{
li.iItem = i;
li.iSubItem = ncurSortCol;
li.cchTextMax = 1024;
li.pszText = szItemText;
lc->GetItem(&li); //之后li要有相关的数据.
  TCHAR * szlparam = (TCHAR *)li.lParam;
/*ASSERT(szlparam != NULL);*/
if (szlparam != NULL)
// 删除以前的信息,释放空间
// 添加List Item时应注意将lParam初始化NULL
delete szlparam;

// 复制当前列的szItemText到Item的lParam中
szlparam = new TCHAR[lstrlen(szItemText) + 1];
lstrcpy(szlparam, szItemText);
lc->SetItemData(i, (DWORD)szlparam);
}
// 开始排序
GetListCtrl().SortItems(ListViewCompareFunc,(LPARAM) (&nSortOrder));
*pResult = 0;
}
以及回调函数:int CALLBACK CListPaneView::ListViewCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
// 得到排序方式
int * pisortorder = (int *)lParamSort;

// 得到两个列的排序信息
TCHAR * sz1 = (TCHAR *)lParam1;
TCHAR * sz2 = (TCHAR *)lParam2;
// 比较列的信息并返回比较结果。
// 若为减序,则将比较结果乘上-1。
if (* pisortorder == LVS_SORTASCENDING)
return lstrcmp(sz1, sz2);
else
return lstrcmp(sz1, sz2) * (-1);
}
排序的操作只是对栏目上的文字进行排序和显示吧?可是为什么当我经过若干排序操作后,再次刷新列表的时候,,只显示最后一条数据了。数据库的数据还在,但是怎么再次调用我的刷新函数ShowAll()都不能显示全部的数据,只有最后一条。
不知道问题出在什么地方,有经验的朋友帮帮我,好吗?感激不尽。

解决方案 »

  1.   

    说明一下,void CListPaneView::ShowAll()
    {
    //////////////////////////////////////////////////////////////////////////
    // Open recordset
    int iNum = 0;
    CListCtrl &List = GetListCtrl();
    List.DeleteAllItems();
    CMainFrame *pMainFrm = (CMainFrame*) AfxGetMainWnd();
    CString strSQL = "select * from dms";
    if (!OpenRecordSet(m_pRecordset, strSQL)) {
    AfxMessageBox("无法打开数据库");
    return;
    }
    m_pRecordset->MoveFirst();
    while (!m_pRecordset->adoEOF) {
    //////////////////////////////////////////////////////////////////////////
    // prepare to input value to cellsCString strNumber, strName, strIDNumber, strGender, strAddress, strAge, strModifyTime;
    COleDateTime oleBirthdate, oleModifyTime;
    COleDateTime oleCurrentTime = COleDateTime::GetCurrentTime();
    strName = pMainFrm->VariantToCString(m_pRecordset->GetCollect("姓名"));
    strIDNumber = pMainFrm->VariantToCString(m_pRecordset->GetCollect("居民证号码"));
    strAddress = pMainFrm->VariantToCString(m_pRecordset->GetCollect("常住地址"));
    strGender =  pMainFrm->VariantToCString(m_pRecordset->GetCollect("性别"));
    oleBirthdate = m_pRecordset->GetCollect("出生日期");
    oleModifyTime = m_pRecordset->GetCollect("记录修改时间");
    iNum++; 
    strNumber.Format("%d", iNum);
    int iAge = oleCurrentTime.GetYear() - oleBirthdate.GetYear();
    strAge.Format("%d", iAge);
    strModifyTime.Format("%d年%d月%d日", oleModifyTime.GetYear(), oleModifyTime.GetMonth(), oleModifyTime.GetDay());
    // start!
    List.InsertItem(iNum, strNumber);  //序号
    List.SetItemText(iNum, 1, strName); //姓名
    List.SetItemText(iNum, 2, strAge); //年龄
    List.SetItemText(iNum, 3, strGender); //性别
    List.SetItemText(iNum, 4, strIDNumber); // 身份证号码
    List.SetItemText(iNum, 5, strAddress); //地址
    List.SetItemText(iNum, 6, strModifyTime); //最后修改时间
    iNum++;
    m_pRecordset->MoveNext();
    }

    代码中红色的语句是没有的,copy了早期的代码忘记修正。抱歉。
      

  2.   

    红色那句多了吧,倒数第二行已经有过了。如果保留红色那一行,可将int iNum = 0改为int iNum=-1,从0开始插入项。