Methods and Techniques of CListCtrl in MFC Summary (1)

Source: Internet
Author: User
Based on my application in the project, this article describes some usage and skills of CListCtrl. At the beginning, I checked a lot of information and made some fragmented records. Now I want to make a summary for future reference. It includes the following 13 items: basic operations, row numbers of selected rows, check box operations, dynamic setting of the font color of selected rows,

Based on my application in the project, this article describes some usage and skills of CListCtrl. At the beginning, I checked a lot of information and made some fragmented records. Now I want to make a summary for future reference. It includes the following 13 items: basic operations, row numbers of selected rows, check box operations, dynamic setting of the font color of selected rows,



Based on my application in the project, this article describes some usage and skills of CListCtrl. At the beginning, I checked a lot of information and made some fragmented records. Now I want to make a summary for future reference. It mainly includes the followingContent: Basic operations: Obtain the row number, check box operations, dynamically set the font color of the selected row, set the background color of the selected row, disable dragging the header, center the first column, and set the Row Height and font, virtual list technology, classification when you click the header, move up and down, dynamically adjust the size of the problem, to avoid flickering issues.

It can be summarized in two parts. This article focuses on:Basic operations,Obtains the row number of the selected row.,Check box operation,Dynamically set the font color of the selected row,Set the background color of the selected row


1. Basic operations

Here are four basic operations of CListCtrl:

① Set the display mode of the List View

I.CListCtrl has four styles: LVS_ICON, LVS_SMALLICON, LVS_LIST, and LSV_REPORT, which can be set through control properties. All described in this article are the LSV_REPORT attributes.

II.Extended style:

There are three common extended styles: LVS_EX_FULLROWSELECT, LVS_EX_GRIDLINES, and LVS_EX_CHECKBOXES. Each of them corresponds to a selected row to generate the Ckeckbox control before the main line is highlighted, grid lines are set, and items.

UseSetExtendedStyle(Style) function to set the extended style, useGetExtendedStyle() Function to obtain the style, such:

M_listInfo.SetExtendedStyle (LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES );
III.When using CListView, you must add cs. style | = LVS_REPORT in the PreCreateWindow () function;

To set it to the LVS_REPORT style. Otherwise, the insertion is invalid. You can also use another method to set the style, that is, obtain the CListCtrl control in OnInitialUpate (), and then modify the style, as shown below:

CListCtrl & theCtrl =GetListCtrl();

TheCtrl.ModifyStyle(0, LVS_REPORT );

② Insert operation

Insert columns first:

IntInsertColumn(Int nCol, LPCTSTRlpszColumnHeading, int nFormat, int nWidth, int nSubItem)

When you insert a column, you can specify the column number, column name, column name display style, column width, and other information. If the column number is 0, it is always displayed on the left. The method used to display the column in the play will be modified later. Other columns can be centered by setting the nFormat attribute.

Insert row:

IntInsertItem(Int nItem, LPCTSTRlpszItem)

Insert a row directly, nItem indicates the row number, and lpszItem indicates the information of column 0th of the row.

Settings:

BOOLSetItemText(Int nItem, int nSubItem, LPCTSTR lpszText)

Set the information of the nSubItem column of the row nItem (nItem ......; NSubItem: 1, 2, 3 ......)

③ Delete operation

There are three operation functions:

BOOLDeleteAllItems() ------- Delete all rows

BOOLDeleteItem(NItem) -------- delete a row

BOOLDeleteColumn(NCol) ----- delete a column

④ Get/set attribute functions

There are a lot of functions, so I will not discuss them one by one. Commonly used

IntGetItemCount() -------- Get the number of rows inserted

BOOLSetItemState(Int iLink, UINTstate, UINTstateMask) --------- set the row status, such as highlighted

And so on.


2. Get the row number of the selected row

Obtain the row number of the selected row, and then process the row accordingly. This is a lot of used in programming.

When you click an item, the control sends it to the parent window.NM_CLICK messageThe response function is OnNMClickXXXX (NMHDR * pNMHDR, LRESULT * pResult). Compile the code to obtain the row number clicked by the mouse.

There are two ways to get the row number: the first is to useGetFirstSelectedItemPositionAndGetNextSelectedItemThe second method is to obtain the mouse position information first, and then callHitTestFunction to find the row number. Examples are as follows:

Method 1: This example is taken from MSDN and can be modified and used later.

