天天看點

VC++中CList使用

在Clist控件中顯示網格

m_ctrlListCtrl.SetExtendedStyle(LVS_EX_GRIDLINES );

VC++ 清單控件(CList) 使用方法2009-12-07 19:06VC++ 清單控件(CList) 使用方法2009-11-25 10:46清單控件可以看作是功能增強的ListBox,它提供了四種風格,而且可以同時顯示一列的多中屬性值。

MFC中使用CListCtrl類來封裝清單控件的各種操作。

通過調用BOOL Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );建立一個視窗,dwStyle中可以使用以下一些清單控件的專用風格:

LVS_ICON LVS_SMALLICON LVS_LIST LVS_REPORT 這四種風格決定控件的外觀,同時隻可以選擇其中一種,分别對應:大圖示顯示,小圖示顯示,清單顯示,詳細報表顯示

LVS_EDITLABELS 結點的顯示字元可以被編輯,對于報表風格來講可編輯的隻為第一列。

LVS_SHOWSELALWAYS 在失去焦點時也顯示目前選中的結點

LVS_SINGLESEL 同時隻能選中清單中一項

首先你需要設定清單控件所使用的ImageList,如果你使用大圖示顯示風格,你就需要以如下形式調用:

CImageList* SetImageList( CImageList* pImageList, LVSIL_NORMAL);

如果使用其它三種風格顯示而不想顯示圖示你可以不進行任何設定,否則需要以如下形式調用:

CImageList* SetImageList( CImageList* pImageList, LVSIL_SMALL);

通過調用int InsertItem( int nItem, LPCTSTR lpszItem );可以在清單控件中nItem指明位置插入一項,lpszItem為顯示字元。除LVS_REPORT風格外其他三種風格都隻需要直接調用 InsertItem就可以了,但如果使用報表風格就必須先設定清單控件中的列資訊。

通過調用int InsertColumn( int nCol, LPCTSTR lpszColumnHeading, int nFormat , int nWidth, int nSubItem);可以插入列。iCol為列的位置,從零開始,lpszColumnHeading為顯示的列名,nFormat為顯示對齊方式,nWidth為顯示寬度,nSubItem為配置設定給該列的列索引。

在有多列的清單控件中就需要為每一項指明其在每一列中的顯示字元,通過調用BOOL SetItemText( int nItem, int nSubItem, LPTSTR lpszText );可以設定每列的顯示字元。nItem為設定的項的位置,nSubItem為列位置,lpszText為顯示字元。下面的代碼示範了如何設定多列并插入資料:

m_list.SetImageList(&m_listSmall,LVSIL_SMALL);//設定ImageList

m_list.InsertColumn(0,"Col 1",LVCFMT_LEFT,300,0);//設定列

m_list.InsertColumn(1,"Col 2",LVCFMT_LEFT,300,1);

m_list.InsertColumn(2,"Col 3",LVCFMT_LEFT,300,2);

m_list.InsertItem(0,"Item 1_1");//插入行

m_list.SetItemText(0,1,"Item 1_2");//設定該行的不同列的顯示字元

m_list.SetItemText(0,2,"Item 1_3");

此外CListCtrl還提供了一些函數用于得到/修改控件的狀态。

COLORREF GetTextColor( )/BOOL SetTextColor( COLORREF cr );用于得到/設定顯示的字元顔色。

COLORREF GetTextBkColor( )/BOOL SetTextBkColor( COLORREF cr );用于得到/設定顯示的背景顔色。

void SetItemCount( int iCount );用于得到添加進清單中項的數量。

BOOL DeleteItem(int nItem);用于删除某一項,BOOL DeleteAllItems( );将删除所有項。

BOOL SetBkImage(HBITMAP hbm, BOOL fTile , int xOffsetPercent, int yOffsetPercent);用于設定背景位圖。

CString GetItemText( int nItem, int nSubItem );用于得到某項的顯示字元。

清單控件的消息映射同樣使用ON_NOTIFY宏,形式如同:ON_NOTIFY( wNotifyCode, id, memberFxn ),wNotifyCode為通知代碼,id為産生該消息的視窗ID,memberFxn為處理函數,函數的原型如同void OnXXXList(NMHDR* pNMHDR, LRESULT* pResult),其中pNMHDR為一資料結構,在具體使用時需要轉換成其他類型的結構。對于清單控件可能取值和對應的資料結構為:

