Detailed first draft of the use of ClistCtrl

zhaozj2021-02-08  227

Strictly said that this article is a collection of other people's results, joining my own experience, and the content of the article is experimenting in actual development. This is just a first draft, there are still many things that are not joined, the reason is that there is no verification, and will join later, form a complete guide for the use of CListCtrl.

CListCtrl list and create graphics and association: m_image_list.Create (IDB_CALLER2, 16, 10, RGB (192,192, 192)); m_image_list.SetBkColor (GetSysColor (COLOR_WINDOW)); m_caller_list.SetImageList (& m_image_list, LVSIL_SMALL); add 4 for a report : Char * szcolumn [] = {"Nickname", "IP Address", "Login Time", "Status"}; int widths [] = {100, 98, 70, 55}; lv_column lvc; lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; LVC.FMT = LVCFMT_LEFT; for (INT i = 0; i <4; i ) {// Insert Number LVC.psztext = SZColumn [i]; lvc.cx = widths [i]; Lvc.isubitem = i; m_caller_list.insertColumn (i, & lvc);} Add two items to add: Char * Data [4]; Data [0] = "All people"; data [1] = " 0.0.0.0 "; DATA [3] =" Online "; data [2] = new char; ctime now = ctime :: getcurrenttime (); cstract temp = now.format ("% h:% m:% s ") Data [2] = Temp.getBuffer (1); lv_item lvi; lvi.mask = lvif_text | lvif_image | lvif_param; lvi.isubitem = 0; lvi.psztext = (char *) Data [0]; lvi.iimage = 0 Lvi.iitem = 0; m_caller_list.insertitem (& lvi); for (int J = 0; j <4; j ) m_caller_list.setitemtext (count, j, data [j]); count ; lvi.iimage = 1; lvi .iitem = count; m_caller_list.inserti TEM (& lvi); DATA [0] = "Cherami"; Data [1] = "127.0.0.1"; for (int N = 0; n <4; n ) m_caller_list.setitemtext (count, n, data [n] COUNT ;

Styling of the report to select an entire row: m_list_ctrl.SetExtendedStyle (m_list_ctrl.GetExtendedStyle () | LVS_EX_FULLROWSELECT); Draw Table: m_list_ctrl.SetExtendedStyle (m_list_ctrl.GetExtendedStyle () | LVS_EX_GRIDLINES); with check boxes: m_list_ctrl.SetExtendedStyle (m_list_ctrl.GetExtendedStyle () | LVS_EX_CHECKBOXES); automatic switching: m_list_ctrl.SetExtendedStyle (m_list_ctrl.GetExtendedStyle () | LVS_EX_TRACKSELECT); select a line: set the CListCtrl Show selection always options SetItemState (iIndex, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED) select one or more When the project is sent, the LVN_ItemChanged message will be sent, you can use the getSelectedCount () method to get the number of items selected.

Click on the message response of the list: ON_NOTIFY (HDN_ItemClickW, 0, ResponseFunc) message, you need to add yourself or: on_notify (id_columnclick, id_yource), add the former, then add the former, the latter responded first

Response function: Responsefunc (nmHDR * pnmhdr, lresult * presult)

Double-click the item message in CListCtrl is and message functions: ON_NOTIFY (nm_dblclk, id_yourcectrl, responsefunc)

Click on Item Message Response: ON_NOTIFY (NM_Click, ID_YourCtrl, Responsefunc) ResponseFunc (NmHDR * PNMHDR, LRESULT * PRESULT)

HDN_ItemClick is Header Control Notify Message for Mouse Left Click on the header control! And HDN_ItemClick is when there is a Header Control in the List view, Header Ctrl informs the parent window List view!

The Item in ClistCtrl is selected to trigger lbn_selchange message in the LBN_SELCHANGE!

Delete selected items in ClistCtrl: Position Pos; Int Nindex;

For (; pOS = getfirstselecteditemposition ();) {nindex = getNextSelectedItem (POS); deleteItem (NINDEX);

The top of the Sort List Control (CListCtrl) is performed in ListCtrl, and the user can sort the records by selecting a different column. But CListCtrl does not automatically sort, we need to add a callback function for sorting to compare the size of the two data, and therefore also need to respond to the sort button clicked message. The specific practice will be described below.

CListCtrl provides a function for sorting, the function is: BOOL ClistCtrl :: SortItems (PfnlvCompare PFNCompare, DWORD DWDATA). Where the first parameter is the address of the global sort function, the second parameter is user data, you can pass a data or pointers according to your needs. This function returns -1 represents the first item in front of the second item, and returns 1 represents the first item in the second item, and returns 0 represents two levels. The function of the sorted function is: int Callback ListCompare (LParam LPARAM1, LPARAM LPARAM2, LPARAM LPARMSORT), where the third parameter is the data passed by the caller (ie, the second parameter DWDATA when calling SortItems). The first and second parameters are two itemdata for comparison, you can pass DWord ClistCtrl :: GetItemData (int NITEM) / BOOL Clistctrl :: Setitemdata (int NITEM, DWORD DWDATA) to perform each item ItemData access. This value can also be set when you select a specific CListCtrl :: INSERTITEM when adding items. Since you can only determine the location of the item by this value when you are sorting, you should define the meaning of this value.

In the last point, we need to know when to sort, implement this, can be processed in the parent window to process the LVN_COLUMNCLICK message.

Let's take a look at an example, this example is a derived class and supports both sequential / reverse order. For simple me to sort global data, there will be multiple groups of data that need to be sorted in practical applications, so you need to tell the sending function to sort any data by passing the parameters.

// Global data struct demo_data {char szname [20]; int IAGE;} stralldata [5] = {{"王", 30}, {"Zhang Mou", 40}, {"Wu Mou", 32}, {"Chen", 20}, {"李", 36}};

// ClistCtrl derived class definition class csortlist: public clistCtrl {// constructionPublic: csortlist (); bool m_fasc; // Whether or not sequential order INT m_NSORTEDCOL; // Current Sort Column protected: // {AFX_MSG (csortlist) //} AFX_MSG ...};

// In the parent window, contains the clistctrl derived class object class csort_in_list_ctrldlg: public cdialog {// constructionpublic: csort_list_ctrldlg (cwnd * pparent = null); // Standard Constructionor

// Dialog data // {{AFX_DATA (csort_in_list_ctrldlg) enum {IDD = IDD_SORT_IN_LIST_CTRL_DIALOG}; csortlist m_listtest; //}} AFX_DATA}

// definition of message mapping LVN_COLUMNCLICK BEGIN_MESSAGE_MAP (CSort_in_list_ctrlDlg, CDialog) // in the parent window {{AFX_MSG_MAP (CSort_in_list_ctrlDlg) ON_NOTIFY (LVN_COLUMNCLICK, IDC_LIST1, OnColumnclickList1) //}} AFX_MSG_MAPEND_MESSAGE_MAP ()

// Initialization Data BOOL CSORT_IN_LIST_CTRLG :: OnNInitdialog () {cdialog :: OnItDialog (); // Initialization ListCtrl Data List M_ListTest.insertColumn (0, "Name"); M_ListTest.insertColumn (1, "Age"; M_ListTest. SetColumnWidth (0, 80); M_ListTest.SetColumnWidth (1,80); for (int i = 0; i <5; i ) {m_listtest.insertitem (i, stralldata [i] .szname); char szage [10]; Sprintf (szage, "% d", stralldata [i] .IAGE); M_ListTest.SetItemText (i, 1, szage); // Setting each itemData is the index of data in the array // through this itemData in the sort function To determine the data M_ListTest.SetItemData (i, i);} return true; // Return True unless} you set the focus to a control}

// process the message void CSort_in_list_ctrlDlg :: OnColumnclickList1 (NMHDR * pNMHDR, LRESULT * pResult) {NM_LISTVIEW * pNMListView = (NM_LISTVIEW *) pNMHDR; // set the sort mode if (pNMListView-> iSubItem == m_listTest.m_nSortedCol) m_listTest.m_fAsc = ! m_listTest.m_fAsc; else {m_listTest.m_fAsc = TRUE; m_listTest.m_nSortedCol = pNMListView-> iSubItem;} // function invocation sequencing m_listTest.SortItems (ListCompare, (DWORD) & m_listTest); * pResult = 0;}

// Sort function Implement INT CALLBACK LISTCompare (LPARAM LPARAM1, LPARAM LPARAM2, LPARAMSORT) {// Gets the csortlist object pointer by passing parameters, giving sorting method csortlist * pv = (csortlist *) lparamsort; // coming through ItemData Determine data demo_data * pinfo1 = stralldata lParam1; demo_data * pinfo2 = stralldata lParam2; cstract szcomp1, szcomp2; int icompres; switch (pv-> m_nsortedcol) {case (0): // Sort SZComp1 = Pinfo1-> szname; szcomp2 = pinfo2-> szname; iComprees = szcomp1.compare (szcomp2); Break; case (1): // is based on the second list (Pinfo1-> IAGE == PINFO2-> IAGE) ICompRES = 0; Else iComprees = (Pinfo1-> IAGE IAGE)? - 1: 1; Break; default: assert (0); Break;} // adjustment IF according to current sorting mode (PV-> m_fasc) Return iCompres; Else Return iComprees * -1;} Quick Sort: CListCtrl :: SortItemSexample

// Sort the item in reverse alphabetical order.static int CALLBACK MyCompareProc (LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) {// lParamSort contains a pointer to the list view control. // The lParam of an item is just its index. CListCtrl * PListCtrl = (clistctrl *) LParamsort; CString stritem1 = pListCtrl-> GetItemText (lparam1, 0); cstring stritem2 = pListCtrl-> GetItemText (lparam2, 0);

Return strcmp (stritem2, stritem1);

Void Snip_clistCtrl_sortItems () {// The Pointer to my list view control. exTern ClistCtrl * PmylistCtrl;

// sort the list view items using my callback procedure. Pmylistctrl-> sortitems (mycompareproc, (lparam) PMYListCtrl;}

If you do not want to allow the users to sort the list by clicking on the header, you can use the style LVS_NOSORTHEADER. However, if you do want to allow sorting, you do not specify the LVS_NOSORTHEADER. The control, though, does not sort the items. You have to handle the HDN_ITEMCLICK notification from the header control and process it appropriately. in the code below, we have used the sorting function SortTextItems () developed in a previous section. You may choose to sort the items in a . different manner Step 1: Add two member variablesAdd two member variables to the CListCtrl The first variable to track which column has been sorted on, if any The second variable to track if the sort is ascending or descending int nSortedCol; BOOL bSortAscending... ;

Step 2: Initialize them in the constructor.Initialize nSortedCol to -1 to indicate that no column has been sorted on If the list is initially sorted, then this variable should reflect that nSortedCol = -1; bSortAscending = TRUE; Step 3..: Add entry in message map to handle HDN_ITEMCLICKActually you need to add two entries. For HDN_ITEMCLICKA and HDN_ITEMCLICKW. Do not use the class wizard to add the entry. For one, you need to add two entries whereas the class wizard will allow you only one. Secondly, the class wizard uses the wrong macro in the entry. It uses ON_NOTIFY_REFLECT () instead of ON_NOTIFY (). Since the HDN_ITEMCLICK is a notification from the header control to the list view control, it is a direct notification and not a reflected one . ON_NOTIFY (HDN_ITEMCLICKA, 0, OnHeaderClicked) ON_NOTIFY (HDN_ITEMCLICKW, 0, OnHeaderClicked) Note that we specify the same function for both the notification. Actually the program will receive one or the other and not both. W hat notification it receives will depend on the OS. The list view control on Windows 95 will send the ANSI version and the control on NT will send the UNICODE version. Also, note that the second argument is zero. This value filters for the id of The control and we know what header control id is zero.

Step 4: Write the OnHeaderClicked () functionHere's where you decide what to do when the user clicks on a column header The expected behaviour is to sort the list based on the values ​​of the items in that column In this function we have used the.. SortTextItems () function developed in a previous section. If any of the columns displays numeric or date values, then you would have to provide custom sorting for them. void CMyListCtrl :: OnHeaderClicked (NMHDR * pNMHDR, LRESULT * pResult) {HD_NOTIFY * phdn = (Hd_notify *) pnmhdr; if (phDN-> ibutton == 0) {// user clicked On Header Using Left Mouse Button if (phDN-> IIITEM == NSORTEDCOL) BSORTASCENDING =! Bsortascending; else bsortascending = true;

NSortedCol = phDN-> IIITEM; SortTextItems (NSortedcol, BSortascending);

} * PRESULT = 0;}

Lets ClistCtrl also have editing features: To overload a text box, then change the text box location when lvn_beginlabeledit. Cinedit m_inedit;

IF ((GetStyle () & lvs_typemask == lvs_report && (m_neditsubitem! = 0)) {hwnd hwndedit; cstract r;

hwndEdit = (HWND) SendMessage (LVM_GETEDITCONTROL); GetSubItemRect (pDispInfo-> item.iItem, m_nEditSubItem, LVIR_LABEL, rtBound); m_InEdit.SubclassWindow (hwndEdit); m_InEdit.m_left = rtBound.left; strText = GetItemText (pDispInfo-> item. IIITEM, M_NeditsubItem); M_INEdit.SetWindowText (strText);

Void Cinedit :: OnWindowPosch;

lpwndpos-> x = m_left; // m_left set in lvn_beginlabeledit

转载请注明原文地址:https://www.9cbs.com/read-1911.html

New Post(0)