关于ListView控件的“列隐藏”与“排序”功能二者不可兼得的难题,高手请进!!!

terrywolf 2006-04-15 08:44:11
我想实现这样的功能:
1。单击列首则按所单击的列排序
2。隐藏第2列

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

代码如下:
...全文
274 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
terrywolf 2006-04-15
  • 打赏
  • 举报
回复
没办法,分就给summer兄台了!
Summer006 2006-04-15
  • 打赏
  • 举报
回复
哈哈,那就恭喜lz解决问题辣~~
terrywolf 2006-04-15
  • 打赏
  • 举报
回复
解决了!
添加了一句Action = lvHeaderActionClick!
祝大家周末愉快!

terrywolf 2006-04-15
  • 打赏
  • 举报
回复
'模块代码如下(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 Type

Private Type HD_HITTESTINFO
pt As POINTAPI
flags As Long
iItem As Long
End Type

Private Const HHT_ONHEADER = &H2
Private Const HHT_ONDIVIDER = &H4

Private Const HDM_HITTEST As Long = &H1206

Private 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 Enum

Private RegisteredListViewControls As New Collection

Public 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 Sub

Public 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 Sub

Public 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 Function

Public 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
==========================================
terrywolf 2006-04-15
  • 打赏
  • 举报
回复
'窗体代码如下(1个ListView和2个按钮):
Option Explicit
Dim HideFlag As Boolean
Dim OldWidth As Single
Dim SORT As Integer

Private Sub Command1_Click()
HideFlag = True
OldWidth = lvListView.ColumnHeaders(2).Width
lvListView.ColumnHeaders(2).Width = 0
End Sub

Private Sub Command2_Click()
HideFlag = False
lvListView.ColumnHeaders(2).Width = 500

End Sub

Private 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 Sub

Private Sub Form_Unload(Cancel As Integer)

Call UnregisterListView(lvListView)

End Sub

Public Function lvListView_HeaderEvent(ByVal Action As lvHeaderActions, ByVal Column As Long) As Boolean
If Column = 2 And HideFlag = True Then
lvListView_HeaderEvent = True
End If

End Function

Private 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 = True

End Sub


-----------------------------

1,451

社区成员

发帖
与我相关
我的任务
社区描述
VB 控件
社区管理员
  • 控件
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