一個ListCtrl的詳細實現

四、實踐學習:一個ListCtrl的詳細實現

1.切換到第一個對話框點擊ListCtrl控件

2.在屬性窗口,改變View屬性爲Report

3.創建ListCtrl的列,在OnInitDialog()中添加代碼如下:

 

複製代碼
BOOL CDeptStore2Dlg::OnInitDialog() { CDialog::OnInitDialog(); // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here LVCOLUMN lvColumn; lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH; lvColumn.fmt = LVCFMT_CENTER; lvColumn.cx =60; lvColumn.pszText ="Item #"; this->m_StoreItems.InsertColumn(0, &lvColumn); lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH; lvColumn.fmt = LVCFMT_LEFT; lvColumn.cx =100; lvColumn.pszText ="Category"; this->m_StoreItems.InsertColumn(1, &lvColumn); lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH; lvColumn.fmt = LVCFMT_LEFT; lvColumn.cx =160; lvColumn.pszText ="Item Name"; this->m_StoreItems.InsertColumn(2, &lvColumn); lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH; lvColumn.fmt = LVCFMT_LEFT; lvColumn.cx =80; lvColumn.pszText ="Size"; this->m_StoreItems.InsertColumn(3, &lvColumn); lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH; lvColumn.fmt = LVCFMT_RIGHT; lvColumn.cx =60; lvColumn.pszText ="Unit Price"; this->m_StoreItems.InsertColumn(4, &lvColumn); lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH; lvColumn.fmt = LVCFMT_RIGHT; lvColumn.cx =30; lvColumn.pszText ="Qty"; this->m_StoreItems.InsertColumn(5, &lvColumn); this->m_StoreItems.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES); return TRUE; // return TRUE unless you set the focus to a control }
複製代碼

4.準備創建一個完全的項,設計一個第一個對話框如下:

Control

Caption

ID

Other Properties

Static Text

Category:

 

 

Combo Box

 

IDC_CATEGORIES

Data: Babies;Teens;Women;Men;Miscellaneous

Static Text

Item Name:

 

 

Edit Control

 

IDC_ITEMNAME

 

Static Text

Item Size:

 

 

Edit Control

 

IDC_ITEMSIZE

 

Static Text

Qty:

 

 

Edit Control

 

IDC_QUANTITY

 

Static Text

Unit Price:

 

 

Edit Control

 

IDC_UNITPRICE

 

Static Text

Item #:

 

 

Edit Control

 

IDC_ITEMNUMBER

 

Button

OK

IDOK

 

Button

Cancel

IDCANCEL

 

5.如下創建CString變量

ID

Value Variable

IDC_CATEGORIES

m_Categories

IDC_ITEMNAME

m_ItemName

IDC_ITEMSIZE

m_ItemSize

IDC_QUANTITY

m_Quantity

IDC_UNITPRICE

m_UnitPrice

6.在主窗口中,雙擊新建項改變它的實現爲:

 

複製代碼
void CDeptStore2Dlg::OnBnClickedNewitem() { // TODO: 在此添加控件通知處理程序代碼 CNewStoreItemDlg1 dlg; srand( (unsigned)time(NULL) ); wchar_t strNumber[20]; int number1 = rand() %999; int number2 = rand() %999; swprintf(strNumber, TEXT("%d-%d"), number1, number2); dlg.m_ItemNumber = strNumber; if( dlg.DoModal() ) { LVITEM lvItem; int nItem; lvItem.mask = LVIF_TEXT; lvItem.iItem =0; lvItem.iSubItem =0; lvItem.pszText = strNumber; nItem =this->m_StoreItems.InsertItem(&lvItem); this->m_StoreItems.SetItemText(nItem, 1, dlg.m_Categories); this->m_StoreItems.SetItemText(nItem, 2, dlg.m_ItemName); this->m_StoreItems.SetItemText(nItem, 3, dlg.m_ItemSize); this->m_StoreItems.SetItemText(nItem, 4, dlg.m_UnitPrice); this->m_StoreItems.SetItemText(nItem, 5, dlg.m_Quantity); } }
複製代碼

 

7.運行應用程序,用下面的數據創建數據項(讓計算機隨機生成itemNumber)

Category

Item Name

Size

Qty

Unit Price

Women

Cashmere Lined Glove

8

12

115.95

Miscellaneous

Chocolate Gift Box

Medium

5

45.00

Men

Trendy Jacket

Medium

8

45.85

Women

Stretch Flare Jeans

Petite

6

27.75

Women

Belted Sweater

Large

10

15.95

Teens

Girls Classy Handbag

One Size

4

95.95

Women

Casual Dress Shoes

9.5M

16

45.95

Babies

Infant Girls Ballerina Dress

2M

14

22.85

Teens

Girls Velour Dress

10

8

12.55

Women

Lace Desire Panty

M

22

7.15

Teens

Boys Hooded Sweatshirt

M (7/8)

16

42.75

Men

Classic Pinstripe Suit

38

8

145.90

8.關閉窗口,返回應用程序

Views轉換 

你可以創建一個ListCtrl顯示一個單獨的View,你也可以允許用戶區改變從一個View到另外一個。和剛纔所說的一樣,在設計的時候或者程序動態創建一個ListCtrl,你可以設置一個初始化View用ComboBox去選擇一個View。如果你想在初始化的時候顯示,你可以停到那裏,否則你可以提供改變的一種。

因爲在一個ListCtrl顯示的View是它風格的一部分。爲了動態改變它的View模型,你可以用GetWindowLong()返回控件的風格。GetWindowLong()函數只返回當前控件的風格。你可能需要在改變它之前選擇它。通過爲GetWindowLong()函數增加LVS_TYPEMASK常量,在選擇控件的View之後,你接着可以用SetWindowLong()函數來改變它的風格。示例如下:

 

複製代碼
void COthersDlg::OnIconBtn() { // TODO: Add your control notification handler code here LONG mListStyle = GetWindowLong(m_List.m_hWnd, GWL_STYLE); mListStyle &=~LVS_TYPEMASK; mListStyle |= LVS_ICON; SetWindowLong(m_List.m_hWnd, GWL_STYLE, mListStyle); } void COthersDlg::OnSmallIconBtn() { // TODO: Add your control notification handler code here LONG mListStyle = GetWindowLong(m_List.m_hWnd, GWL_STYLE); mListStyle &=~LVS_TYPEMASK; mListStyle |= LVS_SMALLICON; SetWindowLong(m_List.m_hWnd, GWL_STYLE, mListStyle); } void COthersDlg::OnListBtn() { // TODO: Add your control notification handler code here LONG mListStyle = GetWindowLong(m_List.m_hWnd, GWL_STYLE); mListStyle &=~LVS_TYPEMASK; mListStyle |= LVS_LIST; SetWindowLong(m_List.m_hWnd, GWL_STYLE, mListStyle); } void COthersDlg::OnReportBtn() { // TODO: Add your control notification handler code here LONG mListStyle = GetWindowLong(m_List.m_hWnd, GWL_STYLE); mListStyle &=~LVS_TYPEMASK; mListStyle |= LVS_REPORT; SetWindowLong(m_List.m_hWnd, GWL_STYLE, mListStyle); }
複製代碼

 

五、實踐學習:改變ListCtrl的View

1.在類視圖中,擴展DeptStore2,右擊CDeptStoreDlg2->Add->Add Function

2.設置返回值爲DWORD類型,函數名爲GetViewType

3.點擊完成,函數實現如下:

 

DWORD CDeptStore2Dlg::GetViewType(void) { return (GetStyle() & LVS_TYPEMASK); }

4.在類視圖中,右擊CDeptStore2Dlg->Add->Add Function

5.設置返回值爲void,函數名稱爲SetViewType,參數類型爲DWORD,參數名爲dwViewType,點擊Add。

6.點擊完成,函數實現如下:

 

複製代碼
void CDeptStore2Dlg::SetViewType(DWORD dwViewType) { DWORD dwCurType; HWND hWnd; hWnd =this->m_StoreItems; GetSafeHwnd(); dwCurType = ::GetWindowLong(hWnd, GWL_STYLE); dwCurType &=~LVS_TYPEMASK; dwViewType |= dwCurType; ::SetWindowLong(hWnd, GWL_STYLE, dwViewType); }
複製代碼

7.切換到第一個對話框,如下增加四個按鈕:

Button ID

Caption

IDC_LARGE

Large

IDC_SMALL

Small

IDC_LIST

List

IDC_DETAILS

Details

8.雙擊Large按鈕,如下實現OnBnClicked事件:

 

void CDeptStore2Dlg::OnBnClickedLarge() { // TODO: Add your control notification handler code here SetViewType(LVS_ICON); }

 

9.類似添加其他按鈕的事件響應函數,如下:

 

複製代碼
void CDeptStore2Dlg::OnBnClickedSmall() { // TODO: Add your control notification handler code here if( GetViewType() != LVS_SMALLICON) SetViewType(LVS_SMALLICON); } void CDeptStore2Dlg::OnBnClickedList() { // TODO: Add your control notification handler code here if( GetViewType() != LVS_LIST) SetViewType(LVS_LIST); } void CDeptStore2Dlg::OnBnClickedDetails() { // TODO: Add your control notification handler code here if( GetViewType() != LVS_REPORT) SetViewType(LVS_REPORT); }
複製代碼

10.保存

ListCtrl和Icon

ListCtrl可以將實現圖片,顯示記錄或者將兩者組合顯示。如果你想在列上顯示一幅位圖,你應該聲明一個CImageList變量並初始化。然後調用CListCtrl::SetImageList()方法,併爲之傳參。如果你想這麼做,並且你用的是第一個版本傳遞LVCOLUMN指針參數CListCtrl::InsertColumn()方法,需要給mask參數添加LVCF_IMAGE值,並且爲fmt添加LVCFMT_IMAGE值。指定的圖像會顯示在列的首項上,把列的索引賦給iImage變量。示例如下:

 

複製代碼
BOOL COthersDlg::OnInitDialog() { CDialog::OnInitDialog(); // TODO: Add extra initialization here LVCOLUMN lvColumn; CImageList *ImgHeaders = new CImageList; ImgHeaders->Create(16, 16, ILC_MASK, 1, 1); ImgHeaders->Add(AfxGetApp()->LoadIcon(IDI_UP)); ImgHeaders->Add(AfxGetApp()->LoadIcon(IDI_LOSANGE)); m_List.SetImageList(ImgHeaders, LVSIL_SMALL); lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_IMAGE; lvColumn.fmt = LVCFMT_LEFT | LVCFMT_IMAGE; lvColumn.cx = 120; lvColumn.pszText = "Full Name"; lvColumn.iImage = 0; m_List.InsertColumn(0, &lvColumn); lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH; lvColumn.fmt = LVCFMT_LEFT; lvColumn.cx = 100; lvColumn.pszText = "Profession"; m_List.InsertColumn(1, &lvColumn); lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_IMAGE; lvColumn.fmt = LVCFMT_LEFT | LVCFMT_IMAGE; lvColumn.iImage = 1; lvColumn.cx = 80; lvColumn.pszText = "Fav Sport"; m_List.InsertColumn(2, &lvColumn); lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH; lvColumn.fmt = LVCFMT_LEFT; lvColumn.cx = 75; lvColumn.pszText = "Hobby"; m_List.InsertColumn(3, &lvColumn); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE }
複製代碼

 

在控件上使用位圖或圖標,你應該首先創建位圖或圖。如果你不打算使用Report View並且你想使用位圖,你可以創建一個很長的位圖(由一些小的大小相似的位圖組成)。每一幅圖像供每一個項使用。正常情況下,每個圖片應該大小爲16*16或者更小。下面是示例:

 

位圖是由6幅相同大小的圖片組成的。如果你不打算使用Report View並且你打算使用icons,那麼就應該單獨的創建16*16大小的icon。

如果你想使用ReportView和其他Views顯示控件項,如果你想使用位圖,你用該創建兩個長位圖。一個應該是16*16大小的。這樣的圖片用來做小圖標(small icon),List,和ReportViews。你應該創建第二個位圖,大小爲32*32。這些圖片用來爲ListView服務。

 

在你創建完位圖或者圖標之後,緊接着聲明一個指向CImageList類的指針並且用CImageList::Create方法來初始化。調用CListCtrl::SetImageList()方法來確定有效。語法如下:

CImageList* SetImageList(CImageList* pImageList, int nImageList);

pImageList:CImageList變量或者已被初始化的指針。

nImageList:使用ImageList的類型標識,它可以是如下幾個值:

Value

Description

LVSIL_NORMAL

The image list is made of large bitmap or icons, typically 32x32

LVSIL_SMALL

The image list is made of small bitmap or icons, typically 16x16

LVSIL_STATE

The image list is made of pictures that will be used as mask

你可以使用CListCtrl::InsertItem()的幾個版本來實現,向列表項關聯圖片:

 

複製代碼
int InsertItem(int nItem, LPCTSTR lpszItem, int nImage ); int InsertItem(UINT nMask, int nItem, LPCTSTR lpszItem, UINT nState, UINT nStateMask, int nImage, LPARAM lParam );
複製代碼

 

nImage:使用圖片的索引。

nMask:和LVITEM::mask成員類似,它簡單的指定你需要在項上顯示的信息。

nState:和LVITEM::state成員變量相似,指定項的行爲。是否能被選中,失去焦點時,以及有沒有剪切粘貼操作,高亮和拖拽功能。

nStateMask:用來結合nState參數。指定精確的類型信息。

lParam:和TVITEM的lParam成員一樣,用來執行指定項的操作,例如牽涉到項的排序和查找。

六、實踐學習:爲ListCtrl控件項關聯位圖

1.創建位圖,在主菜單,右擊工程->添加資源,在添加資源對話框內選擇位圖->單擊新建

2.在設置屬性窗口中,改變ID爲IDB_SMALLIMG,設置高度爲16,寬度爲144.設計如下位圖:

3.在增加位圖,設置ID爲IDB_LARGING,設置寬度爲32,高度爲288。設計位圖如下:

4.在主對話框的頭文件中聲明兩個CImageList變量,如下:

private:

    CImageList m_SmallImg;

    CImageList m_LargeImg;

};

5. 在OnInitDialog()方法中添加如下初始化代碼:

 

m_SmallImg.Create(IDB_SMALLING, 16, 1, RGB(255, 255, 255)); m_LargeImg.Create(IDB_LARGING, 32, 1, RGB(255, 255, 245)); m_StoreItems.SetImageList(&m_SmallImg, LVSIL_SMALL); m_StoreItems.SetImageList(&m_LargeImg, LVSIL_NORMAL);

6.使用圖像,改變新建的事件響應函數:

 

複製代碼
void CDeptStore2Dlg::OnBnClickedNewitem() { // TODO: 在此添加控件通知處理程序代碼 CNewStoreItemDlg1 dlg; srand( (unsigned)time(NULL) ); wchar_t strNumber[20]; int number1 = rand() %999; int number2 = rand() %999; swprintf(strNumber, TEXT("%d-%d"), number1, number2); dlg.m_ItemNumber = strNumber; if( dlg.DoModal() ) { LVITEM lvItem; int nItem; int imgNbr; if( dlg.m_Categories == TEXT("Babies") ) imgNbr =0; elseif( dlg.m_Categories == TEXT("Teens") ) imgNbr =1; elseif( dlg.m_Categories == TEXT("Women") ) imgNbr =2; elseif( dlg.m_Categories == TEXT("Men") ) imgNbr =3; else// if( dlg.m_Category == "Miscellaneous" ) imgNbr =4; lvItem.mask = LVIF_TEXT; lvItem.iItem =0; lvItem.iSubItem =0; lvItem.iImage = imgNbr; lvItem.pszText = strNumber; nItem =this->m_StoreItems.InsertItem(&lvItem); this->m_StoreItems.SetItemText(nItem, 1, dlg.m_Categories); this->m_StoreItems.SetItemText(nItem, 2, dlg.m_ItemName); this->m_StoreItems.SetItemText(nItem, 3, dlg.m_ItemSize); this->m_StoreItems.SetItemText(nItem, 4, dlg.m_UnitPrice); this->m_StoreItems.SetItemText(nItem, 5, dlg.m_Quantity); } }
複製代碼

7.運行程序

 

<完>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章