ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 23369|回复: 32

[分享] ★可以编辑的ListView (Frame + TextBox)VBA版1★

[复制链接]

TA的精华主题

TA的得分主题

发表于 2010-4-25 21:48 | 显示全部楼层 |阅读模式
本帖已被收录到知识树中,索引项:控件
'模块1 代码:   以下代码出自于老外之手,首先非常感谢他,我在这里只是把代码引进了 EXCEL VBA,当然其他VBA大多也可
'此版本为 ListView + Frame + TextBox  组合, 大家知道在EXCEL VBA中 ,TextBox控件 没有句柄也无法置于 LISTVIEW 上层, 但 EH  LDY 指点 FRAME(框架)控件是可以 置于 LISTVIEW 之上, 而且可通过 FRAME1.SETFOCUS 得到焦点 ,然后利用 API 函数 GetFocus 得到句柄,然后就可以 指挥它做我们要它做的大多数事.
  1. Option Explicit

  2. Public Type POINTAPI        'pt

  3.     x As Long

  4.     y As Long

  5. End Type



  6. Public Type RECT            'rct

  7.     Left As Long

  8.     Top As Long

  9.     Right As Long

  10.     Bottom As Long

  11. End Type



  12. Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long

  13. Declare Function ScreenToClient Lib "user32" (ByVal hWnd As Long, lpPoint As POINTAPI) As Long

  14. Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As Long) As Integer

  15. Declare Function SetParent Lib "user32" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long

  16. Declare Function MapWindowPoints Lib "user32" (ByVal hwndFrom As Long, ByVal hwndTo As Long, lppt As Any, ByVal cPoints As Long) As Long

  17. Declare Function SendMessage Lib "user32" Alias "SendMessageA" _

  18.                              (ByVal hWnd As Long, _

  19.                               ByVal wMsg As Long, _

  20.                               ByVal wParam As Long, _

  21.                               lParam As Any) As Long



  22. Private Const WM_DESTROY = &H2

  23. Private Const WM_KILLFOCUS = &H8

  24. Private Declare Function GetProp Lib "user32" Alias "GetPropA" (ByVal hWnd As Long, ByVal lpString As String) As Long

  25. Private Declare Function SetProp Lib "user32" Alias "SetPropA" (ByVal hWnd As Long, ByVal lpString As String, ByVal hData As Long) As Long

  26. Private Declare Function RemoveProp Lib "user32" Alias "RemovePropA" (ByVal hWnd As Long, ByVal lpString As String) As Long

  27. Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

  28. Private Const GWL_WNDPROC = (-4)

  29. Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, _

  30.                                                                      ByVal lpWindowName As String) As Long

  31. 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 Long

  32. Public Declare Function GetFocus Lib "user32" () As Long

  33. Private Const OLDWNDPROC = "OldWndProc"





  34. Public Const LVI_NOITEM = -1

  35. Public Const LVM_FIRST = &H1000

  36. Public Const LVM_GETSUBITEMRECT = (LVM_FIRST + 56)

  37. Public Const LVM_SUBITEMHITTEST = (LVM_FIRST + 57)



  38. Public Const LVIR_ICON = 1

  39. Public Const LVIR_LABEL = 2

  40. Public Type LVHITTESTINFO

  41.     pt As POINTAPI

  42.     flags As Long

  43.     iItem As Long

  44.     iSubItem As Long

  45. End Type

  46. Public Const LVHT_ONITEMLABEL = &H4



  47. Public Function ListView_GetSubItemRect(hWnd As Long, iItem As Long, iSubItem As Long, _

  48.                                         code As Long, prc As RECT) As Boolean

  49.     prc.Top = iSubItem

  50.     prc.Left = code

  51.     ListView_GetSubItemRect = SendMessage(hWnd, LVM_GETSUBITEMRECT, ByVal iItem, prc)

  52. End Function



  53. Public Function ListView_SubItemHitTest(hWnd As Long, plvhti As LVHITTESTINFO) As Long

  54.     ListView_SubItemHitTest = SendMessage(hWnd, LVM_SUBITEMHITTEST, 0, plvhti)

  55. End Function





  56. Public Function SubClass(hWnd As Long, lpfnNew As Long) As Boolean

  57.     Dim lpfnOld As Long

  58.     Dim fSuccess As Boolean

  59.     If (GetProp(hWnd, OLDWNDPROC) = 0) Then

  60.         lpfnOld = SetWindowLong(hWnd, GWL_WNDPROC, lpfnNew)

  61.         If lpfnOld Then

  62.             fSuccess = SetProp(hWnd, OLDWNDPROC, lpfnOld)

  63.         End If

  64.     End If

  65.     If fSuccess Then

  66.         SubClass = True

  67.     Else

  68.         If lpfnOld Then Call UnSubClass(hWnd)

  69.         MsgBox "Unable to successfully subclass &H" & Hex(hWnd), vbCritical

  70.     End If

  71. End Function



  72. Public Function UnSubClass(hWnd As Long) As Boolean

  73.     Dim lpfnOld As Long

  74.     lpfnOld = GetProp(hWnd, OLDWNDPROC)

  75.     If lpfnOld Then

  76.         If RemoveProp(hWnd, OLDWNDPROC) Then

  77.             UnSubClass = SetWindowLong(hWnd, GWL_WNDPROC, lpfnOld)

  78.         End If

  79.     End If

  80. End Function



  81. Public Function WndProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

  82.     Select Case uMsg

  83.     Case WM_KILLFOCUS

  84.         Call CallWindowProc(GetProp(hWnd, OLDWNDPROC), hWnd, uMsg, wParam, lParam)

  85.         Call UserForm1.HideTextBox(True)

  86.         Exit Function

  87.     Case WM_DESTROY

  88.         Call CallWindowProc(GetProp(hWnd, OLDWNDPROC), hWnd, uMsg, wParam, lParam)

  89.         Call UnSubClass(hWnd)

  90.         Exit Function

  91.     End Select

  92.     WndProc = CallWindowProc(GetProp(hWnd, OLDWNDPROC), hWnd, uMsg, wParam, lParam)

  93. End Function
