First draft of the use of report-type clistctrl (Abstract)

Source: Internet
Author: User

Strictly speaking, this article is a collection of other people's achievements. I have added some of my experiences, andArticleThe content can be used in actual development. This is only the first draft, and there is still a lot of content not added, because it has not been verified and will be added later to form a complete guide for using clistctrl.

Create a graph list and associate it with clistctrl:
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 four columns to the report:
Char * szcolumn [] = {"nickname", "ip address", "Logon Time", "status "};
Int widths [] = };
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 Columns
LVC. psztext = szcolumn [I];
LVC. Cx = widths [I];
LVC. isubitem = I;
M_caller_list.insertcolumn (I, & LVC );
}
Add two items for the report as an attachment:
Char * Data [4];
Data [0] = "all ";
Data [1] = "0.0.0.0 ";
Data [3] = "online ";
Data [2] = new char;
Ctime now = ctime: getcurrenttime ();
Cstring 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.insertitem (& 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 ++;

Set the Report Style
Select the entire line:
M_list_ctrl.setextendedstyle (m_list_ctrl.getextendedstyle () | lvs_ex_fullrowselect );
Draw a table:
M_list_ctrl.setextendedstyle (m_list_ctrl.getextendedstyle () | lvs_ex_gridlines );
Check box:
M_list_ctrl.setextendedstyle (m_list_ctrl.getextendedstyle () | lvs_ex_checkboxes );
Automatic Switch:
M_list_ctrl.setextendedstyle (m_list_ctrl.getextendedstyle () | lvs_ex_trackselect );

Select a row:
Set the show selection always option of clistctrl
Setitemstate (iindex, lvis_selected | lvis_focused, lvis_selected | lvis_focused)
 
When one or more projects are selected, the lvn_itemchanged message is sent. You can use
The getselectedcount () method returns the number of items selected.

Click the message response in the column header:
On_policy (hdn_itemclickw, 0, responsefunc)
Message, you need to add it yourself
Or:
On_policy (lvn_columnclick, id_yourctrl, responsefunc) // Wizard to add
The former is followed by the latter.

Response Function:
Responsefunc (nmhdr * pnmhdr, lresult * presult)

Double-click the message of the item in clistctrl and the message function:
On_notify (nm_dblclk, id_yourctrl, responsefunc)

Click message response of item:
On_policy (nm_click, id_yourctrl, responsefunc)
Responsefunc (nmhdr * pnmhdr, lresult * presult)

Hdn_itemclick is the header control permission y message for mouse left click on the header control!
Hdn_itemclick: When a header contrl exists in the List View, the header CTRL notifies the parent window list view!

The item in clistctrl is selected to trigger the lbn_selchange (via wm_command) message!

Delete the selected items in clistctrl:
Position Pos;
Int nindex;

For (; Pos = getfirstselecteditemposition ();)
{
Nindex = getnextselecteditem (POS );
Deleteitem (nindex );
}

Sort in listctrl
There is a row of buttons at the top of the list control (clistctrl). You can sort records by selecting different columns. However, clistctrl does not support Automatic Sorting. We need to add a callback function for sorting to compare the two data sizes. In addition, we need to respond to the Message clicked by the sorting button. The following describes the specific practices.

Clistctrl provides a function for sorting. Its prototype is bool clistctrl: sortitems (pfnlvcompare pfncompare, DWORD dwdata ). The first parameter is the address of the global sorting function, and the second parameter is user data. You can transmit a data or pointer as needed. This function returns-1, indicating that the first row should be before the second item. Return 1, indicating that the first row should be behind the second item. Return 0, indicating that the two items are equal.

The original form of the function used for sorting is: int callback listcompare (lparam lparam1, lparam lparam2, lparam lparamsort ), the third parameter is the data passed by the caller (that is, the second parameter dwdata when sortitems is called ). The first and second parameters are itemdata for comparison. You can use DWORD clistctrl: getitemdata (INT nitem)/bool clistctrl: setitemdata (INT nitem, DWORD dwdata) to access the itemdata of each item. You can also set this value by selecting clistctrl: insertitem when adding an item. Because you can only use this value to determine the position of the item during sorting, you should clearly determine the meaning of this value.

Finally, we need to know when to sort the messages. To achieve this, we can process the lvn_columnclick message in the parent window.

Let's look at an example. This example is a derived class and supports sorting in order or in reverse order. In order to sort the global data in a simple way, there are multiple groups of data to be sorted in actual application, so we need to pass the parameter to tell the sort function what data needs to be sorted.

// Global data
Struct demo_data
{
Char szname [20];
Int iage;
} Stralldata [5] = {"Wang", 30 },{ "Zhang", 40 },{ "Wu", 32 },{ "Chen ", 20 },{ "Li", 36 }};

// Clistctrl, derived class definition
Class csortlist: Public clistctrl
{
// Construction
Public:
Csortlist ();
Bool m_fasc; // whether to order
Int m_nsortedcol; // column of the current sorting
Protected:
// {Afx_msg (csortlist)
//} Afx_msg
...
};

// The parent window contains the clistctrl derived class Object
Class csort_in_list_ctrldlg: Public cdialog
{
// Construction
Public:
Csort_in_list_ctrldlg (cwnd * pparent = NULL); // standard Constructor

// Dialog data
// {Afx_data (csort_in_list_ctrldlg)
Enum {IDD = idd_sort_in_list_ctrl_dialog };
Csortlist m_listtest;
//} Afx_data
}

// Define lvn_columnclick message ing in the parent window
Begin_message_map (csort_in_list_ctrldlg, cdialog)
// {Afx_msg_map (csort_in_list_ctrldlg)
On_policy (lvn_columnclick, idc_list1, oncolumnclicklist1)
//} Afx_msg_map
End_message_map ()

// Initialize data
Bool csort_in_list_ctrldlg: oninitdialog ()
{
Cdialog: oninitdialog ();

// Initialize the data list in listctrl
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 );
// Set itemdata of each item as the index of the data in the array
// Use itemdata in the sorting 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 sorting method
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;
}
// Call the sorting Function
M_listtest.sortitems (listcompare, (DWORD) & m_listtest );
* Presult = 0;
}

// Sorting function implementation
Int callback listcompare (lparam lparam1, lparam lparam2, lparam lparamsort)
{
// Obtain the csortlist Object Pointer through the passed parameter to obtain the sorting method
Csortlist * Pv = (csortlist *) lparamsort;

// Use itemdata to determine data
Demo_data * pinfo1 = stralldata + lparam1;
Demo_data * pinfo2 = stralldata + lparam2;
Cstring szcomp1, szcomp2;
Int icompres;
Switch (Pv-> m_nsortedcol)
{
Case (0 ):
// Sort by Column
Szcomp1 = pinfo1-> szname;
Szcomp2 = pinfo2-> szname;
Icompres = szcomp1.compare (szcomp2 );
Break;
Case (1 ):
// Sort by the second column
If (pinfo1-> iage = pinfo2-> iage)
Icompres = 0;
Else
Icompres = (pinfo1-> iage <pinfo2-> iage )? -1:1;
Break;
Default:
Assert (0 );
Break;
}
// Adjust according to the current sorting method
If (Pv-> m_fasc)
Return icompres;
Else
Return icompres *-1;
}

Fastest sorting:
Clistctrl: sortitems
Example

// 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 don't 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 variables
Add 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 shoshould reflect that.

Nsortedcol =-1;
Bsortascending = true;

Step 3: Add entry in message map to handle hdn_itemclick
Actually 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_policy_reflect () instead of on_policy (). 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_policy (hdn_itemclicka, 0, onheaderclicked)
On_policy (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. what notification it takes es 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 that header Control ID is zero.

Step 4: Write the onheaderclicked () function
Here'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 wowould have to provide custom sorting for them.

Void cmylistctrl: onheaderclicked (nmhdr * pnmhdr, lresult * presult)
{
Hd_notify * phdn = (hd_notify *) pnmhdr;

If (phdn-> iButton = 0)
{< br> // user clicked on header using left mouse button
If (phdn-> iItem = nsortedcol)
bsortascending =! Bsortascending;
else
bsortascending = true;

Nsortedcol = phdn-> iItem;
Sorttextitems (nsortedcol, bsortascending );

}
* Presult = 0;
}

Let the subitem of clistctrl also have the Edit function:
You need to reload a text box, and then change the text box position when lvn_beginlabeledit.
Cinedit m_inedit;

If (getstyle () & lvs_typemask) = lvs_report & (m_neditsubitem! = 0 ))
{
Hwnd hwndedit;
Crect rtbound;
Cstring strtext;

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. iItem, m_neditsubitem );
M_inedit.setwindowtext (strtext );
}

Void cinedit: onwindowposchanging (windowpos far * lpwndpos)
{
Crect rtclient;

Lpwndpos-> X = m_left; // m_left is set in lvn_beginlabeledit.

cedit: onwindowposchanging (lpwndpos);
// todo: add your message handler code here
}

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.