找回密码  加入

AUTOIT CN

搜索
楼主: 298311657

[原创] ListView虚表 复选框 原地编辑例子 By_Crossdoor(2015-11-03更新)

[复制链接]
发表于 2015-10-31 22:30:58 | 显示全部楼层
回复 59# chzj589

chzj589  兄

手上有 INPUT 框 重繪 相關的消息範例嗎??
 楼主| 发表于 2015-11-1 22:27:47 | 显示全部楼层
回复 58# kk_lee69

你的这个问题,可以试试这份代码


  1. #cs ______________________
  2.         Au3 版本: 3.3.14.2
  3.         脚本作?? CrossDoor
  4.         电子邮件: [email]382869232@qq.com[/email]
  5.         QQ/TM: 382869232
  6. #ce _______________脚本开始_________________
  7. #PRE_UseX64=n
  8. #include <WindowsConstants.au3>
  9. #include <GUIConstantsEx.au3>
  10. #include <GuiImageList.au3>
  11. #include <WinAPITheme.au3>
  12. #include <GuiListView.au3>
  13. #include <WinAPISys.au3>
  14. #include <WinAPI.au3>
  15. #include <GuiEdit.au3>
  16. #include <array.au3>
  17. #include <Misc.au3>

  18. Global $B_DESCENDING[3] ; 排序用数组

  19. Global $bCtrlDown = False;listview控件ctrl键按下标识
  20. Global $hEdit, $Item = -1, $SubItem = 0
  21. Global $hEditForm, $hEnter, $aAccelKeys[1][2] = [["{ENTER}", $hEnter]];虚拟控件的句柄和绑定的快捷键

  22. Local $hUser32 = DllOpen("user32.dll")
  23. Local $ichked = 0;勾选的行数
  24. Local $tText = DllStructCreate("wchar Text[256]");建个结构,用来放listview列数据
  25. Local $GUI, $hImage
  26. Local $iITEM_COUNT = 94304, $aShowdata[$iITEM_COUNT][4];注意数组最大项目数为2^24(16777216),所以$iITEM_COUNT = 4194304为二维数组$aShowdata最大行数
  27. Local $sSomeString = ""

  28. GUIRegisterMsg($WM_KEYDOWN, "WM_KEYDOWN")
  29. GUIRegisterMsg($WM_KEYUP, "WM_KEYUP")
  30. GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
  31. GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
  32. $hGUI = GUICreate("ListView虚表 加载[" & UBound($aShowdata) & "]数据 复选框 原地编辑例子 By_Crossdoor", 500, 350)

  33. $hListView = GUICtrlCreateListView("Item1|nSubItem1|nSubItem2", 2, 2, 494, 296, BitOR($LVS_REPORT, $LVS_SINGLESEL, $LVS_SHOWSELALWAYS, $LVS_OWNERDATA), $LVS_EX_GRIDLINES + $LVS_EX_FULLROWSELECT + $LVS_EX_DOUBLEBUFFER + $LVS_EX_CHECKBOXES)
  34. ;~ _WinAPI_SetWindowTheme(GUICtrlGetHandle($hListView), 'Explorer');设置主题

  35. ;设置列宽
  36. GUICtrlSendMsg($hListView, $LVM_SETCOLUMNWIDTH, 0, 150)
  37. GUICtrlSendMsg($hListView, $LVM_SETCOLUMNWIDTH, 1, 150)
  38. GUICtrlSendMsg($hListView, $LVM_SETCOLUMNWIDTH, 2, 150)
  39. GUICtrlSendMsg($hListView, $LVM_SETITEMCOUNT, $iITEM_COUNT, 0);设定数据总数

  40. ;===========创建并关联图像列表
  41. $hImage = _GUIImageList_Create()
  42. _GUIImageList_AddIcon($hImage, @SystemDir & "\shell32.dll", 110)
  43. _GUICtrlListView_SetImageList($hListView, $hImage, 1);分配图像列表到列表视图控件

  44. $Button1 = GUICtrlCreateButton("选中行", 20, 310, 75, 25)
  45. $Button2 = GUICtrlCreateButton("未选行", 100, 310, 75, 25)
  46. $Button3 = GUICtrlCreateButton("修改", 180, 310, 75, 25)
  47. $Button4 = GUICtrlCreateButton("清空", 260, 310, 75, 25)
  48. GUISetState()

  49. ;==================在窗体显示后再初始化数据,因为初始化数组数据比较慢
  50. ;如果先初始化数组后显示窗口,会卡很久,就造成虚表也很慢的假象
  51. For $i = 0 To $iITEM_COUNT - 1
  52.         ;重绘 刷新 listview 0-13行(让ListView显示数组数据),不用太多行,只需要一屏的行数就就可以
  53.         ;因为下拉滚动的时候listview会收到LVN_GETDISPINFO消息,这个消息我们在WM_NOTIFY内处理过了
  54.         If $i = 18 Then GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 0, $i)
  55.        
  56.         $aShowdata[$i][0] = "爷爷" & $i
  57.         $aShowdata[$i][1] = "爸爸" & $i
  58.         $aShowdata[$i][2] = "儿子" & $i
  59.         $aShowdata[$i][3] = 4096;复选框状态4096未选中 8192选中
  60. Next

  61. While 1
  62.         $bCtrlDown = _IsPressed("11", $hUser32);取ctrl按键的状态
  63.         Switch GUIGetMsg()
  64.                 Case -3
  65.                         ExitLoop
  66.                 Case $Button1
  67.                         $aShowdata[3][3] = 8192
  68.                         $aShowdata[7][3] = 8192
  69.                         GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 3, 7)
  70.                        
  71. ;~                         $a = _GetChkIndex(8192)
  72. ;~                         If $a[0] = -1 Then
  73. ;~                                 MsgBox(32, "提示", "未勾选任何数据")
  74. ;~                         Else
  75. ;~                                 _ArrayDisplay($a, "勾选行的索引");数组很大时,_ArrayDisplay会非常耗时
  76. ;~                         EndIf
  77.                 Case $Button2
  78.                         $a = _GetChkIndex(4096)
  79.                         If $a[0] = -1 Then
  80.                                  MsgBox(32, "提示", "数据全都被勾选了。")
  81.                         Else
  82.                                 ;MsgBox(32, "提示", "未勾选的数据有" & UBound($a) & "行")
  83.                                 _ArrayDisplay($a, "未勾选行的索");数组很大时,_ArrayDisplay会非常耗时
  84.                         EndIf
  85.                 Case $Button3
  86.                         If StringLen($sSomeString) Then
  87.                                 $sSomeString = ""
  88.                         Else
  89.                                 $sSomeString = Asc(Random(48, 255, 1))
  90.                         EndIf
  91.                         For $i = 0 To $iITEM_COUNT - 1
  92.                                 $aShowdata[$i][0] = "爷爷" & $i & "-" & $sSomeString
  93.                                 $aShowdata[$i][1] = "爸爸" & $i & "-" & $sSomeString
  94.                                 $aShowdata[$i][2] = "儿子" & $i & "-" & $sSomeString
  95.                         Next
  96.                         GUICtrlSendMsg($hListView, $LVM_ENSUREVISIBLE, 1, 0)
  97.                         GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 0, 20)
  98.                 Case $Button4
  99.                         $aShowdata = 0
  100.                         $iITEM_COUNT = 0
  101.                         GUICtrlSendMsg($hListView, $LVM_SETITEMCOUNT, $iITEM_COUNT, 0)
  102.                         GUICtrlSendMsg($hListView, $LVM_ENSUREVISIBLE, 1, 0)
  103.                         GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 0, 20)
  104.         EndSwitch
  105. WEnd
  106. GUIDelete()
  107. DllClose($hUser32)

  108. Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
  109.         #forceref $hWnd, $iMsg, $iwParam
  110.         Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $tInfo

  111.         $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
  112.         $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
  113.         $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
  114.         $iCode = DllStructGetData($tNMHDR, "Code")
  115.         Local $iIndex = DllStructGetData($tNMHDR, 'Index')
  116.         Switch $iIDFrom
  117.                 Case $hListView
  118.                         Switch $iCode
  119.                                 Case $LVN_COLUMNCLICK ; 点击列头排序
  120.                                         $tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)
  121.                                         $iSub = DllStructGetData($tInfo, "SubItem")
  122.                                         _ArraySort($aShowdata, $B_DESCENDING[$iSub], 0, 0, $iSub)
  123.                                         GUICtrlSendMsg($hListView, $LVM_ENSUREVISIBLE, 1, 0)
  124.                                         GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 0, 20)
  125.                                         $B_DESCENDING[$iSub] = Not $B_DESCENDING[$iSub]
  126.                                 Case $NM_CUSTOMDRAW;自绘消息  处理选中行背景色
  127.                                         Local $tCustDraw = DllStructCreate('hwnd hwndFrom;int idFrom;int code;dword DrawStage;hwnd hdc;long rect[4];dword ItemSpec;int ItemState;dword Itemlparam;dword clrText;dword clrTextBk;int SubItem; dword ItemType;dword clrFace;int IconEffect;int IconPhase;int PartID;int StateID;long rectText[4];int Align', $ilParam)
  128.                                         Local $iDrawStage = DllStructGetData($tCustDraw, 'DrawStage')
  129.                                         If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW ;request custom drawing of items
  130.                                         If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW ;request drawing each cell separately
  131.                                         If Not BitAND($iDrawStage, $CDDS_SUBITEM) Then Return $CDRF_DODEFAULT
  132.                                         $iIndex = DllStructGetData($tCustDraw, 'ItemSpec')
  133.                                         If $aShowdata[$iIndex][3] = 4096 Then
  134.                                                 DllStructSetData($tCustDraw, 'clrTextBk', 0xFFFFFF);BGR格式颜色值
  135.                                         Else
  136.                                                 DllStructSetData($tCustDraw, 'clrTextBk', 0xF7D3AD);BGR格式颜色值
  137.                                         EndIf
  138.                                         Return $CDRF_NEWFONT
  139.                                 Case $LVN_ITEMCHANGED ; An item has changed
  140.                                         If $bCtrlDown Then;ctrl键按下
  141.                                                 $tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)
  142.                                                 Local $iIndex = DllStructGetData($tInfo, "Item")
  143.                                                 Local $iNewState = DllStructGetData($tInfo, "NewState")
  144.                                                 If $iIndex > -1 And $iNewState = BitOR($LVIS_FOCUSED, $LVIS_SELECTED) Then
  145.                                                         If $aShowdata[$iIndex][3] = 4096 Then
  146.                                                                 $ichked+=1
  147.                                                                 $aShowdata[$iIndex][3] = 8192;4096未选中 8192选中
  148.                                                         Else
  149.                                                                 $ichked-=1
  150.                                                                 $aShowdata[$iIndex][3] = 4096;4096未选中 8192选中
  151.                                                         EndIf
  152.                                                         $tInfo = DllStructCreate($tagNMLVDISPINFO, $ilParam)
  153.                                                         DllStructSetData($tInfo, "State", $aShowdata[$iIndex][3]);设置复选框状态
  154.                                                         ;====立刻刷新复选框显示状态 重绘$iIndex-1到iIndex+20的项
  155.                                                         GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, $iIndex - 1, $iIndex + 20)
  156.                                                 EndIf
  157.                                         EndIf
  158.                 Case $LVN_BEGINSCROLL ; 滚动事件开始
  159.                                         If IsHWnd($hEdit) Then _EndItemEdit();如果存在$hEdit控件,则结束编辑
  160. ;~                                         $tInfo = DllStructCreate($tagNMLVSCROLL, $ilParam)
  161. ;~                                         ToolTip("$LVN_BEGINSCROLL" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _
  162. ;~                                         "-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _
  163. ;~                                         "-->Code:" & @TAB & $iCode & @CRLF & _
  164. ;~                                         "-->DX:" & @TAB & DllStructGetData($tInfo, "DX") & @CRLF & _
  165. ;~                                         "-->DY:" & @TAB & DllStructGetData($tInfo, "DY"))
  166.                 ; ; No return value                                       
  167.                                 Case $NM_CLICK;单击
  168.                                         If IsHWnd($hEdit) Then _EndItemEdit()
  169.                                         $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
  170.                                         $iIndex = DllStructGetData($tInfo, "Index")
  171.                                         $x = DllStructGetData($tInfo, "X")
  172.                                         If ($x < 16) And (3 < $x) And (BitAND(_GUICtrlListView_GetExtendedListViewStyle($hListView), $LVS_EX_CHECKBOXES) = $LVS_EX_CHECKBOXES) Then;使用点击的x坐标来判断是否在复选框上点击
  173.                                                 If $aShowdata[$iIndex][3] = 4096 Then
  174.                                                         $ichked+=1
  175.                                                         $aShowdata[$iIndex][3] = 8192;4096未选中 8192选中
  176.                                                 Else
  177.                                                         $ichked-=1
  178.                                                         $aShowdata[$iIndex][3] = 4096;4096未选中 8192选中
  179.                                                 EndIf
  180.                                                 ;====立刻刷新复选框显示状态 重绘$iIndex-1至iIndex+20的项
  181.                                                 GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, $iIndex - 1, $iIndex + 20)
  182.                                         EndIf
  183.                                 Case $NM_DBLCLK ; 双击
  184.                                         $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
  185.                                         $iIndex = DllStructGetData($tInfo, "Index")
  186.                                         $iSub = DllStructGetData($tInfo, "SubItem")
  187.                                         $x = DllStructGetData($tInfo, "X")
  188.                                         If ($iIndex <> -1) And ($iSub >= 0) And ($x > 16) Then;点击的x>16才响应原地编辑
  189.                                                 Local $aformPos = WinGetPos($hGUI)
  190.                                                 Local $SM_CYCAPTION = 4
  191.                                                 Local $iCaptionH = _WinAPI_GetSystemMetrics($SM_CYCAPTION);获取以像素计算的普通窗口标题的高度
  192.                                                 $Item = $iIndex
  193.                                                 $SubItem = $iSub
  194.                                                 ;==========计算编辑框坐标
  195.                                                 Local $aRect = _GUICtrlListView_GetSubItemRect($hListView, $iIndex, $iSub)
  196.                                                 Local $iEdit_X = $aRect[0] + 8 + $aformPos[0]
  197.                                                 Local $iEdit_Y = $aRect[1] + 7 + $aformPos[1] + $iCaptionH
  198.                                                 Local $iEdit_Width = _GUICtrlListView_GetColumnWidth($hListView, $iSub)
  199.                                                 Local $iEdit_Height = $aRect[3] - $aRect[1]
  200.                                                 If $iSub = 0 Then
  201.                                                         Local $i1 = 0, $i2 = 0
  202.                                                         If (BitAND(_GUICtrlListView_GetExtendedListViewStyle($hListView), $LVS_EX_CHECKBOXES) = $LVS_EX_CHECKBOXES) Then $i1 = 18;判断是否有复选框
  203.                                                         If _GUICtrlListView_GetImageList($hListView, 1) Then $i2 = 20;判断是否有分配图像列表到列表视图控件
  204.                                                         $iEdit_X += ($i2 + $i1)
  205.                                                         $iEdit_Width -= ($i2 + $i1)
  206.                                                 EndIf
  207.                                                 $hEditForm = GUICreate("", $iEdit_Width, $iEdit_Height, $iEdit_X, $iEdit_Y, $WS_POPUP, -1, $hGUI);创建一个子窗口用于装载input控件
  208.                                                 Local $iEdit = GUICtrlCreateInput($aShowdata[$iIndex][$iSub], 0, 0, $iEdit_Width, $iEdit_Height, BitOR($WS_CHILD, $WS_VISIBLE, $ES_LEFT))
  209.                                                 GUICtrlSetFont($iEdit, 12)
  210.                                                 GUICtrlSetState($iEdit, $GUI_FOCUS)
  211.                                                 $hEdit = GUICtrlGetHandle($iEdit)
  212.                                                 _GUICtrlEdit_SetSel($hEdit, 0, -1) ;全选编辑框文字
  213.                                                 Local $iEnter = GUICtrlCreateDummy()
  214.                                                 $hEnter = GUICtrlGetHandle($iEnter)
  215.                                                 GUISetAccelerators($aAccelKeys, $hWnd);在虚拟控件上绑定一个回车快捷按键
  216.                                                 GUISetState(@SW_SHOW, $hEditForm)
  217.                                         EndIf

  218.                                 Case -150, -177 ;$LVN_GETDISPINFOA = -150, $LVN_GETDISPINFOW = -177   请求显示数据
  219.                                         If Not IsArray($aShowdata) Then ContinueCase
  220.                                         $tInfo = DllStructCreate($tagNMLVDISPINFO, $ilParam)
  221.                                         $iIndex = Int(DllStructGetData($tInfo, "Item"))
  222.                                         $iSub = Int(DllStructGetData($tInfo, "SubItem"))

  223.                                         If BitAND(DllStructGetData($tInfo, "Mask"), $LVIF_IMAGE) And $iSub = 0 Then DllStructSetData($tInfo, "Image", 0);判断是否有LVIF_IMAGE属性,有则设置列图像。不设置_GUICtrlListView_SetImageList则无

  224.                                         If (BitAND(_GUICtrlListView_GetExtendedListViewStyle($hListView), $LVS_EX_CHECKBOXES) = $LVS_EX_CHECKBOXES) Then
  225.                                                 ;===============设置复选框信息
  226.                                                 DllStructSetData($tInfo, "Mask", BitOR($LVIF_STATE, DllStructGetData($tInfo, "Mask")))
  227.                                                 DllStructSetData($tInfo, "StateMask", $LVIS_STATEIMAGEMASK)
  228.                                                 DllStructSetData($tInfo, "State", $aShowdata[$iIndex][3])
  229.                                         EndIf

  230.                                         DllStructSetData($tText, "Text", $aShowdata[$iIndex][$iSub]);列数据放入$tText结构
  231.                                         DllStructSetData($tInfo, "Text", DllStructGetPtr($tText));$tText结构的指针来设置列数据
  232.                                         DllStructSetData($tInfo, "TextMax", StringLen($aShowdata[$iIndex][$iSub]));设置列数据字串长
  233.                         EndSwitch
  234.         EndSwitch
  235.         Return $GUI_RUNDEFMSG
  236. EndFunc   ;==>WM_NOTIFY


  237. Func WM_KEYDOWN($hWnd, $iMsg, $wParam, $lParam)
  238.         If $wParam = 27 Then $bCtrlDown = True
  239.     Return $GUI_RUNDEFMSG
  240. EndFunc   ;==>WM_KEYDOWN

  241. Func WM_KEYUP($hWnd, $iMsg, $wParam, $lParam)
  242.         If $wParam = 27 Then $bCtrlDown = False
  243.     Return $GUI_RUNDEFMSG
  244. EndFunc   ;==>WM_KEYUP

  245. Func WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
  246.         $iIDFrom = _WinAPI_LoWord($wParam)
  247.         $iCode = _WinAPI_HiWord($wParam)
  248.         Switch $lParam
  249.                 Case $hEdit
  250.                         Switch $iCode
  251.                                 Case $EN_KILLFOCUS
  252.                                        
  253.                                 Case $EN_UPDATE

  254.                         EndSwitch
  255.                 Case $hEnter;虚拟控件消息触发  收到回车消息才触发
  256.                         If IsHWnd($hEdit) Then
  257.                                 _EndItemEdit()
  258.                         EndIf
  259.         EndSwitch
  260.         Return $GUI_RUNDEFMSG
  261. EndFunc   ;==>WM_COMMAND

  262. Func _EndItemEdit()
  263.         If ($Item < UBound($aShowdata, 1)) And ($SubItem < UBound($aShowdata, 2)) Then
  264.                 Local $sText = _GUICtrlEdit_GetText($hEdit)
  265.                 _GUICtrlListView_SetItemText($hListView, $Item, $sText, $SubItem)
  266.                 If IsHWnd($hEdit) Then _WinAPI_DestroyWindow($hEdit)
  267.                 If IsHWnd($hEnter) Then _WinAPI_DestroyWindow($hEnter)
  268.                 If IsHWnd($hEditForm) Then GUIDelete($hEditForm)
  269.                 $hEditForm = Null
  270.                 $hEnter = Null
  271.                 $hEdit = Null
  272.                 If ($Item >= 0) Then
  273.                         $aShowdata[$Item][$SubItem] = $sText
  274.                         GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 0, 20)
  275.                 EndIf
  276.                 $Item = -1
  277.                 $SubItem = 0
  278.         EndIf
  279. EndFunc   ;==>_EndItemEdit

  280. Func _GetChkIndex($iChkState)
  281.         Local $aIndex[1] = [-1], $j = 0
  282.         If $ichked = 0 Then Return $aIndex
  283.         If $iChkState = 8192 Then
  284.                 ReDim $aIndex[$ichked]
  285.         Else
  286.                 ReDim $aIndex[UBound($aShowdata)-$ichked]
  287.         EndIf
  288.         For $i = 0 To UBound($aShowdata) -1
  289.                 If $aShowdata[$i][3] == $iChkState Then
  290.                         $aIndex[$j] = $i
  291.                         $j+=1
  292.                 EndIf
  293.         Next
  294.         Return $aIndex
  295. EndFunc