LVN_BEGINLABELEDIT 在開始某項編輯字元時發送,所用結構:NMLVDISPINFO

LVN_ENDLABELEDIT 在結束某項編輯字元時發送,所用結構:NMLVDISPINFO

LVN_GETDISPINFO 在需要得到某項資訊時發送,(如得到某項的顯示字元)所用結構:NMLVDISPINFO

關于ON_NOTIFY有很多内容,将在以後的内容中進行詳細講解。

關于動态提供結點所顯示的字元:首先你在項時需要指明lpszItem參數為:LPSTR_TEXTCALLBACK。在控件顯示該結點時會通過發送 TVN_GETDISPINFO來取得所需要的字元,在處理該消息時先将參數pNMHDR轉換為LPNMLVDISPINFO,然後填充其中 item.pszText。通過item中的iItem,iSubItem可以知道目前顯示的為那一項。下面的代碼示範了這種方法:

char szOut[8][3]={"No.1","No.2","No.3"};

//添加結點

m_list.InsertItem(LPSTR_TEXTCALLBACK,...)

m_list.InsertItem(LPSTR_TEXTCALLBACK,...)

//處理消息

void CParentWnd::OnGetDispInfoList(NMHDR* pNMHDR, LRESULT* pResult)

{

    LV_DISPINFO* pLVDI = (LV_DISPINFO*)pNMHDR;

    pLVDI->item.pszText=szOut[pTVDI->item.iItem];//通過iItem得到需要顯示的字元在數組中的位置

    *pResult = 0;

}

關于編輯某項的顯示字元:(在報表風格中隻對第一列有效)首先需要設定清單控件的LVS_EDITLABELS風格,在開始編輯時該控件将會發送 LVN_BEGINLABELEDIT,你可以通過在處理函數中傳回TRUE來取消接下來的編輯,在編輯完成後會發送LVN_ENDLABELEDIT,在處理該消息時需要将參數pNMHDR轉換為LPNMLVDISPINFO,然後通過其中的item.pszText得到編輯後的字元,并重置顯示字元。如果編輯在中途中取消該變量為NULL。下面的代碼說明如何處理這些消息:

//處理消息 LVN_BEGINLABELEDIT void CParentWnd::OnBeginEditList(NMHDR* pNMHDR, LRESULT* pResult)

{

    LV_DISPINFO* pLVDI = (LV_DISPINFO*)pNMHDR;

    if(pLVDI->item.iItem==0);//判斷是否取消該操作

         *pResult = 1;

    else

         *pResult = 0;

}

//處理消息 LVN_BEGINLABELEDIT

void CParentWnd::OnBeginEditList(NMHDR* pNMHDR, LRESULT* pResult)

{

    LV_DISPINFO* pLVDI = (LV_DISPINFO*)pNMHDR;

    if(pLVDI->item.pszText==NULL);//判斷是否已經取消取消編輯

          m_list.SetItemText(pLVDI->item.iItem,0,pLVDI->pszText);//重置顯示字元

    *pResult = 0;

}

上面講述的方法所進行的消息映射必須在父視窗中進行(同樣WM_NOTIFY的所有消息都需要在父視窗中處理)。

如何得到目前選中項位置:在清單控件中沒有一個類似于ListBox中GetCurSel()的函數,但是可以通過調用GetNextItem( -1, LVNI_ALL   LVNI_SelectED);得到選中項位置。

一、基本使用

1.新加ListControl 控件,屬性中的style屬性頁下的View選擇Report。

并設定其對應的控制變量如:m_list1。

2.初始化,即設定列。       用m_list1。

         m_list1.InsertColumn(0,"曲名");           //插入列

m_list1.InsertColumn(1,"類型");

m_list1.InsertColumn(2,"長度");

m_list1.InsertColumn(3,"路徑");

CRect rect4;

m_list1.GetClientRect(rect4);                     //獲得目前客戶區資訊

m_list1.SetColumnWidth(0,rect4.Width()/4);         //設定列的寬度。

m_list1.SetColumnWidth(1,rect4.Width()/5);

m_list1.SetColumnWidth(2,rect4.Width()/5);

m_list1.SetColumnWidth(3,rect4.Width()*8/20);

這部分初始化操作,最好放在對話框類的OnInitDialog()函數裡,自動初始化。

