CtrlList排序后怎么刷新啊?

plutolxl 2008-11-03 09:52:56
int CALLBACK CMyView::SortCompareStringFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
CMyView* pThis = (CMyView*)lParamSort;
int c ;
CString strItem1=_T(""), strItem2=_T("");

strItem1 = pThis->m_ctrlMainListClient.GetItemText(lParam1,pThis->m_nClickItem);
strItem2 = pThis->m_ctrlMainListClient.GetItemText(lParam2,pThis->m_nClickItem);

c = strItem1.CompareNoCase(strItem2);


if(pThis->m_bCmpType)
c = -c;

return c;

}


void CMyView::OnHdnItemclickListclient(NMHDR *pNMHDR, LRESULT *pResult)
{
for(int i=0;i<m_ctrlMainListClient.GetItemCount();++i)
m_ctrlMainListClient.SetItemData(i,i);//供排序使用的Item编号

LPNMHEADER phdr = reinterpret_cast<LPNMHEADER>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
if(phdr->iItem == m_nClickItem)
m_bCmpType = ! m_bCmpType;
else
{
m_bCmpType = TRUE;
m_nClickItem = phdr->iItem;

}

m_ctrlMainListClient.SortItems(SortCompareStringFunc,(DWORD_PTR) this);

*pResult = 0;
}

调试在回调函数里可以看到strItem1 ,strItem12读到了所点列的值,也进行了比较,返回了C,可最后执行完,列表里的内容就没了,找了好久资料也没解决,郁闷啊!
...全文
137 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
plutolxl 2008-11-04
  • 打赏
  • 举报
回复
先谢谢zhaoyihui888 和cnzdgs ,这个主要是要实现点击列表头后下面的内容自动排序,就像系统的任务管理器那样.
zhaoyihui888说的把数据放在CStringList里面,那样排序可能会很麻烦.
代码方面其他好象和这个没联系了,最开始程序是能显示信息,但排不了序的
zhaoyihui888 2008-11-04
  • 打赏
  • 举报
回复
这样,你把代码发给我,我帮你调下吧,我觉得这个问题应该可以搞定,我QQ,175671267,邮箱zhaoyihui888@163.com或者175671267@qq.com
plutolxl 2008-11-04
  • 打赏
  • 举报
回复
实在是被这个问题折磨的受不了了,我最后决定放弃采用m_ctrlMainListClient.SortItems(SortCompareStringFunc,(DWORD_PTR) this)的方法,换成的下面的来解决.
顺便简单总结下流程,也好让后来者少走弯路...
m_ctrlMainListClient为我的CListCtrl控件名

1.在含有ClistCtrl的父类中添加变量
BOOL m_bCmpType;//是否顺序排序
int m_nClickItem ;//当前排序的列
2.在资源中添加事件处理函数ON_NOTIFY(LVN_COLUMNCLICK, IDC_LIST1, OnLvnColumnclickListclient);
3.void CMyView::OnLvnColumnclickListclient(NMHDR *pNMHDR, LRESULT *pResult)
{
//20081104
// TODO: Add your control notification handler code here
static int m_nClickItem = -1; // 保存当前的排序列。
static BOOL m_bCmpType = TRUE;
// 一开始表示为-1,表示尚未按任何列排序。
NM_LISTVIEW* phdr = (NM_LISTVIEW*)pNMHDR;

if (m_nClickItem == phdr->iSubItem)
{
if (m_bCmpType)
m_bCmpType = FALSE;
else
m_bCmpType = TRUE;
}
else
{
m_nClickItem = phdr->iSubItem;
}
m_nClickItem = phdr->iSubItem;
SortTextItems(m_nClickItem, m_bCmpType, 0, -1);
}



