La funcionalidad extendida de la dll Comctl32.dll sólo está disponible para la versión 4.70 y superiores (instaladas por el IE 3.x y el IE 4)
En un módulo:
Public Declare Function SendMessageLong Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As Long, _
ByVal Msg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long
Public Const LVM_FIRST = &H1000
Public Const LVM_SETEXTENDEDLISTVIEWSTYLE = LVM_FIRST + 54
Public Const LVM_GETEXTENDEDLISTVIEWSTYLE = LVM_FIRST + 55
Public Const LVS_EX_HEADERDRAGDROP = &H10
Si queremos que las columnas se puedan mover :
Call SendMessageLong(ListView1.hwnd, _
LVM_SETEXTENDEDLISTVIEWSTYLE, _
LVS_EX_HEADERDRAGDROP, true)
Y para que no se puedan mover :
Call SendMessageLong(ListView1.hwnd, _
LVM_SETEXTENDEDLISTVIEWSTYLE, _
LVS_EX_HEADERDRAGDROP, false)
No debemos preocuparnos del código (por ejemplo de ordenación) que hayamos escrito ya que para el Visual Basic las columnas siguen en el mismo orden y si recorremos la colección ColumHeaders siempre nos las devolverá en el orden en el que fueron creadas.
Si necesitamos saber en qué orden han quedado las columnas podremos emplear :
En un módulo declaramos también :
Public Const LVM_GETCOLUMN = (LVM_FIRST + 25)
Public Const LVM_GETCOLUMNORDERARRAY = (LVM_FIRST + 59)
Public Const LVCF_TEXT = &H4
Public 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 GetColumnsOrder_Click()
'variables de trabajo
Dim i As Long
Dim r As Long
Dim firstCol As Long
Dim lastCol As Long
Dim totalCols As Long
'usada para el messagebox
Dim msg As String
'el valor devuelto por el API
Dim tmp As String
'Columna de un Listview
Dim LVC As LVCOLUMN
'inicializamos las variables necesarias. totalCols comienza en 1
'lastCol comienza en 0
'número de columnas del listview.
totalCols = ListView1.ColumnHeaders.Count
firstCol = 0
lastCol = totalCols - 1
'para obtener el orden de las columnas, debemos pasar una matriz al API
'En ella nos devolverá la propiedad index de cada posición.
'Por ejemplo, si la columna 2 la movemos a la posición 0 nos
'devolverá 2,0,1,3.
ReDim posArray(firstCol To lastCol) As Long
Call SendMessageAny(ListView1.hwnd, _
LVM_GETCOLUMNORDERARRAY, _
totalCols, _
posArray(firstCol))
'con la matriz rellena, debemos recorrerla
For i = firstCol To lastCol
'obtenemos el string asociado con la posición.
tmp = Space$(32)
With LVC
.mask = LVCF_TEXT
.pszText = tmp
.cchTextMax = Len(tmp)
End With
Call SendMessageAny(ListView1.hwnd, LVM_GETCOLUMN, posArray(i), LVC)
'quitamos los null del final
tmp = Left$(LVC.pszText, InStr(LVC.pszText, Chr$(0)) - 1)
'añadimoe el valor devuelto al mensaje
msg = msg & vbTab & tmp & vbTab & _
vbTab & posArray(i) & vbTab & vbCrLf
Next i
MsgBox " Orden actual / Index original: " & vbCrLf & vbCrLf & msg
End Sub