复制代码
'以下是窗体代码:
  1. Private Const SB_HORZ = &H0

  2. Private Const SB_VERT = &H1

  3. Private m_hwndLV As Long     ' ListView1.hWnd

  4. Private m_hwndTB As Long     ' TextBox1.hWnd

  5. Private m_iItem As Long      ' ListItem.Index whose SubItem is being edited

  6. Private m_iSubItem As Long   ' zero based index of ListView1.ListItems(m_iItem).SubItem being edited



  7. Private Sub ListView1_DblClick()

  8.     Dim lvhti As LVHITTESTINFO

  9.     Dim rc As RECT

  10.     Dim hWnd As Long

  11.     Dim li As ListItem



  12.     If (GetKeyState(1) And &H8000) Then             'vbKeyLButton鼠标左键,双击



  13.         Call GetCursorPos(lvhti.pt)

  14.         Call ScreenToClient(m_hwndLV, lvhti.pt)

  15.         If (ListView_SubItemHitTest(m_hwndLV, lvhti) <> LVI_NOITEM) Then

  16.             If lvhti.iSubItem Then

  17.                 If ListView_GetSubItemRect(m_hwndLV, lvhti.iItem, lvhti.iSubItem, LVIR_LABEL, rc) Then

  18.                     hWnd = FindWindow(vbNullString, Me.Caption)

  19.                     Call MapWindowPoints(m_hwndLV, hWnd, rc, 2)

  20.                     Frame1.Move (rc.Left) * 15 / 20, _

  21.                                 rc.Top * 15 / 20, _

  22.                                 (rc.Right - rc.Left) * 15 / 20 + 1, _

  23.                                 (rc.Bottom - rc.Top) * 15 / 20 + 1

  24.                     Text1.Move -2, -2, (rc.Right - rc.Left) * 15 / 20 + 1, _

  25.                                (rc.Bottom - rc.Top) * 15 / 20 + 1

  26.                     m_iItem = lvhti.iItem + 1

  27.                     m_iSubItem = lvhti.iSubItem

  28.                     If m_iSubItem > 1 Then

  29.                         Text1.Text = ListView1.ListItems(m_iItem).SubItems(m_iSubItem)

  30.                         Text1.Tag = Text1.Text

  31.                         ListView1.ListItems(m_iItem).SubItems(m_iSubItem) = ""

  32.                         Frame1.Visible = True      '为得到焦点

  33.                         Frame1.SetFocus            '为得到焦点

  34.                         m_hwndTB = GetFocus()      '为得到焦点

  35.                         ListView1.SetFocus         '转移焦点

  36.                         Frame1.ZOrder 0

  37.                         Text1.SelStart = 0

  38.                         Text1.SelLength = Len(Text1.Text)

  39.                         Text1.SetFocus

  40.                         '可以用其他程序代替它

  41.                         Call SubClass(m_hwndTB, AddressOf WndProc)

  42.                     End If

  43.                 End If

  44.             End If

  45.         End If

  46.     End If

  47. End Sub



  48. Private Sub Text1_GotFocus()

  49. '   ListView1.ListItems(m_iItem).Selected = True

  50. End Sub

  51. Private Sub Text1_Change()

  52.     If m_iItem Then Text1.Width = ListView1.ColumnHeaders(m_iSubItem + 1).Width

  53. End Sub



  54. Friend Sub HideTextBox(fApplyChanges As Boolean)

  55.     If fApplyChanges Then

  56.         ListView1.ListItems(m_iItem).SubItems(m_iSubItem) = Text1

  57.     Else

  58.         ListView1.ListItems(m_iItem).SubItems(m_iSubItem) = Text1.Tag

  59.     End If

  60.     Call UnSubClass(m_hwndTB)

  61.     Frame1.Visible = False

  62.     Text1 = ""

  63.     m_iItem = 0

  64. End Sub



  65. Private Sub Text1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)

  66.     If (KeyAscii = vbKeyReturn) Then

  67.         Call HideTextBox(True)

  68.         KeyAscii = 0

  69.     ElseIf (KeyAscii = vbKeyEscape) Then

  70.         Call HideTextBox(False)

  71.         KeyAscii = 0

  72.     End If

  73. End Sub



  74. Private Sub UserForm_Initialize()

  75.    

  76.     Me.Frame1.ZOrder 1

  77.     With ListView1

  78.         .LabelEdit = lvwManual

  79.         .HideSelection = False

  80.         .Appearance = cc3D

  81.         .Icons = ImageList1

  82.         .MultiSelect = True

  83.         .Gridlines = True

  84.         .View = lvwReport

  85.         .FullRowSelect = True

  86.         .SmallIcons = ImageList1

  87.         m_hwndLV = .hWnd

  88.         For i = 1 To 4

  89.             .ColumnHeaders.Add Text:="column" & i

  90.         Next

  91.         For i = &H0 To &HF

  92.             Set Item = .ListItems.Add(, , "item" & i, &H1, &H1)

  93.             Item.SubItems(1) = i * 10

  94.             Item.SubItems(2) = i * 100

  95.             Item.SubItems(3) = i * 1000

  96.         Next

  97.     End With



  98. End Sub
复制代码

[ 本帖最后由 office2008 于 2010-4-27 14:58 编辑 ]

可以编辑的ListView(Frame+TextBox)VBA版1.rar

98.23 KB, 下载次数: 3491

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2010-4-25 22:58 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2010-7-7 14:51 | 显示全部楼层
高手中和高手,引用别的就是高手,一般人还不会引用。谢谢楼主分享。

TA的精华主题

TA的得分主题

发表于 2010-7-31 21:40 | 显示全部楼层
楼子的水平高,菜鸟还无法运用,下面的listview模糊查询如何实现可编辑啊?谢谢!

http://club.excelhome.net/viewth ... e%3D1&frombbs=1

TA的精华主题

TA的得分主题

发表于 2010-8-13 09:38 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2010-8-13 13:16 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2010-9-4 10:59 | 显示全部楼层
不太明白,学习中。谢谢分享!

TA的精华主题

TA的得分主题

发表于 2010-10-19 09:03 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2010-10-20 10:08 | 显示全部楼层
谢谢分享,学习你的两个版本

TA的精华主题

TA的得分主题

发表于 2010-10-20 10:18 | 显示全部楼层
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-5-13 21:55 , Processed in 0.044646 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表