转载ListCtrl控件

、本文为翻译文章,水平有限,错误之处,烦请指正([email protected])。

2、使用VS2005,所以在某些细节上和原作者不太一样

3、工程中使用图片和作者略有不同

4、文章如有争议,以原作者文章为准

5、转载请标明出处

原文链接:http://www.functionx.com/visualc/controls/listcontrol.htm

一、ListControl概述

概述:

ListCtrl控件由四种列表的显示方式构成,它最典型的用法是使用icon来显示。ListCtrl通常显示下面四种项目(item):

Icons: 控件显示项的列表,使用32*32(像素)大小的icons,推荐使用这么大小的icon,如果你想用图标来概述你的观点。

Small Icons:和剩下的两项相似的想法,它使用16*16(像素)大小的图标来显示一个单一的列表项。再次,没有提供关于这个列表的详细说明。这种列表是用来组织和其他主题在不同的列,如果列表有序,序列编排为按字母顺序从左到右。

List:这种列表,使用small icons,也是组织列;这种情况下,在第二列填充之前必须填充第一列。如果列表有序,序列编排为自顶向下的顺序。

Report:安排项的目的是提供列表开发者的信息。

二、实践学习:List Control介绍

1. 用Visual C++或者Visual Studio 创建一个名为DeptStore2的MFC应用程序

2. 基于Dialog创建它

3. 删除“TODO: 在此放置对话框控件。”行和确定按钮。

4. 将“取消”按钮的标题改为“关闭”

(1)      创建List Control

ListCtrl控件在MFC类库用CListCtrl类来实现。在设计的时候,创建一个ListCtrl,在toolbox中点击按钮 后单击对话框中想要放置的区域。通常来说,需要拉伸默认ListCtrl的默认大小,因为它通常需要一个更大的区域。

为了编程创建一个ListCtrl,声明CListCtrl变量或者CListCtrl指针。初始化控件调用它的Create方法,示例如下:

BOOL CDeptStore2Dlg::OnInitDialog()
{
    CDialog::OnInitDialog();
    // ...
    // TODO: 在此添加额外的初始化代码
    CListCtrl *lstCtrl =new CListCtrl;
    lstCtrl->Create(WS_CHILD | WS_VISIBLE,
        CRect(10, 10, 320, 280), this, 0x285);
    return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

译者提示:这是内存泄露的做法,也许作者意图只是为了说明应在OnInitDialog添加代码,正确的做法在CDeptStore2Dlg中添加变量m_lstCtrl,之后在OnInitDialog中new,最后在析构函数中delete。

在之前提到,ListCtrl可以显示四种情况之一,在设计的时候应该在窗口属性中指定想要的风格,在属性中选择combo box,默认值是Icon,他可能是情况是:

Icon:当编程创建控件的时候,增加LVS_ICON风格;

Small Icon:类似的可以动态添加LVS_SMALLICON风格:

List:当创建的时候可以类似的添加LVS_REPORT风格;

Report:这种情况清楚的显示了列,同样应添加LVS_REPORT风格。

除了常规的几种风格外,Win32类库为ListCtrl提供了扩展风格,提供了一个扩展风格,调用CListCtrl::SetExtendStyle()方法,它的语法为:

DWORD SetExtendedStyle(DWORD dwNewStyle);

当调用这个函数的时候,把指定的扩展风格或者他们的组合风格作为参数来传递。其中的一些值是:

LVS_EX_CHECKBOXES:在左侧显示选择框(check box)

LVS_EX_FULLROWSELECT:这种风格允许Report View的整行来被选择而不是仅仅一项;

LVS_EX_GRIDLINES:相对上一种风格来说增加了水平和垂直分割线。

LVS_EX_TRACKSELECT:当设置这种风格的时候,用户可以隔项选取。

列表控件仅仅能在控件内显示,如果这儿他们太多或者各项的总宽度比控件可以显示的区域大,应该给它配备水平滚动条和垂直滚动条,或者两个都有。如果你想阻止滚动条的显示,设置无滚动条的属性为true或者创建属性为LVS_NOSCROLL风格。

一旦list控件创建,使用者可以选择一个选项通过点击它,然后选择更多的项,使用者也可以辅助ctrl来随机选择或者辅助shift连续选取,下面是一个随机选取的一个样例:

如果你不想用户每次选择多项的话,你可以设置通过增加LVS_SINGLESEL单选属性为true。

任何项被选中的时候都是高亮的,当用户点击另一个控件或者另一个应用程序的时候,你是否可以确定你想那些被选项仍旧被选中呢?典型的情况是在设计的时候通过选择“Always”属性来实现。默认情况下,设置为false,意味着当控件失去焦点或者它的父窗口无效的情况下,被选项将不会显示(高亮)。否则,你可以把这个属性设置为true,这样即使它失去焦点也也可以是选中状态。这个属性也可以通过设置LVS_SHOWSELALWAYS风格来实现。

三、实践学习:创建一个ListCtrl

1.在ToolBox上,单击ListCtrl控件然后点击对话框,将ID改为IDC_STORE_ITEMS

2.右击控件,添加变量

3.设置变量为:m_StoreItems

4.点击完成

ListCtrl的项

通过添加(使用toolboax)或者动态创建一个ListCtrl之后,下一个环节你应该让它来显示项。这个可以通过调用CListCtrl::InsertItem()方法,它的一种声明如下:

int InsertItem(const LVITEM* pItem);

这个版本需要一个LVITEM的指针作为参数,LVITEM定义如下:

typedef struct {
  UINT   mask;
  int    iItem;
  int    iSubItem;
  UINT   state;
  UINT   stateMask;
  LPTSTR pszText;
  int    cchTextMax;
  int    iImage;
  LPARAM lParam;
#if (_WIN32_IE >= 0x0300)
  int    iIndent;
#endif
#if (_WIN32_WINNT >= 0x0501)
  int    iGroupId;
  UINT   cColumns;
  UINT   puColumns;
#endif
#if (_WIN32_WINNT >= 0x0600)
  int    piColFmt;
  int    iGroup;
#endif
} LVITEM, *LPLVITEM;

mask:用来指定你想给当前项设置的类型。

iItem:指定改变项的索引,第一个item应该为0,第二个item为1等等。

iSumItem:当前值的的子项,如果当前项是主导项,iSumItem应该存储从0开始的数组。

pszText:要显示项的字符串,你可以通过cchTextMask指定文本的长度。

初始化LVITEM之后,调用InsertItem()方法来为list添加一个项。以下是范例:

BOOL CDeptStore2Dlg::OnInitDialog()
{
    CDialog::OnInitDialog();
    // ...
    // TODO: 在此添加额外的初始化代码
    LVITEM lvItem;

    lvItem.mask = LVIF_TEXT;
    lvItem.iItem =0;
    lvItem.iSubItem =0;
    lvItem.pszText = _T("Sandra C. Anschwitz");
    m_StoreItems.InsertItem(&lvItem);

    lvItem.mask = LVIF_TEXT;
    lvItem.iItem =1;
    lvItem.iSubItem =0;
    lvItem.pszText = _T("Roger A. Miller");
    m_StoreItems.InsertItem(&lvItem);

    lvItem.mask = LVIF_TEXT;
    lvItem.iItem =2;
    lvItem.iSubItem =0;
    lvItem.pszText = _T("Marie-Julie W. Gross");
    m_StoreItems.InsertItem(&lvItem);

    lvItem.mask = LVIF_TEXT;
    lvItem.iItem =3;
    lvItem.iSubItem =0;
    lvItem.pszText = _T("Ella Pius Roger");
    m_StoreItems.InsertItem(&lvItem);

    return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

LVITEM结构体的值将决定新项的功能。例如,一旦增加了一个项,你可能想要准备删除前面的项、剪切和粘贴操作,在这种情况下,你应该将设置为LVIS_CUT;如果你想实现拖放操作,你可以设置LVIS_DROPHILIGHTED;如果想让项获得焦点,设置LVIS_FOCUSED;包含LVIS_SELECTED属性的情况下可以被选中。

除了上面的CListCtrl::InsertItem()版本,CListCtrl类还提供了如下版本:

int InsertItem(int nItem, LPCTSTR lpszItem);

这是一个早期最简洁的版本。nItem表示新增项的索引。和LVITEM::iItem成员类似,如果参数为0,新增项是首项。lpszItem参数值是当前项内容的字符串。

四、实战学习:构建(Populating)ListCtrl

1.             新建一个dialog box,选择主菜单项->右击工程->增加资源

2.             在增加资源对话框中选择dialog

3.             修改对话框的ID为:IDD_STOREITEMS_DLG

4.             设计对话框如下:


Control


ID


Caption


Static Text


Item #:


Edit Control


IDC_ITEMNUMBER

5.    右击对话框,选择添加类

6.    设置类的名字为CNewStoreItemDlg基类为CDialog

7.    点击完成

8.    为edit control增加一个CString变量,命名为m_ItemNumber

9.    切换到第一个对话框,在ListCtrl下面,增加一个按钮,设置它的属性如下:

标题:新建项

ID:IDC_NEWITEM

10.  双击新建项按钮,生成它的OnBnClicked事件。

11.  在文件的前面,键入:#include "NewStoreItemDlg.h"

#include "stdafx.h"
#include "DeptStore2.h"
#include "DeptStore2Dlg.h"

#include "NewStoreItemDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif

12.   如下实现事件内容:

void CDeptStore2Dlg::OnBnClickedNewitem()
{
    // TODO: Add your control notification handler code here
    CNewStoreItemDlg dlg;
    srand( (unsigned)time(NULL) );
    char strNumber[20];

    int number1 = rand() %999;
    int number2 = rand() %999;

    sprintf(strNumber, "%d-%d", number1, number2);
    dlg.m_ItemNumber = strNumber;

    if( dlg.DoModal() )
    {
        LVITEM lvItem;

        lvItem.mask = LVIF_TEXT;
        lvItem.iItem =0;
        lvItem.iSubItem =0;
        lvItem.pszText = strNumber;
        this->m_StoreItems.InsertItem(&lvItem);
    }
}

13.  运行应用程序,测试新建项

报告方式显示(The Report View)

无论你是用第一还是第二个版本,InsertItem只允许你去创建你要显示的图标,小图标,或者控件的List Views的项。如果你计划去显示在Report View(或者允许用户在几种显示方式中转换)或者你想要提供更多的信息为每一个项,你必须要创建一个关于每一个项信息的报告。

在ListCtrl可能的显示方式中,其中有一种可以显示列。这种使用报告的方式。这种方式不需要一个列表,而是提供一个列表的项的详细信息。如果你打算在你的ListCtrl控件中显示,那么你应该去创建列。(要么,你可以省略创建列而是每个分离的列的首项,可以使用CHeaderCtrl类来实现。否则,ListCtrl提供创建列为它的报告显示)

To create the column(s) of a list control, you can use the CListCtrl::InsertColumn() method. One of its syntaxes is:

创建一个ListCtrl的列,你可以使用CListCtrl::InsertColumn()方法,它的一种声明为:

int InsertColumn(int nCol, const LVCOLUMN* pColumn);

nCol:将要创建列的索引

pColumn:指向LVCOLUMN结构体指针,结构体定义如下:

typedef struct _LVCOLUMN {
    UINT mask;
    int fmt;
    int cx;
    LPTSTR pszText;
    int cchTextMax;
    int iSubItem;
    #if (_WIN32_IE >= 0x0300)
        int iImage;
        int iOrder;
    #endif
} LVCOLUMN, FAR *LPLVCOLUMN;

mask: 用来指定你想要的列的属性

Fmt: 格式化列的文本。例如,它可以使列左对齐(默认值LVCFMT_LEFT),居中(LVCFMT_CENTER),或者右对齐(LVCFMT_RIGHT)。如果你想为这个值设置一个值,那么在初始化mask变量的时候增加LVCF_FMT属性。

cx 用来指定列文本的宽度。如果你初始化,它的长度将被初始化为刚好能显示文本的长度。因此,除非你有一个好的理由去省略它,你应该总是指定它的值。如果你打算去初始化这个值,那么在初始化mask变量的时候增加LVCF_WIDTH属性。

pszText 是将要显示的列的字符串。和其他成员一样,此变量不是必须要初始化的,除了每一个列的第一个元素。这个成员可能是最重要的列的特征,因为它告诉用户这一列的作用。它的值是一个"\0"结尾的字符串。和其他MFC应用程序中的字符串一样,该字符串可以是一个字符串表项。它也可以从一个字符串数组中获取。为此变量初始化值,在初始化mask时应增加LVCF_TEXT变量,它的长度可以通过cchTextMax成员来设置。

初始化LVCOLUMN之后,把它作为InsertColumn的第二个参数进行传递。下面是示例:

BOOL CDeptStore2Dlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    // TODO: 在此添加额外的初始化代码
    LVCOLUMN lvColumn;
    int nCol;

    lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
    lvColumn.fmt = LVCFMT_LEFT;
    lvColumn.cx =120;
    lvColumn.pszText = TEXT("Full Name");
    nCol = m_StoreItems.InsertColumn(0, &lvColumn);

    lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
    lvColumn.fmt = LVCFMT_LEFT;
    lvColumn.cx =100;
    lvColumn.pszText = TEXT("Profession");
    m_StoreItems.InsertColumn(1, &lvColumn);

    lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
    lvColumn.fmt = LVCFMT_LEFT;
    lvColumn.cx =80;
    lvColumn.pszText = TEXT("Fav Sport");
    m_StoreItems.InsertColumn(2, &lvColumn);

    lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
    lvColumn.fmt = LVCFMT_LEFT;
    lvColumn.cx =75;
    lvColumn.pszText = TEXT("Hobby");
    m_StoreItems.InsertColumn(3, &lvColumn);

    return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

(译者注:需要修改ListCtrl为Report型)

iOrder:用来标识列的地址(列的索引)

你也可以用CListCtrl::InsertColumn()方法的另一个版本,你可以用下面的版本,来为控件创建列:

int InsertColumn(int nCol,
                 LPCTSTR lpszColumnHeading,
                 int nFormat = LVCFMT_LEFT,
                 int nWidth =-1,
                 int nSubItem =-1);

这个版本是上个版本的简化版。

nCol: 列的索引,必须要指定的;

lpszColumnHeading:在列的开始要显示的字符串,和LVCOLUMN::pszText成员相似;

nFormat:用来指定lpszColumnHeading的水平对齐方式。默认为左对齐(LVCFMT_LEFT),居中为LVCFMT_CENTER,右对齐为LVCFMT_RIGHT;

nWidth:以像素为单位来设定列的宽度,如果你不想指定它的大小,可设置为-1;

nSubItem:用来设定当前列子项的索引。

列配置好之后,你必须要提供在特定列下显示的字符串项。为了实现这一功能,你必须先设定你要增加项的信息。InsertColumn()方法将会返回一个整形值来标识你增加列的信息。接着为每一列指定将要显示的项的字符串,调用CListCtrl::SetItemText()方法。它的声明为:

BOOL SetItemText(int nItem, int nSubItem, LPTSTR lpszText);

nItem:你要增加行的索引,它可以通过InsertColumn()的返回值获得。每一项的信息存储在一个以"\0"结尾的数组。

nSubItem:当前项所在的位置。(译者注:通过nItem和nSumItem确定项的位置,在平面中第nItem行,第nSumItem列)

lpszText:当前项的信息

示例:

BOOL CDeptStore2Dlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    // TODO: 在此添加额外的初始化代码
    LVCOLUMN lvColumn;

    lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
    lvColumn.fmt = LVCFMT_LEFT;
    lvColumn.cx =120;
    lvColumn.pszText = TEXT("Full Name");
    m_StoreItems.InsertColumn(0, &lvColumn);

    lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
    lvColumn.fmt = LVCFMT_LEFT;
    lvColumn.cx =100;
    lvColumn.pszText = TEXT("Profession");
    m_StoreItems.InsertColumn(1, &lvColumn);

    lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
    lvColumn.fmt = LVCFMT_LEFT;
    lvColumn.cx =80;
    lvColumn.pszText = TEXT("Fav Sport");
    m_StoreItems.InsertColumn(2, &lvColumn);

    lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
    lvColumn.fmt = LVCFMT_LEFT;
    lvColumn.cx =75;
    lvColumn.pszText = TEXT("Hobby");
    m_StoreItems.InsertColumn(3, &lvColumn);

    LVITEM lvItem;
    int nItem;

    lvItem.mask = LVIF_TEXT;
    lvItem.iItem =0;
    lvItem.iSubItem =0;
    lvItem.pszText = TEXT("Sandra C. Anschwitz");
    nItem = m_StoreItems.InsertItem(&lvItem);

    m_StoreItems.SetItemText(nItem, 1, TEXT("Singer"));
    m_StoreItems.SetItemText(nItem, 2, TEXT("HandBall"));
    m_StoreItems.SetItemText(nItem, 3, TEXT("Beach"));

    lvItem.mask = LVIF_TEXT;
    lvItem.iItem =1;
    lvItem.iSubItem =0;
    lvItem.pszText = TEXT("Roger A. Miller");
    nItem = m_StoreItems.InsertItem(&lvItem);

    m_StoreItems.SetItemText(nItem, 0, TEXT("Footballer"));
    m_StoreItems.SetItemText(nItem, 1, TEXT("Tennis"));
    m_StoreItems.SetItemText(nItem, 2, TEXT("Teaching"));

    lvItem.mask = LVIF_TEXT;
    lvItem.iItem =2;
    lvItem.iSubItem =0;
    lvItem.pszText = TEXT("Marie-Julie W. Gross");
    nItem = m_StoreItems.InsertItem(&lvItem);

    m_StoreItems.SetItemText(nItem, 1, TEXT("Student"));
    m_StoreItems.SetItemText(nItem, 2, TEXT("Boxing"));
    m_StoreItems.SetItemText(nItem, 3, TEXT("Programming"));

    lvItem.mask = LVIF_TEXT;
    lvItem.iItem =3;
    lvItem.iSubItem =0;
    lvItem.pszText = TEXT("Ella Pius Roger");
    nItem = m_StoreItems.InsertItem(&lvItem);

    m_StoreItems.SetItemText(nItem, 1, TEXT("Architect"));
    m_StoreItems.SetItemText(nItem, 2, TEXT("Ping-Pong"));
    m_StoreItems.SetItemText(nItem, 3, TEXT("Songo"));

    return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

时间: 2024-11-03 20:52:24

转载ListCtrl控件的相关文章

[转载]WebBrowser控件表单(form)的自动填写和提交

话说有了WebBrowser类,终于不用自己手动封装SHDocVw的AxWebBrowser这个ActiveX控件了.这个类如果仅仅作为一个和IE一模一样浏览器,那就太没意思了(还不如直接用IE呢).那么,无论我们是想做一个"定制版IE",还是希望利用HTML来做用户界面(指WinApp而非WebApp.许多单机软件,包括Windows的帮助支持中心,都是HTML做的),都少不了Windows Form和包含在WebBrowser中的Web页面的交互.本文将通过几个实际的例子,初步介绍

LISTCTRL控件方法

以下未经说明,listctrl默认view风格为report ------------------------------------------------------------------------------- 1. CListCtrl 风格 LVS_ICON: 为每个item显示大图标 LVS_SMALLICON: 为每个item显示小图标 LVS_LIST: 显示一列带有小图标的item LVS_REPORT: 显示item详细资料 直观的理解:windows资源管理器,"查看&q

VC/MFC之ListCtrl控件使用经验总结

以下未经说明,listctrl默认view 风格为report 相关类及处理函数 MFC:CListCtrl类 SDK:以 "ListView_"开头的一些宏.如 ListView_InsertColumn -------------------------------------------------------------------------------- 1. CListCtrl 风格      LVS_ICON: 为每个item显示大图标      LVS_SMALLIC

VC在ListCtrl控件中插入图标

在ListCttrl控件(Report风格)的使用上,有时需要向子列中插入图标,例如要制作一个下载软件,我们计划在控件的第一列用图标的形式显示下载状态:排队.下载中.出错等等,第二列计划用图标显示下载文件类型,要做出这样的效果,就必须使用CListCtrl的SetItem(八个参数)方法,由于我这台电脑上没有MSDN所以这八个参数具体都是什么意思我暂时不清楚,在这只介绍下跟我们的操作关系密切的几个参数. SetItem()从左向右数第一个参数(从1起计数)表示操作行的行号,这个行号从0计数,最好

VC/MFC ListCtrl 控件功能使用汇总(转)

以下未经说明,listctrl默认view 风格为report 相关类及处理函数 MFC:CListCtrl类 SDK:以 "ListView_"开头的一些宏.如 ListView_InsertColumn -------------------------------------------------------------------------------- 1. CListCtrl 风格      LVS_ICON: 为每个item显示大图标      LVS_SMALLIC

在ListCtrl控件中设置自定义光标

::SetCursor(::LoadCursor   (::AfxGetInstanceHandle(),   MAKEINTRESOURCE(IDB_BMP_MOUSE))); void   CMyListCtrl::OnItemchanged(NMHDR*   pNMHDR,   LRESULT*   pResult) {                   NM_LISTVIEW*   pNMListView   =   (NM_LISTVIEW*)   pNMHDR;          

ListCtrl控件

一 CListCtrl类型 LVS_EDITLABELS LVS_OWNERDRAWFIXED LVS_REPORT LVS_SHOWSELALWAYS LVS_SINGLESEL LVS_SMALLICONw LVS_SORTASCENDING LVS_SORTDESCENDING LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_HEADERDRAGDROP (1)添加或删除风格nStyle |= 或 nStyle &~        (2)设

[转载]SysListView32控件响应鼠标单击消息

本文出自程序人生 >> SysListView32控件响应鼠标单击消息作者:代码疯子 SysListView32控件就是列表视图控件(MFC里面的CListCtrl就是对SysListView32进行的封装).如果想知道用户选择了哪个元素,可以这么响应消息(注意,这里是Report风格): 1 // Coded by 代码疯子 2 // http://www.programlife.net/ 3 case WM_NOTIFY: 4 switch (((LPNMHDR)lParam)->c

win32 listctrl控件右键菜单的实现

HMENU Menu_list,Menu_all; POINT point; HINSTANCE hInstance;//下面代码放到BOOL WINAPI DialogProc下 case WM_CONTEXTMENU: if((HWND)wParam == GetDlgItem(hWnd,IDC_LIST_VIEW)) { Menu_all=GetSubMenu(Menu_list,0); GetCursorPos(&point);//得到鼠标当前坐标, TrackPopupMenu(Men