复制代码
发表于 2015-11-1 23:54:15 | 显示全部楼层
回复 62# 298311657
OK 老大 太感謝您了 ~~

原來再多加一個透明的 $hEditForm  就可以解決掉 很多殘影了問題

太感謝了~~~
发表于 2015-11-2 01:23:02 | 显示全部楼层
回复 62# 298311657

老大 有個地方搞不懂 還真的有點怪
新舊方法 在計算 INPUT框 位置的時候  有問題

原本的範例裡面 沒有考慮進去 如果 LISTVIEW 的位置 不是從最上面開始的話
所以 我後來改了計算法法
OK 了

改成 新版的 方式 可是框的位置不對了
程式沒變動到  但是位置 不對了 我不知道是何原因




計算位置的算法如下


  1. ;==========計算編輯方塊座標
  2. Local $aPos = ControlGetPos("", "", $hVListView);獲取Listview座標
  3. Local $aRect = _GUICtrlListView_GetSubItemRect($hVListView, $Item, $SubItem)
  4.        
  5. Local $iEdit_X = $aRect[0]+$aPos[0] + 4
  6. Local $iEdit_Y = $aRect[1]+$aPos[1] + 3
  7. Local $iEdit_Width = _GUICtrlListView_GetColumnWidth($hVListView, $SubItem) ;+ 3
  8. Local $iEdit_Height = $aRect[3] - $aRect[1]; + 3
  9.        
  10. If $SubItem = 0 Then
  11.         Local $i1 = 0, $i2 = 0
  12.         If (BitAND(_GUICtrlListView_GetExtendedListViewStyle($hVListView), $LVS_EX_CHECKBOXES) = $LVS_EX_CHECKBOXES) Then $i1 = 18;判斷是否有核取方塊
  13.         If _GUICtrlListView_GetImageList($hVListView, 1) Then $i2 = $hImageX;判斷是否有分配圖像清單到清單視圖控制項
  14.         $iEdit_X += ($i2 + $i1)
  15.         $iEdit_Width -= ($i2 + $i1)
  16. EndIf


  17. ;新版程式的寫法
  18. $hEditForm = GUICreate("", $iEdit_Width, $iEdit_Height, $iEdit_X, $iEdit_Y, $WS_POPUP, -1, $WinMain);創建一個子視窗用於裝載input控制項
  19. $iEdit = GUICtrlCreateInput($aShowdata2[$Item][$SubItem], 0, 0, $iEdit_Width, $iEdit_Height, BitOR($WS_CHILD, $WS_VISIBLE, $ES_LEFT));BitOR($WS_CHILD, $WS_VISIBLE, $ES_AUTOHSCROLL, $ES_LEFT )



  20. ;舊版程式的寫法
  21. $hEdit = GUICtrlCreateInput( $aShowdata2[$Item][$SubItem], $iEdit_X, $iEdit_Y, $iEdit_Width, $iEdit_Height );,$ES_RIGHT 右對齊
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?加入

