一、在Windows應用程序中添加ListControl控件的幾種方法
1、在對話框中添加控件:
創(chuàng)建對話框應用程序,在資源視圖中添加對話框。如下圖所示,在控件工具條中選擇ListControl控件添加到對話框中,并調整控件尺寸。在ListControl控件的屬性頁中設置控件樣式(Styles)和擴展樣式等。為了顯示詳細數(shù)據(jù)信息,可以設置控件的顯示風格為報表視圖(Report)。
![](http://image4.360doc.com/DownloadImg/2009/11/5/327526_8445596_1)
為了在對話框中使用控件,需要在ClassWizard中為對話框類添加控件成員變量,如下圖所示:
![](http://image4.360doc.com/DownloadImg/2009/11/5/327526_8445596_2)
執(zhí)行以上操作后,系統(tǒng)自動添加了一個ClistControl對象,并與ListControl控件資源關聯(lián),相關代碼如下:
// ListDialogDlg.h : header file
......
public:
CListCtrl m_cListCtrl;
......
// ListDialogDlg.cpp : implementation file
......
void CListDialogDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CListDialogDlg)
DDX_Control(pDX, IDC_LIST_CTRL, m_cListCtrl);
//}}AFX_DATA_MAP
}
......
因為本例只為演示在對話框中添加ListControl控件,所以只在對話框初始化消息函數(shù)中添加了以下顯示控件的示例代碼(代碼含義請參照MSDN文獻):
BOOL CListDialogDlg::OnInitDialog()
{
CDialog::OnInitDialog();
......
// TODO: Add extra initialization here
DWORD exstyle = m_cListCtrl.GetExtendedStyle();
m_cListCtrl.SetExtendedStyle(exstyle | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES |
LVS_EX_CHECKBOXES | WS_EX_STATICEDGE );
CRect rect;
m_cListCtrl.GetClientRect(&rect);
int nColInterval = rect.Width()/5;
m_cListCtrl.InsertColumn(0, _T("Item Name"), LVCFMT_LEFT, nColInterval*3);
m_cListCtrl.InsertColumn(1, _T("Value"), LVCFMT_LEFT, nColInterval);
m_cListCtrl.InsertColumn(2, _T("Time"), LVCFMT_LEFT, rect.Width()-4*nColInterval);
m_cListCtrl.InsertItem(0,"name");
m_cListCtrl.SetItemText(0,1,"value");
m_cListCtrl.SetItemText(0,2,"time");
......
return TRUE; // return TRUE unless you set the focus to a control
}
2、在單文檔視圖中自行添加ListControl控件:
創(chuàng)建單文檔應用程序,如下圖所示為視圖類添加CListCtrl對象成員變量:
![](http://image4.360doc.com/DownloadImg/2009/11/5/327526_8445596_3)
如下圖所示,在資源視圖中打開String Table資源,在右鍵菜單中選擇new string,為將要創(chuàng)建的ListControl控件添加資源編號:
![](http://image4.360doc.com/DownloadImg/2009/11/5/327526_8445596_4)
為創(chuàng)建和顯示控件,在視圖的初始化消息函數(shù)中添加如下代碼:
void CAddListView::OnInitialUpdate()
{
CView::OnInitialUpdate();
// TODO: Add your specialized code here and/or call the base class
m_cListCtrl.Create( LVS_REPORT,CRect(0,0,800,600),this,IDC_LISTCTRL);
m_cListCtrl.ModifyStyle(0,LVS_REPORT|LVS_SHOWSELALWAYS|LVS_SORTASCENDING);
//m_cListCtrl.SendMessage(LVM_SETEXTENDEDLISTVIEWSTYLE,0,
LVS_EX_GRIDLINES|LVS_EX_FULLROWSELECT|LVS_EX_CHECKBOXES);
m_cListCtrl.ShowWindow(SW_SHOW);
CRect rect;
m_cListCtrl.GetClientRect(&rect);
int nColInterval = rect.Width()/5;
m_cListCtrl.InsertColumn(0, _T("Item Name"), LVCFMT_LEFT, nColInterval*3);
m_cListCtrl.InsertColumn(1, _T("Value"), LVCFMT_LEFT, nColInterval);
m_cListCtrl.InsertColumn(2, _T("Time"), LVCFMT_LEFT, rect.Width()-4*nColInterval);
m_cListCtrl.InsertItem(0,"name");
m_cListCtrl.SetItemText(0,1,"value");
m_cListCtrl.SetItemText(0,2,"time");
}
3、在ListView視圖中顯示ListControl控件:
創(chuàng)建單文檔應用程序,如下圖所示,在選擇窗口視圖類型時,選擇CListView視圖:
![](http://image4.360doc.com/DownloadImg/2009/11/5/327526_8445596_5)
在視圖類的初始化消息函數(shù)中添加如下顯示控件的代碼:
void CTestlistView::OnInitialUpdate()
{
CListView::OnInitialUpdate();
CDC* dc = GetDC();
TEXTMETRIC tm;
dc->GetTextMetrics(&tm);
GetListCtrl().ModifyStyle(0,LVS_REPORT|LVS_SHOWSELALWAYS|LVS_SORTASCENDING);
GetListCtrl().SendMessage(LVM_SETEXTENDEDLISTVIEWSTYLE,0,
LVS_EX_GRIDLINES|LVS_EX_FULLROWSELECT|LVS_EX_CHECKBOXES|LVS_EX_TRACKSELECT);
GetListCtrl().InsertColumn(0,"Name",LVCFMT_LEFT,30*tm.tmAveCharWidth,0);
GetListCtrl().InsertColumn(1,"Comment",LVCFMT_LEFT,70*tm.tmAveCharWidth,1);
// TODO: You may populate your ListView with items by directly accessing
// its list control through a call to GetListCtrl().
}
二、為ListControl控件添加消息處理函數(shù)
1、關于ListControl控件消息
在ListControl控件中有以下消息(通知)可以發(fā)送:NM_CLICK、NM_DBLCLK、NM_RCLICK、LVN_COLUMNCLICK、HDN_ITEMCLICK等。
其中HDN_ITEMCLICK是List Control的子控件ListCtrl發(fā)給它的Parent(CListCtrl)的;LVN_COLUMNCLICK是HeaderCtrl發(fā)給它的Parent的。所以在Dialog里面,試圖通過ClassWizard產生的ON_NOTIFY宏:ON_NOTIFY(HDN_ITEMCLICK, IDC_LIST_CTRL,OnItemClick),來接收HDN_ITEMCLICK消息是無法成功的。要解決這個問題,可以從CListCtrl派生一個新的類,并在CListCtrl派生類中處理HDN_ITEMCLICK消息。注意消息映射的時候,Header的控件ID是0,類似如下消息映射宏代碼:
ON_NOTIFY(HDN_ITEMCLICK, 0, OnItemClick)
另外,可以使用NM_CLICK、NM_RCLICK等消息,以NM打頭的消息是可以在Dialog里處理的。
2、關于ListControl控件的行選擇:
要在控件中選擇行,需要設置控件的擴展屬性LVS_EX_FULLROWSELECT。右鍵或左鍵都可以選擇行,而且,List Control控件默認可以一次選擇(使用Ctrl鍵)多行,被選擇的行默認以藍色背景顯示。
3、為ListControl控件添加NM_CLICK消息:
以前面創(chuàng)建的對話框應用程序為例,在ClassWizard中選擇List Control控件,在對話框類中添加NM_CLICK消息處理函數(shù)。如下圖所示:
![](http://image4.360doc.com/DownloadImg/2009/11/5/327526_8445596_6)
系統(tǒng)自動添加的消息映射與消息處理函數(shù)代碼如下:
// ListDialogDlg.h : header file
protected:
......
afx_msg void OnClickListCtrl(NMHDR* pNMHDR, LRESULT* pResult);
......
// ListDialogDlg.cpp : implementation file
BEGIN_MESSAGE_MAP(CListDialogDlg, CDialog)
//{{AFX_MSG_MAP(CListDialogDlg)
......
ON_NOTIFY(NM_CLICK, IDC_LIST_CTRL, OnClickListCtrl)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void CListDialogDlg::OnClickListCtrl(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
CString str;
str.Format(_T("Item index: %d,SubItem:%d"), pNMListView->iItem,
pNMListView->iSubItem);
MessageBox(str);
*pResult = 0;
}
其中黑體部分代碼為自行添加的測試代碼,主要為了獲取選擇的行編號與列編號,有了行編號和就可以使用m_cListCtrl.GetItemText(選擇的行編號,某一列的列編號)獲取某行某字段的值(如數(shù)據(jù)庫表表示字段的值),可以定義一個對話框類成員變量存儲該值,用于菜單或按鈕命令,如修改記錄、顯示備注型(或圖片型)字段內容、刪除記錄等。
4、添加NM_RCLICK消息和右鍵菜單:
與NM_CLICK類似,添加NM_RCLICK消息處理函數(shù)。如下圖所示創(chuàng)建菜單資源:
![](http://image4.360doc.com/DownloadImg/2009/11/5/327526_8445596_7)
在NM_RCLICK消息處理函數(shù)中添加如下顯示右鍵菜單的代碼:
void CListDialogDlg::OnRclickListCtrl(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
//CPoint point;
//::GetCursorPos(&point);//::可以提示全局函數(shù)和當前類成員函數(shù)
DWORD dwPos = GetMessagePos();
CPoint point( LOWORD(dwPos), HIWORD(dwPos) );
CMenu menu;
VERIFY( menu.LoadMenu( IDR_MENU1 ) ); //IDR_MENU1是新建菜單ID
CMenu* popup = menu.GetSubMenu(0);
//ASSERT( popup != NULL );
popup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,
this );//TPM_RIGHTBUTTON使右鍵點擊菜單也起作用
*pResult = 0;
}
在ClassWizard中為菜單項ID_DELETE添加刪除命令消息處理函數(shù)。以下是測試代碼:
void CListDialogDlg::OnDelete()
{
// TODO: Add your command handler code here
int iItemSel = m_cListCtrl.GetNextItem(-1, LVIS_SELECTED);
CString str="";
while(iItemSel != -1)
{
//m_cListCtrl.DeleteItem(iItemSel);//delete selected item in the list control
str=str+m_cListCtrl.GetItemText(iItemSel,0);//利用該方法可以獲取數(shù)據(jù)記錄編號列
iItemSel = m_cListCtrl.GetNextItem(iItemSel, LVIS_SELECTED);
}
MessageBox(str);
}
代碼中的循環(huán)是為了處理同時選擇了多行的情況。可以在代碼中添加根據(jù)選擇的行編號iItemSel獲得數(shù)據(jù)記錄編號的代碼,在控件中刪除行的同時,刪除數(shù)據(jù)庫表中的相應記錄。