3.插入資料

         m_list1.InsertItem(0,"大海");       //插入第一個資料,即第0條資料。先插入,然後在修改其他的資訊。

         m_list1.SetItemText(0,1,"mp3");     //修改第0條資料的其他資訊。

         m_list1.SetItemText(0,2,"4:20");

         m_list1.SetItemText(0,3,"c:/");

4.删除所有資料

         m_list1.DeleteAllItems();

5.補充:

     特别注意的地方是,在插入新項(記錄)的時候,使用m_list1.GetItemCount()擷取目前報表中的項目總數。但是m_list1.InsertItem()函數調用時候不能使用m_list1.GetItemCount()+1。因為項目是從0

開始計數的。

二、其他技巧

 1.如何設定ListView控件的完全行(Full Row)選項。

     這個控件有個地方常常很惱人,那就是在報告視圖中選中一行時,它隻加亮最左邊的一個欄目。

     為了克服這個問題,這裡告訴你一個方法:向ListView控件發送一個LVM_SETEXTENDEDLISTVIEWSTYLE消息。

::SendMessage(m_list1.m_hWnd, LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_FULLROWSelect, LVS_EX_FULLROWSelect);

VC通用控件程式設計之CList控件2009-03-19 14:30VC通用控件程式設計之CList控件

(一)清單控制的主要功能

清單控制和視(List Control&View)主要用來以各種方式顯示一組資料記錄供使用者進行各種操作,Windows98/95中資料總管中的“檢視”标簽下的“大圖示|小圖示|清單|詳細資源”就是一個非常好的典型應用。清單中的記錄可以包括多個資料項,也可以包括表示資料内容的大小圖示,用來表示資料記錄的 清單控制提供了對Windows清單功能操作的基本方法,而使用清單視的視函數可以對清單視進行各種操作,通過調用視成員GetListCtrl擷取嵌在清單視内清單控制的引用(GetListCtrl& ctrlList = GetListCtrl()),就可以和清單控制一樣進行各種操作。操作一個清單控制和視的基本方法為:建立清單控制;建立清單控制所需要的圖像清單;向清單控制添加表列和表項;對清單進行各種控制,主要包括查找、排序、删除、顯示方式、排列方式以及各種消息處理功能等;最後撤消清單控制。

對于一個清單控制,其最典型最常用的顯示控制方式為:大圖示方式(LVS_ICON)、小圖示方式(LVS_SMALLICON)、清單顯示方式(LVS_LIST)和詳細資料(即報告LVS_REPORT)顯示方式。這可以通過設定其顯示方式屬性來實作。要控制清單所在視窗的風格,可通過功能函數GetWindowLong和SetWindowLong來實作,要控制清單圖示的對齊方式,可通過設定清單視窗的風格LVS_ALIGNTOP或LVS_ALIGNLEFT來實作,

(二)清單控制的對象結構

1、清單控制的建立方法

CListCtrl&listCtrl 定義清單對象的結構

Create 建立清單控制并綁定對象

清單控制CListCtrl::Create的調用格式如下:

BOOL Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );

其中參數dwStyle用來确定清單控制的風格;rect用來确定清單控制的大小和位置;pParentWnd用來确定清單控制的父視窗,通常是一個對話框;nID用來确定清單控制的辨別。其中清單控制的風格可以是下列值的組合:

LVS_ALIGNLEFT 用來确定表項的大小圖示以左對齊方式顯示;

LVS_ALIGNTOP 用來确定表項的大小圖示以頂對齊方式顯示;

LVS_AUTOARRANGE 用來确定表項的大小圖示以自動排列方式顯示;

LVS_EDITLABELS 設定表項文本可以編輯,父視窗必須設有LVN_ENDLABELEDIT風格;

LVS_ICON 用來确定大圖示的顯示方式;

LVS_LIST 用來确定清單方式顯示;

LVS_NOCOLUMNHEADER 用來确定在詳細資料方式時不顯示清單頭;

LVS_NOLABELWRAP 用來确定以單行方式顯示圖示的文本項;

LVS_NOSCROLL 用來屏蔽滾動條;

LVS_NOSORTHEADER 用來确定清單頭不能用作按鈕功能;

LVS_OWNERDRAWFIXED 在詳細清單方式時允許自繪視窗;

LVS_REPORT 用來确定以詳細資料即報告方式顯示;

