Trucos ListView : Cambiar la posición de las columnas

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



Trucos Trucos

Visual Basic Página de Visual Basic

Página principal Página principal

www.jrubi.com