We
have seen how to allow the user to reorder columns by sending
the HEADERDRAGDROP message. The listview control provides another means to reorder the report view columns - programmatically via the
COLUMNORDERARRAY message. This page demonstrates this technique.
The principle is simple. We dim an array then use SendMessage along with LVM_GETCOLUMNORDERARRAY to retrieve into it the current column
positions. By default, on first creating the control column 1 will have a listview index of 0, column 2 will be 1, and so on for the
number of columns in the control. Once the array has been populated, the developer is free to reassign indices to the respective array
member. In this demonstration, the array looks like:
|
colArray()
members |
After calling
LVM_GET... |
When calling
LVM_SET... |
0 |
0 |
0 |
1 |
1 |
3 |
2 |
2 |
2 |
3 |
3 |
1 |
|
As the table indicates, we have swapped the second and fourth columns
by reassigning its column order. Once this has be changed, another SendMessage is used to pass the array back to the control with the
LVM_SETCOLUMNORDERARRAY message.
This example does not contain all code required to construct
the illustration shown. The routine provided here is designed to be applied to an existing project utilizing a ListView control with
sub items. |
Option Explicit
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Copyright ©1996-2011 VBnet/Randy Birch, All Rights Reserved.
' Some pages may also contain other copyrights by the author.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Distribution: You can freely use this code in your own
' applications, but you may not reproduce
' or publish this code on any web site,
' online service, or distribute as source
' on any media without express permission.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Declare Function SendMessage Lib "user32" _
Alias "SendMessageA" _
(ByVal hwnd As Long, _
ByVal Msg As Long, _
ByVal wParam As Long, _
lParam As Any) As Long
Private Const LVM_FIRST = &H1000
Private Const LVM_GETCOLUMNORDERARRAY = (LVM_FIRST + 59)
Private Const LVM_SETCOLUMNORDERARRAY = (LVM_FIRST + 58)
Private Sub Command1_Click()
'working vars
Dim success As Long
Dim i As Long
Dim colCount As Long
'create an array of columns totaling
'the number of columns in the control
colCount = ListView1.ColumnHeaders.Count
ReDim colArray(0 To colCount) As Long
success = SendMessage(ListView1.hwnd, _
LVM_GETCOLUMNORDERARRAY, _
colCount, colArray(0))
'-----------------
'DEBUG - output column order to listbox
List1.Clear
List1.AddItem "before =" & success
For i = 0 To colCount - 1
List1.AddItem colArray(i)
Next
'-----------------
'if success is non-zero, then the call above succeeded,
'and the array contains the current order of columns
'from left to right. This order was determined by the
'order the columns were added to the control
'(typically 0, 1, 2, 3 etc)
If success <> 0 Then
'change the column order by setting the
'array to new values
colArray(0) = 0
colArray(1) = 3
colArray(2) = 2
colArray(3) = 1
'and call the API to make the change
success = SendMessage(ListView1.hwnd, _
LVM_SETCOLUMNORDERARRAY, _
colCount, colArray(0))
'the columns have changed, but the control needs
'to redisplay its contents in the new order
ListView1.Refresh
End If
'-----------------
'DEBUG - retrieve again and output column
'order to listbox
success = SendMessage(ListView1.hwnd, _
LVM_GETCOLUMNORDERARRAY, _
colCount, colArray(0))
List1.AddItem "after =" & success
For i = 0 To colCount - 1
List1.AddItem colArray(i)
Next
'-----------------
End Sub |