x
发表于 2015-11-2 02:06:35 | 显示全部楼层
回复 64# kk_lee69

老大找到方法了  原來你的範例裡面有考慮到 剛剛沒注意
Local $aformPos = WinGetPos($WinMain)

這個加上去就可以了 感謝  另外

有個問一可以請教嗎??

這個我想只有您能解決這個問題

一個畫面裡面  如果同時要兩個 LISTVIEW 就得要兩個 $aShowdata
一個程式裡面  如果 會用到10個 就得要10個 $aShowdata
因為 每個LISTVIEW 的單擊 雙擊 的需求都不一樣

這樣寫下來 程式好長喔

有辦法縮短 或者弄成 UDF 嗎??

譬如 _EndItemEdit 這個是 一個 函數
我有10個 LISTVIEW 都要共用這個 所以 我設了第11個 共用的 LISTVIEW 譬如叫做 HLISTVIEW
這樣我只要  HLISTVIEW=ListView1  或者 HLISTVIEW=ListView2
這樣在 函數裡面就可以用
但是  $aShowdata  卻不能這樣用.......
目前的做法只好是

Select
        Case $hVListView = $VListView1
                $aShowdata1
        Case $hVListView = $VListView2
                $aShowdata2
        Case $hVListView = $VListView3
                $aShowdata3
               
EndSelect

這樣一個一個寫

所以 想請教 您在實際應用上 有更好的簡便寫法 可學習嗎??
发表于 2015-11-2 08:13:56 | 显示全部楼层
谢谢LZ分享~!
 楼主| 发表于 2015-11-2 21:57:48 | 显示全部楼层
本帖最后由 298311657 于 2015-11-3 13:43 编辑

回复 65# kk_lee69

对数据进行判断并没有简洁的写法,因为不同的数据对应不同的处理方法。
UDF只是把可以重复的代码打包成函数,以便调用。数据判断显然不是可以重复的代码,每一个数据都是独立的。

比如我们可以把listview请求数据显示部分写成函数:

  1. Func _LVN_GETDISPINFO($hlst, $ilParam, ByRef $aDataArray)
  2.         If Not IsArray($aDataArray) Then Return
  3.         $tInfo = DllStructCreate($tagNMLVDISPINFO, $ilParam)
  4.         $iIndex = Int(DllStructGetData($tInfo, "Item"))
  5.         $iSub = Int(DllStructGetData($tInfo, "SubItem"))

  6.         If BitAND(DllStructGetData($tInfo, "Mask"), $LVIF_IMAGE) And $iSub = 0 Then DllStructSetData($tInfo, "Image", 0);判断是否有LVIF_IMAGE属性,有则设置列图像。不设置_GUICtrlListView_SetImageList则无

  7.         If (BitAND(_GUICtrlListView_GetExtendedListViewStyle($hlst), $LVS_EX_CHECKBOXES) = $LVS_EX_CHECKBOXES) Then
  8.                 ;===============设置复选框信息
  9.                 DllStructSetData($tInfo, "Mask", BitOR($LVIF_STATE, DllStructGetData($tInfo, "Mask")))
  10.                 DllStructSetData($tInfo, "StateMask", $LVIS_STATEIMAGEMASK)
  11.                 DllStructSetData($tInfo, "State", $aDataArray[$iIndex][3])
  12.         EndIf

  13.         DllStructSetData($tText, "Text", $aDataArray[$iIndex][$iSub]);列数据放入$tText结构
  14.         DllStructSetData($tInfo, "Text", DllStructGetPtr($tText));$tText结构的指针来设置列数据
  15.         DllStructSetData($tInfo, "TextMax", StringLen($aDataArray[$iIndex][$iSub]));设置列数据字串长
  16. EndFunc
复制代码

   
然后再调用:

  1. Case -150, -177 ;$LVN_GETDISPINFOA = -150, $LVN_GETDISPINFOW = -177   请求显示数据
  2.         _LVN_GETDISPINFO($iIDFrom, $ilParam, $aShowdata3)
复制代码