LVS_SHAREIMAGELISTS用來确定共享圖像清單方式;

LVS_SHOWSELALWAYS 用來确定一直顯示被選中表項方式;

LVS_SINGLESEL 用來确定在某一時刻隻能有一項被選中;

LVS_SMALLICON 用來确定小圖示顯示方式;

LVS_SORTASCENDING 用來确定表項排序時是基于表項文本的升序方式;

LVS_SORTDESCENDING 用來确定表項排序時是基于表項文本的降序方式;

2、清單控制的屬性類

清單控制的屬性類包括取得清單控制的背景色GetBkColor、設定清單控制的背景色SetBkColor、取得清單控制的圖像清單GetImageList、設定清單控制的圖像清單SetImageList、取得清單項數目GetItemCount、取得清單控制的屬性GetItem、取得與表項相關的資料GetItemData、設定表項的屬性SetItem、設定與表項相關的數值SetItemData、取得相關聯的下一個表項GetNextItem、設定清單控制的文本顔色SetTextColor、取得清單控制的文本背景顔色GetTextBkColor、設定表項的最大數目SetItemCount和取得被選中表項的數目GetSelectedCount等。

3、清單控制的操作方法

清單控制的操作方法包括插入一個新的表項InsertItem、删除一個表項DeleteItem、排序表項SortItems、測試清單的位置HitTest、重繪表項RedrawItems、插入一個表列InsertColumn、删除一個表列DeleteColumn、編輯一個表項文本EditLabel和重繪一個表項DrawItem等。

(三)清單控制的資料結構

清單控制中包含兩個非常重要的資料結構LV_ITEM和LV_COLUMN。LV_ITEM用于定義清單控制的一個表項,LV_COLUMN用于定義清單控制的一個表列,其定義格式分别為:

typedef struct _LV_ITEM {

UINT mask; //結構成員屏蔽位

int iItem; //表項索引号

int iSubItem; //子表項索引号

UINT state; //表項狀态

UINT stateMask; //狀态有效性屏蔽位

LPTSTR pszText; //表項名文本

int cchTextMax; //表項名最大長度

int iImage; // 表項圖示的索引号

LPARAM lParam; // 與表項相關的32位數

} LV_ITEM;

typedef struct _LV_COLUMN {

UINT mask; //結構成員有效性屏蔽位

int fmt; //表列對齊方式

int cx; //表列的象素寬度

LPTSTR pszText; //表列的表頭名

int cchTextMax; //表列名的文本長度

int iSubItem; //與表列關聯的子表項索引号

} LV_COLUMN;

  其中fmt可以取如下值:

LVCFMT_CENTER 表列居中對齊

LVCFMT_LEFT 表列左對齊

(四)清單控制的應用技巧示例

本文給出具體執行個體示範清單控制及前面的表頭控制和圖像清單的應用技巧。步驟如下:

1、   通過“FILE->NEW->PROJECTS->MFC AppWizard(EXE)”建立名為VCLIST的工程,在建立過程中選擇基于對話框(Dialog based)的應用;将對話框中的預設控件删除,并将所有對話框屬性中的Language域設定為Chinese(P.R.C.),以使應用程式支援中文;

2、   建立兩個圖示IDI_GJ和IDI_XS,用來表示圖示的選中和非選中狀态,對于每個圖示都應建立32X32和16X16兩種大小,以保證程式的需要;

3、   在對話框視窗中設計組合框(Group Box),組合框中設定四個無線按鈕(Radio)“大圖示|小圖示|清單|資料”,同時設定排序、删除和關閉三個控制按鈕(Button),并在對話框中設定大小合适的清單控制(List Ctrl),其對應辨別分别如下:

--------------------------------------------------------------------------------

控制名稱 标題名稱辨別符号

--------------------------------------------------------------------------------

清單控制 IDC_LISTCTRL

組合框 方式 IDC_STATIC

無線按鈕 大圖示 IDC_STDICON

小圖示 IDC_SMLICON

列 表 IDC_LIST

資 料 IDC_REPORT

按鈕 排 序 IDC_SORT

删 除 IDC_DEL

關 閉 IDOK

--------------------------------------------------------------------------------

4、在設定無線按鈕時,需要注意的是隻有大圖示的Group屬性為選中狀态,而其它無線按鈕的狀态均為預設值。

