|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Visual Basic Common
Control API Routines SendMessage: Determine Positions of Re-Ordered ListView Columns |
||
Posted: | Friday August 14, 1997 | |
Updated: | Monday December 26, 2011 | |
Applies to: | VB4-32, VB5, VB6 | |
Developed with: | VB4-32, Windows 95 | |
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. |
|
Sending
the listview extended style message LVS_EX_HEADERDRAGDROP enables repositioning/reordering of a
Listview's main and sub item columns. However, this does not alter the index of the columns to match their new physical locations. VB remains unaware that repositioning has taken place (since it was done via APIs "outside" of VB's native control handling methods), so performing an indexed loop through the ColumnHeaders collection will always return the columns in the order they were created. This maintains the validity of the code used in adding items and sub items to the listview as the indexes continue to point to the original columns. There are times, however, when it is desirable to know what the current column arrangement is. LVM_GETCOLUMNORDERARRAY, LVM_GETCOLUMN and the LVCOLUMN Type, together with SendMessage, will return the order of the columns that the user may have changed. 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. It also assumes that you have implemented the code necessary to provide the column-rearrangement functionality. |
BAS Module Code |
None. |
|
Form Code |
Add a command button to the project (Command1), and add the following code to the Command1_Click sub: |
|
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_SETEXTENDEDLISTVIEWSTYLE = (LVM_FIRST + 54) Private Const LVM_GETEXTENDEDLISTVIEWSTYLE = (LVM_FIRST + 55) Private Const LVS_EX_FULLROWSELECT = &H20 Private Const LVS_EX_GRIDLINES = &H1 Private Const LVS_EX_CHECKBOXES = &H4 Private Const LVS_EX_HEADERDRAGDROP = &H10 Private Const LVM_GETCOLUMN = (LVM_FIRST + 25) Private Const LVM_GETCOLUMNORDERARRAY = (LVM_FIRST + 59) Private Const LVCF_TEXT = &H4 Private Type LVCOLUMN mask As Long fmt As Long cx As Long pszText As String cchTextMax As Long iSubItem As Long iImage As Long iOrder As Long End Type Private Sub Command1_Click() 'working variables Dim i As Long Dim firstCol As Long Dim lastCol As Long Dim totalCols As Long 'used for the message box Dim msg As String 'the return value from the API Dim tmp As String 'the Listview Column structure Dim LVC As LVCOLUMN 'initialize the variables needed. totalCols is the 1-based 'total required for the API. lastCol is the 0-based 'number of columns in the listview. totalCols = ListView1.ColumnHeaders.Count firstCol = 0 lastCol = totalCols - 1 'to get the column order, we have to pass an array to the API. 'On return, it will be filled with the index of the column in 'incrementing positions. For example, if column 2 was moved 'to position 0, the return array would hold 2, 1, 0, 3. 'And because this will be used directly in the API calls, it 'is declared As Long. ReDim posArray(firstCol To lastCol) As Long Call SendMessage(ListView1.hwnd, _ LVM_GETCOLUMNORDERARRAY, _ totalCols, _ posArray(firstCol)) 'with the array filled, it's now a matter of looping through the 'array, and passing each item as the position (wParam). The 'LVCOLUMN type (LVC) will be filled with the data for the 'passed index (LVCF_TEXT in this example). For i = firstCol To lastCol 'get the string associated with the position. The string to fill 'must be padded with sufficient room to hold the ColumnHeader 'string. tmp = Space$(32) With LVC .mask = LVCF_TEXT .pszText = tmp .cchTextMax = Len(tmp) End With Call SendMessage(ListView1.hwnd, LVM_GETCOLUMN, posArray(i), LVC) 'strip the trailing null tmp = Left$(LVC.pszText, InStr(LVC.pszText, Chr$(0)) - 1) 'add the returned value to the msg for display List1.AddItem tmp msg = msg & vbTab & tmp & vbTab & _ vbTab & posArray(i) & vbTab & vbCrLf Next MsgBox " Current column order / Original index: " & vbCrLf & vbCrLf & msg End Sub |
Comments |
Run your project, and populate your Listview as usual. Enable the Allow Repositioning checkbox, and click and drag the column headers to new positions. Test the routine by hitting the Get Columns button. |
|
|
|
|||||
|
|||||
|
|||||
Copyright ©1996-2011 VBnet and Randy Birch. All Rights Reserved. |