原本是想用LabelEdit事件来编辑SubItems的,但好像不行?于是,想自己用TextBox来编辑SubItems的值,
应该是通过MouseDown MouseUp来启动编辑,
做一个自己的LabelEdit事件,
把TextBox移到子项的位置显示出来。问题是,如何触发LabelEdit呢?
触发的时机怎样掌握呢?应该不是简单的MouseDown吧?希望做到和原来的LabelEdit一样,
这样,操作的用户才不会感到异样!

解决方案 »

  1.   

    CSDN中有编辑Listview的贴子。
    自己查一下。
      

  2.   

    老大,我说的是何时触发自定义的LabelEdit事件!
    既不是单击编辑,也不是双击编辑,是单击之后在一定时间内的点击,才触发的。
    其实很简单的,我已经想到了,呵呵:)剩下的才是难点:如何定位TextBox???本贴说的ListView是Common Control 5.0(SP2)(绝对是有理由不使用6.0的)
    这个控件是没有ListSubItems的属性的,也没有ListItems(I).Left之类的属性,
    就是说,不能用以下方法移动Text到指定位置的!'Text1.Left = ListView1.ListItems(ListView1.HitTest(x, y).Index).Left + ListView1.Left
    'Text1.Top = ListView1.ListItems(ListView1.HitTest(x, y).Index).Top + ListView1.Top
    'Text1.Height = ListView1.ListItems(ListView1.HitTest(x, y).Index).Height
    'Text1.Width = ListView1.ListItems(ListView1.HitTest(x, y).Index).Width现在我已经取得了ListItems的索引项编号,以及子项编号,就是不知道如何求出它们的位置???加一句,为什么ColumnHeader(I).Left的位置总是不准确的呢?
      

  3.   

    Text1.Left = ListView1.HitTest(x, y).Left + ColumnHeader(I).Left + ListView1.Left
      

  4.   

    谢谢兄弟!但是无效上面说了,正因为使用的是5。0的控件,所以
    ListItem是没有Top 和Left属性的!解决的办法应该是发送消息之类的,就是说用自编HitTest方法,
    但是俺不知道如何编啊???另外,试下来,由控件本身返回的ColumnHeader(I).Left 数据相当有问题,
    会随着列数的增加而出现误差的成倍增长,实际上根本无法用它来定位左边界的,
    不知道怎么回事?是不是也直接用API才能取得正确值?
      

  5.   

    //解决的办法应该是发送消息之类的,就是说用自编HitTest方法,
    但是俺不知道如何编啊???应该有定义好的消息的,看看msdn
      

  6.   

    LVM_SUBITEMHITTEST 消息:
    http://msdn.microsoft.com/library/en-us/shellcc/platform/commctls/listview/messages/lvm_subitemhittest.asp?frame=true
      

  7.   

    老大,上面我已经写了://现在我已经取得了ListItems的索引项编号,以及子项编号,用的就是LVM_SUBITEMHITTEST现在想要的就是取得这个项目的具体位置,
    为了把Text控件移到相应地点用。
    (而且,俺的ListItems是没有Top 和Left属性的!)
      

  8.   

    模块1(modLVWRect):
    Option ExplicitPrivate mlhWndLV As Long
    Private mlhWndTB As Long
    Private mlItem As Long
    Private mlSubItm As Long
    Private Sub Form_Load()
        Dim i As Long
        Dim iTm As ListItem
        Text1.Appearance = ccFlat
        Text1.Visible = False
        mlhWndTB = Text1.hWnd
        With ListView1
            .LabelEdit = lvwManual
            .HideSelection = False
            mlhWndLV = .hWnd
            For i = 1 To 4
                .ColumnHeaders.Add Text:="Col " & i
            Next
            For i = 0 To &H3F
                Set iTm = .ListItems.Add(, , "Item " & i)
                iTm.SubItems(1) = i * 10
                iTm.SubItems(2) = i * 100
                iTm.SubItems(3) = i * 1000
            Next
        End With
        ListView1.View = lvwReport
        ListView1.Arrange = lvwAutoTop
    End SubPrivate Sub ListView1_DblClick()
        Dim lvhti As LVHITTESTINFO
        Dim rc As RECT
        Dim li As ListItem
        If (GetKeyState(vbKeyLButton) And &H8000) Then
            Call GetCursorPos(lvhti.pt)
            Call ScreenToClient(mlhWndLV, lvhti.pt)
            If (ListView_SubItemHitTest(mlhWndLV, lvhti) <> LVI_NOITEM) Then
                If lvhti.lSubItem Then
                    If GetSubItemRect(mlhWndLV, lvhti.lItem, lvhti.lSubItem, LVIR_LABEL, rc) Then
                        Call SetParent(mlhWndTB, mlhWndLV)
                        'Call MapWindowPoints(mlhWndLV, hWnd, rc, 2)
                        Text1.Move (rc.Left + 4) * Screen.TwipsPerPixelX - 30, rc.Top * Screen.TwipsPerPixelY, _
                        (rc.Right - rc.Left) * Screen.TwipsPerPixelX, (rc.Bottom - rc.Top) * Screen.TwipsPerPixelY
                        mlItem = lvhti.lItem + 1
                        mlSubItm = lvhti.lSubItem
                        Text1 = ListView1.ListItems(mlItem).SubItems(mlSubItm)
                        Text1.Tag = Text1
                        ListView1.ListItems(mlItem).SubItems(mlSubItm) = ""
                        Text1.ZOrder 0
                        Text1.Visible = True
                        Text1.SelStart = 0
                        Text1.SelLength = Len(Text1)
                        Text1.SetFocus
                        If chkDisableScrollbars.Value = 1 Then
                            Call EnableScrollBar(ListView1.hWnd, SB_BOTH, ESB_DISABLE_BOTH)
                        Else
                            Call EnableScrollBar(ListView1.hWnd, SB_BOTH, ESB_ENABLE_BOTH)
                        End If
                        Call SubClass(mlhWndTB, AddressOf WndProc)
                    End If
                End If
            End If
        End If
    End SubPrivate Sub Text1_GotFocus()
        ListView1.ListItems(mlItem).Selected = True
    End SubPrivate Sub Text1_Change()
        If mlItem Then Text1.Width = TextWidth(Text1) + 180
    End SubPrivate Sub Text1_KeyPress(KeyAscii As Integer)
        If (KeyAscii = vbKeyReturn) Then
            Call HideTextBox(True)
            If chkDisableScrollbars.Value = 1 Then
                Call EnableScrollBar(ListView1.hWnd, SB_BOTH, ESB_ENABLE_BOTH)
            Else
                Call EnableScrollBar(ListView1.hWnd, SB_BOTH, ESB_DISABLE_BOTH)
            End If
            KeyAscii = 0
        ElseIf (KeyAscii = vbKeyEscape) Then
            Call HideTextBox(False)
            If chkDisableScrollbars.Value = 1 Then
                Call EnableScrollBar(ListView1.hWnd, SB_BOTH, ESB_ENABLE_BOTH)
            Else
                Call EnableScrollBar(ListView1.hWnd, SB_BOTH, ESB_DISABLE_BOTH)
            End If
            KeyAscii = 0
        End If
    End SubFriend Sub HideTextBox(bApply As Boolean)
        If bApply Then
            ListView1.ListItems(mlItem).SubItems(mlSubItm) = Text1
        Else
            ListView1.ListItems(mlItem).SubItems(mlSubItm) = Text1.Tag
        End If
        Call UnSubClass(mlhWndTB)
        Text1.Visible = False
        Text1 = ""
        mlItem = 0
    End Sub
      

  9.   

    模块2(modSubClass):
    Option ExplicitPrivate Const WM_DESTROY = &H2
    Private Const WM_KILLFOCUS = &H8
    Private Const GWL_WNDPROC = (-4)
    Private Const OLDWNDPROC = "OldWndProc"Private Declare Function GetProp Lib "user32" Alias "GetPropA" (ByVal hWnd As Long, ByVal lpString As String) As Long
    Private Declare Function SetProp Lib "user32" Alias "SetPropA" (ByVal hWnd As Long, ByVal lpString As String, ByVal hData As Long) As Long
    Private Declare Function RemoveProp Lib "user32" Alias "RemovePropA" (ByVal hWnd As Long, ByVal lpString As String) As Long
    Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, _
    ByVal dwNewLong As Long) As Long
    Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, _
    ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As LongPublic Function SubClass(hWnd As Long, lNew As Long) As Boolean
        Dim lOld As Long
        Dim bSuccess As Boolean
        If (GetProp(hWnd, OLDWNDPROC) = 0) Then
            lOld = SetWindowLong(hWnd, GWL_WNDPROC, lNew)
            If lOld Then
                bSuccess = SetProp(hWnd, OLDWNDPROC, lOld)
            End If
        End If
        If bSuccess Then
            SubClass = True
        Else
            If lOld Then Call UnSubClass(hWnd)
            MsgBox "Unable to sub-class", vbOKOnly + vbCritical
        End If
    End FunctionPublic Function UnSubClass(hWnd As Long) As Boolean
        Dim lOld As Long
        lOld = GetProp(hWnd, OLDWNDPROC)
        If lOld Then
            If RemoveProp(hWnd, OLDWNDPROC) Then
                UnSubClass = SetWindowLong(hWnd, GWL_WNDPROC, lOld)
            End If
        End If
    End FunctionPublic Function WndProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
        Select Case uMsg
            'Hide the TextBox when it loses focus
            '(its LostFocus event it not fired when losing focus to a window outside the app).
            Case WM_KILLFOCUS
                'UnSubClass.
                Call CallWindowProc(GetProp(hWnd, OLDWNDPROC), hWnd, uMsg, wParam, lParam)
                Call Form1.HideTextBox(True)
                Exit Function
                'Unsubclass the window
            Case WM_DESTROY
                Call CallWindowProc(GetProp(hWnd, OLDWNDPROC), hWnd, uMsg, wParam, lParam)
                Call UnSubClass(hWnd)
                Exit Function
        End Select
        WndProc = CallWindowProc(GetProp(hWnd, OLDWNDPROC), hWnd, uMsg, wParam, lParam)
    End Function
      

  10.   

    窗体,一个listview 5.0,一个textbox,一个checkbox(名为:chkDisableScrollbars)代码如下:
    Option ExplicitPrivate mlhWndLV As Long
    Private mlhWndTB As Long
    Private mlItem As Long
    Private mlSubItm As Long
    Private Sub Form_Load()
        Dim i As Long
        Dim iTm As ListItem
        Text1.Appearance = ccFlat
        Text1.Visible = False
        mlhWndTB = Text1.hWnd
        With ListView1
            .LabelEdit = lvwManual
            .HideSelection = False
            mlhWndLV = .hWnd
            For i = 1 To 4
                .ColumnHeaders.Add Text:="Col " & i
            Next
            For i = 0 To &H3F
                Set iTm = .ListItems.Add(, , "Item " & i)
                iTm.SubItems(1) = i * 10
                iTm.SubItems(2) = i * 100
                iTm.SubItems(3) = i * 1000
            Next
        End With
        ListView1.View = lvwReport
        ListView1.Arrange = lvwAutoTop
    End SubPrivate Sub ListView1_DblClick()
        Dim lvhti As LVHITTESTINFO
        Dim rc As RECT
        Dim li As ListItem
        If (GetKeyState(vbKeyLButton) And &H8000) Then
            Call GetCursorPos(lvhti.pt)
            Call ScreenToClient(mlhWndLV, lvhti.pt)
            If (ListView_SubItemHitTest(mlhWndLV, lvhti) <> LVI_NOITEM) Then
                If lvhti.lSubItem Then
                    If GetSubItemRect(mlhWndLV, lvhti.lItem, lvhti.lSubItem, LVIR_LABEL, rc) Then
                        Call SetParent(mlhWndTB, mlhWndLV)
                        'Call MapWindowPoints(mlhWndLV, hWnd, rc, 2)
                        Text1.Move (rc.Left + 4) * Screen.TwipsPerPixelX - 30, rc.Top * Screen.TwipsPerPixelY, _
                        (rc.Right - rc.Left) * Screen.TwipsPerPixelX, (rc.Bottom - rc.Top) * Screen.TwipsPerPixelY
                        mlItem = lvhti.lItem + 1
                        mlSubItm = lvhti.lSubItem
                        Text1 = ListView1.ListItems(mlItem).SubItems(mlSubItm)
                        Text1.Tag = Text1
                        ListView1.ListItems(mlItem).SubItems(mlSubItm) = ""
                        Text1.ZOrder 0
                        Text1.Visible = True
                        Text1.SelStart = 0
                        Text1.SelLength = Len(Text1)
                        Text1.SetFocus
                        If chkDisableScrollbars.Value = 1 Then
                            Call EnableScrollBar(ListView1.hWnd, SB_BOTH, ESB_DISABLE_BOTH)
                        Else
                            Call EnableScrollBar(ListView1.hWnd, SB_BOTH, ESB_ENABLE_BOTH)
                        End If
                        Call SubClass(mlhWndTB, AddressOf WndProc)
                    End If
                End If
            End If
        End If
    End SubPrivate Sub Text1_GotFocus()
        ListView1.ListItems(mlItem).Selected = True
    End SubPrivate Sub Text1_Change()
        If mlItem Then Text1.Width = TextWidth(Text1) + 180
    End SubPrivate Sub Text1_KeyPress(KeyAscii As Integer)
        If (KeyAscii = vbKeyReturn) Then
            Call HideTextBox(True)
            If chkDisableScrollbars.Value = 1 Then
                Call EnableScrollBar(ListView1.hWnd, SB_BOTH, ESB_ENABLE_BOTH)
            Else
                Call EnableScrollBar(ListView1.hWnd, SB_BOTH, ESB_DISABLE_BOTH)
            End If
            KeyAscii = 0
        ElseIf (KeyAscii = vbKeyEscape) Then
            Call HideTextBox(False)
            If chkDisableScrollbars.Value = 1 Then
                Call EnableScrollBar(ListView1.hWnd, SB_BOTH, ESB_ENABLE_BOTH)
            Else
                Call EnableScrollBar(ListView1.hWnd, SB_BOTH, ESB_DISABLE_BOTH)
            End If
            KeyAscii = 0
        End If
    End SubFriend Sub HideTextBox(bApply As Boolean)
        If bApply Then
            ListView1.ListItems(mlItem).SubItems(mlSubItm) = Text1
        Else
            ListView1.ListItems(mlItem).SubItems(mlSubItm) = Text1.Tag
        End If
        Call UnSubClass(mlhWndTB)
        Text1.Visible = False
        Text1 = ""
        mlItem = 0
    End Sub
      

  11.   

    不知道模块1(modLVWRect):在哪啊???呵呵:)
      

  12.   

    不好意思,贴错了,下面的是:
    Option ExplicitPublic Type POINTAPI
        X As Long
        Y As Long
    End TypePublic Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
    End TypePublic Type LVHITTESTINFO
        pt As POINTAPI
        lFlags As Long
        lItem As Long
        lSubItem As Long
    End TypePublic 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 GetKeyState Lib "user32" (ByVal nVirtKey As KeyCodeConstants) As Integer
    Public Declare Function SetParent Lib "user32" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long
    Public Declare Function MapWindowPoints Lib "user32" (ByVal hwndFrom As Long, ByVal hwndTo As Long, lppt As Any, ByVal cPoints As Long) As Long
    Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, _
    lParam As Any) As LongPublic Const LVI_NOITEM = -1
    Public Const LVM_FIRST = &H1000
    Public Const LVM_GETSUBITEMRECT = (LVM_FIRST + 56)
    Public Const LVM_SUBITEMHITTEST = (LVM_FIRST + 57)
    Public Const LVIR_ICON = 1
    Public Const LVIR_LABEL = 2
    Public Const LVHT_ONITEMLABEL = &H4Public Declare Function EnableScrollBar Lib "user32.dll" (ByVal hWnd As Long, ByVal wSBflags As Long, ByVal wArrows As Long) As Long'SCROLLBAR CONSTS
    Public Const SB_HORZ As Long = 0
    Public Const SB_VERT As Long = 1
    Public Const SB_CTL As Long = 2
    Public Const SB_BOTH As Long = 3Public Const ESB_DISABLE_BOTH = &H3
    Public Const ESB_DISABLE_DOWN = &H2
    Public Const ESB_DISABLE_LEFT = &H1
    Public Const ESB_DISABLE_RIGHT = &H2
    Public Const ESB_DISABLE_UP = &H1
    Public Const ESB_ENABLE_BOTH = &H0Public Function GetSubItemRect(hWnd As Long, lItem As Long, lSubItm As Long, lLeft As Long, oRect As RECT) As Boolean
        oRect.Top = lSubItm
        oRect.Left = lLeft
        GetSubItemRect = SendMessage(hWnd, LVM_GETSUBITEMRECT, ByVal lItem, oRect)
    End FunctionPublic Function ListView_SubItemHitTest(hWnd As Long, plvhti As LVHITTESTINFO) As Long
        ListView_SubItemHitTest = SendMessage(hWnd, LVM_SUBITEMHITTEST, 0, plvhti)
    End Function