5、選中清單控制控件,選擇“VIEW->ClassWizard->Memory Variables”,并利用IDC_ LISTCTRL引入成員變量,其變量類型為:

變量名 種類 變量類型

m_ListCtrl Control ClistCtrl

同時利用“MESSAGES MAP”為各無線按鈕和指令按鈕增加控制功能

6、然後在包含檔案和代碼檔案中分别加入如下代碼:

(1)在VCLISTDlg.h中增加資料結構和定義

typedef struct tagSPS { //定義結構

char szPm[10]; //品名

int Lx; //0-GJ 1-XS

char szSl[10]; //數量

char szDj[10]; //單價

char szJe[10]; //金額

} SPS;

int CALLBACK CompareFunc(LPARAM lParam1,LPARAM lParam2,LPARAM lParamSort);

(2)在VCLISTDlg.CPP中的起始處增加初始化資料和程式定義

//在檔案開始處增加資料結構初始化

SPS Sps[]={//資訊

{"紅梅",0,"1000","30","30000"},

{"黃梅",0,"1000","29","29000"},

{"綠梅",0,"1000","28","28000"},

{"青梅",0,"1000","27","27000"},

{"白梅",0,"1000","31","31000"},

{"紅梅",1,"1000","30","30000"},

{"黃梅",1,"1000","29","29000"},

{"綠梅",1,"1000","28","28000"},

{"青梅",1,"1000","27","27000"},

{"白梅",1,"1000","31","31000"}};

CImageList Cil1,Cil2;//大小圖像清單

(3)在程式初始化處增加表頭、圖像和清單控制建立代碼

BOOL CVCLISTDlg::OnInitDialog()

{   CDialog::OnInitDialog();

//......//其它代碼

// TODO: Add extra initialization here此處增加代碼

LV_ITEM lvitem;

LV_COLUMN lvcol;

int i,iPos,iItemNum;

CVCLISTApp *pApp=(CVCLISTApp *)AfxGetApp();//建立圖象清單

Cil1.Create(32,32,TRUE,2,2);

Cil1.Add(pApp->LoadIcon(IDI_GJ));

Cil1.Add(pApp->LoadIcon(IDI_XS));

Cil2.Create(16,16,TRUE,2,2);

Cil2.Add(pApp->LoadIcon(IDI_GJ));

Cil2.Add(pApp->LoadIcon(IDI_XS));//設定圖象清單

m_ListCtrl.SetImageList(&Cil1,LVSIL_NORMAL);

m_ListCtrl.SetImageList(&Cil2,LVSIL_SMALL);//向清單控制中添加表列

lvcol.mask=LVCF_FMT|LVCF_SUBITEM|LVCF_TEXT|LVCF_WIDTH;

lvcol.fmt=LVCFMT_CENTER;//居中

i=0;

lvcol.pszText="品 名";

lvcol.iSubItem=i;

lvcol.cx=70;

m_ListCtrl.InsertColumn(i++,&lvcol);

lvcol.pszText="數 量";

lvcol.iSubItem=i;

lvcol.cx=70;

m_ListCtrl.InsertColumn(i++,&lvcol);

lvcol.pszText="單 價";

lvcol.iSubItem=i;

lvcol.cx=70;

m_ListCtrl.InsertColumn(i++,&lvcol);

lvcol.pszText="金 額";

lvcol.iSubItem=i;

lvcol.cx=70;

m_ListCtrl.InsertColumn(i++,&lvcol);

//向清單控制中添加表項

iItemNum=sizeof(Sps)/sizeof(SPS);

for(i=0;i<iItemNum;i++){

lvitem.mask=LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM;

lvitem.iItem=i;

lvitem.iSubItem=0;

lvitem.pszText=Sps[i].szPm;

lvitem.iImage=Sps[i].Lx;

lvitem.lParam=i;

iPos=m_ListCtrl.InsertItem(&lvitem);//傳回表項插入後的索引号

lvitem.mask=LVIF_TEXT;

lvitem.iItem=iPos;

lvitem.iSubItem=1;

lvitem.pszText=Sps[i].szSl;

m_ListCtrl.SetItem(&lvitem);

lvitem.iSubItem=2;

lvitem.pszText=Sps[i].szDj;

m_ListCtrl.SetItem(&lvitem);

lvitem.iSubItem=3;

lvitem.pszText=Sps[i].szJe;

m_ListCtrl.SetItem(&lvitem);

}

CheckRadioButton(IDC_STDICON,IDC_REPORT,IDC_STDICON);

return TRUE; // return TRUE unless you set the focus to a control

}