这是一份完整的代码,我在这里使用了3个listview控件:

  1. #cs ______________________
  2.     Au3 版本: 3.3.14.2
  3.     脚本作?? CrossDoor
  4.     电子邮件: [email]382869232@qq.com[/email]
  5.     QQ/TM: 382869232
  6. #ce _______________脚本开始_________________
  7. #PRE_UseX64=n
  8. #include <WindowsConstants.au3>
  9. #include <GUIConstantsEx.au3>
  10. #include <GuiImageList.au3>
  11. #include <WinAPITheme.au3>
  12. #include <GuiListView.au3>
  13. #include <WinAPISys.au3>
  14. #include <WinAPI.au3>
  15. #include <GuiEdit.au3>
  16. #include <array.au3>
  17. #include <Misc.au3>

  18. Global $B_DESCENDING[3] ; 排序用数组

  19. Global $hActLst
  20. Global $bCtrlDown = False;listview控件ctrl键按下标识
  21. Global $hEdit, $Item = -1, $SubItem = 0
  22. Global $hEnter, $aAccelKeys[1][2] = [["{ENTER}", $hEnter]];虚拟控件的句柄和绑定的快捷键

  23. Local $hUser32 = DllOpen("user32.dll")
  24. Local $ichked = 0;勾选的行数
  25. Local $tText = DllStructCreate("wchar Text[256]");建个结构,用来放listview列数据
  26. Local $GUI, $hImage
  27. Local $iITEM_COUNT = 1000, $aShowdata[$iITEM_COUNT][4], $aShowdata2[$iITEM_COUNT][4], $aShowdata3[$iITEM_COUNT][4];注意数组最大项目数为2^24(16777216),所以$iITEM_COUNT = 4194304为二维数组$aShowdata最大行数
  28. Local $sSomeString = ""
  29. Local $hGUI, $hListView, $hListView2, $hListView3

  30. GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
  31. GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
  32. $hGUI = GUICreate("ListView虚表 加载[" & UBound($aShowdata) & "]数据 复选框 原地编辑例子 By_Crossdoor", 600, 605)

  33. $hListView = GUICtrlCreateListView("$hListView| | ", 2, 2, 295, 296, BitOR($LVS_REPORT, $LVS_SINGLESEL, $LVS_SHOWSELALWAYS, $LVS_OWNERDATA), $LVS_EX_GRIDLINES + $LVS_EX_FULLROWSELECT + $LVS_EX_DOUBLEBUFFER + $LVS_EX_CHECKBOXES)
  34. ;~ _WinAPI_SetWindowTheme(GUICtrlGetHandle($hListView), "Explorer");设置主题

  35. ;设置列宽
  36. GUICtrlSendMsg($hListView, $LVM_SETCOLUMNWIDTH, 0, 110)
  37. GUICtrlSendMsg($hListView, $LVM_SETCOLUMNWIDTH, 1, 80)
  38. GUICtrlSendMsg($hListView, $LVM_SETCOLUMNWIDTH, 2, 80)
  39. GUICtrlSendMsg($hListView, $LVM_SETITEMCOUNT, $iITEM_COUNT, 0);设定数据总数



  40. $hListView2 = GUICtrlCreateListView("$hListView2| | ", 300, 2, 295, 296, BitOR($LVS_REPORT, $LVS_SINGLESEL, $LVS_SHOWSELALWAYS, $LVS_OWNERDATA), $LVS_EX_GRIDLINES + $LVS_EX_FULLROWSELECT + $LVS_EX_DOUBLEBUFFER)
  41. ;~ _WinAPI_SetWindowTheme(GUICtrlGetHandle($hListView), "Explorer");设置主题

  42. ;设置列宽
  43. GUICtrlSendMsg($hListView2, $LVM_SETCOLUMNWIDTH, 0, 110)
  44. GUICtrlSendMsg($hListView2, $LVM_SETCOLUMNWIDTH, 1, 80)
  45. GUICtrlSendMsg($hListView2, $LVM_SETCOLUMNWIDTH, 2, 80)
  46. GUICtrlSendMsg($hListView2, $LVM_SETITEMCOUNT, $iITEM_COUNT, 0);设定数据总数


  47. $hListView3 = GUICtrlCreateListView("$hListView3| | ", 300, 300, 295, 296, BitOR($LVS_REPORT, $LVS_SINGLESEL, $LVS_SHOWSELALWAYS, $LVS_OWNERDATA), $LVS_EX_GRIDLINES + $LVS_EX_FULLROWSELECT + $LVS_EX_DOUBLEBUFFER + $LVS_EX_CHECKBOXES)
  48. ;~ _WinAPI_SetWindowTheme(GUICtrlGetHandle($hListView), "Explorer");设置主题

  49. ;设置列宽
  50. GUICtrlSendMsg($hListView3, $LVM_SETCOLUMNWIDTH, 0, 110)
  51. GUICtrlSendMsg($hListView3, $LVM_SETCOLUMNWIDTH, 1, 80)
  52. GUICtrlSendMsg($hListView3, $LVM_SETCOLUMNWIDTH, 2, 80)
  53. GUICtrlSendMsg($hListView3, $LVM_SETITEMCOUNT, $iITEM_COUNT, 0);设定数据总数

  54. ;===========创建并关联图像列表
  55. $hImage = _GUIImageList_Create()
  56. _GUIImageList_AddIcon($hImage, @SystemDir & "\shell32.dll", 110)
  57. _GUICtrlListView_SetImageList($hListView, $hImage, 1);分配图像列表到列表视图控件$hListView
  58. _GUICtrlListView_SetImageList($hListView2, $hImage, 1);分配图像列表到列表视图控件$hListView2

  59. $Button1 = GUICtrlCreateButton("选中行", 10, 310, 70, 25)
  60. $Button2 = GUICtrlCreateButton("未选行", 80, 310, 70, 25)
  61. $Button3 = GUICtrlCreateButton("修改", 150, 310, 70, 25)
  62. $Button4 = GUICtrlCreateButton("清空", 220, 310, 70, 25)
  63. GUISetState()

  64. ;==================在窗体显示后再初始化数据,因为初始化数组数据比较慢
  65. ;如果先初始化数组后显示窗口,会卡很久,就造成虚表也很慢的假象
  66. For $i = 0 To $iITEM_COUNT - 1
  67.     ;重绘 刷新 listview 0-13行(让ListView显示数组数据),不用太多行,只需要一屏的行数就就可以
  68.     ;因为下拉滚动的时候listview会收到LVN_GETDISPINFO消息,这个消息我们在WM_NOTIFY内处理过了
  69.     If $i = 18 Then
  70.         GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 0, $i)
  71.         GUICtrlSendMsg($hListView2, $LVM_REDRAWITEMS, 0, $i)
  72.         GUICtrlSendMsg($hListView3, $LVM_REDRAWITEMS, 0, $i)
  73.     EndIf
  74.    
  75.     $aShowdata[$i][0] = "爷爷" & $i
  76.     $aShowdata[$i][1] = "爸爸" & $i
  77.     $aShowdata[$i][2] = "儿子" & $i
  78.     $aShowdata[$i][3] = 4096;复选框状态4096未选中 8192选中
  79.    
  80.     $aShowdata2[$i][0] = "2爷爷" & $i
  81.     $aShowdata2[$i][1] = "2爸爸" & $i
  82.     $aShowdata2[$i][2] = "2儿子" & $i
  83.     $aShowdata2[$i][3] = 4096;复选框状态4096未选中 8192选中
  84.    
  85.    
  86.     $aShowdata3[$i][0] = "3爷爷" & $i
  87.     $aShowdata3[$i][1] = "3爸爸" & $i
  88.     $aShowdata3[$i][2] = "3儿子" & $i
  89.     $aShowdata3[$i][3] = 4096;复选框状态4096未选中 8192选中
  90. Next

  91. While 1
  92.     $bCtrlDown = _IsPressed("11", $hUser32);取ctrl按键的状态
  93.     Switch GUIGetMsg()
  94.         Case -3
  95.             ExitLoop
  96.         Case $Button1
  97.             $aShowdata[3][3] = 8192
  98.             $aShowdata[7][3] = 8192
  99.             GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 3, 7)
  100.             
  101. ;~             $a = _GetChkIndex(8192)
  102. ;~             If $a[0] = -1 Then
  103. ;~                 MsgBox(32, "提示", "未勾选任何数据")
  104. ;~             Else
  105. ;~                 _ArrayDisplay($a, "勾选行的索引");数组很大时,_ArrayDisplay会非常耗时
  106. ;~             EndIf
  107.         Case $Button2
  108.             $a = _GetChkIndex(4096)
  109.             If $a[0] = -1 Then
  110.                  MsgBox(32, "提示", "数据全都被勾选了。")
  111.             Else
  112.                 ;MsgBox(32, "提示", "未勾选的数据有" & UBound($a) & "行")
  113.                 _ArrayDisplay($a, "未勾选行的索");数组很大时,_ArrayDisplay会非常耗时
  114.             EndIf
  115.         Case $Button3
  116.             If StringLen($sSomeString) Then
  117.                 $sSomeString = ""
  118.             Else
  119.                 $sSomeString = Asc(Random(48, 255, 1))
  120.             EndIf
  121.             For $i = 0 To $iITEM_COUNT - 1
  122.                 $aShowdata[$i][0] = "爷爷" & $i & "-" & $sSomeString
  123.                 $aShowdata[$i][1] = "爸爸" & $i & "-" & $sSomeString
  124.                 $aShowdata[$i][2] = "儿子" & $i & "-" & $sSomeString
  125.             Next
  126.             GUICtrlSendMsg($hListView, $LVM_ENSUREVISIBLE, 1, 0)
  127.             GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 0, 20)
  128.         Case $Button4
  129.             $aShowdata = 0
  130.             $iITEM_COUNT = 0
  131.             GUICtrlSendMsg($hListView, $LVM_SETITEMCOUNT, $iITEM_COUNT, 0)
  132.             GUICtrlSendMsg($hListView, $LVM_ENSUREVISIBLE, 1, 0)
  133.             GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 0, 20)
  134.     EndSwitch
  135. WEnd
  136. GUIDelete()
  137. DllClose($hUser32)

  138. Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
  139.     #forceref $hWnd, $iMsg, $iwParam
  140.     Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $tInfo

  141.     $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
  142.     $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
  143.     $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
  144.     $iCode = DllStructGetData($tNMHDR, "Code")
  145.    
  146.     Local $iIndex = DllStructGetData($tNMHDR, "Index")
  147.     Switch $iIDFrom
  148.         Case $hListView
  149.             Switch $iCode
  150.                 Case $LVN_COLUMNCLICK ; 点击列头排序
  151.                     _SortItems($iIDFrom, $ilParam, $aShowdata)
  152.                 Case $NM_CUSTOMDRAW;自绘消息  处理选中行背景色
  153. ;~                     _SetchkboxBkClr($ilParam, $aShowdata)
  154.                     Local $tCustDraw = DllStructCreate("hwnd hwndFrom;int idFrom;int code;dword DrawStage;hwnd hdc;long rect[4];dword ItemSpec;int ItemState;dword Itemlparam;dword clrText;dword clrTextBk;int SubItem; dword ItemType;dword clrFace;int IconEffect;int IconPhase;int PartID;int StateID;long rectText[4];int Align", $ilParam)
  155. ;~                     
  156.                     Local $iDrawStage = DllStructGetData($tCustDraw, "DrawStage")
  157.                     If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW ;request custom drawing of items
  158.                     If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW ;request drawing each cell separately
  159.                     If Not BitAND($iDrawStage, $CDDS_SUBITEM) Then Return $CDRF_DODEFAULT
  160.                     $iIndex = DllStructGetData($tCustDraw, "ItemSpec")
  161.                     If $aShowdata[$iIndex][3] = 4096 Then
  162.                         DllStructSetData($tCustDraw, "clrTextBk", 0xFFFFFF);BGR格式颜色值
  163.                     Else
  164.                         DllStructSetData($tCustDraw, "clrTextBk", 0xF7D3AD);BGR格式颜色值
  165.                     EndIf
  166.                     Return $CDRF_NEWFONT
  167.                 Case $LVN_ITEMCHANGED ; An item has changed
  168.                     _CtrlSel($iIDFrom, $ilParam, $aShowdata)
  169.                 Case $LVN_BEGINSCROLL ; 滚动事件开始
  170.                     If IsHWnd($hEdit) Then _EndItemEdit($iIDFrom, $aShowdata);如果存在$hEdit控件,则结束编辑                           
  171.                 Case $NM_CLICK;单击
  172.                     If IsHWnd($hEdit) Then _EndItemEdit($iIDFrom, $aShowdata)
  173.                     _chkboxState($iIDFrom, $ilParam, $aShowdata);刷新复选框状态
  174.                 Case $NM_DBLCLK ; 双击
  175.                     _StartItemEdit($iIDFrom, $ilParam, $aShowdata);开始原地编辑
  176.                 Case -150, -177 ;$LVN_GETDISPINFOA = -150, $LVN_GETDISPINFOW = -177   请求显示数据
  177.                     _LVN_GETDISPINFO($iIDFrom, $ilParam, $aShowdata)
  178.             EndSwitch
  179.         Case $hListView2
  180.             Switch $iCode
  181.                 Case -150, -177 ;$LVN_GETDISPINFOA = -150, $LVN_GETDISPINFOW = -177   请求显示数据
  182.                     _LVN_GETDISPINFO($iIDFrom, $ilParam, $aShowdata2)
  183.                 Case $LVN_COLUMNCLICK ; 点击列头排序
  184.                     _SortItems($iIDFrom, $ilParam, $aShowdata2)
  185.                 Case $NM_CUSTOMDRAW;自绘消息  处理选中行背景色
  186.                     Local $tCustDraw = DllStructCreate("hwnd hwndFrom;int idFrom;int code;dword DrawStage;hwnd hdc;long rect[4];dword ItemSpec;int ItemState;dword Itemlparam;dword clrText;dword clrTextBk;int SubItem; dword ItemType;dword clrFace;int IconEffect;int IconPhase;int PartID;int StateID;long rectText[4];int Align", $ilParam)
  187.                     Local $iDrawStage = DllStructGetData($tCustDraw, "DrawStage")
  188.                     If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW ;request custom drawing of items
  189.                     If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW ;request drawing each cell separately
  190.                     If Not BitAND($iDrawStage, $CDDS_SUBITEM) Then Return $CDRF_DODEFAULT
  191.                     $iIndex = DllStructGetData($tCustDraw, "ItemSpec")
  192.                     If $aShowdata2[$iIndex][3] = 4096 Then
  193.                         DllStructSetData($tCustDraw, "clrTextBk", 0xFFFFFF);BGR格式颜色值
  194.                     Else
  195.                         DllStructSetData($tCustDraw, "clrTextBk", 0xF7D3AD);BGR格式颜色值
  196.                     EndIf
  197.                     Return $CDRF_NEWFONT
  198.                 Case $LVN_ITEMCHANGED ; An item has changed
  199.                     _CtrlSel($iIDFrom, $ilParam, $aShowdata2)
  200.                 Case $LVN_BEGINSCROLL ; 滚动事件开始
  201.                     If IsHWnd($hEdit) Then _EndItemEdit($iIDFrom, $aShowdata2);如果存在$hEdit控件,则结束编辑
  202.                 Case $NM_CLICK;单击
  203.                     If IsHWnd($hEdit) Then _EndItemEdit($iIDFrom, $aShowdata2)
  204.                     _chkboxState($iIDFrom, $ilParam, $aShowdata2)
  205.                 Case $NM_DBLCLK ; 双击
  206.                     _StartItemEdit($iIDFrom, $ilParam, $aShowdata2)
  207.             EndSwitch
  208.         Case $hListView3
  209.             Switch $iCode
  210.                 Case -150, -177 ;$LVN_GETDISPINFOA = -150, $LVN_GETDISPINFOW = -177   请求显示数据
  211.                     _LVN_GETDISPINFO($iIDFrom, $ilParam, $aShowdata3)
  212.                 Case $LVN_COLUMNCLICK ; 点击列头排序
  213.                     _SortItems($iIDFrom, $ilParam, $aShowdata3)
  214.                 Case $NM_CUSTOMDRAW;自绘消息  处理选中行背景色
  215.                     Local $tCustDraw = DllStructCreate("hwnd hwndFrom;int idFrom;int code;dword DrawStage;hwnd hdc;long rect[4];dword ItemSpec;int ItemState;dword Itemlparam;dword clrText;dword clrTextBk;int SubItem; dword ItemType;dword clrFace;int IconEffect;int IconPhase;int PartID;int StateID;long rectText[4];int Align", $ilParam)
  216.                     Local $iDrawStage = DllStructGetData($tCustDraw, "DrawStage")
  217.                     If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW ;request custom drawing of items
  218.                     If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW ;request drawing each cell separately
  219.                     If Not BitAND($iDrawStage, $CDDS_SUBITEM) Then Return $CDRF_DODEFAULT
  220.                     $iIndex = DllStructGetData($tCustDraw, "ItemSpec")
  221.                     If $aShowdata3[$iIndex][3] = 4096 Then
  222.                         DllStructSetData($tCustDraw, "clrTextBk", 0xFFFFFF);BGR格式颜色值
  223.                     Else
  224.                         DllStructSetData($tCustDraw, "clrTextBk", 0xF7D3AD);BGR格式颜色值
  225.                     EndIf
  226.                     Return $CDRF_NEWFONT
  227.                 Case $LVN_ITEMCHANGED ; An item has changed
  228.                     _CtrlSel($iIDFrom, $ilParam, $aShowdata3)
  229.                 Case $LVN_BEGINSCROLL ; 滚动事件开始
  230.                     If IsHWnd($hEdit) Then _EndItemEdit($iIDFrom, $aShowdata3);如果存在$hEdit控件,则结束编辑
  231.                 Case $NM_CLICK;单击
  232.                     If IsHWnd($hEdit) Then _EndItemEdit($iIDFrom, $aShowdata3)
  233.                     _chkboxState($iIDFrom, $ilParam, $aShowdata3)
  234.                 Case $NM_DBLCLK ; 双击
  235.                     _StartItemEdit($iIDFrom, $ilParam, $aShowdata3)
  236.             EndSwitch
  237.     EndSwitch
  238.     Return $GUI_RUNDEFMSG
  239. EndFunc

  240. Func WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
  241.     $iIDFrom = _WinAPI_LoWord($wParam)
  242.     $iCode = _WinAPI_HiWord($wParam)
  243.     Switch $lParam
  244.         Case $hEdit
  245.             Switch $iCode
  246.                 Case $EN_KILLFOCUS;编辑框失去焦点,结束编辑
  247.                     Switch $hActLst
  248.                         Case $hListView
  249.                             _EndItemEdit($hListView, $aShowdata)
  250.                         Case $hListView2
  251.                             _EndItemEdit($hListView2, $aShowdata2)
  252.                         Case $hListView3
  253.                             _EndItemEdit($hListView3, $aShowdata3)
  254.                     EndSwitch
  255.                 Case $EN_UPDATE

  256.             EndSwitch
  257.         Case $hEnter;虚拟控件消息触发  收到回车消息才触发
  258.             If IsHWnd($hEdit) Then
  259.                 If $SubItem = 0 Then
  260.                     __ClickListViewItem($hActLst, $Item, True);使用点击来结束编辑,省去判断listview的数据数组
  261.                 Else
  262.                     __ClickListViewItem($hActLst, $Item)
  263.                 EndIf
  264.             EndIf
  265.     EndSwitch
  266.     Return $GUI_RUNDEFMSG
  267. EndFunc

  268. Func _SetchkboxBkClr(ByRef $ilParam, ByRef $aDataArray)
  269.     Local $tCustDraw = DllStructCreate("hwnd hwndFrom;int idFrom;int code;dword DrawStage;hwnd hdc;long rect[4];dword ItemSpec;int ItemState;dword Itemlparam;dword clrText;dword clrTextBk;int SubItem; dword ItemType;dword clrFace;int IconEffect;int IconPhase;int PartID;int StateID;long rectText[4];int Align", $ilParam)
  270.     Local $iDrawStage = DllStructGetData($tCustDraw, "DrawStage")
  271.    
  272.     If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW ;request custom drawing of items
  273.     If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW ;request drawing each cell separately
  274.     If Not BitAND($iDrawStage, $CDDS_SUBITEM) Then Return $CDRF_DODEFAULT
  275.     $iIndex = DllStructGetData($tCustDraw, "ItemSpec")
  276.     If $aDataArray[$iIndex][3] = 4096 Then
  277.         DllStructSetData($tCustDraw, "clrTextBk", 0xFFFFFF);BGR格式颜色值
  278.     Else
  279.         DllStructSetData($tCustDraw, "clrTextBk", 0xF7D3AD);BGR格式颜色值
  280.     EndIf   
  281. EndFunc

  282. Func _chkboxState($hlst, $ilParam, ByRef $aDataArray);刷新复选框状态
  283.     $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
  284.     $iIndex = DllStructGetData($tInfo, "Index")
  285.     $x = DllStructGetData($tInfo, "X")
  286.     If ($x < 16) And (3 < $x) And (BitAND(_GUICtrlListView_GetExtendedListViewStyle($hlst), $LVS_EX_CHECKBOXES) = $LVS_EX_CHECKBOXES) Then;使用点击的x坐标来判断是否在复选框上点击
  287.         If $aDataArray[$iIndex][3] = 4096 Then
  288.             $ichked+=1
  289.             $aDataArray[$iIndex][3] = 8192;4096未选中 8192选中
  290.         Else
  291.             $ichked-=1
  292.             $aDataArray[$iIndex][3] = 4096;4096未选中 8192选中
  293.         EndIf
  294.         ;====立刻刷新复选框显示状态 重绘$iIndex项
  295.         GUICtrlSendMsg($hlst, $LVM_REDRAWITEMS, $iIndex, $iIndex)
  296.     EndIf   
  297. EndFunc

  298. Func _SortItems($hlst, $ilParam, ByRef $aDataArray);排序
  299.     $tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)
  300.     $iSub = DllStructGetData($tInfo, "SubItem")
  301.     _ArraySort($aDataArray, $B_DESCENDING[$iSub], 0, 0, $iSub)
  302.     GUICtrlSendMsg($hlst, $LVM_REDRAWITEMS, 0, 20)
  303.     $B_DESCENDING[$iSub] = Not $B_DESCENDING[$iSub]
  304. EndFunc

  305. Func _CtrlSel($hlst, $ilParam, ByRef $aDataArray);按住ctrl键点选item
  306.     If $bCtrlDown Then;ctrl键按下
  307.         $tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)
  308.         Local $iIndex = DllStructGetData($tInfo, "Item")
  309.         Local $iNewState = DllStructGetData($tInfo, "NewState")
  310.         If $iIndex > -1 And $iNewState = BitOR($LVIS_FOCUSED, $LVIS_SELECTED) Then
  311.             If $aDataArray[$iIndex][3] = 4096 Then
  312.                 $ichked+=1
  313.                 $aDataArray[$iIndex][3] = 8192;4096未选中 8192选中
  314.             Else
  315.                 $ichked-=1
  316.                 $aDataArray[$iIndex][3] = 4096;4096未选中 8192选中
  317.             EndIf
  318.             $tInfo = DllStructCreate($tagNMLVDISPINFO, $ilParam)
  319.             DllStructSetData($tInfo, "State", $aDataArray[$iIndex][3]);设置复选框状态
  320.             ;====立刻刷新复选框显示状态 重绘$iIndex项
  321.             GUICtrlSendMsg($hlst, $LVM_REDRAWITEMS, $iIndex, $iIndex)
  322.         EndIf
  323.     EndIf
  324. EndFunc

  325. Func _LVN_GETDISPINFO($hlst, $ilParam, ByRef $aDataArray)
  326.     If Not IsArray($aDataArray) Then Return
  327.     $tInfo = DllStructCreate($tagNMLVDISPINFO, $ilParam)
  328.     $iIndex = Int(DllStructGetData($tInfo, "Item"))
  329.     $iSub = Int(DllStructGetData($tInfo, "SubItem"))

  330.     If BitAND(DllStructGetData($tInfo, "Mask"), $LVIF_IMAGE) And $iSub = 0 Then DllStructSetData($tInfo, "Image", 0);判断是否有LVIF_IMAGE属性,有则设置列图像。不设置_GUICtrlListView_SetImageList则无

  331.     If (BitAND(_GUICtrlListView_GetExtendedListViewStyle($hlst), $LVS_EX_CHECKBOXES) = $LVS_EX_CHECKBOXES) Then
  332.         ;===============设置复选框信息
  333.         DllStructSetData($tInfo, "Mask", BitOR($LVIF_STATE, DllStructGetData($tInfo, "Mask")))
  334.         DllStructSetData($tInfo, "StateMask", $LVIS_STATEIMAGEMASK)
  335.         DllStructSetData($tInfo, "State", $aDataArray[$iIndex][3])
  336.     EndIf

  337.     DllStructSetData($tText, "Text", $aDataArray[$iIndex][$iSub]);列数据放入$tText结构
  338.     DllStructSetData($tInfo, "Text", DllStructGetPtr($tText));$tText结构的指针来设置列数据
  339.     DllStructSetData($tInfo, "TextMax", StringLen($aDataArray[$iIndex][$iSub]));设置列数据字串长
  340. EndFunc

  341. Func _StartItemEdit($hlst, $ilParam, ByRef $aDataArray)
  342.     $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
  343.     $iIndex = DllStructGetData($tInfo, "Index")
  344.     $iSub = DllStructGetData($tInfo, "SubItem")
  345.     $x = DllStructGetData($tInfo, "X")
  346.     If ($iIndex <> -1) And ($iSub >= 0) And ($x > 16) Then;点击的x>16才响应原地编辑
  347.         $hActLst = $hlst
  348.         If _GUICtrlListView_EnsureVisible($hlst, $iIndex) Then GUICtrlSendMsg($hlst, $LVM_REDRAWITEMS, $iIndex, $iIndex + 1);确保列表视图项目可见
  349.         Local $alstPos = ControlGetPos($hGUI, "", $hlst)
  350.         $Item = $iIndex
  351.         $SubItem = $iSub
  352.         ;==========计算编辑框坐标
  353.         Local $aRect = _GUICtrlListView_GetSubItemRect($hlst, $iIndex, $iSub)
  354.         Local $iEdit_X = $aRect[0] + $alstPos[0] + 4
  355.         Local $iEdit_Y = $aRect[1] + $alstPos[1] + 2
  356.         Local $iEdit_Width = _GUICtrlListView_GetColumnWidth($hlst, $iSub) - 1
  357.         Local $iEdit_Height = $aRect[3] - $aRect[1]
  358.         If $iSub = 0 Then
  359.             Local $i1 = 0, $i2 = 0
  360.             If (BitAND(_GUICtrlListView_GetExtendedListViewStyle($hlst), $LVS_EX_CHECKBOXES) = $LVS_EX_CHECKBOXES) Then $i1 = 17;判断是否有复选框
  361.             If _GUICtrlListView_GetImageList($hlst, 1) Then $i2 = 19;判断是否有分配图像列表到列表视图控件
  362.             $iEdit_X += ($i2 + $i1)
  363.             $iEdit_Width -= ($i2 + $i1)
  364.         EndIf
  365.         Local $iEdit = GUICtrlCreateInput($aDataArray[$iIndex][$iSub], $iEdit_X, $iEdit_Y, $iEdit_Width, $iEdit_Height, BitOR($WS_CHILD, $WS_VISIBLE, $ES_LEFT))
  366.         GUICtrlSetFont($iEdit, 11)
  367.         GUICtrlSetState($iEdit, $GUI_FOCUS)
  368.         $hEdit = GUICtrlGetHandle($iEdit)
  369.         _WinAPI_BringWindowToTop($hEdit)
  370.         _GUICtrlEdit_SetSel($hEdit, 0, -1) ;全选编辑框文字
  371.         Local $iEnter = GUICtrlCreateDummy()
  372.         $hEnter = GUICtrlGetHandle($iEnter)
  373.         GUISetAccelerators($aAccelKeys, $hGUI);在虚拟控件上绑定一个回车快捷按键
  374.     EndIf   
  375. EndFunc

  376. Func _EndItemEdit($hlst, ByRef $aDataArray)
  377.     If ($Item < UBound($aDataArray, 1)) And ($SubItem < UBound($aDataArray, 2)) And ($hActLst == $hlst) Then
  378.         Local $sText = _GUICtrlEdit_GetText($hEdit)
  379.         _GUICtrlListView_SetItemText($hlst, $Item, $sText, $SubItem)
  380.         If IsHWnd($hEdit) Then _WinAPI_DestroyWindow($hEdit)
  381.         If IsHWnd($hEnter) Then _WinAPI_DestroyWindow($hEnter)
  382.         $hEnter = Null
  383.         $hEdit = Null
  384.         If ($Item >= 0) Then $aDataArray[$Item][$SubItem] = $sText
  385.         $Item = -1
  386.         $SubItem = 0
  387.     EndIf
  388. EndFunc

  389. Func _GetChkIndex($iChkState)
  390.     Local $aIndex[1] = [-1], $j = 0
  391.     If $ichked = 0 Then Return $aIndex
  392.     If $iChkState = 8192 Then
  393.         ReDim $aIndex[$ichked]
  394.     Else
  395.         ReDim $aIndex[UBound($aShowdata)-$ichked]
  396.     EndIf
  397.     For $i = 0 To UBound($aShowdata) -1
  398.         If $aShowdata[$i][3] == $iChkState Then
  399.             $aIndex[$j] = $i
  400.             $j+=1
  401.         EndIf
  402.     Next
  403.     Return $aIndex
  404. EndFunc

  405. Func __ClickListViewItem($hWnd, $iIndex, $baddX = False)
  406.     If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)

  407.     Local $tRECT = _GUICtrlListView_GetItemRectEx($hWnd, $iIndex, $LVIR_LABEL)
  408.     Local $tPoint = _WinAPI_PointFromRect($tRECT, True)
  409.     $tPoint = _WinAPI_ClientToScreen($hWnd, $tPoint)
  410.     Local $iX, $iY
  411.     _WinAPI_GetXYFromPoint($tPoint, $iX, $iY)
  412.     If $baddX Then $iX += DllStructGetData($tRECT, "Right")
  413.     Local $iMode = Opt("MouseCoordMode", 1)
  414.     Local $aPos = MouseGetPos()
  415.     MouseClick("left", $iX, $iY, 1, 0)
  416.     MouseMove($aPos[0], $aPos[1], 0)
  417.     Opt("MouseCoordMode", $iMode)
  418. EndFunc
