📄 ch18.htm
字号:
with the list view style are left undisturbed. This is usually done in the following
four steps:
<DL>
<DD>1. Get the existing window style bit information using <TT>GetWindowLong</TT>.<BR>
<BR>
2. Strip off the list view style information, leaving the other style information
intact.<BR>
<BR>
3. Combine a new list view style with the old style information.<BR>
<BR>
4. Apply the new style information using <TT>SetWindowLong</TT>.
</DL>
<P>These steps are often combined into a few lines of code in the following way:</P>
<PRE><FONT COLOR="#0066FF"><TT>DWORD dwNewStyle = LVS_ICON; // Changing to icon view</TT>
<TT>DWORD dwOldStyle = GetWindowLong( hWndList, GWL_STYLE );</TT>
<TT>dwNewStyle |= ( dwOldStyle &= ~LVS_TYPEMASK );</TT>
<TT>SetWindowLong( hWndList, GWL_STYLE, dwNewStyle );</TT>
</FONT></PRE>
<H3><FONT COLOR="#000077"><B>Switching Between View Styles</B></FONT></H3>
<P>The source code provided in Listing 18.3 is used to switch between list view styles.
When a radio button is selected, its message-handling function is called. Each message-handling
function passes a different list view style parameter to the <TT>SetListView</TT>
member function. The <TT>SetListView</TT> function uses the <TT>SetWindowLong</TT>
function to change the list view to the selected style.
<H4><FONT COLOR="#000077">TYPE: Listing 18.3. Functions used to change the control's
view style.</FONT></H4>
<PRE><FONT COLOR="#0066FF"><TT>void CListExDlg::OnRadioIcon()</TT>
<TT>{</TT>
<TT> SetListView( LVS_ICON );</TT>
<TT>}</TT>
<TT>void CListExDlg::OnRadioList()</TT>
<TT>{</TT>
<TT> SetListView( LVS_LIST );</TT>
<TT>}</TT>
<TT>void CListExDlg::OnRadioReport()</TT>
<TT>{</TT>
<TT> SetListView( LVS_REPORT );</TT>
<TT>}</TT>
<TT>void CListExDlg::OnRadioSmall()</TT>
<TT>{</TT>
<TT> SetListView( LVS_SMALLICON );</TT>
<TT>}</TT>
<TT>void CListExDlg::SetListView( DWORD dwNewStyle )</TT>
<TT>{</TT>
<TT> DWORD dwOldStyle;</TT>
<TT> HWND hWndList;</TT>
<TT> hWndList = m_listCtrl.GetSafeHwnd();</TT>
<TT> dwOldStyle = GetWindowLong( hWndList, GWL_STYLE );</TT>
<TT> if( (dwOldStyle & LVS_TYPEMASK) != dwNewStyle )</TT>
<TT> {</TT>
<TT> // Don't forget the tilde before LVS_TYPEMASK !</TT>
<TT> dwOldStyle &= ~LVS_TYPEMASK;</TT>
<TT> dwNewStyle |= dwOldStyle;</TT>
<TT> SetWindowLong( hWndList, GWL_STYLE, dwNewStyle );</TT>
<TT> }</TT>
<TT>}</TT>
</FONT></PRE>
<P>Compile and run the ListEx sample program. The list view initially displays its
contents in the icon view. Try using the radio buttons to switch between views. When
the report view is displayed, use the header control to change the spacing between
columns. Figure 18.4 shows the ListEx program running.</P>
<P><A NAME="04"></A><A HREF="04.htm"><B>Figure 18.4.</B> </A><I><BR>
The ListEx sample program shows subitems and small icons in Report view.</I></P>
<P>Congratulations! You now have an example of a basic list view control. In the
next few sections, you will add label editing and drag-and-drop functionality.
<H3><FONT COLOR="#000077"><B>Editing Items in Place</B></FONT></H3>
<P>The list view control offers a built-in edit control that you can use to edit
items contained in the control. You can add this feature to the ListEx example in
a few minutes. In order to take advantage of this capability, the list view control
must have the <TT>LVS_EDITLABELS</TT> style, which is set by clicking the Edit Labels
check box on the list view's property page.</P>
<P>In addition to setting the list view control's style, you must handle two notification
messages that relate to label editing:
<UL>
<LI><TT>LVN_BEGINLABELEDIT</TT> is sent just before editing begins.<BR>
<BR>
<LI><TT>LVN_ENDLABELEDIT</TT> is sent after editing has been completed.
</UL>
<P>When your application receives the <TT>LVN_BEGINLABELEDIT</TT> message, you have
the opportunity to allow or prevent editing of the label. As with other notification
messages, one of the parameters passed to your handler for the notification messages
is <TT>*pResult</TT>. You should set this value to <TT>FALSE</TT> or zero to allow
the label edit to begin, or <TT>TRUE</TT> to prevent the label edit from starting.
<BLOCKQUOTE>
<P>
<HR>
<B> </B><FONT COLOR="#000077"><B>Time Saver:</B></FONT><B> </B>To access the edit
control used to edit the label, use the <TT>GetEditControl</TT> member function in
the <TT>CListCtrl</TT> class.
<HR>
</BLOCKQUOTE>
<P>In most cases, you respond to the <TT>LVN_ENDLABELEDIT</TT> message and update
the application's data. To allow a change, set <TT>*pResult</TT> to <TT>TRUE</TT>;
to reject a label change, set <TT>*pResult</TT> to <TT>FALSE</TT>.
<BLOCKQUOTE>
<P>
<HR>
<B> </B><FONT COLOR="#000077"><B>CAUTION:</B></FONT><B> </B>If you allow the user
to change a label, you might need to update the underlying data. There are two cases
in which you should not update your data: if the <TT>LV_ITEM pszText</TT> member
passed with the message is <TT>NULL</TT>, or if the <TT>LV_ITEM iItem</TT> member
is set to <TT>-1</TT>. In these cases, the user has canceled the label-editing operation.
<HR>
</BLOCKQUOTE>
<P>To add label editing to the ListEx example, begin by opening the <TT>IDD_LISTEX_DIALOG</TT>
dialog box resource. Check the Edit Labels check box in the styles property sheet
for the list control. Next, add message-handling functions for the label editing
messages, using the values from Table 18.5.
<H4><FONT COLOR="#000077">Table 18.5. Values for drag-and-drop functions in CListExDlg.</FONT></H4>
<P>
<TABLE BORDER="1">
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP"><B>Object ID</B></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><B>Class Name</B></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><B>Message</B></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><B>Function</B></TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP"><TT>IDC_RADIO_LIST</TT></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><TT>CListExDlg</TT></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><TT>LVN_BEGINEDIT</TT></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><TT>OnBeginlabeleditList</TT></TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP"><TT>IDC_RADIO_LIST</TT></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><TT>CListExDlg</TT></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><TT>LVN_ENDEDIT</TT></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><TT>OnEndlabeleditList</TT></TD>
</TR>
</TABLE>
</P>
<P>Listing 18.4 shows the source code for the message-notification handlers to be
added to the <TT>CListExDlg</TT> class.
<H4><FONT COLOR="#000077">TYPE: Listing 18.4. Handling the LVN_ENDLABELEDIT and LVN_ENDLABELEDIT
messages.</FONT></H4>
<PRE><FONT COLOR="#0066FF"><TT>void CListExDlg::OnBeginlabeleditList(NMHDR* pNMHDR,</TT>
<TT> LRESULT* pResult)</TT>
<TT>{</TT>
<TT> *pResult = FALSE;</TT>
<TT>}</TT>
<TT>void CListExDlg::OnEndlabeleditList(NMHDR* pNMHDR,</TT>
<TT> LRESULT* pResult)</TT>
<TT>{</TT>
<TT> LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;</TT>
<TT> if((pDispInfo->item.pszText != NULL)&&</TT>
<TT> (pDispInfo->item.iItem != -1))</TT>
<TT> {</TT>
<TT> // Label edit not cancelled by user</TT>
<TT> }</TT>
<TT> *pResult = TRUE;</TT>
<TT>}</TT>
</FONT></PRE>
<BLOCKQUOTE>
<P>
<HR>
<B> </B><FONT COLOR="#000077"><B>Just a Minute:</B></FONT><B> </B>Remember that the
Edit control updates only what is displayed in the list view control; you must update
your document or other database in response to <TT>LVN_ENDLABELEDIT</TT>.
<HR>
</P>
<P>
<HR>
<B> </B><FONT COLOR="#000077"><B>DO/DON'T:</B></FONT><B> <BR>
DO</B> set the Edit labels property for the list control.<BR>
<B>DO</B> handle the <TT>LVN_BEGINLABELEDIT</TT> message and set <TT>*pResult</TT>
to <TT>FALSE</TT> to allow an edit to begin.<BR>
<B>DO</B> handle the <TT>LVN_ENDLABELEDIT</TT> message and set <TT>*pResult</TT>
to <TT>TRUE</TT> to allow an edit to be completed.<BR>
<B>DO</B> remember to update your application's data after an edit has been completed.<BR>
<B>DON'T</B> forget to test <TT>iItem</TT> and <TT>pszText</TT> to see whether the
user has canceled the edit operation.
<HR>
</BLOCKQUOTE>
<H2><FONT COLOR="#000077"><B>Summary</B></FONT></H2>
<P>In this hour, you learned about the list view control and how it is used in an
MFC-based program. You have also learned how this control interacts with image lists
and header controls, and you built a sample application to demonstrate how a list
view control is used.
<H2><FONT COLOR="#000077"><B>Q&A</B></FONT></H2>
<DL>
<DD><B>Q How can I limit the amount of text the user can enter when editing a label?</B><BR>
<BR>
<B>A</B> When handling the <TT>LVN_BEGINLABELEDIT</TT> message, set the maximum text
limit by calling the edit control's <TT>LimitText</TT> member function:
</DL>
<BLOCKQUOTE>
<PRE><FONT COLOR="#0066FF"><TT>void CListExDlg::OnBeginlabeleditList(NMHDR* pNMHDR, LRESULT* pResult)</TT>
<TT>{</TT>
<TT> LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;</TT>
<TT> CEdit* pEdit = m_listCtrl.GetEditControl();</TT>
<TT> pEdit->LimitText( 15 );</TT>
<TT> *pResult = 0;</TT>
<TT>}</TT></FONT></PRE>
</BLOCKQUOTE>
<PRE><FONT COLOR="#0066FF"><TT></TT></FONT></PRE>
<DL>
<DD><B>Q In a multiple selection list view, how can I determine which items have
been selected?</B><BR>
<BR>
<B>A</B> As discussed earlier this hour, you can use <TT>CListCtrl</TT>'s <TT>GetNextItem</TT>
member function to determine the first selected item in a list view control. To determine
all selected items, you must use a <TT>while</TT> loop to continue to search for
selected items until you reach the end of the list, like this:
</DL>
<BLOCKQUOTE>
<PRE><FONT COLOR="#0066FF"><TT>void CListExDlg::OnTest()</TT>
<TT>{</TT>
<TT> int nTotalSelected = 0;</TT>
<TT> int nSel = m_listCtrl.GetNextItem(-1, LVNI_SELECTED);</TT>
<TT> while(nSel != -1)</TT>
<TT> {</TT>
<TT> nTotalSelected++;</TT>
<TT> nSel = m_listCtrl.GetNextItem(nSel, LVNI_SELECTED);</TT>
<TT> }</TT>
<TT> TRACE("Total selected = %d\n", nTotalSelected);</TT>
<TT>}</TT></FONT></PRE>
</BLOCKQUOTE>
<PRE><FONT COLOR="#0066FF"><TT></TT></FONT></PRE>
<H2><FONT COLOR="#000077"><B>Workshop</B></FONT></H2>
<P>The Workshop is designed to help you anticipate possible questions, review what
you've learned, and begin thinking ahead to put your knowledge into practice. The
answers to the quiz are in Appendix B, "Quiz Answers."
<H3><FONT COLOR="#000077"><B>Quiz</B></FONT></H3>
<DL>
<DD>1. What styles are available for the list view?<BR>
<BR>
2. What are the sizes of the icons used by the list view control?<BR>
<BR>
3. What messages must be handled when the user edits a label?<BR>
<BR>
4. How do you discover that the user has canceled a label edit?<BR>
<BR>
5. What Windows function is used to change list view styles?<BR>
<BR>
6. What steps are required to add a column to a list view?<BR>
<BR>
7. How do you add text for a list view subitem?<BR>
<BR>
8. What is the return value when the <TT>InsertItem</TT> function fails?
</DL>
<H3><FONT COLOR="#000077"><B>Exercises</B></FONT></H3>
<DL>
<DD>1. Make it possible for a user to add new items to the list view control in the
ListEx project.<BR>
<BR>
2. Add a pop-up menu to the ListEx project that enables the user to select which
list view style should be used. Display the pop-up menu when the user right-clicks
the list view control.<FONT COLOR="#000077"></FONT>
</DL>
<CENTER>
<P>
<HR>
<A HREF="../ch17/ch17.htm"><IMG SRC="../button/previous.gif" WIDTH="128" HEIGHT="28"
ALIGN="BOTTOM" ALT="Previous chapter" BORDER="0"></A><A HREF="../ch19/ch19.htm"><IMG
SRC="../button/next.gif" WIDTH="128" HEIGHT="28" ALIGN="BOTTOM" ALT="Next chapter"
BORDER="0"></A><A HREF="../index.htm"><IMG SRC="../button/contents.gif" WIDTH="128"
HEIGHT="28" ALIGN="BOTTOM" ALT="Contents" BORDER="0"></A> <BR>
<BR>
<BR>
<IMG SRC="../button/corp.gif" WIDTH="284" HEIGHT="45" ALIGN="BOTTOM" ALT="Macmillan Computer Publishing USA"
BORDER="0"></P>
<P>© <A HREF="../copy.htm">Copyright</A>, Macmillan Computer Publishing. All
rights reserved.
</CENTER>
</BODY>
</HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -