If you are not a paid subscriber, you must have signed up for our free trial at http://www.codeoftheweek.com. Our ezine is not an unsolicited message (in other words a spam email). Keep in mind that if you signed up for our free trial you can still receive a total of four issues at no cost to you. After you receive the four issues you will be notified about continuing your subscription.
If you do not wish to continue to receive this ezine, please email us at cancel@codeoftheweek.com
The source code in this issue is designed for Visual Basic 5.0 and above. This is due to the use of the new AddressOf feature of VB 5. AddressOf allows you to pass the address of a subroutine created in a code module. It is for the intermediate to advanced developer.
If you have any questions about this issue, please email us at questions@codeoftheweek.com
This issue introduces a method to sort the subitems of a ListView. Sure, you are saying that is easy, just set the SortKey and Sorted properties and you are off and running. Unfortunately the built-in sort is by Text only. This means that if you have a date column or a numeric column you can not properly sort the data in the HeadClick routine. We accomplish this task by using some API calls and some callbacks.
Some of you might not have used callbacks before in Visual Basic. It is a routine that you can pass as a parameter to some functions that can be called at a later time by that function. The definition that Microsoft gives in the Visual Basic help file is: "A callback procedure is a procedure within your program that Windows can call at certain times. You enable Windows to call this procedure by passing a reference to the procedure as an argument in an API call that is preceded by the AddressOf operator. Since the caller of a callback is not within your program, it is important that an error in the callback procedure not be propagated back to the caller."
This issue uses message passing and callbacks to accomplish the task of sorting a list view by date or numbers.
There are a two callback routines that are needed to provide the sorting functionality. One is for sorting by Long and the other for sorting by Date. The Compare routines work by comparing the two items that are passed to them and returning 0, 1 or 2 depending on whether the value1 is less than, greater than or equal to value2. It returns 0 when Value1 is less than Value2, 1 when Value1 is equal to Value2 and 2 when Value1 is greater than Value2.
In our source code we send the LVM_SORTITEMS message to the ListView control with the address of our callback routine. See sample code for complete details on how to make the calls.
If you require additional custom sorting, all you need to do is to write another callback routine similiar to CompareDates or CompareLongs. One example might be a CompareCurrency which would sort currency columns correctly.
Public Function CompareDates(ByVal lngParam1 As Long, _ ByVal lngParam2 As Long, _ ByVal hWnd As Long) As Long Public Function CompareLongs(ByVal lngParam1 As Long, _ ByVal lngParam2 As Long, _ ByVal hWnd As Long) As Long
On Form1 we created a ListView control called lvFiles. We added several columns: Name, File Date, and File Size. If you click on the Name column it will use the built-in text sorting. If you click on the File Date column it will use the CompareDates subroutine to sort by date and the CompareLongs to sort by number. We assume you have added a bunch of items using the ListView.ListItems.Add method.
Private Sub lvFiles_ColumnClick(ByVal ColumnHeader As ComctlLib.ColumnHeader) Dim strName As String Dim dDate As Date Dim lListViewItem As Long Dim dStart As Double 'Handle User click on column header Select Case ColumnHeader.Index Case 1 ' name column lvFiles.Sorted = True lvFiles.SortKey = ColumnHeader.Index - 1 Case 2 lvFiles.Sorted = False 'User clicked on the Date header SortColumn = ColumnHeader.Index - 1 SendMessage lvFiles.hWnd, _ LVM_SORTITEMS, _ lvFiles.hWnd, _ AddressOf CompareDates Case 3 lvFiles.Sorted = False 'User clicked on the Size header SortColumn = ColumnHeader.Index - 1 SendMessage lvFiles.hWnd, _ LVM_SORTITEMS, _ lvFiles.hWnd, _ AddressOf CompareLongs End Select 'Refresh the ListView lvFiles.Refresh End Sub
To see the source code for this issue you must be a subscriber to Code of the Week. If you are a subscriber the source code is available at the following address: http://www.codeoftheweek.com/membersonly/bi/0049.html
That concludes this issue of COTW. We hope you find the source code useful in your development.
The below describes the ways you can supply us some feedback about COTW. We would like to see our members help mold COTW into the best Visual Basic source code resource available. But to do that we need your feedback about what you like and what you do not like about COTW.
If you are interested in advertising in COTW please email us at sponsor@codeoftheweek.com Our rates are VERY reasonable, actually they are almost FREE. We reach over three thousand Visual Basic developers each week.
If you have any suggestions for topics you would like to see covered or questions about this issue, please email them to info@codeoftheweek.com or use online feedback form at http://www.codeoftheweek.com/feedback.html.
If you have any source code you would like to submit for possible inclusion in COTW, please fill out our online submission form at http://www.codeoftheweek.com/submission.html.
Thank you for trying Code of the Week for Visual Basic.
Your free trial expires after you receive your fourth issue. If you want to continue to receive Code of the Week you can get 52 issues of COTW for only $19.95. This is a full year of Visual Basic source code and information to help with all your development. So don't wait, subscribe now! The quickest way to subscribe is to jump to our online order form at http://www.codeoftheweek.com/order.html