社区
界面
帖子详情
关于CListCtrl表头单击消息
devzhao
2003-12-19 05:38:05
我想单击某一列的表头,则内容就按该列排序显示,该如何实现,
对应的windows message是什么?
...全文
661
8
打赏
收藏
关于CListCtrl表头单击消息
我想单击某一列的表头,则内容就按该列排序显示,该如何实现, 对应的windows message是什么?
复制链接
扫一扫
分享
转发到动态
举报
AI
作业
写回复
配置赞助广告
用AI写文章
8 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
brytison
2004-02-02
打赏
举报
回复
mark
popyyb
2004-01-14
打赏
举报
回复
mark
brytison
2003-12-20
打赏
举报
回复
恩,不错。
sinhighly
2003-12-19
打赏
举报
回复
强烈同意
wangweixing2000
2003-12-19
打赏
举报
回复
ninsenki(流浪鸟) 说的对
arvid_gs
2003-12-19
打赏
举报
回复
列表控件(CListCtrl)的顶部有一排按钮,用户可以通过选择不同的列来对记录进行排序。但是 CListCtrl并没有自动排序的功能,我们需要自己添加一个用于排序的回调函数来比较两个数据的大小,此外还需要响应排序按钮被点击的消息。下面讲述一下具体的做法。
CListCtrl提供了用于排序的函数,函数原型为:BOOL CListCtrl::SortItems( PFNLVCOMPARE pfnCompare, DWORD dwData )。其中第一个参数为全局排序函数的地址,第二个参数为用户数据,你可以根据你的需要传递一个数据或是指针。该函数返回-1代表第一项排应在第二项前面,返回1代表第一项排应在第二项后面,返回0代表两项相等。
用于排序的函数原形为:int CALLBACK ListCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort),其中第三个参数为调用者传递的数据(即调用SortItems时的第二个参数dwData)。第一和第二个参数为用于比较的两项的ItemData,你可以通过DWORD CListCtrl::GetItemData( int nItem )/BOOL CListCtrl::SetItemData( int nItem, DWORD dwData )来对每一项的ItemData进行存取。在添加项时选用特定的CListCtrl::InsertItem也可以设置该值。由于你在排序时只能通过该值来确定项的位置所以你应该比较明确的确定该值的含义。
下面我们看一个例子,这个例子是一个派生类,并支持顺序/倒序两种方式排序。 //全局数据
struct DEMO_DATA
{
char szName[20];
int iAge;
}strAllData[5]={{"王某",30},{"张某",40},{"武某",32},{"陈某",20},{"李某",36}};
//使用方法
BOOL CSort_in_list_ctrlDlg::OnInitDialog()
{
CDialog::OnInitDialog();
//初始化ListCtrl中数据列表
m_listTest.InsertColumn(0,"姓名");
m_listTest.InsertColumn(1,"年龄");
m_listTest.SetColumnWidth(0,80);
m_listTest.SetColumnWidth(1,80);
for(int i=0;i<5;i++)
{
m_listTest.InsertItem(i,strAllData[i].szName);
char szAge[10];
sprintf(szAge,"%d",strAllData[i].iAge);
m_listTest.SetItemText(i,1,szAge);
//设置每项的ItemData为数组中数据的索引
//在排序函数中通过该ItemData来确定数据
m_listTest.SetItemData(i,i);
}
return TRUE; // return TRUE unless you set the focus to a control
}
//类定义
class CSortList : public CListCtrl
{
// Construction
public:
CSortList();
BOOL m_fAsc;//是否顺序排序
int m_nSortedCol;//当前排序的列
protected:
//{{AFX_MSG(CSortList)
//}}AFX_MSG
//手工定义消息映射,处理顶部按钮被按下的消息
afx_msg void OnHeaderClicked(NMHDR* pNMHDR, LRESULT* pResult);
...
};
//CPP文件
//排序函数
int CALLBACK ListCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
CSortList::CSortList()
{
m_fAsc=TRUE;
}
CSortList::~CSortList()
{
}
BEGIN_MESSAGE_MAP(CSortList, CListCtrl)
//{{AFX_MSG_MAP(CSortList)
//}}AFX_MSG_MAP
//手工定义消息映射,处理顶部按钮被按下的消息
ON_NOTIFY(HDN_ITEMCLICK, 0, OnHeaderClicked)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSortList message handlers
//处理顶部按钮被按下的消息
void CSortList::OnHeaderClicked(NMHDR* pNMHDR, LRESULT* pResult)
{
HD_NOTIFY *phdn = (HD_NOTIFY *) pNMHDR;
if( phdn->iButton == 0 )
{
//设置排序方式
if( phdn->iItem == m_nSortedCol )
m_fAsc = !m_fAsc;
else
m_fAsc = TRUE;
//设置排序的列
m_nSortedCol = phdn->iItem;
//开始排序
SortItems( ListCompare, (DWORD)this );
}
}
//排序函数实现
int CALLBACK ListCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
//通过传递的参数来得到CSortList对象指针
CSortList* pV=(CSortList*)lParamSort;
//通过ItemData来确定数据
DEMO_DATA* pInfo1=strAllData+lParam1;
DEMO_DATA* pInfo2=strAllData+lParam2;
CString szComp1,szComp2;
int iCompRes;
switch(pV->m_nSortedCol)
{
case(0):
//以第一列为根据排序
szComp1=pInfo1->szName;
szComp2=pInfo2->szName;
iCompRes=szComp1.Compare(szComp2);
break;
case(1):
//以第二列为根据排序
if(pInfo1->iAge == pInfo2->iAge)
iCompRes = 0;
else
iCompRes=(pInfo1->iAge < pInfo2->iAge)?-1:1;
break;
default:
ASSERT(0);
break;
}
//根据当前的排序方式进行调整
if(pV->m_fAsc)
return iCompRes;
else
return iCompRes*-1;
}
ninsenki
2003-12-19
打赏
举报
回复
LVN_COLUMNCLICK
arvid_gs
2003-12-19
打赏
举报
回复
排序功能的实现
列表控制有一个特殊的功能,当以详细资料方式显示时,列表顶部的表头可以当作按钮来使用,这可以通过列表控制创建时的风格来控制。当鼠标点击列表头名称时,列表控制就会向其父窗口发送一个LNV_COLUMNCLICK消息,利用类导向中列表控制IDC_LISTCTRL对应的LNV_COLUMNCLICK消息加入相应处理函数,就可将表列按照特定顺序进行排列。其函数使用方法见程序,其中iSort为排序的表列索引号,(PFNLVCOMPARE)CompareFunc为进行具体排序的回调函数,也就是说,通过鼠标点击表头实现的排序过程是由第三方开发的专用排序函数来实现的,排序函数只是实现表项的具体比较操作,而整个排序过程是由SortItemS属性通过不断调用这个函数来实现的。正常的排序过程是升序方式,通过调换排序函数中的参数值,就可实现降序排列,即将PARAM1与PARAM2调换位置。这个回调函数的前两个参数为表列中表项的索引号,第三个参数为排序的表列索引号。
void CVCLISTDlg::OnColumnclickListctrl(NMHDR* pNMHDR, LRESULT* pResult)
{ //鼠标左键单击表头处理函数
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
static int iSorted=-1;//排列序号
if (pNMListView->iSubItem==iSorted) return;
iSorted=pNMListView->iSubItem;
m_ListCtrl.SortItems((PFNLVCOMPARE)CompareFunc,iSorted);
*pResult = 0;
}
//排序时比较表项的回调函数
int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2,LPARAM lParamSort)
{ char *text1,*text2;
switch (lParamSort){
case 0L:text1=Sps[lParam1].szPm;
text2=Sps[lParam2].szPm;break;
case 1L:text1=Sps[lParam1].szSl;
text2=Sps[lParam2].szSl;break;
case 2L:text1=Sps[lParam1].szDj;
text2=Sps[lParam2].szDj;break;
case 3L:text1=Sps[lParam1].szJe;
text2=Sps[lParam2].szJe;break;
}
return (strcmp(text1,text2));//结果为>0 =0 <0
}
同样,也可以通过专用按钮来实现排序功能,如本文的排序按钮对应的功能代码如下:
void CVCLISTDlg::OnSort()
{ // TODO: Add your control notification handler code here
m_ListCtrl.SortItems((PFNLVCOMPARE)CompareFunc,0);}
CLi
stCtrl
的主要事件及鼠标响应函数
- 描述:NM_
CLI
CK 表示
单击
列表视图控件时触发的事件;NM_DBLCLK 则是在双击列表视图控件时触发的事件。 - 处理方式:分别通过重写 `On
Cli
ck` 和 `OnDblclk` 函数来实现。 7. **LVN_ENDLABELEDIT** - 描述:当...
CLi
stCtrl
的使用
- `LVS_EX_HEADERDRAGDROP` 允许拖动
表头
来重新排序; - `LVS_EX_ONE
CLI
CKACTIVATE`
单击
即可激活项。 #### 三、其他代码分析 此外,还提供了一段`OnInitDialog`函数的代码,这部分主要用于初始化对话框。 ```...
CLi
stCtrl
Ex
开发者可以通过重载或附加
消息
映射来响应用户的交互,如
单击
、双击、滚动等事件。 7. **编程接口**:
CLi
stCtrl
Ex通过增加新的成员函数和属性,提供了方便的编程接口,让开发者能够轻松地设置和修改上述外观属性。...
VC++常用功能实例
问:关于用户自定义的
消息
使用? 71 问:在打开一个文档时退出? 71 问:在
CLi
stCtrl
控件中多选择项的删除? 71 问:工作线程的登录状态? 72 问:如何控制菜单的大小? 72 问:改变LVIS_SELECTED的状态颜色? 73 问:如何...
VC++常用的共用函数100多页
问:关于用户自定义的
消息
使用? 71 问:在打开一个文档时退出? 71 问:在
CLi
stCtrl
控件中多选择项的删除? 71 问:工作线程的登录状态? 72 问:如何控制菜单的大小? 72 问:改变LVIS_SELECTED的状态颜色? 73 问:如何...
界面
15,980
社区成员
115,867
社区内容
发帖
与我相关
我的任务
界面
VC/MFC 界面
复制链接
扫一扫
分享
社区描述
VC/MFC 界面
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章