原本是想用LabelEdit事件来编辑SubItems的,但好像不行?于是,想自己用TextBox来编辑SubItems的值,
应该是通过MouseDown MouseUp来启动编辑,
做一个自己的LabelEdit事件,
把TextBox移到子项的位置显示出来。问题是,如何触发LabelEdit呢?
触发的时机怎样掌握呢?应该不是简单的MouseDown吧?希望做到和原来的LabelEdit一样,
这样,操作的用户才不会感到异样!
应该是通过MouseDown MouseUp来启动编辑,
做一个自己的LabelEdit事件,
把TextBox移到子项的位置显示出来。问题是,如何触发LabelEdit呢?
触发的时机怎样掌握呢?应该不是简单的MouseDown吧?希望做到和原来的LabelEdit一样,
这样,操作的用户才不会感到异样!
解决方案 »
- 运行界面关闭,进程依然存在?
- 新手求教,winsock客户端连服务器端有时候连接失败?
- 可否在Toolbar里加载Windows的图标?Windows 的工具栏图标文件放在哪啊?
- 如何通过程序拷贝拨号网络中的文件:??
- 请大家帮帮小弟,急,在线等
- 咨询一下:VMware Workstation VS Connectix Virtual PC 功能上有什么区别,哪个更好用一点
- 如何获取fpSpread中的一行记录
- 怎么样在vb程序加入程序入口函数sub main()
- 如何获取文件大小的信息??
- 如何遍写NT的服务,150分呈上
- 请问,在VB中如何直接用打印机打印位图文件?
- 有谁知道QQ的程序是什么语言编的吗?
自己查一下。
既不是单击编辑,也不是双击编辑,是单击之后在一定时间内的点击,才触发的。
其实很简单的,我已经想到了,呵呵:)剩下的才是难点:如何定位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的位置总是不准确的呢?
ListItem是没有Top 和Left属性的!解决的办法应该是发送消息之类的,就是说用自编HitTest方法,
但是俺不知道如何编啊???另外,试下来,由控件本身返回的ColumnHeader(I).Left 数据相当有问题,
会随着列数的增加而出现误差的成倍增长,实际上根本无法用它来定位左边界的,
不知道怎么回事?是不是也直接用API才能取得正确值?
但是俺不知道如何编啊???应该有定义好的消息的,看看msdn
http://msdn.microsoft.com/library/en-us/shellcc/platform/commctls/listview/messages/lvm_subitemhittest.asp?frame=true
为了把Text控件移到相应地点用。
(而且,俺的ListItems是没有Top 和Left属性的!)
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
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
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
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