BOOL CMyView::SortTextItems(int nCol, BOOL bAscending, int low, int high)
{
if( nCol >= m_ctrlMainListClient.GetHeaderCtrl()->GetItemCount() )//与列数比较
return FALSE;

if( high == -1 ) high = m_ctrlMainListClient.GetItemCount() - 1;

int lo = low;
int hi = high;
CString midItem;

if( hi <= lo ) return FALSE;

midItem = m_ctrlMainListClient.GetItemText( (lo+hi)/2, nCol );

// loop through the list until indices cross
while( lo <= hi )
{
// rowText will hold all column text for one row
CStringArray rowText;

// find the first element that is greater than or equal to
// the partition element starting from the left Index.
if( bAscending )
while( ( lo < high ) && ( m_ctrlMainListClient.GetItemText(lo, nCol) < midItem ) )
++lo;
else
while( ( lo < high ) && ( m_ctrlMainListClient.GetItemText(lo, nCol) > midItem ) )
++lo;

// find an element that is smaller than or equal to
// the partition element starting from the right Index.
if( bAscending )
while( ( hi > low ) && ( m_ctrlMainListClient.GetItemText(hi, nCol) > midItem ) )
--hi;
else
while( ( hi > low ) && ( m_ctrlMainListClient.GetItemText(hi, nCol) < midItem ) )
--hi;

// if the indexes have not crossed, swap
// and if the items are not equal
if( lo <= hi )
{
// swap only if the items are not equal
if( m_ctrlMainListClient.GetItemText(lo, nCol) != m_ctrlMainListClient.GetItemText(hi, nCol))
{
// swap the rows
LV_ITEM lvitemlo, lvitemhi;
int nColCount = m_ctrlMainListClient.GetHeaderCtrl()->GetItemCount();//列数
rowText.SetSize( nColCount );
int i;
for( i=0; i<nColCount; i++)
rowText[i] = m_ctrlMainListClient.GetItemText(lo, i);
lvitemlo.mask = LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
lvitemlo.iItem = lo;
lvitemlo.iSubItem = 0;
lvitemlo.stateMask = LVIS_CUT | LVIS_DROPHILITED |
LVIS_FOCUSED | LVIS_SELECTED |
LVIS_OVERLAYMASK | LVIS_STATEIMAGEMASK;

lvitemhi = lvitemlo;
lvitemhi.iItem = hi;

m_ctrlMainListClient.GetItem( &lvitemlo );
m_ctrlMainListClient.GetItem( &lvitemhi );

for( i=0; i<nColCount; i++)
m_ctrlMainListClient.SetItemText(lo, i, m_ctrlMainListClient.GetItemText(hi, i));

lvitemhi.iItem = lo;
m_ctrlMainListClient.SetItem( &lvitemhi );

for( i=0; i<nColCount; i++)
m_ctrlMainListClient.SetItemText(hi, i, rowText[i]);

lvitemlo.iItem = hi;
m_ctrlMainListClient.SetItem( &lvitemlo );
}

++lo;
--hi;
}
}

// If the right index has not reached the left side of array
// must now sort the left partition.
if( low < hi )
SortTextItems( nCol, bAscending , low, hi);
// If the left index has not reached the right side of array
// must now sort the right partition.
if( lo < high )
SortTextItems( nCol, bAscending , lo, high );
return TRUE;
}


先结帖了,再次感谢zhaoyihui888 和cnzdgs,如果大家谁有m_ctrlMainListClient.SortItems(SortCompareStringFunc,(DWORD_PTR) this)的解决方法,欢迎赐教,我会给分的
cnzdgs 2008-11-04
  • 打赏
  • 举报
回复
跟Unicode没关系。
plutolxl 2008-11-04
  • 打赏
  • 举报
回复
另外我程序采用的是Unicode编码,会不会是这里面的问题
plutolxl 2008-11-04
  • 打赏
  • 举报
回复
没显示好象和
for(int i=0;i <m_ctrlMainListClient.GetItemCount();++i)
m_ctrlMainListClient.SetItemData(i,i);//供排序使用的Item编号
有关系....我再看看
plutolxl 2008-11-04
  • 打赏
  • 举报
回复
cnzdgs 你说的LVN_COLUMNCLICK消息响应我试过,那样strItem1 ,strItem12都读不了列表里的内容.
......网上说的CListCtrl的排序都挺简单的,流程也清晰,可为什么我照做了就是不行呢?
cnzdgs 2008-11-04
  • 打赏
  • 举报
回复
OnHdnItemclickListclient,从这个函数名来看,你响应的是HDN_ITEMCLICK通知,应该响应LVN_COLUMNCLICK通知才对。
cnzdgs 2008-11-03
  • 打赏
  • 举报
回复
不像是这段代码的问题,还有其它有关的代码吗?
zhaoyihui888 2008-11-03
  • 打赏
  • 举报
回复
提供一个笨办法哈,把数据放在CStringList里面,然后重新写到CListCtrl控件中
plutolxl 2008-11-03
  • 打赏
  • 举报
回复
没剩多少分了,那位大侠帮忙解决下,万分感谢!!

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