(4)完善清單顯示方式代碼

在利用Classwizard類向導建立各功能按鈕顯示功能函數之後,必須依次完善這些功能函數的代碼,這些功能函數如下:

void CVCLISTDlg::OnStdicon()//設定大圖示顯示方式

{ // TODO: Add your control notification handler code here

LONG lStyle;

lStyle=GetWindowLong(m_ListCtrl.m_hWnd,GWL_STYLE);//擷取目前視窗類型

lStyle&=~LVS_TYPEMASK; //清除顯示方式位

lStyle|=LVS_ICON; //設定顯示方式

SetWindowLong(m_ListCtrl.m_hWnd,GWL_STYLE,lStyle);//設定視窗類型

}

void CVCLISTDlg::OnSmlicon() //設定小圖示顯示方式

{ // TODO: Add your control notification handler code here

LONG lStyle;

lStyle=GetWindowLong(m_ListCtrl.m_hWnd,GWL_STYLE);//擷取目前視窗類型

lStyle&=~LVS_TYPEMASK; //清除顯示方式位

lStyle|=LVS_SMALLICON; //設定顯示方式

SetWindowLong(m_ListCtrl.m_hWnd,GWL_STYLE,lStyle);//設定視窗類型

}

void CVCLISTDlg::OnList() //設定清單顯示方式

{ // TODO: Add your control notification handler code here

LONG lStyle;

lStyle=GetWindowLong(m_ListCtrl.m_hWnd,GWL_STYLE);//擷取目前視窗類型

lStyle&=~LVS_TYPEMASK; //清除顯示方式位

lStyle|=LVS_LIST; //設定顯示方式

SetWindowLong(m_ListCtrl.m_hWnd,GWL_STYLE,lStyle);//設定視窗類型

}

void CVCLISTDlg::OnReport() //詳細資料顯示方式

{ // TODO: Add your control notification handler code here

LONG lStyle;

lStyle=GetWindowLong(m_ListCtrl.m_hWnd,GWL_STYLE);//擷取目前視窗類型

lStyle&=~LVS_TYPEMASK; //清除顯示方式位

lStyle|=LVS_REPORT; //設定顯示方式

SetWindowLong(m_ListCtrl.m_hWnd,GWL_STYLE,lStyle);//設定視窗類型

}

(5)删除功能的實作

要實作删除功能,必須取得選中表項的數和表項總數,并且需要從後向前進行依次删除,其原因是每個表項被删除後,其後各表項的索引号均會發生遞減變化,如果采取從前向後删除的方法,就會造成無法正常删除選中的表項,其功能代碼如下:

void CVCLISTDlg::OnDel() //删除按鈕功能

{ // TODO: Add your control notification handler code here

int i,iState;

int nItemSelected=m_ListCtrl.GetSelectedCount();//所選表項數

int nItemCount=m_ListCtrl.GetItemCount();//表項總數

if(nItemSelected<1) return;

for(i=nItemCount-1;i>=0;i--){

iState=m_ListCtrl.GetItemState(i,LVIS_SELECTED);

if(iState!=0) m_ListCtrl.DeleteItem(i);

}

}

(6)排序功能的實作

清單控制有一個特殊的功能,當以詳細資料方式顯示時,清單頂部的表頭可以當作按鈕來使用,這可以通過清單控制建立時的風格來控制。當滑鼠點選清單頭名稱時,清單控制就會向其父視窗發送一個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);

}

7、清單視的演練技巧

在使用清單視時,其方法與清單控制基本相同,隻不過清單視是在視窗中來實作的而清單控制是在對話框中實作,清單視的各種功能是通過菜單來實作的而清單控制是通過按鈕等方式來實作的,清單控制需要在對話框中建立清單控制控件而清單視直接占據整個視窗,在設計過程中隻要将按鈕和清單控制設計過程變為菜單設計,并注意在功能增加是在類向導中是通過菜單指令來操作,同時在每個功能函數前面增加取得清單視引用的指令( CListCtrl& ListCtrl = GetListCtrl()),而其餘資料結構和代碼均不需要修改,實作起來比較容易。

繼續閱讀