添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
本帖最后由 yhxhappy 于 2017-12-17 12:06 编辑
我想复制 ListView 中 鼠标所点中行单元格 数据,所以就做了一个右键菜单,鼠标在ListView中点击右键时弹出菜单复制内容。
现在的问题是:如果ListView中一旦有水平滚动条,并且拖动后,获取的行列数据就不准了。
以下是演示的代码,初始状态是可以获取的,一旦向右滚动获取的内容就不准。
自己研究解决了,增加滚动条的补偿,_GUIScrollBars_GetScrollInfoPos 获取滚动条的位置,见第51,54行代码
实际还是有些误差,大概5个像素左右,当点击两列之间时会发现。但对我影响不大就不研究了。
  1. #include <GUIConstantsEx.au3>
  2. #include <GuiListView.au3>
  3. #Include <GuiScrollBars.au3>


  4. Opt("MouseCoordMode", 0)                ;设置用于鼠标函数的 coords 坐标参照 = 激活窗口的相对坐标

  5. $GUI = GUICreate("listview 列表视图", 300, 250)
  6. $listview = GUICtrlCreateListView("列 1  |列 2 |列 3 |列 4 |列 5 |列 6 |列 7  ", 10, 10, 280, 150)
  7. GUICtrlCreateListViewItem("项目 1|子项 12|子项 13|项目 14|子项 15|子项 16|子项 17", $listview)
  8. GUICtrlCreateListViewItem("项目 2|子项 22|子项 23|项目 24|子项 25|子项 26|子项 27", $listview)
  9. GUICtrlCreateListViewItem("项目 3|子项 32|子项 33|项目 34|子项 35|子项 36|子项 37", $listview)

  10. $ColumnNum = _GUICtrlListView_GetColumnCount($listview)                ;取得列数
  11. Global $xyArray[$ColumnNum]
  12. For $i = 0 To $ColumnNum-1
  13. $ItemXY = _GUICtrlListView_GetSubItemRect($listview, 0, $i)
  14. $xyArray[$i] = $ItemXY[0]
  15. Next

  16. ;===右键 系统菜单窗口=======================================================================
  17. $OptionsDummy = GUICtrlCreateDummy()                                                                ;创建一个虚拟控件,让菜单依托于控件, 这个控制必须创建于主窗口,否则不能触发事件
  18. $ContextMenu = GUICtrlCreateContextMenu($OptionsDummy)                                ;创造菜单
  19. $CopyMenu = GUICtrlCreateMenuItem("复制单元格内容", $ContextMenu)        ;"复制单元格内容"
  20. ;==========================================================================================

  21. Global $ClickLVRowIndex        ;LV选中的行序号
  22. Global $ClickLVRowIndex ;LV鼠标所在的列序号

  23. GUISetState()

  24. While 1
  25. Switch GUIGetMsg()
  26. Case $GUI_EVENT_CLOSE
  27. Exit
  28. Case $GUI_EVENT_SECONDARYUP
  29. $Pos = GUIGetCursorInfo($GUI)                                                                        ;取得鼠标当前停留控件的信息
  30. If @error Or Not IsArray($Pos) Then ContinueLoop
  31. If $Pos[4] <> $listview Then ContinueLoop                                                ;鼠标没有点在LV内,则返回
  32. If Not StringInStr(ControlGetFocus($GUI), "SysListView") Then ContinueLoop                ;如果当前激活的控件不是LV,则返回

  33. $ClickLVRowIndex = _GUICtrlListView_GetHotItem($listview)                ;取得选中项的行序号
  34. If $ClickLVRowIndex < 0 Then ContinueLoop                                                ;没有项目被选中,则返回

  35. $GPos = WinGetPos($GUI)                                                                                ;取得窗口的坐标
  36. If @error Or Not IsArray($GPos) Then ContinueLoop

  37. $MPos = MouseGetPos()                                                                                        ;取得鼠标相对于窗口的坐标
  38. If @error Then ContinueLoop

  39. $ScrollBarsPOS = _GUIScrollBars_GetScrollInfoPos(GUICtrlGetHandle($listview), $SB_HORZ)                ;LV控件水平滚动条位置

  40. For $i = UBound($xyArray)-1 To 0 Step -1                                                ;当前鼠标X坐标 在 列坐标数组内 从大到小对比
  41. If $MPos[0]+$GPos[0]+$ScrollBarsPOS-10 > $xyArray[$i]+$GPos[0] Then                        ;10是LV的X坐标,如果X坐标大于某列的X坐标,且小于下一列的X坐标,则说明鼠标点击了该列
  42. $ClickLVColumnIndex = $i
  43. ExitLoop
  44. EndIf
  45. Next

  46. DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", GUICtrlGetHandle($ContextMenu), "int", 0, "int", $GPos[0]+$MPos[0], "int", $GPos[1]+$MPos[1], "hwnd", $GUI, "ptr", 0)        ; 显示指定坐标(x,y), 属于一个指定 GUI 窗口(hWnd)的弹出菜单(hMenu).
  47. Case $CopyMenu
  48. $String = _GUICtrlListView_GetItemText($listview, $ClickLVRowIndex, $ClickLVColumnIndex)
  49. MsgBox(0, "鼠标点中的单元格内容", $String)
  50. EndSwitch
  51. WEnd
复制代码