POSITION pos = pList->GetFirstSelectedItemPosition();if (pos == NULL)   TRACE0("No items were selected!\n");else{   while (pos)   {      int nItem = pList->GetNextSelectedItem(pos);      TRACE1("Item %d was selected!\n", nItem);      // you could do your own processing on nItem here   }}

Method 2: This example is from my project and can be modified and used.

// Obtain the row number where the click is located // locate the mouse position DWORD dwPos = GetMessagePos (); CPoint point (LOWORD (dwPos), HIWORD (dwPos); m_listCtrl.ScreenToClient (& point ); // define the struct LVHITTESTINFO lvinfo; lvinfo.pt = point; // obtain the row number information int nItem = m_listCtrl.HitTest (& lvinfo); if (nItem! =-1) m_itemSel = lvinfo. iItem; // current row number

The LVHITTESTINFO struct has four members. In the above HitTest call, the first member serves as the input and the other three as the output. For more information about the variable meanings, see MSDN.

typedef struct _LVHITTESTINFO {    POINT pt;    UINT flags;    int iItem;    int iSubItem;} LVHITTESTINFO, *LPLVHITTESTINFO;
3. Check box operations

Sometimes you need to add a CheckBox before the item for the user to choose, and then process all the selected items.

There are two problems involved: first, how to add the CheckBox style; second, how to determine whether the CheckBox status of a row has changed.

For the first questionBasic operationsYou can use the SetExtendedStyle function to add the LVS_EX_CHECKBOXES extension style.

Here we will focus on the second issue. First, there are two functions to operate the check box status:

BOOLGetCheck(Int nItem) ------- get check box status

BOOLSetCheck(Int nItem, BOOL fCheck = TRUE) ------- set the check box status

Secondly, we need to clarify the following four points:

When the item in the list changes, the control will sendLVN_ITEMCHANGEDThe status of the check box can be processed (query or set) in the response function of the LVN_ITEMCHANGED message ).

When you click CheckBox, the message order is NM_CLICK-> LVN_ITEMCHANGED. That is, the status of the CheckBox changes only after the message function of NM_CLICK is complete. It is invalid to use GetCheck in NM_CLICK.

When you click Item (not in the CheckBox area), the order of messages is LVN_ITEMCHANGED-> NM_CLICK.

When the InsertItem function is called, The LVN_ITEMCHANGED message is also generated. In view of this, a BOOL variable m_bHit is usually customized to determine whether to click the operation or insert the operation. The variable is initially set to FALSE and TRUE when the mouse clicks the item, check whether a CheckBox is clicked and reset to FALSE again.

Example:

Void CXXXX: OnNMClickXXXX (NMHDR * pNMHDR, LRESULT * pResult) {// obtain the row number where the click is located // locate the mouse position DWORD dwPos = GetMessagePos (); CPoint point (LOWORD (dwPos), HIWORD (dwPos); m_listCtrl.ScreenToClient (& point); // defines the structure LVHITTESTINFO lvinfo; lvinfo.pt = point; // obtain the row number information int nItem = m_listCtrl.HitTest (& lvinfo); if (nItem! =-1) m_itemSel = lvinfo. iItem; // current row number // determine whether to click if (lvinfo. flags = LVHT_ONITEMSTATEICON) m_bHit = TRUE; * pResult = 0;} void CXXXX: OnLvnItemchangedXXXX (NMHDR * pNMHDR, LRESULT * pResult) {LPNMLISTVIEW pNMLV = reinterpret_cast
 
  
(PNMHDR); // judge m_bHit, that is, whether CheckBoxif (m_bHit) {m_bHit = FALSE; // reset if (m_listCtrl.GetCheck (m_itemSel )) {// CheckBox selected // do your own processing} else {// CheckBox unselect // do your own processing} * pResult = 0 ;}
 


4. dynamically set the font color of the selected row. Sometimes, you may need to set the text color of a row as a special color to indicate a special meaning. For example, the information being downloaded is in green, the download is suspended in gray.

First, give a link to the CodeProject. This article is very good at using Custom Draw. Http://www.codeproject.com/Articles/79/Neat-Stuff-to-Do-in-List-Controls-Using-Custom-Dra

Next, let's talk about my methods. Here we mainly talk about the dynamic modification of the font color of the selected row. Of course, it is also obtained by combining the above article with my own practices.

We need to clarify the following points (you can modify the font color of a line below ):

① When the control is drawn, it will be sentNM_CUSTOMDRAWMessage. The message response function of the message is

void CXXXX::OnNMCustomdrawXXXX(NMHDR *pNMHDR, LRESULT *pResult){LPNMLVCUSTOMDRAW pLVCD = reinterpret_cast
 
  (pNMHDR);// TODO: Add your control notification handler code here*pResult = CDRF_DODEFAULT;       //……………… }
 
② Where, PNMHDR is the input parameter, Which points NMLVCUSTOMDRAWStruct, which contains a lot of information, including the font color and background, especially the first member NMCUSTOMDRAWStruct variable, which contains Current drawing stage(I don't know how to compile it). The possible values are shown in (captured from MSDN ).


PResult is the output parameter.This parameter determines the message to be sent to windows (related to the drawing). By sending this message, we can proceed to the processing phase required by the next step. The specific output value depends on the Current drawing stage. The possible values are shown in (captured from MSDN ).


④ Pay attention to one thing (in English, I think it looks more accurate than the translation ):

One thing to keep in mind is you must alwaysCheck the draw stage before doing anything else, Because your handler will receive messages, and the draw stage determines what action your code takes.

Let's take a look at how to modify the font color of a line:

① First, we should understand that to modify the font color, we shouldPre-paint stageTo complete

② Therefore, in the message response function, we first determine whether it is in the pre-paint stage (that is, pLVCD-> nmcd. dwDrawStage = CDDS_PREPAINT), and then modify the value of the output value pResult to notify windows that we need to process the message for each item (that is, Set * pResult = cdrf_policyitemdraw ).

③ When we enter the message response function again, we determine whether it is in the Item pre-paint stage (that is, pLVCD-> nmcd. dwDrawStage = CDDS_ITEMPREPAINT). If yes, modify the font color.

④ After processing, Set * pResult = CDRF_DODEFAULT again, indicating that we no longer need other special messages. By default, we can execute the command.

Example:

Void CXXXX: OnNMCustomdrawXXXX (NMHDR * pNMHDR, LRESULT * pResult) {LPNMLVCUSTOMDRAW pLVCD = reinterpret_cast
 
  
(PNMHDR); * pResult = CDRF_DODEFAULT; // First thing-check the draw stage. if it's the control's pre-paint stage, // then tell Windows we want messages for every item. if (CDDS_PREPAINT = pLVCD-> nmcd. dwDrawStage) {* pResult = cdrf_policyitemdraw;} else if (CDDS_ITEMPREPAINT = pLVCD-> nmcd. dwDrawStage) {// This is the notification message for an item. // process and change the background color of the item. if (/* meet the condition */) pLVCD-> clrText = RGB (255,); * pResult = CDRF_DODEFAULT ;}}
 


The above interview method is mainly used to set the static font color. Of course, if the information in your list is constantly changing (that is, you can use SetItemText to continuously modify it), it will achieve dynamic changes, otherwise, you need to call the re-painting function in the appropriate place:

BOOL RedrawItems (int nFirst, int nLast)

Indicates that the line between nFirst and nLast needs to be repainted.


5. Set the background color of the selected row.
Set the background color of the selected row to display the selected row in a special color, so that you can easily understand which row is being processed. Although there is a highlighted line, the highlighted line is based on the focus. If you select a line and the focus is shifted, you cannot determine which line you selected.

The method for setting the background color of the selected row is similar to the method for changing the font color described in section 4. Custom Draw is used. This involves setting a special color for the current selected behavior, and restoring the color of the previous selected row, otherwise it will be messy. Therefore, it is not difficult to record the row number of the selected row and the selected row. Redraw the selected row and the selected row.

Example:

Void CXXXX: OnNMClickXXXX (NMHDR * pNMHDR, LRESULT * pResult ){//............ // Re-paint the item and change the background color int nFirst = min (m_itemSel, m_itemForeSel); int nLast = max (m_itemSel, m_itemForeSel); m_listCtrl.RedrawItems (nFirst, nLast ); // re-paint * pResult = 0 between the previously selected item and the currently selected Item;} void CXXXX: OnNMCustomdrawXXXX (NMHDR * pNMHDR, LRESULT * pResult) {LPNMLVCUSTOMDRAW pLVCD = reinterpret_cast
 
  
(PNMHDR); * pResult = CDRF_DODEFAULT; // First thing-check the draw stage. if it's the control's prepaint // stage, then tell Windows we want messages for every item. if (CDDS_PREPAINT = pLVCD-> nmcd. dwDrawStage) {* pResult = cdrf_policyitemdraw;} else if (CDDS_ITEMPREPAINT = pLVCD-> nmcd. dwDrawStage) {// This is the notification message for an item. // process and change the background color of the item if (m_itemSel = pLVCD-> nmcd. dwItemSpec) {// the currently selected itempLVCD-> clrTextBk = RGB (255, 0);} else if (m_itemForeSel = pLVCD-> nmcd. dwItemSpec) {// The previously selected item is restored to white pLVCD-> clrTextBk = RGB (255,255,255);} * pResult = CDRF_DODEFAULT ;}}
 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.