Visual Basic Common Control API Routines
SendMessage: Reorder ListView Columns Programmatically
     
Posted:   Monday March 8, 1999
Updated:   Monday December 26, 2011
     
Applies to:   VB4-32, VB5, VB6
Developed with:   VB6, Windows 98
OS restrictions:   None
Author:   VBnet - Randy Birch
     
 Prerequisites
This method is intended for Visual Basic 5 or Visual Basic 6 where the Common Control library used is the MSComCtl 5 version (comctl32.ocx). Because the VB6-specific mscomctl.ocx (Common Controls 6) is a complete implementation of comctl32.dll and not reliant on the version of comctl32.dll installed, this routine may not work when applied to a listview created from the VB6-specific mscomctl.ocx.

Enhanced Comctl32 functionality is only available to users with comctl32.dll version 4.70 or greater installed. This dll is typically installed with IE3.x or greater.


lvcolreorder.gif (16667 bytes)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.

 BAS Module Code
None.

 Form Code
Add a command button to the project (Command1) and a List box for debug purposes only. Add the following code to the command button:

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
 Comments
Run your project, and populate your report-view ListView as usual. Click the command button to reorder the columns.

 
 

PayPal Link
Make payments with PayPal - it's fast, free and secure!

 
 
 
 

Copyright ©1996-2011 VBnet and Randy Birch. All Rights Reserved.
Terms of Use  |  Your Privacy

 

Hit Counter