复制代码
发表于 2015-11-2 22:42:00 | 显示全部楼层
谢谢楼主分享   学习学习
发表于 2015-11-3 02:15:19 | 显示全部楼层
回复 67# 298311657

感謝樓主 我又學到了東西
我想請教的就是
_LVN_GETDISPINFO($hlst, $ilParam, ByRef $aDataArray)


DllStructSetData($tInfo, "TextMax", StringLen($aDataArray[$iIndex][$iSub]));設置列數據字串長
這樣子的用法....

怎麼我的觀念認為這樣是不可以的??......原來是我的認知有問題.....

這個突破 可以讓我更縮短我的 寫法了 感列樓主!!
发表于 2015-11-4 10:54:23 | 显示全部楼层
回复 67# 298311657

樓主 你好  又來打擾了 真不好意思.....  能請教觀念嗎??

  Case $NM_CUSTOMDRAW;自绘消息  处理选中行背景色
   
為何 這個 寫成 Func 後 功能就失效了,雖然不會出現錯誤,但是 都無法上顏色呢??

原因是甚麼呢??
 楼主| 发表于 2015-11-6 00:15:25 | 显示全部楼层
回复 70# kk_lee69

只能这样做:

  1. #cs ______________________
  2.     Au3 版本: 3.3.14.2
  3.     脚本作?? CrossDoor
  4.     电子邮件: [email]382869232@qq.com[/email]
  5.     QQ/TM: 382869232
  6. #ce _______________脚本开始_________________
  7. #PRE_UseX64=n
  8. #include <WindowsConstants.au3>
  9. #include <GUIConstantsEx.au3>
  10. #include <GuiImageList.au3>
  11. #include <WinAPITheme.au3>
  12. #include <GuiListView.au3>
  13. #include <WinAPISys.au3>
  14. #include <WinAPI.au3>
  15. #include <GuiEdit.au3>
  16. #include <array.au3>
  17. #include <Misc.au3>

  18. Global $B_DESCENDING[3] ; 排序用数组

  19. Global $hActLst
  20. Global $bCtrlDown = False;listview控件ctrl键按下标识
  21. Global $hEdit, $Item = -1, $SubItem = 0
  22. Global $hEnter, $aAccelKeys[1][2] = [["{ENTER}", $hEnter]];虚拟控件的句柄和绑定的快捷键

  23. Local $hUser32 = DllOpen("user32.dll")
  24. Local $ichked = 0;勾选的行数
  25. Local $tText = DllStructCreate("wchar Text[256]");建个结构,用来放listview列数据
  26. Local $GUI, $hImage
  27. Local $iITEM_COUNT = 1000, $aShowdata[$iITEM_COUNT][4], $aShowdata2[$iITEM_COUNT][4], $aShowdata3[$iITEM_COUNT][4];注意数组最大项目数为2^24(16777216),所以$iITEM_COUNT = 4194304为二维数组$aShowdata最大行数
  28. Local $sSomeString = ""
  29. Local $hGUI, $hListView, $hListView2, $hListView3

  30. GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
  31. GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
  32. $hGUI = GUICreate("ListView虚表 加载[" & UBound($aShowdata) & "]数据 复选框 原地编辑例子 By_Crossdoor", 600, 605)

  33. $hListView = GUICtrlCreateListView("$hListView| | ", 2, 2, 295, 296, BitOR($LVS_REPORT, $LVS_SINGLESEL, $LVS_SHOWSELALWAYS, $LVS_OWNERDATA), $LVS_EX_GRIDLINES + $LVS_EX_FULLROWSELECT + $LVS_EX_DOUBLEBUFFER + $LVS_EX_CHECKBOXES)
  34. ;~ _WinAPI_SetWindowTheme(GUICtrlGetHandle($hListView), "Explorer");设置主题

  35. ;设置列宽
  36. GUICtrlSendMsg($hListView, $LVM_SETCOLUMNWIDTH, 0, 110)
  37. GUICtrlSendMsg($hListView, $LVM_SETCOLUMNWIDTH, 1, 80)
  38. GUICtrlSendMsg($hListView, $LVM_SETCOLUMNWIDTH, 2, 80)
  39. GUICtrlSendMsg($hListView, $LVM_SETITEMCOUNT, $iITEM_COUNT, 0);设定数据总数



  40. $hListView2 = GUICtrlCreateListView("$hListView2| | ", 300, 2, 295, 296, BitOR($LVS_REPORT, $LVS_SINGLESEL, $LVS_SHOWSELALWAYS, $LVS_OWNERDATA), $LVS_EX_GRIDLINES + $LVS_EX_FULLROWSELECT + $LVS_EX_DOUBLEBUFFER + $LVS_EX_CHECKBOXES)
  41. ;~ _WinAPI_SetWindowTheme(GUICtrlGetHandle($hListView), "Explorer");设置主题

  42. ;设置列宽
  43. GUICtrlSendMsg($hListView2, $LVM_SETCOLUMNWIDTH, 0, 110)
  44. GUICtrlSendMsg($hListView2, $LVM_SETCOLUMNWIDTH, 1, 80)
  45. GUICtrlSendMsg($hListView2, $LVM_SETCOLUMNWIDTH, 2, 80)
  46. GUICtrlSendMsg($hListView2, $LVM_SETITEMCOUNT, $iITEM_COUNT, 0);设定数据总数


  47. $hListView3 = GUICtrlCreateListView("$hListView3| | ", 300, 300, 295, 296, BitOR($LVS_REPORT, $LVS_SINGLESEL, $LVS_SHOWSELALWAYS, $LVS_OWNERDATA), $LVS_EX_GRIDLINES + $LVS_EX_FULLROWSELECT + $LVS_EX_DOUBLEBUFFER + $LVS_EX_CHECKBOXES)
  48. ;~ _WinAPI_SetWindowTheme(GUICtrlGetHandle($hListView), "Explorer");设置主题

  49. ;设置列宽
  50. GUICtrlSendMsg($hListView3, $LVM_SETCOLUMNWIDTH, 0, 110)
  51. GUICtrlSendMsg($hListView3, $LVM_SETCOLUMNWIDTH, 1, 80)
  52. GUICtrlSendMsg($hListView3, $LVM_SETCOLUMNWIDTH, 2, 80)
  53. GUICtrlSendMsg($hListView3, $LVM_SETITEMCOUNT, $iITEM_COUNT, 0);设定数据总数

  54. ;===========创建并关联图像列表
  55. $hImage = _GUIImageList_Create()
  56. _GUIImageList_AddIcon($hImage, @SystemDir & "\shell32.dll", 110)
  57. _GUICtrlListView_SetImageList($hListView, $hImage, 1);分配图像列表到列表视图控件$hListView
  58. _GUICtrlListView_SetImageList($hListView2, $hImage, 1);分配图像列表到列表视图控件$hListView2

  59. $Button1 = GUICtrlCreateButton("选中行", 10, 310, 70, 25)
  60. $Button2 = GUICtrlCreateButton("未选行", 80, 310, 70, 25)
  61. $Button3 = GUICtrlCreateButton("修改", 150, 310, 70, 25)
  62. $Button4 = GUICtrlCreateButton("清空", 220, 310, 70, 25)
  63. GUISetState()

  64. ;==================在窗体显示后再初始化数据,因为初始化数组数据比较慢
  65. ;如果先初始化数组后显示窗口,会卡很久,就造成虚表也很慢的假象
  66. For $i = 0 To $iITEM_COUNT - 1
  67.     ;重绘 刷新 listview 0-13行(让ListView显示数组数据),不用太多行,只需要一屏的行数就就可以
  68.     ;因为下拉滚动的时候listview会收到LVN_GETDISPINFO消息,这个消息我们在WM_NOTIFY内处理过了
  69.     If $i = 18 Then
  70.         GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 0, $i)
  71.         GUICtrlSendMsg($hListView2, $LVM_REDRAWITEMS, 0, $i)
  72.         GUICtrlSendMsg($hListView3, $LVM_REDRAWITEMS, 0, $i)
  73.     EndIf
  74.    
  75.     $aShowdata[$i][0] = "爷爷" & $i
  76.     $aShowdata[$i][1] = "爸爸" & $i
  77.     $aShowdata[$i][2] = "儿子" & $i
  78.     $aShowdata[$i][3] = 4096;复选框状态4096未选中 8192选中
  79.    
  80.     $aShowdata2[$i][0] = "2爷爷" & $i
  81.     $aShowdata2[$i][1] = "2爸爸" & $i
  82.     $aShowdata2[$i][2] = "2儿子" & $i
  83.     $aShowdata2[$i][3] = 4096;复选框状态4096未选中 8192选中
  84.    
  85.    
  86.     $aShowdata3[$i][0] = "3爷爷" & $i
  87.     $aShowdata3[$i][1] = "3爸爸" & $i
  88.     $aShowdata3[$i][2] = "3儿子" & $i
  89.     $aShowdata3[$i][3] = 4096;复选框状态4096未选中 8192选中
  90. Next

  91. While 1
  92.     $bCtrlDown = _IsPressed("11", $hUser32);取ctrl按键的状态
  93.     Switch GUIGetMsg()
  94.         Case -3
  95.             ExitLoop
  96.         Case $Button1
  97.             $aShowdata[3][3] = 8192
  98.             $aShowdata[7][3] = 8192
  99.             GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 3, 7)
  100.             
  101. ;~             $a = _GetChkIndex(8192)
  102. ;~             If $a[0] = -1 Then
  103. ;~                 MsgBox(32, "提示", "未勾选任何数据")
  104. ;~             Else
  105. ;~                 _ArrayDisplay($a, "勾选行的索引");数组很大时,_ArrayDisplay会非常耗时
  106. ;~             EndIf
  107.         Case $Button2
  108.             $a = _GetChkIndex(4096)
  109.             If $a[0] = -1 Then
  110.                  MsgBox(32, "提示", "数据全都被勾选了。")
  111.             Else
  112.                 ;MsgBox(32, "提示", "未勾选的数据有" & UBound($a) & "行")
  113.                 _ArrayDisplay($a, "未勾选行的索");数组很大时,_ArrayDisplay会非常耗时
  114.             EndIf
  115.         Case $Button3
  116.             If StringLen($sSomeString) Then
  117.                 $sSomeString = ""
  118.             Else
  119.                 $sSomeString = Asc(Random(48, 255, 1))
  120.             EndIf
  121.             For $i = 0 To $iITEM_COUNT - 1
  122.                 $aShowdata[$i][0] = "爷爷" & $i & "-" & $sSomeString
  123.                 $aShowdata[$i][1] = "爸爸" & $i & "-" & $sSomeString
  124.                 $aShowdata[$i][2] = "儿子" & $i & "-" & $sSomeString
  125.             Next
  126.             GUICtrlSendMsg($hListView, $LVM_ENSUREVISIBLE, 1, 0)
  127.             GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 0, 20)
  128.         Case $Button4
  129.             $aShowdata = 0
  130.             $iITEM_COUNT = 0
  131.             GUICtrlSendMsg($hListView, $LVM_SETITEMCOUNT, $iITEM_COUNT, 0)
  132.             GUICtrlSendMsg($hListView, $LVM_ENSUREVISIBLE, 1, 0)
  133.             GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 0, 20)
  134.     EndSwitch
  135. WEnd
  136. GUIDelete()
  137. DllClose($hUser32)

  138. Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
  139.     #forceref $hWnd, $iMsg, $iwParam
  140.     Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $tInfo

  141.     $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
  142.     $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
  143.     $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
  144.     $iCode = DllStructGetData($tNMHDR, "Code")
  145.    
  146.     Switch $iIDFrom
  147.         Case $hListView
  148.             Switch $iCode
  149.                 Case $LVN_COLUMNCLICK ; 点击列头排序
  150.                     _SortItems($iIDFrom, $ilParam, $aShowdata)
  151.                 Case $NM_CUSTOMDRAW;自绘消息  处理选中行背景色
  152.                     Local $tCustDraw = DllStructCreate("hwnd hwndFrom;int idFrom;int code;dword DrawStage;hwnd hdc;long rect[4];dword ItemSpec;int ItemState;dword Itemlparam;dword clrText;dword clrTextBk;int SubItem; dword ItemType;dword clrFace;int IconEffect;int IconPhase;int PartID;int StateID;long rectText[4];int Align", $ilParam)
  153.                     Local $iDrawStage = DllStructGetData($tCustDraw, "DrawStage")
  154.                     If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW ;request custom drawing of items
  155.                     If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW ;request drawing each cell separately
  156.                     If Not BitAND($iDrawStage, $CDDS_SUBITEM) Then Return $CDRF_DODEFAULT
  157.                     _SetchkedBkClr($tCustDraw, $aShowdata)
  158.                     Return $CDRF_NEWFONT
  159.                 Case $LVN_ITEMCHANGED ; An item has changed
  160.                     _CtrlSel($iIDFrom, $ilParam, $aShowdata)
  161.                 Case $LVN_BEGINSCROLL ; 滚动事件开始
  162.                     If IsHWnd($hEdit) Then _EndItemEdit($iIDFrom, $aShowdata);如果存在$hEdit控件,则结束编辑                           
  163.                 Case $NM_CLICK;单击
  164.                     If IsHWnd($hEdit) Then _EndItemEdit($iIDFrom, $aShowdata)
  165.                     _chkboxState($iIDFrom, $ilParam, $aShowdata);刷新复选框状态
  166.                 Case $NM_DBLCLK ; 双击
  167.                     _StartItemEdit($iIDFrom, $ilParam, $aShowdata);开始原地编辑
  168.                 Case -150, -177 ;$LVN_GETDISPINFOA = -150, $LVN_GETDISPINFOW = -177   请求显示数据
  169.                     _LVN_GETDISPINFO($iIDFrom, $ilParam, $aShowdata)
  170.             EndSwitch
  171.         Case $hListView2
  172.             Switch $iCode
  173.                 Case -150, -177 ;$LVN_GETDISPINFOA = -150, $LVN_GETDISPINFOW = -177   请求显示数据
  174.                     _LVN_GETDISPINFO($iIDFrom, $ilParam, $aShowdata2)
  175.                 Case $LVN_COLUMNCLICK ; 点击列头排序
  176.                     _SortItems($iIDFrom, $ilParam, $aShowdata2)
  177.                 Case $NM_CUSTOMDRAW;自绘消息  处理选中行背景色
  178.                     Local $tCustDraw = DllStructCreate("hwnd hwndFrom;int idFrom;int code;dword DrawStage;hwnd hdc;long rect[4];dword ItemSpec;int ItemState;dword Itemlparam;dword clrText;dword clrTextBk;int SubItem; dword ItemType;dword clrFace;int IconEffect;int IconPhase;int PartID;int StateID;long rectText[4];int Align", $ilParam)
  179.                     Local $iDrawStage = DllStructGetData($tCustDraw, "DrawStage")
  180.                     If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW ;request custom drawing of items
  181.                     If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW ;request drawing each cell separately
  182.                     If Not BitAND($iDrawStage, $CDDS_SUBITEM) Then Return $CDRF_DODEFAULT
  183.                     _SetchkedBkClr($tCustDraw, $aShowdata2, 0x738393)
  184.                     Return $CDRF_NEWFONT
  185.                 Case $LVN_ITEMCHANGED ; An item has changed
  186.                     _CtrlSel($iIDFrom, $ilParam, $aShowdata2)
  187.                 Case $LVN_BEGINSCROLL ; 滚动事件开始
  188.                     If IsHWnd($hEdit) Then _EndItemEdit($iIDFrom, $aShowdata2);如果存在$hEdit控件,则结束编辑
  189.                 Case $NM_CLICK;单击
  190.                     If IsHWnd($hEdit) Then _EndItemEdit($iIDFrom, $aShowdata2)
  191.                     _chkboxState($iIDFrom, $ilParam, $aShowdata2)
  192.                 Case $NM_DBLCLK ; 双击
  193.                     _StartItemEdit($iIDFrom, $ilParam, $aShowdata2)
  194.             EndSwitch
  195.         Case $hListView3
  196.             Switch $iCode
  197.                 Case -150, -177 ;$LVN_GETDISPINFOA = -150, $LVN_GETDISPINFOW = -177   请求显示数据
  198.                     _LVN_GETDISPINFO($iIDFrom, $ilParam, $aShowdata3)
  199.                 Case $LVN_COLUMNCLICK ; 点击列头排序
  200.                     _SortItems($iIDFrom, $ilParam, $aShowdata3)
  201.                 Case $NM_CUSTOMDRAW;自绘消息  处理选中行背景色
  202.                     Local $tCustDraw = DllStructCreate("hwnd hwndFrom;int idFrom;int code;dword DrawStage;hwnd hdc;long rect[4];dword ItemSpec;int ItemState;dword Itemlparam;dword clrText;dword clrTextBk;int SubItem; dword ItemType;dword clrFace;int IconEffect;int IconPhase;int PartID;int StateID;long rectText[4];int Align", $ilParam)
  203.                     Local $iDrawStage = DllStructGetData($tCustDraw, "DrawStage")
  204.                     If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW ;request custom drawing of items
  205.                     If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW ;request drawing each cell separately
  206.                     If Not BitAND($iDrawStage, $CDDS_SUBITEM) Then Return $CDRF_DODEFAULT
  207.                     _SetchkedBkClr($tCustDraw, $aShowdata3, 0xD307AD, 0xE3F7ED)
  208.                     Return $CDRF_NEWFONT
  209.                 Case $LVN_ITEMCHANGED ; An item has changed
  210.                     _CtrlSel($iIDFrom, $ilParam, $aShowdata3)
  211.                 Case $LVN_BEGINSCROLL ; 滚动事件开始
  212.                     If IsHWnd($hEdit) Then _EndItemEdit($iIDFrom, $aShowdata3);如果存在$hEdit控件,则结束编辑
  213.                 Case $NM_CLICK;单击
  214.                     If IsHWnd($hEdit) Then _EndItemEdit($iIDFrom, $aShowdata3)
  215.                     _chkboxState($iIDFrom, $ilParam, $aShowdata3)
  216.                 Case $NM_DBLCLK ; 双击
  217.                     _StartItemEdit($iIDFrom, $ilParam, $aShowdata3)
  218.             EndSwitch
  219.     EndSwitch
  220.     Return $GUI_RUNDEFMSG
  221. EndFunc

  222. Func WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
  223.     $iIDFrom = _WinAPI_LoWord($wParam)
  224.     $iCode = _WinAPI_HiWord($wParam)
  225.     Switch $lParam
  226.         Case $hEdit
  227.             Switch $iCode
  228.                 Case $EN_KILLFOCUS;编辑框失去焦点,结束编辑
  229.                     Switch $hActLst
  230.                         Case $hListView
  231.                             _EndItemEdit($hListView, $aShowdata)
  232.                         Case $hListView2
  233.                             _EndItemEdit($hListView2, $aShowdata2)
  234.                         Case $hListView3
  235.                             _EndItemEdit($hListView3, $aShowdata3)
  236.                     EndSwitch
  237.                 Case $EN_UPDATE

  238.             EndSwitch
  239.         Case $hEnter;虚拟控件消息触发  收到回车消息才触发
  240.             If IsHWnd($hEdit) Then
  241.                 If $SubItem = 0 Then
  242.                     __ClickListViewItem($hActLst, $Item, True);使用点击来结束编辑,省去判断listview的数据数组
  243.                 Else
  244.                     __ClickListViewItem($hActLst, $Item)
  245.                 EndIf
  246.             EndIf
  247.     EndSwitch
  248.     Return $GUI_RUNDEFMSG
  249. EndFunc

  250. Func _SetchkedBkClr(ByRef $tCustDraw, ByRef $aDataArray, $ihighBkClr = 0xF7D3AD, $idefBkclr = 0xFFFFFF)
  251.     Local $iIndex = DllStructGetData($tCustDraw, "ItemSpec")
  252.     If $aDataArray[$iIndex][3] = 4096 Then
  253.         DllStructSetData($tCustDraw, "clrTextBk", $idefBkclr);BGR格式颜色值 默认背景色
  254.     Else
  255.         DllStructSetData($tCustDraw, "clrTextBk", $ihighBkClr);BGR格式颜色值 高亮背景色
  256.     EndIf
  257. EndFunc

  258. Func _chkboxState($hlst, $ilParam, ByRef $aDataArray);刷新复选框状态
  259.     $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
  260.     $iIndex = DllStructGetData($tInfo, "Index")
  261.     $x = DllStructGetData($tInfo, "X")
  262.     If ($x < 16) And (3 < $x) And (BitAND(_GUICtrlListView_GetExtendedListViewStyle($hlst), $LVS_EX_CHECKBOXES) = $LVS_EX_CHECKBOXES) Then;使用点击的x坐标来判断是否在复选框上点击
  263.         If $aDataArray[$iIndex][3] = 4096 Then
  264.             $ichked+=1
  265.             $aDataArray[$iIndex][3] = 8192;4096未选中 8192选中
  266.         Else
  267.             $ichked-=1
  268.             $aDataArray[$iIndex][3] = 4096;4096未选中 8192选中
  269.         EndIf
  270.         ;====立刻刷新复选框显示状态 重绘$iIndex项
  271.         GUICtrlSendMsg($hlst, $LVM_REDRAWITEMS, $iIndex, $iIndex)
  272.     EndIf   
  273. EndFunc

  274. Func _SortItems($hlst, $ilParam, ByRef $aDataArray);排序
  275.     $tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)
  276.     $iSub = DllStructGetData($tInfo, "SubItem")
  277.     _ArraySort($aDataArray, $B_DESCENDING[$iSub], 0, 0, $iSub)
  278.     GUICtrlSendMsg($hlst, $LVM_REDRAWITEMS, 0, 20)
  279.     $B_DESCENDING[$iSub] = Not $B_DESCENDING[$iSub]
  280. EndFunc

  281. Func _CtrlSel($hlst, $ilParam, ByRef $aDataArray);按住ctrl键点选item
  282.     If $bCtrlDown Then;ctrl键按下
  283.         $tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)
  284.         Local $iIndex = DllStructGetData($tInfo, "Item")
  285.         Local $iNewState = DllStructGetData($tInfo, "NewState")
  286.         If $iIndex > -1 And $iNewState = BitOR($LVIS_FOCUSED, $LVIS_SELECTED) Then
  287.             If $aDataArray[$iIndex][3] = 4096 Then
  288.                 $ichked+=1
  289.                 $aDataArray[$iIndex][3] = 8192;4096未选中 8192选中
  290.             Else
  291.                 $ichked-=1
  292.                 $aDataArray[$iIndex][3] = 4096;4096未选中 8192选中
  293.             EndIf
  294.             $tInfo = DllStructCreate($tagNMLVDISPINFO, $ilParam)
  295.             DllStructSetData($tInfo, "State", $aDataArray[$iIndex][3]);设置复选框状态
  296.             ;====立刻刷新复选框显示状态 重绘$iIndex项
  297.             GUICtrlSendMsg($hlst, $LVM_REDRAWITEMS, $iIndex, $iIndex)
  298.         EndIf
  299.     EndIf
  300. EndFunc

  301. Func _LVN_GETDISPINFO($hlst, $ilParam, ByRef $aDataArray)
  302.     If Not IsArray($aDataArray) Then Return
  303.     $tInfo = DllStructCreate($tagNMLVDISPINFO, $ilParam)
  304.     $iIndex = Int(DllStructGetData($tInfo, "Item"))
  305.     $iSub = Int(DllStructGetData($tInfo, "SubItem"))

  306.     If BitAND(DllStructGetData($tInfo, "Mask"), $LVIF_IMAGE) And $iSub = 0 Then DllStructSetData($tInfo, "Image", 0);判断是否有LVIF_IMAGE属性,有则设置列图像。不设置_GUICtrlListView_SetImageList则无

  307.     If (BitAND(_GUICtrlListView_GetExtendedListViewStyle($hlst), $LVS_EX_CHECKBOXES) = $LVS_EX_CHECKBOXES) Then
  308.         ;===============设置复选框信息
  309.         DllStructSetData($tInfo, "Mask", BitOR($LVIF_STATE, DllStructGetData($tInfo, "Mask")))
  310.         DllStructSetData($tInfo, "StateMask", $LVIS_STATEIMAGEMASK)
  311.         DllStructSetData($tInfo, "State", $aDataArray[$iIndex][3])
  312.     EndIf

  313.     DllStructSetData($tText, "Text", $aDataArray[$iIndex][$iSub]);列数据放入$tText结构
  314.     DllStructSetData($tInfo, "Text", DllStructGetPtr($tText));$tText结构的指针来设置列数据
  315.     DllStructSetData($tInfo, "TextMax", StringLen($aDataArray[$iIndex][$iSub]));设置列数据字串长
  316. EndFunc

  317. Func _StartItemEdit($hlst, $ilParam, ByRef $aDataArray)
  318.     $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
  319.     $iIndex = DllStructGetData($tInfo, "Index")
  320.     $iSub = DllStructGetData($tInfo, "SubItem")
  321.     $x = DllStructGetData($tInfo, "X")
  322.     If ($iIndex <> -1) And ($iSub >= 0) And ($x > 16) Then;点击的x>16才响应原地编辑
  323.         $hActLst = $hlst
  324.         If _GUICtrlListView_EnsureVisible($hlst, $iIndex) Then GUICtrlSendMsg($hlst, $LVM_REDRAWITEMS, $iIndex, $iIndex + 1);确保列表视图项目可见
  325.         Local $alstPos = ControlGetPos($hGUI, "", $hlst)
  326.         $Item = $iIndex
  327.         $SubItem = $iSub
  328.         ;==========计算编辑框坐标
  329.         Local $aRect = _GUICtrlListView_GetSubItemRect($hlst, $iIndex, $iSub)
  330.         Local $iEdit_X = $aRect[0] + $alstPos[0] + 4
  331.         Local $iEdit_Y = $aRect[1] + $alstPos[1] + 3
  332.         Local $iEdit_Width = _GUICtrlListView_GetColumnWidth($hlst, $iSub) - 1
  333.         Local $iEdit_Height = $aRect[3] - $aRect[1]
  334.         If $iSub = 0 Then
  335.             Local $i1 = 0, $i2 = 0
  336.             If (BitAND(_GUICtrlListView_GetExtendedListViewStyle($hlst), $LVS_EX_CHECKBOXES) = $LVS_EX_CHECKBOXES) Then $i1 = 17;判断是否有复选框
  337.             If _GUICtrlListView_GetImageList($hlst, 1) Then $i2 = 19;判断是否有分配图像列表到列表视图控件
  338.             $iEdit_X += ($i2 + $i1)
  339.             $iEdit_Width -= ($i2 + $i1)
  340.         EndIf
  341.         Local $iEdit = GUICtrlCreateInput($aDataArray[$iIndex][$iSub], $iEdit_X, $iEdit_Y, $iEdit_Width, $iEdit_Height, BitOR($WS_CHILD, $WS_VISIBLE, $ES_LEFT))
  342.         GUICtrlSetFont($iEdit, 11)
  343.         GUICtrlSetState($iEdit, $GUI_FOCUS)
  344.         $hEdit = GUICtrlGetHandle($iEdit)
  345.         _WinAPI_BringWindowToTop($hEdit)
  346.         _GUICtrlEdit_SetSel($hEdit, 0, -1) ;全选编辑框文字
  347.         Local $iEnter = GUICtrlCreateDummy()
  348.         $hEnter = GUICtrlGetHandle($iEnter)
  349.         GUISetAccelerators($aAccelKeys, $hGUI);在虚拟控件上绑定一个回车快捷按键
  350.     EndIf   
  351. EndFunc

  352. Func _EndItemEdit($hlst, ByRef $aDataArray)
  353.     If ($Item < UBound($aDataArray, 1)) And ($SubItem < UBound($aDataArray, 2)) And ($hActLst == $hlst) Then
  354.         Local $sText = _GUICtrlEdit_GetText($hEdit)
  355.         _GUICtrlListView_SetItemText($hlst, $Item, $sText, $SubItem)
  356.         If IsHWnd($hEdit) Then _WinAPI_DestroyWindow($hEdit)
  357.         If IsHWnd($hEnter) Then _WinAPI_DestroyWindow($hEnter)
  358.         $hEnter = Null
  359.         $hEdit = Null
  360.         If ($Item >= 0) Then $aDataArray[$Item][$SubItem] = $sText
  361.         $Item = -1
  362.         $SubItem = 0
  363.     EndIf
  364. EndFunc

  365. Func _GetChkIndex($iChkState)
  366.     Local $aIndex[1] = [-1], $j = 0
  367.     If $ichked = 0 Then Return $aIndex
  368.     If $iChkState = 8192 Then
  369.         ReDim $aIndex[$ichked]
  370.     Else
  371.         ReDim $aIndex[UBound($aShowdata)-$ichked]
  372.     EndIf
  373.     For $i = 0 To UBound($aShowdata) -1
  374.         If $aShowdata[$i][3] == $iChkState Then
  375.             $aIndex[$j] = $i
  376.             $j+=1
  377.         EndIf
  378.     Next
  379.     Return $aIndex
  380. EndFunc

  381. Func __ClickListViewItem($hWnd, $iIndex, $baddX = False)
  382.     If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)

  383.     Local $tRECT = _GUICtrlListView_GetItemRectEx($hWnd, $iIndex, $LVIR_LABEL)
  384.     Local $tPoint = _WinAPI_PointFromRect($tRECT, True)
  385.     $tPoint = _WinAPI_ClientToScreen($hWnd, $tPoint)
  386.     Local $iX, $iY
  387.     _WinAPI_GetXYFromPoint($tPoint, $iX, $iY)
  388.     If $baddX Then $iX += DllStructGetData($tRECT, "Right")
  389.     Local $iMode = Opt("MouseCoordMode", 1)
  390.     Local $aPos = MouseGetPos()
  391.     MouseClick("left", $iX, $iY, 1, 0)
  392.     MouseMove($aPos[0], $aPos[1], 0)
  393.     Opt("MouseCoordMode", $iMode)
  394. EndFunc
复制代码
发表于 2015-11-10 14:15:40 | 显示全部楼层
谢谢分享,正需要者呢
发表于 2015-11-11 09:09:46 | 显示全部楼层
感谢分享源码,新手下载学习。
发表于 2015-11-14 06:26:42 | 显示全部楼层
看看~~~~~~~~~
发表于 2015-11-16 15:50:42 | 显示全部楼层
学习学习
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|小黑屋|手机版|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2019-5-22 02:02 , Processed in 0.062500 second(s), 13 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

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