参考http://blog.csdn.net/Joany_yang/article/details/1640448中提出的:
MFC提供了SortItems来支持CListCtrl的排序,但没有提供设置排序标记(头三角)的功能。
如果有这样的需求就得自己实现。
方法一、在CHeaderCtrl的扩展类CHeaderCtrlEx中自己绘制三角(up/down state)
void CHeaderCtrlEx :: DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
//draw arrow up/down here
}
通过这种方式绘制的Header没有了xp style, 还需要你自己绘制xp风格。
方法二:插入图片(两幅图片的替换)
HDITEM hdrItem;
GetHeaderCtrl()->GetItem(m_iSortCol, & hdrItem);
hdrItem.mask = HDI_FORMAT | HDI_IMAGE;
hdrItem.iImage = nImageIndex; //index of up/down bitmap
pHeaderCtrl->SetItem(m_iSortCol, & hdrItem);
可以说这个方法工作代价最小。而且也没破坏xp风格。
不过不要忘了先GetHeaderCtrl()->SetImageList(&m_imageListSort)。其实就是CHeaderctrl中插入图片
我写了代码,不过出现错误,不知道是哪里错了,各位帮忙看看,小弟在此感激不尽 CImageList *ImgHeaders = new CImageList;
ImgHeaders->Create(16,16,ILC_MASK,1,1);
ImgHeaders->Add(AfxGetApp()->LoadIcon(IDI_UP));
ImgHeaders->Add(AfxGetApp()->LoadIcon(IDI_DOWN)); CHeaderCtrl* m_HeaderCtrl=new CHeaderCtrl;
m_HeaderCtrl->SetImageList(ImgHeaders);
HDITEM hdrItem;
m_HeaderCtrl->GetItem(0, & hdrItem);
hdrItem.mask = HDI_FORMAT | HDI_IMAGE;
hdrItem.iImage = 0; //index of up/down bitmap
CHeaderCtrl xyz;
m_HeaderCtrl->SetItem(0,&hdrItem);
MFC提供了SortItems来支持CListCtrl的排序,但没有提供设置排序标记(头三角)的功能。
如果有这样的需求就得自己实现。
方法一、在CHeaderCtrl的扩展类CHeaderCtrlEx中自己绘制三角(up/down state)
void CHeaderCtrlEx :: DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
//draw arrow up/down here
}
通过这种方式绘制的Header没有了xp style, 还需要你自己绘制xp风格。
方法二:插入图片(两幅图片的替换)
HDITEM hdrItem;
GetHeaderCtrl()->GetItem(m_iSortCol, & hdrItem);
hdrItem.mask = HDI_FORMAT | HDI_IMAGE;
hdrItem.iImage = nImageIndex; //index of up/down bitmap
pHeaderCtrl->SetItem(m_iSortCol, & hdrItem);
可以说这个方法工作代价最小。而且也没破坏xp风格。
不过不要忘了先GetHeaderCtrl()->SetImageList(&m_imageListSort)。其实就是CHeaderctrl中插入图片
我写了代码,不过出现错误,不知道是哪里错了,各位帮忙看看,小弟在此感激不尽 CImageList *ImgHeaders = new CImageList;
ImgHeaders->Create(16,16,ILC_MASK,1,1);
ImgHeaders->Add(AfxGetApp()->LoadIcon(IDI_UP));
ImgHeaders->Add(AfxGetApp()->LoadIcon(IDI_DOWN)); CHeaderCtrl* m_HeaderCtrl=new CHeaderCtrl;
m_HeaderCtrl->SetImageList(ImgHeaders);
HDITEM hdrItem;
m_HeaderCtrl->GetItem(0, & hdrItem);
hdrItem.mask = HDI_FORMAT | HDI_IMAGE;
hdrItem.iImage = 0; //index of up/down bitmap
CHeaderCtrl xyz;
m_HeaderCtrl->SetItem(0,&hdrItem);
ImgHeaders->Create(16,16,ILC_MASK,1,1);
ImgHeaders->Add(AfxGetApp()->LoadIcon(IDI_UP));
ImgHeaders->Add(AfxGetApp()->LoadIcon(IDI_DOWN));
m_HeaderCtrl->SetImageList(ImgHeaders);
//兄弟,一定要注意释放资源!!!!!!!!!!!!!!
ImgHeaders->Detach();//经验告诉我,脱离掉才能显示出图片来!
ImgHeaders->DeleteImageList();
//不需要了就加个delete ImgHeaders
HDITEM hdrItem;
m_HeaderCtrl->GetItem(0, & hdrItem);
hdrItem.mask = HDI_FORMAT | HDI_IMAGE;
hdrItem.iImage = 0; //index of up/down bitmap
CHeaderCtrl xyz;
m_HeaderCtrl->SetItem(0,&hdrItem);
CHeaderCtrl* m_HeaderCtrl=new CHeaderCtrl;
不如改为:
CHeaderCtrl *m_HeaderCtrl= m_ListCtrl.GetHeaderCtrl();
试了试,CHeaderCtrl->SetItem(Column,&Hditem)加载图标。
似乎HDITEM .mask = HDI_IMAGE | HDI_FORMAT | HDI_TEXT更容易成功
我的代码如下:
void CMyDlg::OnLvnColumnclickList1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码 /* 若当前排序列与点击列相同,则更改增、减序的排序方式。
若点击列与当前排序列不同的列,则改变排序序,并将排序方式改为增序。*/
enum { sizeOfBuffer = 256 };
TCHAR lpBuffer[sizeOfBuffer];
HDITEM hdi;
hdi.pszText = lpBuffer;
hdi.cchTextMax = sizeOfBuffer; CHeaderCtrl *pHdCtrl = m_ListCtrl.GetHeaderCtrl();
int count = pHdCtrl->GetItemCount();
for (int i=0; i < count; i++)
{
hdi.mask = HDI_TEXT | HDI_IMAGE;
pHdCtrl->GetItem(i, &hdi);
if (i == pNMLV->iSubItem)//当前所选列
{
hdi.iImage = (hdi.iImage+1) %2;
nSortOrder = hdi.iImage==0?1:-1; //nSortOrder -1为降序,1表示升序。
}
else
if (hdi.iImage==-1)
continue;
else
hdi.iImage=-1; //-1为无图标
hdi.mask = HDI_IMAGE | HDI_FORMAT | HDI_TEXT/* | HDI_WIDTH*/;
hdi.fmt = HDF_LEFT | HDF_IMAGE | HDF_STRING;
pHdCtrl->SetItem( i, &hdi );
} Item mItem;
mItem.mlist = &m_ListCtrl;
mItem.Isub = pNMLV->iSubItem;
for(int i=0;i < m_ListCtrl.GetItemCount();i++)
{
m_ListCtrl.SetItemData(i,i);
}
m_ListCtrl.SortItems(CompareFunc,(LPARAM)&mItem);
*pResult = 0;
}// CMyDlg.h : 头文件
//
#pragma once
#include "resource.h"
typedef struct _Item
{
CListCtrl *mlist;
int Isub; //排序列
}Item;
static int nSortOrder=1; // 排序的方式,1升序,-1降序。// CTpsOpDbDlg 对话框
class CTpsOpDbDlg : public CPropertyPage
{
DECLARE_DYNAMIC(CTpsOpDbDlg)
// 构造
public:
CTpsOpDbDlg(CWnd* pParent = NULL); // 标准构造函数
// 对话框数据
enum { IDD = IDD_TPSOPDB_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
HICON m_hIcon; // 生成的消息映射函数
virtual BOOL OnInitDialog();
DECLARE_MESSAGE_MAP()
public:
int citem;
CString ActiveID;
CListCtrl m_ListCtrl;
//排序的回调函数如下:
static int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
// 得到排序方式
Item* pV=(Item*)lParamSort;
// 需要的排序参数比较
CString sz1 = pV->mlist->GetItemText(lParam1,pV->Isub);
CString sz2 = pV->mlist->GetItemText(lParam2,pV->Isub);
if(nSortOrder == 1)
return sz1.Compare(sz2);
else
return -sz1.Compare(sz2);
}
afx_msg void OnLvnColumnclickList1(NMHDR *pNMHDR, LRESULT *pResult);
};
CHeaderCtrl* m_HeaderCtrl=new CHeaderCtrl;
不如改为:
CHeaderCtrl *m_HeaderCtrl= m_ListCtrl.GetHeaderCtrl();
试了试,CHeaderCtrl->SetItem(Column,&Hditem)加载图标。
似乎HDITEM .mask = HDI_IMAGE | HDI_FORMAT | HDI_TEXT更容易成功我的代码如下:
void CMyDlg::OnLvnColumnclickList1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
enum { sizeOfBuffer = 256 };
TCHAR lpBuffer[sizeOfBuffer];
HDITEM hdi;
hdi.pszText = lpBuffer;
hdi.cchTextMax = sizeOfBuffer; CHeaderCtrl *pHdCtrl = m_ListCtrl.GetHeaderCtrl();
int count = pHdCtrl->GetItemCount();
for (int i=0; i < count; i++)
{
hdi.mask = HDI_TEXT | HDI_IMAGE;
pHdCtrl->GetItem(i, &hdi);
if (i == pNMLV->iSubItem)//当前所选列
{
hdi.iImage = (hdi.iImage+1) %2;
nSortOrder = hdi.iImage==0?1:-1; //nSortOrder -1为降序,1表示升序。
}
else
if (hdi.iImage==-1)
continue;
else
hdi.iImage=-1; //-1为无图标
hdi.mask = HDI_IMAGE | HDI_FORMAT | HDI_TEXT/* | HDI_WIDTH*/;
hdi.fmt = HDF_LEFT | HDF_IMAGE | HDF_STRING;
pHdCtrl->SetItem( i, &hdi );
}
//排序
Item mItem;
mItem.mlist = &m_ListCtrl;
mItem.Isub = pNMLV->iSubItem;
for(int i=0;i < m_ListCtrl.GetItemCount();i++)
{
m_ListCtrl.SetItemData(i,i);
}
m_ListCtrl.SortItems(CompareFunc,(LPARAM)&mItem);
*pResult = 0;
}// CMyDlg.h : 头文件
//
#pragma once
#include "resource.h"
typedef struct _Item
{
CListCtrl *mlist;
int Isub; //排序列
}Item;
static int nSortOrder=1; // 排序的方式,1升序,-1降序。// CTpsOpDbDlg 对话框
class CTpsOpDbDlg : public CPropertyPage
{
DECLARE_DYNAMIC(CTpsOpDbDlg)
// 构造
public:
CTpsOpDbDlg(CWnd* pParent = NULL); // 标准构造函数
// 对话框数据
enum { IDD = IDD_TPSOPDB_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
HICON m_hIcon; // 生成的消息映射函数
virtual BOOL OnInitDialog();
DECLARE_MESSAGE_MAP()
public:
int citem;
CString ActiveID;
CListCtrl m_ListCtrl;
//排序的回调函数如下:
static int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
// 得到排序方式
Item* pV=(Item*)lParamSort;
// 需要的排序参数比较
CString sz1 = pV->mlist->GetItemText(lParam1,pV->Isub);
CString sz2 = pV->mlist->GetItemText(lParam2,pV->Isub);
if(nSortOrder == 1)
return sz1.Compare(sz2);
else
return -sz1.Compare(sz2);
}
afx_msg void OnLvnColumnclickList1(NMHDR *pNMHDR, LRESULT *pResult);
};
m_rList.SetExtendedStyle( LVS_EX_FULLROWSELECT );
m_rList.InsertColumn( 0, _T("网址"), LVCFMT_LEFT, 300 );
m_rList.InsertColumn( 1, _T("说明"), LVCFMT_LEFT, 230 );
m_rList.InsertColumn( 3, _T("耗时"), LVCFMT_LEFT, 80 );
//添加ListCtrl数据
int nRet;
nRet = m_rList.InsertItem( m_rList.GetItemCount( ), _T("http://www.a3gs.com/index.asp") );
//设置一个唯一的Item数据,否则无法排序
m_rList.SetItemData( nRet, 0 );
m_rList.SetItemText( nRet, 1, _T("天使知识授理厂") );
m_rList.SetItemText( nRet, 2, _T("100") );
nRet = m_rList.InsertItem( m_rList.GetItemCount( ), _T("http://www.a3gs.com/Info_More.asp?classID=789") );
m_rList.SetItemData( nRet, 1 );
m_rList.SetItemText( nRet, 1, _T("Android") );
m_rList.SetItemText( nRet, 2, _T("20") );
nRet = m_rList.InsertItem( m_rList.GetItemCount( ), _T("http://www.a3gs.com/Info_More.asp?classID=645") );
m_rList.SetItemData( nRet, 2 );
m_rList.SetItemText( nRet, 1, _T("Windows Mobile") );
m_rList.SetItemText( nRet, 2, _T("300") );
nRet = m_rList.InsertItem( m_rList.GetItemCount( ), _T("http://www.a3gs.com/Info_More.asp?classID=643") );
m_rList.SetItemData( nRet, 3 );
m_rList.SetItemText( nRet, 1, _T("iPhone") );
m_rList.SetItemText( nRet, 2, _T("99") );
nRet = m_rList.InsertItem( m_rList.GetItemCount( ), _T("http://www.a3gs.com/Info_More.asp?classID=644") );
m_rList.SetItemData( nRet, 4 );
m_rList.SetItemText( nRet, 1, _T("Symbian") );
m_rList.SetItemText( nRet, 2, _T("20") );
nRet = m_rList.InsertItem( m_rList.GetItemCount( ), _T("http://www.a3gs.com/Info_More.asp?ClassID=799") );
m_rList.SetItemData( nRet, 5 );
m_rList.SetItemText( nRet, 1, _T("嵌入式") );
m_rList.SetItemText( nRet, 2, _T("111") );
nRet = m_rList.InsertItem( m_rList.GetItemCount( ), _T("http://www.a3gs.com/About.asp") );
m_rList.SetItemData( nRet, 6 );
m_rList.SetItemText( nRet, 1, _T("关于我们") );
m_rList.SetItemText( nRet, 2, _T("222") ); CImageList *ImgHeaders = new CImageList;
ImgHeaders->Create(16,16,ILC_MASK,1,1);
ImgHeaders->Add(AfxGetApp()->LoadIcon(IDI_UP));
ImgHeaders->Add(AfxGetApp()->LoadIcon(IDI_DOWN)); enum { sizeOfBuffer = 256 };
TCHAR lpBuffer[sizeOfBuffer];
HDITEM hdi;
hdi.pszText = lpBuffer;
hdi.cchTextMax = sizeOfBuffer;
CHeaderCtrl *pHdCtrl = m_rList.GetHeaderCtrl();
int count = pHdCtrl->GetItemCount();
for (int i=0; i < count; i++)
{
hdi.mask = HDI_TEXT | HDI_IMAGE;
pHdCtrl->GetItem(i, &hdi);
//ImgHeaders->Detach();//经验告诉我,脱离掉才能显示出图片来!
//ImgHeaders->DeleteImageList();
hdi.iImage=1;
hdi.mask = HDI_IMAGE | HDI_FORMAT | HDI_TEXT/* | HDI_WIDTH*/;
hdi.fmt = HDF_LEFT | HDF_IMAGE | HDF_STRING;
pHdCtrl->SetItem( i, &hdi );
}
CHeaderCtrl *pHdCtrl = m_rList.GetHeaderCtrl();
//++++——————————————————————————————————————————————
pHdCtrl->SetImageList(&m_TypeImgList);
m_TypeImgList->Detach();
m_TypeImgList->DeleteImageList();
//——————————————————————————————
int count = pHdCtrl->GetItemCount();