我想实现这样的功能:
1。单击列首则按所单击的列排序
2。隐藏第2列问题如下:
由于在Form_Load事件中调用API:Call RegisterListView(lvListView)
导致单击列首时无法排序,
如果去除调用此API则可以排序,但无法隐藏第2列。
小弟初识API,请问高手们,如何同时实现上述两个功能?代码如下:

解决方案 »

  1.   

    '窗体代码如下(1个ListView和2个按钮):
    Option Explicit
    Dim HideFlag As Boolean
    Dim OldWidth As Single
    Dim SORT As IntegerPrivate Sub Command1_Click()
        HideFlag = True
        OldWidth = lvListView.ColumnHeaders(2).Width
        lvListView.ColumnHeaders(2).Width = 0
    End SubPrivate Sub Command2_Click()
        HideFlag = False
        lvListView.ColumnHeaders(2).Width = 500
        
    End SubPrivate Sub Form_Load()
      Command1.Caption = "隐藏第2列"
      Command2.Caption = "显示第2列"
      lvListView.View = lvwReport
      lvListView.ColumnHeaders.Add , , "第1列"
      lvListView.ColumnHeaders.Add , , "第2列"
      lvListView.ColumnHeaders.Add , , "第3列"
      With lvListView.ListItems.Add(, , "d")
        .ListSubItems.Add , , "d1"
        .ListSubItems.Add , , "d2"
      End With
      With lvListView.ListItems.Add(, , "e")
        .ListSubItems.Add , , "e1"
        .ListSubItems.Add , , "e2"
      End With
      With lvListView.ListItems.Add(, , "f")
        .ListSubItems.Add , , "f1"
        .ListSubItems.Add , , "f2"
      End With
        
      Call RegisterListView(lvListView)End SubPrivate Sub Form_Unload(Cancel As Integer)  Call UnregisterListView(lvListView)End SubPublic Function lvListView_HeaderEvent(ByVal Action As lvHeaderActions, ByVal Column As Long) As Boolean
      If Column = 2 And HideFlag = True Then
        lvListView_HeaderEvent = True
      End IfEnd FunctionPrivate Sub lvListView_ColumnClick(ByVal ColumnHeader As ColumnHeader)
      
      If SORT = 0 Then
        SORT = 1
      Else
        SORT = 0
      End If  lvListView.SortKey = ColumnHeader.Index - 1
      MsgBox SORT
      'SortOrder属性(升序或降序排序):   0-lvwAscending  1-LvwDescending
      lvListView.SortOrder = SORT  lvListView.Sorted = TrueEnd Sub
    -----------------------------
      

  2.   

    '模块代码如下(API):
    Option Explicit
    Public Type POINTAPI
      X As Long
      Y As Long
    End Type
    Public Const GWL_WNDPROC  As Long = -4
    Public Const GWL_STYLE    As Long = -16
    Public Const WM_NOTIFY    As Long = &H4E&
    Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
    Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
    Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal wNewWord As Long) As Long
    Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Public Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
    Public Declare Function ScreenToClient Lib "user32" (ByVal hWnd As Long, lpPoint As POINTAPI) As Long
    Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Any, lParam As Any) As Long
    Public Declare Function GetProp Lib "user32" Alias "GetPropA" (ByVal hWnd As Long, ByVal lpString As String) As Long
    Public Declare Function SetProp Lib "user32" Alias "SetPropA" (ByVal hWnd As Long, ByVal lpString As String, ByVal hData As Long) As Long
    Private Const LVM_FIRST = &H1000
    Private Const LVM_GETHEADER = (LVM_FIRST + 31)Private Type NMHDR
      hWndFrom As Long
      idfrom   As Long
      code     As Long
    End TypePrivate Type HD_HITTESTINFO
      pt    As POINTAPI
      flags As Long
      iItem As Long
    End TypePrivate Const HHT_ONHEADER = &H2
    Private Const HHT_ONDIVIDER = &H4Private Const HDM_HITTEST As Long = &H1206Private Const HDN_FIRST            As Long = -300&
    Private Const HDN_ITEMCLICK        As Long = (HDN_FIRST - 2)
    Private Const HDN_DIVIDERDBLCLICK  As Long = (HDN_FIRST - 5)
    Private Const HDN_BEGINTRACK       As Long = (HDN_FIRST - 6)
    Private Const HDN_ENDTRACK         As Long = (HDN_FIRST - 7)
    Private Const HDN_TRACK            As Long = (HDN_FIRST - 8)
    Private Const HDN_GETDISPINFO      As Long = (HDN_FIRST - 9)
    Private Const HDN_BEGINDRAG        As Long = (HDN_FIRST - 10)
    Private Const HDN_ENDDRAG          As Long = (HDN_FIRST - 11)
    Private Const HDN_ITEMCHANGING     As Long = (HDN_FIRST - 0)
    Private Const HDN_ITEMCHANGED      As Long = (HDN_FIRST - 1)
    Private Const HDN_ITEMDBLCLICK     As Long = (HDN_FIRST - 3)
    Private Const HDN_NM_RCLICK        As Long = -5' 列标头事件
    Public Enum lvHeaderActions
      lvHeaderActionClick = 1
      lvHeaderActionRightClick = 2
      lvHeaderActionDividerDoubleClick = 3
      lvHeaderActionResizeBegin = 4
      lvHeaderActionResizeEnd = 5
      lvHeaderActionChanging = 6
      lvHeaderActionChanged = 7
      lvHeaderActionDragBegin = 8
      lvHeaderActionDragEnd = 9
    End EnumPrivate RegisteredListViewControls As New CollectionPublic Sub RegisterListView(ByVal ListViewControl As ListView)
       
      Call SetProp(ListViewControl.hWnd, "OrigWindowProc", GetWindowLong(ListViewControl.hWnd, GWL_WNDPROC))
      
      Call SetWindowLong(ListViewControl.hWnd, GWL_WNDPROC, AddressOf HandleListViewHeaderMsgs)
      
      Call RegisteredListViewControls.Add(ListViewControl, CStr(ListViewControl.hWnd))
       
    End SubPublic Sub UnregisterListView(ByVal ListViewControl As ListView)
       
      Dim OrigWindowProc As Long
      
      OrigWindowProc = GetProp(ListViewControl.hWnd, "OrigWindowProc")
      
      If (OrigWindowProc <> 0) Then
        Call SetWindowLong(ListViewControl.hWnd, GWL_WNDPROC, OrigWindowProc)
      End If
       
      Call RegisteredListViewControls.Remove(CStr(ListViewControl.hWnd))
       
    End SubPublic Function HandleListViewHeaderMsgs(ByVal ListViewhWnd As Long, ByVal msg As Long, ByVal wp As Long, ByVal lp As Long) As Long
       
      Const EVENT_SUFFIX As String = "_HeaderEvent"
       
      Dim ListViewControl As ListView
      Dim NmHdrMsg        As NMHDR
      Dim PointStruct     As POINTAPI
      Dim HitTestInfo     As HD_HITTESTINFO
      Dim HeaderhWnd      As Long
      Dim HeaderAction    As lvHeaderActions
      Dim CancelMsg       As Boolean
      
      If msg = WM_NOTIFY Then    HandleListViewHeaderMsgs = CallWindowProc(GetProp(ListViewhWnd, "OrigWindowProc"), ListViewhWnd, msg, wp, lp)
      
        Call CopyMemory(NmHdrMsg, ByVal lp, Len(NmHdrMsg))
        
        HeaderhWnd = SendMessage(ListViewhWnd, LVM_GETHEADER, 0&, ByVal 0&)
        
        If (HeaderhWnd <> 0) Then      Call GetCursorPos(PointStruct)
          Call ScreenToClient(HeaderhWnd, PointStruct)
          
          HitTestInfo.flags = HHT_ONHEADER Or HHT_ONDIVIDER
          HitTestInfo.pt = PointStruct
          
          Call SendMessage(HeaderhWnd, HDM_HITTEST, 0&, HitTestInfo)      Select Case NmHdrMsg.code
            Case HDN_ITEMCLICK:       HeaderAction = lvHeaderActionClick
            Case HDN_NM_RCLICK:       HeaderAction = lvHeaderActionRightClick
            Case HDN_DIVIDERDBLCLICK: HeaderAction = lvHeaderActionDividerDoubleClick
            Case HDN_BEGINTRACK:      HeaderAction = lvHeaderActionResizeBegin
            Case HDN_ENDTRACK:        HeaderAction = lvHeaderActionResizeEnd
            Case HDN_ITEMCHANGING:    HeaderAction = lvHeaderActionChanging
            Case HDN_ITEMCHANGED:     HeaderAction = lvHeaderActionChanged
            Case HDN_BEGINDRAG:       HeaderAction = lvHeaderActionDragBegin
            Case HDN_ENDDRAG:         HeaderAction = lvHeaderActionDragEnd
          End Select
          
          If HeaderAction <> 0 Then
                
            On Error Resume Next
            
            Set ListViewControl = RegisteredListViewControls(CStr(ListViewhWnd))
            
            CancelMsg = CallByName(ListViewControl.Parent, ListViewControl.Name & EVENT_SUFFIX, VbCallType.VbMethod, HeaderAction, HitTestInfo.iItem + 1)
            
            On Error GoTo 0
            If CancelMsg Then
              HandleListViewHeaderMsgs = 1
              Exit Function
            End If
            
          End If
          
        End If
      
      End If
      
      HandleListViewHeaderMsgs = CallWindowProc(GetProp(ListViewhWnd, "OrigWindowProc"), ListViewhWnd, msg, wp, lp)
       
    End FunctionPublic Sub ListViewHeaderEventDebugPrint(ByVal ListViewControl As ListView, ByVal Action As lvHeaderActions, ByVal Column As Long)  Dim msg As String  Select Case Action
        Case lvHeaderActionClick:               msg = "clicked"
        Case lvHeaderActionRightClick:          msg = "right-clicked"
        Case lvHeaderActionDividerDoubleClick:  msg = "divider dbl-clicked"
        Case lvHeaderActionResizeBegin:         msg = "resize begin"
        Case lvHeaderActionResizeEnd:           msg = "resize end"
        Case lvHeaderActionChanging:            msg = "changing"
        Case lvHeaderActionChanged:             msg = "changed"
        Case lvHeaderActionDragBegin:           msg = "drag begin"
        Case lvHeaderActionDragEnd:             msg = "drag end"
      End Select
        
      Debug.Print ListViewControl.Parent.Name & "." & ListViewControl.Name & ": " & msg & " (col=" & CStr(Column) & ")"End Sub
    ==========================================
      

  3.   

    解决了!
    添加了一句Action = lvHeaderActionClick!
    祝大家周末愉快!
      

  4.   

    没办法,分就给summer兄台了!