📄 ch10.htm
字号:
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT">LVS_SHAREIMAGELISTS </TD>
<TD ALIGN="LEFT">Prevents the control from destroying its image lists when the control no longer needs
them </TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT">LVS_SINGLESEL </TD>
<TD ALIGN="LEFT">Disallows multiple selection of items </TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT">LVS_SMALLICON </TD>
<TD ALIGN="LEFT">Sets the control to the small-icon view </TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT">LVS_SORTASCENDING </TD>
<TD ALIGN="LEFT">Sorts items in ascending order </TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT">LVS_SORTDESCENDING </TD>
<TD ALIGN="LEFT">Sorts items in descending order </TD>
</TR>
</TABLE>
</P>
<P>The third task in CreateListView() is to associate the control with its image
lists with two calls to SetImageList(). Add these lines to CreateListView():</P>
<P>
<PRE>m_listView.SetImageList(&m_smallImageList, LVSIL_SMALL);
m_listView.SetImageList(&m_largeImageList, LVSIL_NORMAL);
</PRE>
<P>This function takes two parameters: a pointer to the image list and a flag indicating
how the list is to be used. Three constants are defined for this flag: LVSIL_SMALL
(which indicates that the list contains small icons), LVSIL_NORMAL (large icons),
and LVSIL_STATE (state images). The SetImageList() function returns a pointer to
the previously set image list, if any.</P>
<P>
<H3><A NAME="Heading16"></A>Creating the List View's Columns</H3>
<P>The fourth task is to create the columns for the control's report view. You need
one main column for the item itself and one column for each sub-item associated with
an item. For example, in Explorer's list view, the main column holds file and folder
names. Each additional column holds the sub-items for each item, such as the file's
size, type, and modification date. To create a column, you must first declare a LV_COLUMN
structure. You use this structure to pass information to and from the system. After
you add the column to the control with InsertColumn(), you can use the structure
to create and insert another column. Listing 10.6 shows the LV_COLUMN structure.</P>
<P>
<H4>Listing 10.6  The LV_COLUMN Structure, Defined by MFC</H4>
<PRE>typedef struct _LV_COLUMN
{
UINT mask; // Flags indicating valid fields
int fmt; // Column alignment
int cx; // Column width
LPSTR pszText; // Address of string buffer
int cchTextMax; // Size of the buffer
int iSubItem; // Subitem index for this column
</PRE>
<PRE>} LV_COLUMN;
</PRE>
<P>The mask member of the structure tells the system which members of the structure
to use and which to ignore. The flags you can use are</P>
<P>
<UL>
<LI>LVCF_FMT  fmt is valid.
<P>
<LI>LVCF_SUBITEM  iSubItem is valid.
<P>
<LI>LVCF_TEXT  pszText is valid.
<P>
<LI>LVCF_WIDTH  cx is valid.
</UL>
<P>The fmt member denotes the column's alignment and can be LVCFMT_CENTER, LVCFMT_LEFT,
or LVCFMT_RIGHT. The alignment determines how the column's label and items are positioned
in the column.</P>
<BLOCKQUOTE>
<P>
<HR>
<strong>NOTE:</strong> The first column, which contains the main items, is always aligned
to the left. The other columns in the report view can be aligned however you like. 
<HR>
</BLOCKQUOTE>
<P>The cx field specifies the width of each column, whereas pszText is the address
of a string buffer. When you're using the structure to create a column (you also
can use this structure to obtain information about a column), this string buffer
contains the column's label. The cchTextMax member denotes the size of the string
buffer and is valid only when retrieving information about a column.</P>
<P>CreateListView() creates a temporary LV_COLUMN structure, sets the elements, and
then inserts it into the list view as column 0, the main column. This process is
repeated for the other two columns. Add these lines to CreateListView():</P>
<P>
<PRE>// Create the columns.
LV_COLUMN lvColumn;
lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
lvColumn.fmt = LVCFMT_CENTER;
lvColumn.cx = 75;
lvColumn.iSubItem = 0;
lvColumn.pszText = "Column 0";
m_listView.InsertColumn(0, &lvColumn);
lvColumn.iSubItem = 1;
lvColumn.pszText = "Column 1";
m_listView.InsertColumn(1, &lvColumn);
lvColumn.iSubItem = 2;
lvColumn.pszText = "Column 2";
m_listView.InsertColumn(1, &lvColumn);
</PRE>
<H3><A NAME="Heading17"></A>Creating the List View's Items</H3>
<P>The fifth task in CreateListView() is to create the items that will be listed
in the columns when the control is in its report view. Creating items is not unlike
creating columns. As with columns, Visual C++ defines a structure that you must initialize
and pass to the function that creates the items. This structure is called LV_ITEM
and is defined as shown in Listing 10.7.</P>
<P>
<H4>Listing 10.7  The LV_ITEM Structure, Defined by MFC</H4>
<PRE>typedef struct _LV_ITEM
{
UINT mask; // Flags indicating valid fields
int iItem; // Item index
int iSubItem; // Sub-item index
UINT state; // Item's current state
UINT stateMask; // Valid item states.
LPSTR pszText; // Address of string buffer
int cchTextMax; // Size of string buffer
int iImage; // Image index for this item
LPARAM lParam; // Additional information as a 32-bit value
</PRE>
<PRE>} LV_ITEM;
</PRE>
<P>In the LV_ITEM structure, the mask member specifies the other members of the structure
that are valid. The flags you can use are</P>
<P>
<UL>
<LI>LVIF_IMAGE  iImage is valid.
<P>
<LI>LVIF_PARAM  lParam is valid.
<P>
<LI>LVIF_STATE  state is valid.
<P>
<LI>LVIF_TEXT  pszText is valid.
</UL>
<P>The iItem member is the index of the item, which you can think of as the row number
in report view (although the items' position can change when they're sorted). Each
item has a unique index. The iSubItem member is the index of the sub-item, if this
structure is defining a sub-item. You can think of this value as the number of the
column in which the item will appear. For example, if you're defining the main item
(the first column), this value should be 0.</P>
<P>The state and stateMask members hold the item's current state and its valid states,
which can be one or more of the following:</P>
<P>
<UL>
<LI>LVIS_CUT  The item is selected for cut and paste.
<P>
<LI>LVIS_DROPHILITED  The item is a highlighted drop target.
<P>
<LI>LVIS_FOCUSED  The item has the focus.
<P>
<LI>LVIS_SELECTED  The item is selected.
</UL>
<P>The pszText member is the address of a string buffer. When you use the LV_ITEM
structure to create an item, the string buffer contains the item's text. When you
are obtaining information about the item, pszText is the buffer where the information
will be stored, and cchTextMax is the size of the buffer. If pszText is set to LPSTR_TEXTCALLBACK,
the item uses the callback mechanism. Finally, the iImage member is the index of
the item's icon in the small-icon and large-icon image lists. If set to I_IMAGECALLBACK,
the iImage member indicates that the item uses the callback mechanism.</P>
<P>CreateListView() creates a temporary LV_ITEM structure, sets the elements, and
then inserts it into the list view as item 0. Two calls to SetItemText() add sub-items
to this item so that each column has some text in it, and the whole process is repeated
for two other items. Add these lines:</P>
<P>
<PRE>// Create the items.
LV_ITEM lvItem;
lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE;
lvItem.state = 0;
lvItem.stateMask = 0;
lvItem.iImage = 0;
lvItem.iItem = 0;
lvItem.iSubItem = 0;
lvItem.pszText = "Item 0";
m_listView.InsertItem(&lvItem);
m_listView.SetItemText(0, 1, "Sub Item 0.1");
m_listView.SetItemText(0, 2, "Sub Item 0.2");
lvItem.iItem = 1;
lvItem.iSubItem = 0;
lvItem.pszText = "Item 1";
m_listView.InsertItem(&lvItem);
m_listView.SetItemText(1, 1, "Sub Item 1.1");
m_listView.SetItemText(1, 2, "Sub Item 1.2");
lvItem.iItem = 2;
lvItem.iSubItem = 0;
lvItem.pszText = "Item 2";
m_listView.InsertItem(&lvItem);
m_listView.SetItemText(2, 1, "Sub Item 2.1");
m_listView.SetItemText(2, 2, "Sub Item 2.2");
</PRE>
<P>Now you have created a list view with three columns and three items. Normally
the values wouldn't be hard-coded, as this was, but instead would be filled in with
values calculated by the program.</P>
<P>
<H3><A NAME="Heading18"></A>Manipulating the List View</H3>
<P>You can set a list view control to four different types of views: small icon,
large icon, list, and report. In Explorer, for example, the toolbar features buttons
that you can click to change the view, or you can select the view from the View menu.
Although Common doesn't have a snazzy toolbar like Explorer, it will include four
buttons (labeled Small, Large, List, and Report) that you can click to change the
view. Those buttons are created as the sixth step in CreateListView(). Add these
lines to complete the function:</P>
<P>
<PRE>// Create the view-control buttons.
m_smallButton.Create("Small", WS_VISIBLE | WS_CHILD | WS_BORDER,
CRect(400, 120, 450, 140), this, IDC_LISTVIEW_SMALL);
m_largeButton.Create("Large", WS_VISIBLE | WS_CHILD | WS_BORDER,
CRect(400, 145, 450, 165), this, IDC_LISTVIEW_LARGE);
m_listButton.Create("List", WS_VISIBLE | WS_CHILD | WS_BORDER,
CRect(400, 170, 450, 190), this, IDC_LISTVIEW_LIST);
m_reportButton.Create("Report", WS_VISIBLE | WS_CHILD | WS_BORDER,
CRect(400, 195, 450, 215), this, IDC_LISTVIEW_REPORT);
</PRE>
<BLOCKQUOTE>
<P>
<HR>
<strong>TIP:</strong> If you're using large fonts, these buttons will need to be more than
50 pixels wide. This code creates each button from position 400 to 450--make the
second number larger to widen the buttons.
<HR>
</BLOCKQUOTE>
<P>Edit the message map in CommonView.h to declare the handlers for each of these
buttons so that it looks like this:</P>
<P>
<PRE>// Generated message map functions
protected:
//{{AFX_MSG(CCommonView)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnDestroy();
afx_msg void OnTimer(UINT nIDEvent);
afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
//}}AFX_MSG
afx_msg void OnSmall();
afx_msg void OnLarge();
afx_msg void OnList();
afx_msg void OnReport();
DECLARE_MESSAGE_MAP()
};
</PRE>
<P>Edit the message map in CommonView.cpp to associate the messages with the functions:</P>
<P>
<PRE>BEGIN_MESSAGE_MAP(CCommonView, CScrollView)
//{{AFX_MSG_MAP(CCommonView)
ON_WM_CREATE()
ON_WM_LBUTTONDOWN()
ON_WM_DESTROY()
ON_WM_TIMER()
ON_WM_HSCROLL()
//}}AFX_MSG_MAP
ON_COMMAND(IDC_LISTVIEW_SMALL, OnSmall)
ON_COMMAND(IDC_LISTVIEW_LARGE, OnLarge)
ON_COMMAND(IDC_LISTVIEW_LIST, OnList)
ON_COMMAND(IDC_LISTVIEW_REPORT, OnReport)
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CScrollView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CScrollView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CScrollView::OnFilePrintPreview)
END_MESSAGE_MAP()
</PRE>
<P>Choose View, Resource Symbols and click New to add new IDs for each constant referred
to in this new code:</P>
<P>
<UL>
<LI>IDC_LISTVIEW
<P>
<LI>IDC_LISTVIEW_SMALL
<P>
<LI>IDC_LISTVIEW_LARGE
<P>
<LI>IDC_LISTVIEW_LIST
<P>
<LI>IDC_LISTVIEW_REPORT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -