kk_lee69
发表于 2015-10-31 22:30:58
回复 59# chzj589
chzj589兄
手上有 INPUT 框 重繪 相關的消息範例嗎??
298311657
发表于 2015-11-1 22:27:47
回复 58# kk_lee69
你的这个问题,可以试试这份代码
#cs ______________________
Au3 版本: 3.3.14.2
脚本作?? CrossDoor
电子邮件: 382869232@qq.com
QQ/TM: 382869232
#ce _______________脚本开始_________________
#PRE_UseX64=n
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiImageList.au3>
#include <WinAPITheme.au3>
#include <GuiListView.au3>
#include <WinAPISys.au3>
#include <WinAPI.au3>
#include <GuiEdit.au3>
#include <array.au3>
#include <Misc.au3>
Global $B_DESCENDING ; 排序用数组
Global $bCtrlDown = False;listview控件ctrl键按下标识
Global $hEdit, $Item = -1, $SubItem = 0
Global $hEditForm, $hEnter, $aAccelKeys = [["{ENTER}", $hEnter]];虚拟控件的句柄和绑定的快捷键
Local $hUser32 = DllOpen("user32.dll")
Local $ichked = 0;勾选的行数
Local $tText = DllStructCreate("wchar Text");建个结构,用来放listview列数据
Local $GUI, $hImage
Local $iITEM_COUNT = 94304, $aShowdata[$iITEM_COUNT];注意数组最大项目数为2^24(16777216),所以$iITEM_COUNT = 4194304为二维数组$aShowdata最大行数
Local $sSomeString = ""
GUIRegisterMsg($WM_KEYDOWN, "WM_KEYDOWN")
GUIRegisterMsg($WM_KEYUP, "WM_KEYUP")
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
$hGUI = GUICreate("ListView虚表 加载[" & UBound($aShowdata) & "]数据 复选框 原地编辑例子 By_Crossdoor", 500, 350)
$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)
;~ _WinAPI_SetWindowTheme(GUICtrlGetHandle($hListView), 'Explorer');设置主题
;设置列宽
GUICtrlSendMsg($hListView, $LVM_SETCOLUMNWIDTH, 0, 150)
GUICtrlSendMsg($hListView, $LVM_SETCOLUMNWIDTH, 1, 150)
GUICtrlSendMsg($hListView, $LVM_SETCOLUMNWIDTH, 2, 150)
GUICtrlSendMsg($hListView, $LVM_SETITEMCOUNT, $iITEM_COUNT, 0);设定数据总数
;===========创建并关联图像列表
$hImage = _GUIImageList_Create()
_GUIImageList_AddIcon($hImage, @SystemDir & "\shell32.dll", 110)
_GUICtrlListView_SetImageList($hListView, $hImage, 1);分配图像列表到列表视图控件
$Button1 = GUICtrlCreateButton("选中行", 20, 310, 75, 25)
$Button2 = GUICtrlCreateButton("未选行", 100, 310, 75, 25)
$Button3 = GUICtrlCreateButton("修改", 180, 310, 75, 25)
$Button4 = GUICtrlCreateButton("清空", 260, 310, 75, 25)
GUISetState()
;==================在窗体显示后再初始化数据,因为初始化数组数据比较慢
;如果先初始化数组后显示窗口,会卡很久,就造成虚表也很慢的假象
For $i = 0 To $iITEM_COUNT - 1
;重绘 刷新 listview 0-13行(让ListView显示数组数据),不用太多行,只需要一屏的行数就就可以
;因为下拉滚动的时候listview会收到LVN_GETDISPINFO消息,这个消息我们在WM_NOTIFY内处理过了
If $i = 18 Then GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 0, $i)
$aShowdata[$i] = "爷爷" & $i
$aShowdata[$i] = "爸爸" & $i
$aShowdata[$i] = "儿子" & $i
$aShowdata[$i] = 4096;复选框状态4096未选中 8192选中
Next
While 1
$bCtrlDown = _IsPressed("11", $hUser32);取ctrl按键的状态
Switch GUIGetMsg()
Case -3
ExitLoop
Case $Button1
$aShowdata = 8192
$aShowdata = 8192
GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 3, 7)
;~ $a = _GetChkIndex(8192)
;~ If $a = -1 Then
;~ MsgBox(32, "提示", "未勾选任何数据")
;~ Else
;~ _ArrayDisplay($a, "勾选行的索引");数组很大时,_ArrayDisplay会非常耗时
;~ EndIf
Case $Button2
$a = _GetChkIndex(4096)
If $a = -1 Then
MsgBox(32, "提示", "数据全都被勾选了。")
Else
;MsgBox(32, "提示", "未勾选的数据有" & UBound($a) & "行")
_ArrayDisplay($a, "未勾选行的索");数组很大时,_ArrayDisplay会非常耗时
EndIf
Case $Button3
If StringLen($sSomeString) Then
$sSomeString = ""
Else
$sSomeString = Asc(Random(48, 255, 1))
EndIf
For $i = 0 To $iITEM_COUNT - 1
$aShowdata[$i] = "爷爷" & $i & "-" & $sSomeString
$aShowdata[$i] = "爸爸" & $i & "-" & $sSomeString
$aShowdata[$i] = "儿子" & $i & "-" & $sSomeString
Next
GUICtrlSendMsg($hListView, $LVM_ENSUREVISIBLE, 1, 0)
GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 0, 20)
Case $Button4
$aShowdata = 0
$iITEM_COUNT = 0
GUICtrlSendMsg($hListView, $LVM_SETITEMCOUNT, $iITEM_COUNT, 0)
GUICtrlSendMsg($hListView, $LVM_ENSUREVISIBLE, 1, 0)
GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 0, 20)
EndSwitch
WEnd
GUIDelete()
DllClose($hUser32)
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
#forceref $hWnd, $iMsg, $iwParam
Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $tInfo
$tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
$hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
$iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
$iCode = DllStructGetData($tNMHDR, "Code")
Local $iIndex = DllStructGetData($tNMHDR, 'Index')
Switch $iIDFrom
Case $hListView
Switch $iCode
Case $LVN_COLUMNCLICK ; 点击列头排序
$tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)
$iSub = DllStructGetData($tInfo, "SubItem")
_ArraySort($aShowdata, $B_DESCENDING[$iSub], 0, 0, $iSub)
GUICtrlSendMsg($hListView, $LVM_ENSUREVISIBLE, 1, 0)
GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 0, 20)
$B_DESCENDING[$iSub] = Not $B_DESCENDING[$iSub]
Case $NM_CUSTOMDRAW;自绘消息处理选中行背景色
Local $tCustDraw = DllStructCreate('hwnd hwndFrom;int idFrom;int code;dword DrawStage;hwnd hdc;long rect;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;int Align', $ilParam)
Local $iDrawStage = DllStructGetData($tCustDraw, 'DrawStage')
If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW ;request custom drawing of items
If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW ;request drawing each cell separately
If Not BitAND($iDrawStage, $CDDS_SUBITEM) Then Return $CDRF_DODEFAULT
$iIndex = DllStructGetData($tCustDraw, 'ItemSpec')
If $aShowdata[$iIndex] = 4096 Then
DllStructSetData($tCustDraw, 'clrTextBk', 0xFFFFFF);BGR格式颜色值
Else
DllStructSetData($tCustDraw, 'clrTextBk', 0xF7D3AD);BGR格式颜色值
EndIf
Return $CDRF_NEWFONT
Case $LVN_ITEMCHANGED ; An item has changed
If $bCtrlDown Then;ctrl键按下
$tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)
Local $iIndex = DllStructGetData($tInfo, "Item")
Local $iNewState = DllStructGetData($tInfo, "NewState")
If $iIndex > -1 And $iNewState = BitOR($LVIS_FOCUSED, $LVIS_SELECTED) Then
If $aShowdata[$iIndex] = 4096 Then
$ichked+=1
$aShowdata[$iIndex] = 8192;4096未选中 8192选中
Else
$ichked-=1
$aShowdata[$iIndex] = 4096;4096未选中 8192选中
EndIf
$tInfo = DllStructCreate($tagNMLVDISPINFO, $ilParam)
DllStructSetData($tInfo, "State", $aShowdata[$iIndex]);设置复选框状态
;====立刻刷新复选框显示状态 重绘$iIndex-1到iIndex+20的项
GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, $iIndex - 1, $iIndex + 20)
EndIf
EndIf
Case $LVN_BEGINSCROLL ; 滚动事件开始
If IsHWnd($hEdit) Then _EndItemEdit();如果存在$hEdit控件,则结束编辑
;~ $tInfo = DllStructCreate($tagNMLVSCROLL, $ilParam)
;~ ToolTip("$LVN_BEGINSCROLL" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _
;~ "-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _
;~ "-->Code:" & @TAB & $iCode & @CRLF & _
;~ "-->DX:" & @TAB & DllStructGetData($tInfo, "DX") & @CRLF & _
;~ "-->DY:" & @TAB & DllStructGetData($tInfo, "DY"))
; ; No return value
Case $NM_CLICK;单击
If IsHWnd($hEdit) Then _EndItemEdit()
$tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
$iIndex = DllStructGetData($tInfo, "Index")
$x = DllStructGetData($tInfo, "X")
If ($x < 16) And (3 < $x) And (BitAND(_GUICtrlListView_GetExtendedListViewStyle($hListView), $LVS_EX_CHECKBOXES) = $LVS_EX_CHECKBOXES) Then;使用点击的x坐标来判断是否在复选框上点击
If $aShowdata[$iIndex] = 4096 Then
$ichked+=1
$aShowdata[$iIndex] = 8192;4096未选中 8192选中
Else
$ichked-=1
$aShowdata[$iIndex] = 4096;4096未选中 8192选中
EndIf
;====立刻刷新复选框显示状态 重绘$iIndex-1至iIndex+20的项
GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, $iIndex - 1, $iIndex + 20)
EndIf
Case $NM_DBLCLK ; 双击
$tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
$iIndex = DllStructGetData($tInfo, "Index")
$iSub = DllStructGetData($tInfo, "SubItem")
$x = DllStructGetData($tInfo, "X")
If ($iIndex <> -1) And ($iSub >= 0) And ($x > 16) Then;点击的x>16才响应原地编辑
Local $aformPos = WinGetPos($hGUI)
Local $SM_CYCAPTION = 4
Local $iCaptionH = _WinAPI_GetSystemMetrics($SM_CYCAPTION);获取以像素计算的普通窗口标题的高度
$Item = $iIndex
$SubItem = $iSub
;==========计算编辑框坐标
Local $aRect = _GUICtrlListView_GetSubItemRect($hListView, $iIndex, $iSub)
Local $iEdit_X = $aRect + 8 + $aformPos
Local $iEdit_Y = $aRect + 7 + $aformPos + $iCaptionH
Local $iEdit_Width = _GUICtrlListView_GetColumnWidth($hListView, $iSub)
Local $iEdit_Height = $aRect - $aRect
If $iSub = 0 Then
Local $i1 = 0, $i2 = 0
If (BitAND(_GUICtrlListView_GetExtendedListViewStyle($hListView), $LVS_EX_CHECKBOXES) = $LVS_EX_CHECKBOXES) Then $i1 = 18;判断是否有复选框
If _GUICtrlListView_GetImageList($hListView, 1) Then $i2 = 20;判断是否有分配图像列表到列表视图控件
$iEdit_X += ($i2 + $i1)
$iEdit_Width -= ($i2 + $i1)
EndIf
$hEditForm = GUICreate("", $iEdit_Width, $iEdit_Height, $iEdit_X, $iEdit_Y, $WS_POPUP, -1, $hGUI);创建一个子窗口用于装载input控件
Local $iEdit = GUICtrlCreateInput($aShowdata[$iIndex][$iSub], 0, 0, $iEdit_Width, $iEdit_Height, BitOR($WS_CHILD, $WS_VISIBLE, $ES_LEFT))
GUICtrlSetFont($iEdit, 12)
GUICtrlSetState($iEdit, $GUI_FOCUS)
$hEdit = GUICtrlGetHandle($iEdit)
_GUICtrlEdit_SetSel($hEdit, 0, -1) ;全选编辑框文字
Local $iEnter = GUICtrlCreateDummy()
$hEnter = GUICtrlGetHandle($iEnter)
GUISetAccelerators($aAccelKeys, $hWnd);在虚拟控件上绑定一个回车快捷按键
GUISetState(@SW_SHOW, $hEditForm)
EndIf
Case -150, -177 ;$LVN_GETDISPINFOA = -150, $LVN_GETDISPINFOW = -177 请求显示数据
If Not IsArray($aShowdata) Then ContinueCase
$tInfo = DllStructCreate($tagNMLVDISPINFO, $ilParam)
$iIndex = Int(DllStructGetData($tInfo, "Item"))
$iSub = Int(DllStructGetData($tInfo, "SubItem"))
If BitAND(DllStructGetData($tInfo, "Mask"), $LVIF_IMAGE) And $iSub = 0 Then DllStructSetData($tInfo, "Image", 0);判断是否有LVIF_IMAGE属性,有则设置列图像。不设置_GUICtrlListView_SetImageList则无
If (BitAND(_GUICtrlListView_GetExtendedListViewStyle($hListView), $LVS_EX_CHECKBOXES) = $LVS_EX_CHECKBOXES) Then
;===============设置复选框信息
DllStructSetData($tInfo, "Mask", BitOR($LVIF_STATE, DllStructGetData($tInfo, "Mask")))
DllStructSetData($tInfo, "StateMask", $LVIS_STATEIMAGEMASK)
DllStructSetData($tInfo, "State", $aShowdata[$iIndex])
EndIf
DllStructSetData($tText, "Text", $aShowdata[$iIndex][$iSub]);列数据放入$tText结构
DllStructSetData($tInfo, "Text", DllStructGetPtr($tText));$tText结构的指针来设置列数据
DllStructSetData($tInfo, "TextMax", StringLen($aShowdata[$iIndex][$iSub]));设置列数据字串长
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_NOTIFY
Func WM_KEYDOWN($hWnd, $iMsg, $wParam, $lParam)
If $wParam = 27 Then $bCtrlDown = True
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_KEYDOWN
Func WM_KEYUP($hWnd, $iMsg, $wParam, $lParam)
If $wParam = 27 Then $bCtrlDown = False
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_KEYUP
Func WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
$iIDFrom = _WinAPI_LoWord($wParam)
$iCode = _WinAPI_HiWord($wParam)
Switch $lParam
Case $hEdit
Switch $iCode
Case $EN_KILLFOCUS
Case $EN_UPDATE
EndSwitch
Case $hEnter;虚拟控件消息触发收到回车消息才触发
If IsHWnd($hEdit) Then
_EndItemEdit()
EndIf
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_COMMAND
Func _EndItemEdit()
If ($Item < UBound($aShowdata, 1)) And ($SubItem < UBound($aShowdata, 2)) Then
Local $sText = _GUICtrlEdit_GetText($hEdit)
_GUICtrlListView_SetItemText($hListView, $Item, $sText, $SubItem)
If IsHWnd($hEdit) Then _WinAPI_DestroyWindow($hEdit)
If IsHWnd($hEnter) Then _WinAPI_DestroyWindow($hEnter)
If IsHWnd($hEditForm) Then GUIDelete($hEditForm)
$hEditForm = Null
$hEnter = Null
$hEdit = Null
If ($Item >= 0) Then
$aShowdata[$Item][$SubItem] = $sText
GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 0, 20)
EndIf
$Item = -1
$SubItem = 0
EndIf
EndFunc ;==>_EndItemEdit
Func _GetChkIndex($iChkState)
Local $aIndex = [-1], $j = 0
If $ichked = 0 Then Return $aIndex
If $iChkState = 8192 Then
ReDim $aIndex[$ichked]
Else
ReDim $aIndex
EndIf
For $i = 0 To UBound($aShowdata) -1
If $aShowdata[$i] == $iChkState Then
$aIndex[$j] = $i
$j+=1
EndIf
Next
Return $aIndex
EndFunc
kk_lee69
发表于 2015-11-1 23:54:15
回复 62# 298311657
OK 老大 太感謝您了 ~~
原來再多加一個透明的 $hEditForm就可以解決掉 很多殘影了問題
太感謝了~~~
kk_lee69
发表于 2015-11-2 01:23:02
回复 62# 298311657
老大 有個地方搞不懂 還真的有點怪
新舊方法 在計算 INPUT框 位置的時候有問題
原本的範例裡面 沒有考慮進去 如果 LISTVIEW 的位置 不是從最上面開始的話
所以 我後來改了計算法法
OK 了
改成 新版的 方式 可是框的位置不對了
程式沒變動到但是位置 不對了 我不知道是何原因
計算位置的算法如下
;==========計算編輯方塊座標
Local $aPos = ControlGetPos("", "", $hVListView);獲取Listview座標
Local $aRect = _GUICtrlListView_GetSubItemRect($hVListView, $Item, $SubItem)
Local $iEdit_X = $aRect+$aPos + 4
Local $iEdit_Y = $aRect+$aPos + 3
Local $iEdit_Width = _GUICtrlListView_GetColumnWidth($hVListView, $SubItem) ;+ 3
Local $iEdit_Height = $aRect - $aRect; + 3
If $SubItem = 0 Then
Local $i1 = 0, $i2 = 0
If (BitAND(_GUICtrlListView_GetExtendedListViewStyle($hVListView), $LVS_EX_CHECKBOXES) = $LVS_EX_CHECKBOXES) Then $i1 = 18;判斷是否有核取方塊
If _GUICtrlListView_GetImageList($hVListView, 1) Then $i2 = $hImageX;判斷是否有分配圖像清單到清單視圖控制項
$iEdit_X += ($i2 + $i1)
$iEdit_Width -= ($i2 + $i1)
EndIf
;新版程式的寫法
$hEditForm = GUICreate("", $iEdit_Width, $iEdit_Height, $iEdit_X, $iEdit_Y, $WS_POPUP, -1, $WinMain);創建一個子視窗用於裝載input控制項
$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 )
;舊版程式的寫法
$hEdit = GUICtrlCreateInput( $aShowdata2[$Item][$SubItem], $iEdit_X, $iEdit_Y, $iEdit_Width, $iEdit_Height );,$ES_RIGHT 右對齊
kk_lee69
发表于 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
這樣一個一個寫
所以 想請教 您在實際應用上 有更好的簡便寫法 可學習嗎??
雨林GG
发表于 2015-11-2 08:13:56
谢谢LZ分享~!
298311657
发表于 2015-11-2 21:57:48
本帖最后由 298311657 于 2015-11-3 13:43 编辑
回复 65# kk_lee69
对数据进行判断并没有简洁的写法,因为不同的数据对应不同的处理方法。
UDF只是把可以重复的代码打包成函数,以便调用。数据判断显然不是可以重复的代码,每一个数据都是独立的。
比如我们可以把listview请求数据显示部分写成函数:
Func _LVN_GETDISPINFO($hlst, $ilParam, ByRef $aDataArray)
If Not IsArray($aDataArray) Then Return
$tInfo = DllStructCreate($tagNMLVDISPINFO, $ilParam)
$iIndex = Int(DllStructGetData($tInfo, "Item"))
$iSub = Int(DllStructGetData($tInfo, "SubItem"))
If BitAND(DllStructGetData($tInfo, "Mask"), $LVIF_IMAGE) And $iSub = 0 Then DllStructSetData($tInfo, "Image", 0);判断是否有LVIF_IMAGE属性,有则设置列图像。不设置_GUICtrlListView_SetImageList则无
If (BitAND(_GUICtrlListView_GetExtendedListViewStyle($hlst), $LVS_EX_CHECKBOXES) = $LVS_EX_CHECKBOXES) Then
;===============设置复选框信息
DllStructSetData($tInfo, "Mask", BitOR($LVIF_STATE, DllStructGetData($tInfo, "Mask")))
DllStructSetData($tInfo, "StateMask", $LVIS_STATEIMAGEMASK)
DllStructSetData($tInfo, "State", $aDataArray[$iIndex])
EndIf
DllStructSetData($tText, "Text", $aDataArray[$iIndex][$iSub]);列数据放入$tText结构
DllStructSetData($tInfo, "Text", DllStructGetPtr($tText));$tText结构的指针来设置列数据
DllStructSetData($tInfo, "TextMax", StringLen($aDataArray[$iIndex][$iSub]));设置列数据字串长
EndFunc
然后再调用:
Case -150, -177 ;$LVN_GETDISPINFOA = -150, $LVN_GETDISPINFOW = -177 请求显示数据
_LVN_GETDISPINFO($iIDFrom, $ilParam, $aShowdata3)
这是一份完整的代码,我在这里使用了3个listview控件:
#cs ______________________
Au3 版本: 3.3.14.2
脚本作?? CrossDoor
电子邮件: 382869232@qq.com
QQ/TM: 382869232
#ce _______________脚本开始_________________
#PRE_UseX64=n
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiImageList.au3>
#include <WinAPITheme.au3>
#include <GuiListView.au3>
#include <WinAPISys.au3>
#include <WinAPI.au3>
#include <GuiEdit.au3>
#include <array.au3>
#include <Misc.au3>
Global $B_DESCENDING ; 排序用数组
Global $hActLst
Global $bCtrlDown = False;listview控件ctrl键按下标识
Global $hEdit, $Item = -1, $SubItem = 0
Global $hEnter, $aAccelKeys = [["{ENTER}", $hEnter]];虚拟控件的句柄和绑定的快捷键
Local $hUser32 = DllOpen("user32.dll")
Local $ichked = 0;勾选的行数
Local $tText = DllStructCreate("wchar Text");建个结构,用来放listview列数据
Local $GUI, $hImage
Local $iITEM_COUNT = 1000, $aShowdata[$iITEM_COUNT], $aShowdata2[$iITEM_COUNT], $aShowdata3[$iITEM_COUNT];注意数组最大项目数为2^24(16777216),所以$iITEM_COUNT = 4194304为二维数组$aShowdata最大行数
Local $sSomeString = ""
Local $hGUI, $hListView, $hListView2, $hListView3
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
$hGUI = GUICreate("ListView虚表 加载[" & UBound($aShowdata) & "]数据 复选框 原地编辑例子 By_Crossdoor", 600, 605)
$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)
;~ _WinAPI_SetWindowTheme(GUICtrlGetHandle($hListView), "Explorer");设置主题
;设置列宽
GUICtrlSendMsg($hListView, $LVM_SETCOLUMNWIDTH, 0, 110)
GUICtrlSendMsg($hListView, $LVM_SETCOLUMNWIDTH, 1, 80)
GUICtrlSendMsg($hListView, $LVM_SETCOLUMNWIDTH, 2, 80)
GUICtrlSendMsg($hListView, $LVM_SETITEMCOUNT, $iITEM_COUNT, 0);设定数据总数
$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)
;~ _WinAPI_SetWindowTheme(GUICtrlGetHandle($hListView), "Explorer");设置主题
;设置列宽
GUICtrlSendMsg($hListView2, $LVM_SETCOLUMNWIDTH, 0, 110)
GUICtrlSendMsg($hListView2, $LVM_SETCOLUMNWIDTH, 1, 80)
GUICtrlSendMsg($hListView2, $LVM_SETCOLUMNWIDTH, 2, 80)
GUICtrlSendMsg($hListView2, $LVM_SETITEMCOUNT, $iITEM_COUNT, 0);设定数据总数
$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)
;~ _WinAPI_SetWindowTheme(GUICtrlGetHandle($hListView), "Explorer");设置主题
;设置列宽
GUICtrlSendMsg($hListView3, $LVM_SETCOLUMNWIDTH, 0, 110)
GUICtrlSendMsg($hListView3, $LVM_SETCOLUMNWIDTH, 1, 80)
GUICtrlSendMsg($hListView3, $LVM_SETCOLUMNWIDTH, 2, 80)
GUICtrlSendMsg($hListView3, $LVM_SETITEMCOUNT, $iITEM_COUNT, 0);设定数据总数
;===========创建并关联图像列表
$hImage = _GUIImageList_Create()
_GUIImageList_AddIcon($hImage, @SystemDir & "\shell32.dll", 110)
_GUICtrlListView_SetImageList($hListView, $hImage, 1);分配图像列表到列表视图控件$hListView
_GUICtrlListView_SetImageList($hListView2, $hImage, 1);分配图像列表到列表视图控件$hListView2
$Button1 = GUICtrlCreateButton("选中行", 10, 310, 70, 25)
$Button2 = GUICtrlCreateButton("未选行", 80, 310, 70, 25)
$Button3 = GUICtrlCreateButton("修改", 150, 310, 70, 25)
$Button4 = GUICtrlCreateButton("清空", 220, 310, 70, 25)
GUISetState()
;==================在窗体显示后再初始化数据,因为初始化数组数据比较慢
;如果先初始化数组后显示窗口,会卡很久,就造成虚表也很慢的假象
For $i = 0 To $iITEM_COUNT - 1
;重绘 刷新 listview 0-13行(让ListView显示数组数据),不用太多行,只需要一屏的行数就就可以
;因为下拉滚动的时候listview会收到LVN_GETDISPINFO消息,这个消息我们在WM_NOTIFY内处理过了
If $i = 18 Then
GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 0, $i)
GUICtrlSendMsg($hListView2, $LVM_REDRAWITEMS, 0, $i)
GUICtrlSendMsg($hListView3, $LVM_REDRAWITEMS, 0, $i)
EndIf
$aShowdata[$i] = "爷爷" & $i
$aShowdata[$i] = "爸爸" & $i
$aShowdata[$i] = "儿子" & $i
$aShowdata[$i] = 4096;复选框状态4096未选中 8192选中
$aShowdata2[$i] = "2爷爷" & $i
$aShowdata2[$i] = "2爸爸" & $i
$aShowdata2[$i] = "2儿子" & $i
$aShowdata2[$i] = 4096;复选框状态4096未选中 8192选中
$aShowdata3[$i] = "3爷爷" & $i
$aShowdata3[$i] = "3爸爸" & $i
$aShowdata3[$i] = "3儿子" & $i
$aShowdata3[$i] = 4096;复选框状态4096未选中 8192选中
Next
While 1
$bCtrlDown = _IsPressed("11", $hUser32);取ctrl按键的状态
Switch GUIGetMsg()
Case -3
ExitLoop
Case $Button1
$aShowdata = 8192
$aShowdata = 8192
GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 3, 7)
;~ $a = _GetChkIndex(8192)
;~ If $a = -1 Then
;~ MsgBox(32, "提示", "未勾选任何数据")
;~ Else
;~ _ArrayDisplay($a, "勾选行的索引");数组很大时,_ArrayDisplay会非常耗时
;~ EndIf
Case $Button2
$a = _GetChkIndex(4096)
If $a = -1 Then
MsgBox(32, "提示", "数据全都被勾选了。")
Else
;MsgBox(32, "提示", "未勾选的数据有" & UBound($a) & "行")
_ArrayDisplay($a, "未勾选行的索");数组很大时,_ArrayDisplay会非常耗时
EndIf
Case $Button3
If StringLen($sSomeString) Then
$sSomeString = ""
Else
$sSomeString = Asc(Random(48, 255, 1))
EndIf
For $i = 0 To $iITEM_COUNT - 1
$aShowdata[$i] = "爷爷" & $i & "-" & $sSomeString
$aShowdata[$i] = "爸爸" & $i & "-" & $sSomeString
$aShowdata[$i] = "儿子" & $i & "-" & $sSomeString
Next
GUICtrlSendMsg($hListView, $LVM_ENSUREVISIBLE, 1, 0)
GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 0, 20)
Case $Button4
$aShowdata = 0
$iITEM_COUNT = 0
GUICtrlSendMsg($hListView, $LVM_SETITEMCOUNT, $iITEM_COUNT, 0)
GUICtrlSendMsg($hListView, $LVM_ENSUREVISIBLE, 1, 0)
GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 0, 20)
EndSwitch
WEnd
GUIDelete()
DllClose($hUser32)
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
#forceref $hWnd, $iMsg, $iwParam
Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $tInfo
$tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
$hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
$iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
$iCode = DllStructGetData($tNMHDR, "Code")
Local $iIndex = DllStructGetData($tNMHDR, "Index")
Switch $iIDFrom
Case $hListView
Switch $iCode
Case $LVN_COLUMNCLICK ; 点击列头排序
_SortItems($iIDFrom, $ilParam, $aShowdata)
Case $NM_CUSTOMDRAW;自绘消息处理选中行背景色
;~ _SetchkboxBkClr($ilParam, $aShowdata)
Local $tCustDraw = DllStructCreate("hwnd hwndFrom;int idFrom;int code;dword DrawStage;hwnd hdc;long rect;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;int Align", $ilParam)
;~
Local $iDrawStage = DllStructGetData($tCustDraw, "DrawStage")
If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW ;request custom drawing of items
If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW ;request drawing each cell separately
If Not BitAND($iDrawStage, $CDDS_SUBITEM) Then Return $CDRF_DODEFAULT
$iIndex = DllStructGetData($tCustDraw, "ItemSpec")
If $aShowdata[$iIndex] = 4096 Then
DllStructSetData($tCustDraw, "clrTextBk", 0xFFFFFF);BGR格式颜色值
Else
DllStructSetData($tCustDraw, "clrTextBk", 0xF7D3AD);BGR格式颜色值
EndIf
Return $CDRF_NEWFONT
Case $LVN_ITEMCHANGED ; An item has changed
_CtrlSel($iIDFrom, $ilParam, $aShowdata)
Case $LVN_BEGINSCROLL ; 滚动事件开始
If IsHWnd($hEdit) Then _EndItemEdit($iIDFrom, $aShowdata);如果存在$hEdit控件,则结束编辑
Case $NM_CLICK;单击
If IsHWnd($hEdit) Then _EndItemEdit($iIDFrom, $aShowdata)
_chkboxState($iIDFrom, $ilParam, $aShowdata);刷新复选框状态
Case $NM_DBLCLK ; 双击
_StartItemEdit($iIDFrom, $ilParam, $aShowdata);开始原地编辑
Case -150, -177 ;$LVN_GETDISPINFOA = -150, $LVN_GETDISPINFOW = -177 请求显示数据
_LVN_GETDISPINFO($iIDFrom, $ilParam, $aShowdata)
EndSwitch
Case $hListView2
Switch $iCode
Case -150, -177 ;$LVN_GETDISPINFOA = -150, $LVN_GETDISPINFOW = -177 请求显示数据
_LVN_GETDISPINFO($iIDFrom, $ilParam, $aShowdata2)
Case $LVN_COLUMNCLICK ; 点击列头排序
_SortItems($iIDFrom, $ilParam, $aShowdata2)
Case $NM_CUSTOMDRAW;自绘消息处理选中行背景色
Local $tCustDraw = DllStructCreate("hwnd hwndFrom;int idFrom;int code;dword DrawStage;hwnd hdc;long rect;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;int Align", $ilParam)
Local $iDrawStage = DllStructGetData($tCustDraw, "DrawStage")
If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW ;request custom drawing of items
If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW ;request drawing each cell separately
If Not BitAND($iDrawStage, $CDDS_SUBITEM) Then Return $CDRF_DODEFAULT
$iIndex = DllStructGetData($tCustDraw, "ItemSpec")
If $aShowdata2[$iIndex] = 4096 Then
DllStructSetData($tCustDraw, "clrTextBk", 0xFFFFFF);BGR格式颜色值
Else
DllStructSetData($tCustDraw, "clrTextBk", 0xF7D3AD);BGR格式颜色值
EndIf
Return $CDRF_NEWFONT
Case $LVN_ITEMCHANGED ; An item has changed
_CtrlSel($iIDFrom, $ilParam, $aShowdata2)
Case $LVN_BEGINSCROLL ; 滚动事件开始
If IsHWnd($hEdit) Then _EndItemEdit($iIDFrom, $aShowdata2);如果存在$hEdit控件,则结束编辑
Case $NM_CLICK;单击
If IsHWnd($hEdit) Then _EndItemEdit($iIDFrom, $aShowdata2)
_chkboxState($iIDFrom, $ilParam, $aShowdata2)
Case $NM_DBLCLK ; 双击
_StartItemEdit($iIDFrom, $ilParam, $aShowdata2)
EndSwitch
Case $hListView3
Switch $iCode
Case -150, -177 ;$LVN_GETDISPINFOA = -150, $LVN_GETDISPINFOW = -177 请求显示数据
_LVN_GETDISPINFO($iIDFrom, $ilParam, $aShowdata3)
Case $LVN_COLUMNCLICK ; 点击列头排序
_SortItems($iIDFrom, $ilParam, $aShowdata3)
Case $NM_CUSTOMDRAW;自绘消息处理选中行背景色
Local $tCustDraw = DllStructCreate("hwnd hwndFrom;int idFrom;int code;dword DrawStage;hwnd hdc;long rect;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;int Align", $ilParam)
Local $iDrawStage = DllStructGetData($tCustDraw, "DrawStage")
If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW ;request custom drawing of items
If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW ;request drawing each cell separately
If Not BitAND($iDrawStage, $CDDS_SUBITEM) Then Return $CDRF_DODEFAULT
$iIndex = DllStructGetData($tCustDraw, "ItemSpec")
If $aShowdata3[$iIndex] = 4096 Then
DllStructSetData($tCustDraw, "clrTextBk", 0xFFFFFF);BGR格式颜色值
Else
DllStructSetData($tCustDraw, "clrTextBk", 0xF7D3AD);BGR格式颜色值
EndIf
Return $CDRF_NEWFONT
Case $LVN_ITEMCHANGED ; An item has changed
_CtrlSel($iIDFrom, $ilParam, $aShowdata3)
Case $LVN_BEGINSCROLL ; 滚动事件开始
If IsHWnd($hEdit) Then _EndItemEdit($iIDFrom, $aShowdata3);如果存在$hEdit控件,则结束编辑
Case $NM_CLICK;单击
If IsHWnd($hEdit) Then _EndItemEdit($iIDFrom, $aShowdata3)
_chkboxState($iIDFrom, $ilParam, $aShowdata3)
Case $NM_DBLCLK ; 双击
_StartItemEdit($iIDFrom, $ilParam, $aShowdata3)
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc
Func WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
$iIDFrom = _WinAPI_LoWord($wParam)
$iCode = _WinAPI_HiWord($wParam)
Switch $lParam
Case $hEdit
Switch $iCode
Case $EN_KILLFOCUS;编辑框失去焦点,结束编辑
Switch $hActLst
Case $hListView
_EndItemEdit($hListView, $aShowdata)
Case $hListView2
_EndItemEdit($hListView2, $aShowdata2)
Case $hListView3
_EndItemEdit($hListView3, $aShowdata3)
EndSwitch
Case $EN_UPDATE
EndSwitch
Case $hEnter;虚拟控件消息触发收到回车消息才触发
If IsHWnd($hEdit) Then
If $SubItem = 0 Then
__ClickListViewItem($hActLst, $Item, True);使用点击来结束编辑,省去判断listview的数据数组
Else
__ClickListViewItem($hActLst, $Item)
EndIf
EndIf
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc
Func _SetchkboxBkClr(ByRef $ilParam, ByRef $aDataArray)
Local $tCustDraw = DllStructCreate("hwnd hwndFrom;int idFrom;int code;dword DrawStage;hwnd hdc;long rect;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;int Align", $ilParam)
Local $iDrawStage = DllStructGetData($tCustDraw, "DrawStage")
If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW ;request custom drawing of items
If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW ;request drawing each cell separately
If Not BitAND($iDrawStage, $CDDS_SUBITEM) Then Return $CDRF_DODEFAULT
$iIndex = DllStructGetData($tCustDraw, "ItemSpec")
If $aDataArray[$iIndex] = 4096 Then
DllStructSetData($tCustDraw, "clrTextBk", 0xFFFFFF);BGR格式颜色值
Else
DllStructSetData($tCustDraw, "clrTextBk", 0xF7D3AD);BGR格式颜色值
EndIf
EndFunc
Func _chkboxState($hlst, $ilParam, ByRef $aDataArray);刷新复选框状态
$tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
$iIndex = DllStructGetData($tInfo, "Index")
$x = DllStructGetData($tInfo, "X")
If ($x < 16) And (3 < $x) And (BitAND(_GUICtrlListView_GetExtendedListViewStyle($hlst), $LVS_EX_CHECKBOXES) = $LVS_EX_CHECKBOXES) Then;使用点击的x坐标来判断是否在复选框上点击
If $aDataArray[$iIndex] = 4096 Then
$ichked+=1
$aDataArray[$iIndex] = 8192;4096未选中 8192选中
Else
$ichked-=1
$aDataArray[$iIndex] = 4096;4096未选中 8192选中
EndIf
;====立刻刷新复选框显示状态 重绘$iIndex项
GUICtrlSendMsg($hlst, $LVM_REDRAWITEMS, $iIndex, $iIndex)
EndIf
EndFunc
Func _SortItems($hlst, $ilParam, ByRef $aDataArray);排序
$tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)
$iSub = DllStructGetData($tInfo, "SubItem")
_ArraySort($aDataArray, $B_DESCENDING[$iSub], 0, 0, $iSub)
GUICtrlSendMsg($hlst, $LVM_REDRAWITEMS, 0, 20)
$B_DESCENDING[$iSub] = Not $B_DESCENDING[$iSub]
EndFunc
Func _CtrlSel($hlst, $ilParam, ByRef $aDataArray);按住ctrl键点选item
If $bCtrlDown Then;ctrl键按下
$tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)
Local $iIndex = DllStructGetData($tInfo, "Item")
Local $iNewState = DllStructGetData($tInfo, "NewState")
If $iIndex > -1 And $iNewState = BitOR($LVIS_FOCUSED, $LVIS_SELECTED) Then
If $aDataArray[$iIndex] = 4096 Then
$ichked+=1
$aDataArray[$iIndex] = 8192;4096未选中 8192选中
Else
$ichked-=1
$aDataArray[$iIndex] = 4096;4096未选中 8192选中
EndIf
$tInfo = DllStructCreate($tagNMLVDISPINFO, $ilParam)
DllStructSetData($tInfo, "State", $aDataArray[$iIndex]);设置复选框状态
;====立刻刷新复选框显示状态 重绘$iIndex项
GUICtrlSendMsg($hlst, $LVM_REDRAWITEMS, $iIndex, $iIndex)
EndIf
EndIf
EndFunc
Func _LVN_GETDISPINFO($hlst, $ilParam, ByRef $aDataArray)
If Not IsArray($aDataArray) Then Return
$tInfo = DllStructCreate($tagNMLVDISPINFO, $ilParam)
$iIndex = Int(DllStructGetData($tInfo, "Item"))
$iSub = Int(DllStructGetData($tInfo, "SubItem"))
If BitAND(DllStructGetData($tInfo, "Mask"), $LVIF_IMAGE) And $iSub = 0 Then DllStructSetData($tInfo, "Image", 0);判断是否有LVIF_IMAGE属性,有则设置列图像。不设置_GUICtrlListView_SetImageList则无
If (BitAND(_GUICtrlListView_GetExtendedListViewStyle($hlst), $LVS_EX_CHECKBOXES) = $LVS_EX_CHECKBOXES) Then
;===============设置复选框信息
DllStructSetData($tInfo, "Mask", BitOR($LVIF_STATE, DllStructGetData($tInfo, "Mask")))
DllStructSetData($tInfo, "StateMask", $LVIS_STATEIMAGEMASK)
DllStructSetData($tInfo, "State", $aDataArray[$iIndex])
EndIf
DllStructSetData($tText, "Text", $aDataArray[$iIndex][$iSub]);列数据放入$tText结构
DllStructSetData($tInfo, "Text", DllStructGetPtr($tText));$tText结构的指针来设置列数据
DllStructSetData($tInfo, "TextMax", StringLen($aDataArray[$iIndex][$iSub]));设置列数据字串长
EndFunc
Func _StartItemEdit($hlst, $ilParam, ByRef $aDataArray)
$tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
$iIndex = DllStructGetData($tInfo, "Index")
$iSub = DllStructGetData($tInfo, "SubItem")
$x = DllStructGetData($tInfo, "X")
If ($iIndex <> -1) And ($iSub >= 0) And ($x > 16) Then;点击的x>16才响应原地编辑
$hActLst = $hlst
If _GUICtrlListView_EnsureVisible($hlst, $iIndex) Then GUICtrlSendMsg($hlst, $LVM_REDRAWITEMS, $iIndex, $iIndex + 1);确保列表视图项目可见
Local $alstPos = ControlGetPos($hGUI, "", $hlst)
$Item = $iIndex
$SubItem = $iSub
;==========计算编辑框坐标
Local $aRect = _GUICtrlListView_GetSubItemRect($hlst, $iIndex, $iSub)
Local $iEdit_X = $aRect + $alstPos + 4
Local $iEdit_Y = $aRect + $alstPos + 2
Local $iEdit_Width = _GUICtrlListView_GetColumnWidth($hlst, $iSub) - 1
Local $iEdit_Height = $aRect - $aRect
If $iSub = 0 Then
Local $i1 = 0, $i2 = 0
If (BitAND(_GUICtrlListView_GetExtendedListViewStyle($hlst), $LVS_EX_CHECKBOXES) = $LVS_EX_CHECKBOXES) Then $i1 = 17;判断是否有复选框
If _GUICtrlListView_GetImageList($hlst, 1) Then $i2 = 19;判断是否有分配图像列表到列表视图控件
$iEdit_X += ($i2 + $i1)
$iEdit_Width -= ($i2 + $i1)
EndIf
Local $iEdit = GUICtrlCreateInput($aDataArray[$iIndex][$iSub], $iEdit_X, $iEdit_Y, $iEdit_Width, $iEdit_Height, BitOR($WS_CHILD, $WS_VISIBLE, $ES_LEFT))
GUICtrlSetFont($iEdit, 11)
GUICtrlSetState($iEdit, $GUI_FOCUS)
$hEdit = GUICtrlGetHandle($iEdit)
_WinAPI_BringWindowToTop($hEdit)
_GUICtrlEdit_SetSel($hEdit, 0, -1) ;全选编辑框文字
Local $iEnter = GUICtrlCreateDummy()
$hEnter = GUICtrlGetHandle($iEnter)
GUISetAccelerators($aAccelKeys, $hGUI);在虚拟控件上绑定一个回车快捷按键
EndIf
EndFunc
Func _EndItemEdit($hlst, ByRef $aDataArray)
If ($Item < UBound($aDataArray, 1)) And ($SubItem < UBound($aDataArray, 2)) And ($hActLst == $hlst) Then
Local $sText = _GUICtrlEdit_GetText($hEdit)
_GUICtrlListView_SetItemText($hlst, $Item, $sText, $SubItem)
If IsHWnd($hEdit) Then _WinAPI_DestroyWindow($hEdit)
If IsHWnd($hEnter) Then _WinAPI_DestroyWindow($hEnter)
$hEnter = Null
$hEdit = Null
If ($Item >= 0) Then $aDataArray[$Item][$SubItem] = $sText
$Item = -1
$SubItem = 0
EndIf
EndFunc
Func _GetChkIndex($iChkState)
Local $aIndex = [-1], $j = 0
If $ichked = 0 Then Return $aIndex
If $iChkState = 8192 Then
ReDim $aIndex[$ichked]
Else
ReDim $aIndex
EndIf
For $i = 0 To UBound($aShowdata) -1
If $aShowdata[$i] == $iChkState Then
$aIndex[$j] = $i
$j+=1
EndIf
Next
Return $aIndex
EndFunc
Func __ClickListViewItem($hWnd, $iIndex, $baddX = False)
If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)
Local $tRECT = _GUICtrlListView_GetItemRectEx($hWnd, $iIndex, $LVIR_LABEL)
Local $tPoint = _WinAPI_PointFromRect($tRECT, True)
$tPoint = _WinAPI_ClientToScreen($hWnd, $tPoint)
Local $iX, $iY
_WinAPI_GetXYFromPoint($tPoint, $iX, $iY)
If $baddX Then $iX += DllStructGetData($tRECT, "Right")
Local $iMode = Opt("MouseCoordMode", 1)
Local $aPos = MouseGetPos()
MouseClick("left", $iX, $iY, 1, 0)
MouseMove($aPos, $aPos, 0)
Opt("MouseCoordMode", $iMode)
EndFunc
yuji1
发表于 2015-11-2 22:42:00
谢谢楼主分享 学习学习
kk_lee69
发表于 2015-11-3 02:15:19
回复 67# 298311657
感謝樓主 我又學到了東西
我想請教的就是
_LVN_GETDISPINFO($hlst, $ilParam, ByRef $aDataArray)
跟
DllStructSetData($tInfo, "TextMax", StringLen($aDataArray[$iIndex][$iSub]));設置列數據字串長
這樣子的用法....
怎麼我的觀念認為這樣是不可以的??......原來是我的認知有問題.....
這個突破 可以讓我更縮短我的 寫法了 感列樓主!!
kk_lee69
发表于 2015-11-4 10:54:23
回复 67# 298311657
樓主 你好又來打擾了 真不好意思.....能請教觀念嗎??
Case $NM_CUSTOMDRAW;自绘消息处理选中行背景色
為何 這個 寫成 Func 後 功能就失效了,雖然不會出現錯誤,但是 都無法上顏色呢??
原因是甚麼呢??
298311657
发表于 2015-11-6 00:15:25
回复 70# kk_lee69
只能这样做:
#cs ______________________
Au3 版本: 3.3.14.2
脚本作?? CrossDoor
电子邮件: 382869232@qq.com
QQ/TM: 382869232
#ce _______________脚本开始_________________
#PRE_UseX64=n
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiImageList.au3>
#include <WinAPITheme.au3>
#include <GuiListView.au3>
#include <WinAPISys.au3>
#include <WinAPI.au3>
#include <GuiEdit.au3>
#include <array.au3>
#include <Misc.au3>
Global $B_DESCENDING ; 排序用数组
Global $hActLst
Global $bCtrlDown = False;listview控件ctrl键按下标识
Global $hEdit, $Item = -1, $SubItem = 0
Global $hEnter, $aAccelKeys = [["{ENTER}", $hEnter]];虚拟控件的句柄和绑定的快捷键
Local $hUser32 = DllOpen("user32.dll")
Local $ichked = 0;勾选的行数
Local $tText = DllStructCreate("wchar Text");建个结构,用来放listview列数据
Local $GUI, $hImage
Local $iITEM_COUNT = 1000, $aShowdata[$iITEM_COUNT], $aShowdata2[$iITEM_COUNT], $aShowdata3[$iITEM_COUNT];注意数组最大项目数为2^24(16777216),所以$iITEM_COUNT = 4194304为二维数组$aShowdata最大行数
Local $sSomeString = ""
Local $hGUI, $hListView, $hListView2, $hListView3
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
$hGUI = GUICreate("ListView虚表 加载[" & UBound($aShowdata) & "]数据 复选框 原地编辑例子 By_Crossdoor", 600, 605)
$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)
;~ _WinAPI_SetWindowTheme(GUICtrlGetHandle($hListView), "Explorer");设置主题
;设置列宽
GUICtrlSendMsg($hListView, $LVM_SETCOLUMNWIDTH, 0, 110)
GUICtrlSendMsg($hListView, $LVM_SETCOLUMNWIDTH, 1, 80)
GUICtrlSendMsg($hListView, $LVM_SETCOLUMNWIDTH, 2, 80)
GUICtrlSendMsg($hListView, $LVM_SETITEMCOUNT, $iITEM_COUNT, 0);设定数据总数
$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)
;~ _WinAPI_SetWindowTheme(GUICtrlGetHandle($hListView), "Explorer");设置主题
;设置列宽
GUICtrlSendMsg($hListView2, $LVM_SETCOLUMNWIDTH, 0, 110)
GUICtrlSendMsg($hListView2, $LVM_SETCOLUMNWIDTH, 1, 80)
GUICtrlSendMsg($hListView2, $LVM_SETCOLUMNWIDTH, 2, 80)
GUICtrlSendMsg($hListView2, $LVM_SETITEMCOUNT, $iITEM_COUNT, 0);设定数据总数
$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)
;~ _WinAPI_SetWindowTheme(GUICtrlGetHandle($hListView), "Explorer");设置主题
;设置列宽
GUICtrlSendMsg($hListView3, $LVM_SETCOLUMNWIDTH, 0, 110)
GUICtrlSendMsg($hListView3, $LVM_SETCOLUMNWIDTH, 1, 80)
GUICtrlSendMsg($hListView3, $LVM_SETCOLUMNWIDTH, 2, 80)
GUICtrlSendMsg($hListView3, $LVM_SETITEMCOUNT, $iITEM_COUNT, 0);设定数据总数
;===========创建并关联图像列表
$hImage = _GUIImageList_Create()
_GUIImageList_AddIcon($hImage, @SystemDir & "\shell32.dll", 110)
_GUICtrlListView_SetImageList($hListView, $hImage, 1);分配图像列表到列表视图控件$hListView
_GUICtrlListView_SetImageList($hListView2, $hImage, 1);分配图像列表到列表视图控件$hListView2
$Button1 = GUICtrlCreateButton("选中行", 10, 310, 70, 25)
$Button2 = GUICtrlCreateButton("未选行", 80, 310, 70, 25)
$Button3 = GUICtrlCreateButton("修改", 150, 310, 70, 25)
$Button4 = GUICtrlCreateButton("清空", 220, 310, 70, 25)
GUISetState()
;==================在窗体显示后再初始化数据,因为初始化数组数据比较慢
;如果先初始化数组后显示窗口,会卡很久,就造成虚表也很慢的假象
For $i = 0 To $iITEM_COUNT - 1
;重绘 刷新 listview 0-13行(让ListView显示数组数据),不用太多行,只需要一屏的行数就就可以
;因为下拉滚动的时候listview会收到LVN_GETDISPINFO消息,这个消息我们在WM_NOTIFY内处理过了
If $i = 18 Then
GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 0, $i)
GUICtrlSendMsg($hListView2, $LVM_REDRAWITEMS, 0, $i)
GUICtrlSendMsg($hListView3, $LVM_REDRAWITEMS, 0, $i)
EndIf
$aShowdata[$i] = "爷爷" & $i
$aShowdata[$i] = "爸爸" & $i
$aShowdata[$i] = "儿子" & $i
$aShowdata[$i] = 4096;复选框状态4096未选中 8192选中
$aShowdata2[$i] = "2爷爷" & $i
$aShowdata2[$i] = "2爸爸" & $i
$aShowdata2[$i] = "2儿子" & $i
$aShowdata2[$i] = 4096;复选框状态4096未选中 8192选中
$aShowdata3[$i] = "3爷爷" & $i
$aShowdata3[$i] = "3爸爸" & $i
$aShowdata3[$i] = "3儿子" & $i
$aShowdata3[$i] = 4096;复选框状态4096未选中 8192选中
Next
While 1
$bCtrlDown = _IsPressed("11", $hUser32);取ctrl按键的状态
Switch GUIGetMsg()
Case -3
ExitLoop
Case $Button1
$aShowdata = 8192
$aShowdata = 8192
GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 3, 7)
;~ $a = _GetChkIndex(8192)
;~ If $a = -1 Then
;~ MsgBox(32, "提示", "未勾选任何数据")
;~ Else
;~ _ArrayDisplay($a, "勾选行的索引");数组很大时,_ArrayDisplay会非常耗时
;~ EndIf
Case $Button2
$a = _GetChkIndex(4096)
If $a = -1 Then
MsgBox(32, "提示", "数据全都被勾选了。")
Else
;MsgBox(32, "提示", "未勾选的数据有" & UBound($a) & "行")
_ArrayDisplay($a, "未勾选行的索");数组很大时,_ArrayDisplay会非常耗时
EndIf
Case $Button3
If StringLen($sSomeString) Then
$sSomeString = ""
Else
$sSomeString = Asc(Random(48, 255, 1))
EndIf
For $i = 0 To $iITEM_COUNT - 1
$aShowdata[$i] = "爷爷" & $i & "-" & $sSomeString
$aShowdata[$i] = "爸爸" & $i & "-" & $sSomeString
$aShowdata[$i] = "儿子" & $i & "-" & $sSomeString
Next
GUICtrlSendMsg($hListView, $LVM_ENSUREVISIBLE, 1, 0)
GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 0, 20)
Case $Button4
$aShowdata = 0
$iITEM_COUNT = 0
GUICtrlSendMsg($hListView, $LVM_SETITEMCOUNT, $iITEM_COUNT, 0)
GUICtrlSendMsg($hListView, $LVM_ENSUREVISIBLE, 1, 0)
GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 0, 20)
EndSwitch
WEnd
GUIDelete()
DllClose($hUser32)
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
#forceref $hWnd, $iMsg, $iwParam
Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $tInfo
$tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
$hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
$iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
$iCode = DllStructGetData($tNMHDR, "Code")
Switch $iIDFrom
Case $hListView
Switch $iCode
Case $LVN_COLUMNCLICK ; 点击列头排序
_SortItems($iIDFrom, $ilParam, $aShowdata)
Case $NM_CUSTOMDRAW;自绘消息处理选中行背景色
Local $tCustDraw = DllStructCreate("hwnd hwndFrom;int idFrom;int code;dword DrawStage;hwnd hdc;long rect;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;int Align", $ilParam)
Local $iDrawStage = DllStructGetData($tCustDraw, "DrawStage")
If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW ;request custom drawing of items
If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW ;request drawing each cell separately
If Not BitAND($iDrawStage, $CDDS_SUBITEM) Then Return $CDRF_DODEFAULT
_SetchkedBkClr($tCustDraw, $aShowdata)
Return $CDRF_NEWFONT
Case $LVN_ITEMCHANGED ; An item has changed
_CtrlSel($iIDFrom, $ilParam, $aShowdata)
Case $LVN_BEGINSCROLL ; 滚动事件开始
If IsHWnd($hEdit) Then _EndItemEdit($iIDFrom, $aShowdata);如果存在$hEdit控件,则结束编辑
Case $NM_CLICK;单击
If IsHWnd($hEdit) Then _EndItemEdit($iIDFrom, $aShowdata)
_chkboxState($iIDFrom, $ilParam, $aShowdata);刷新复选框状态
Case $NM_DBLCLK ; 双击
_StartItemEdit($iIDFrom, $ilParam, $aShowdata);开始原地编辑
Case -150, -177 ;$LVN_GETDISPINFOA = -150, $LVN_GETDISPINFOW = -177 请求显示数据
_LVN_GETDISPINFO($iIDFrom, $ilParam, $aShowdata)
EndSwitch
Case $hListView2
Switch $iCode
Case -150, -177 ;$LVN_GETDISPINFOA = -150, $LVN_GETDISPINFOW = -177 请求显示数据
_LVN_GETDISPINFO($iIDFrom, $ilParam, $aShowdata2)
Case $LVN_COLUMNCLICK ; 点击列头排序
_SortItems($iIDFrom, $ilParam, $aShowdata2)
Case $NM_CUSTOMDRAW;自绘消息处理选中行背景色
Local $tCustDraw = DllStructCreate("hwnd hwndFrom;int idFrom;int code;dword DrawStage;hwnd hdc;long rect;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;int Align", $ilParam)
Local $iDrawStage = DllStructGetData($tCustDraw, "DrawStage")
If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW ;request custom drawing of items
If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW ;request drawing each cell separately
If Not BitAND($iDrawStage, $CDDS_SUBITEM) Then Return $CDRF_DODEFAULT
_SetchkedBkClr($tCustDraw, $aShowdata2, 0x738393)
Return $CDRF_NEWFONT
Case $LVN_ITEMCHANGED ; An item has changed
_CtrlSel($iIDFrom, $ilParam, $aShowdata2)
Case $LVN_BEGINSCROLL ; 滚动事件开始
If IsHWnd($hEdit) Then _EndItemEdit($iIDFrom, $aShowdata2);如果存在$hEdit控件,则结束编辑
Case $NM_CLICK;单击
If IsHWnd($hEdit) Then _EndItemEdit($iIDFrom, $aShowdata2)
_chkboxState($iIDFrom, $ilParam, $aShowdata2)
Case $NM_DBLCLK ; 双击
_StartItemEdit($iIDFrom, $ilParam, $aShowdata2)
EndSwitch
Case $hListView3
Switch $iCode
Case -150, -177 ;$LVN_GETDISPINFOA = -150, $LVN_GETDISPINFOW = -177 请求显示数据
_LVN_GETDISPINFO($iIDFrom, $ilParam, $aShowdata3)
Case $LVN_COLUMNCLICK ; 点击列头排序
_SortItems($iIDFrom, $ilParam, $aShowdata3)
Case $NM_CUSTOMDRAW;自绘消息处理选中行背景色
Local $tCustDraw = DllStructCreate("hwnd hwndFrom;int idFrom;int code;dword DrawStage;hwnd hdc;long rect;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;int Align", $ilParam)
Local $iDrawStage = DllStructGetData($tCustDraw, "DrawStage")
If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW ;request custom drawing of items
If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW ;request drawing each cell separately
If Not BitAND($iDrawStage, $CDDS_SUBITEM) Then Return $CDRF_DODEFAULT
_SetchkedBkClr($tCustDraw, $aShowdata3, 0xD307AD, 0xE3F7ED)
Return $CDRF_NEWFONT
Case $LVN_ITEMCHANGED ; An item has changed
_CtrlSel($iIDFrom, $ilParam, $aShowdata3)
Case $LVN_BEGINSCROLL ; 滚动事件开始
If IsHWnd($hEdit) Then _EndItemEdit($iIDFrom, $aShowdata3);如果存在$hEdit控件,则结束编辑
Case $NM_CLICK;单击
If IsHWnd($hEdit) Then _EndItemEdit($iIDFrom, $aShowdata3)
_chkboxState($iIDFrom, $ilParam, $aShowdata3)
Case $NM_DBLCLK ; 双击
_StartItemEdit($iIDFrom, $ilParam, $aShowdata3)
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc
Func WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
$iIDFrom = _WinAPI_LoWord($wParam)
$iCode = _WinAPI_HiWord($wParam)
Switch $lParam
Case $hEdit
Switch $iCode
Case $EN_KILLFOCUS;编辑框失去焦点,结束编辑
Switch $hActLst
Case $hListView
_EndItemEdit($hListView, $aShowdata)
Case $hListView2
_EndItemEdit($hListView2, $aShowdata2)
Case $hListView3
_EndItemEdit($hListView3, $aShowdata3)
EndSwitch
Case $EN_UPDATE
EndSwitch
Case $hEnter;虚拟控件消息触发收到回车消息才触发
If IsHWnd($hEdit) Then
If $SubItem = 0 Then
__ClickListViewItem($hActLst, $Item, True);使用点击来结束编辑,省去判断listview的数据数组
Else
__ClickListViewItem($hActLst, $Item)
EndIf
EndIf
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc
Func _SetchkedBkClr(ByRef $tCustDraw, ByRef $aDataArray, $ihighBkClr = 0xF7D3AD, $idefBkclr = 0xFFFFFF)
Local $iIndex = DllStructGetData($tCustDraw, "ItemSpec")
If $aDataArray[$iIndex] = 4096 Then
DllStructSetData($tCustDraw, "clrTextBk", $idefBkclr);BGR格式颜色值 默认背景色
Else
DllStructSetData($tCustDraw, "clrTextBk", $ihighBkClr);BGR格式颜色值 高亮背景色
EndIf
EndFunc
Func _chkboxState($hlst, $ilParam, ByRef $aDataArray);刷新复选框状态
$tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
$iIndex = DllStructGetData($tInfo, "Index")
$x = DllStructGetData($tInfo, "X")
If ($x < 16) And (3 < $x) And (BitAND(_GUICtrlListView_GetExtendedListViewStyle($hlst), $LVS_EX_CHECKBOXES) = $LVS_EX_CHECKBOXES) Then;使用点击的x坐标来判断是否在复选框上点击
If $aDataArray[$iIndex] = 4096 Then
$ichked+=1
$aDataArray[$iIndex] = 8192;4096未选中 8192选中
Else
$ichked-=1
$aDataArray[$iIndex] = 4096;4096未选中 8192选中
EndIf
;====立刻刷新复选框显示状态 重绘$iIndex项
GUICtrlSendMsg($hlst, $LVM_REDRAWITEMS, $iIndex, $iIndex)
EndIf
EndFunc
Func _SortItems($hlst, $ilParam, ByRef $aDataArray);排序
$tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)
$iSub = DllStructGetData($tInfo, "SubItem")
_ArraySort($aDataArray, $B_DESCENDING[$iSub], 0, 0, $iSub)
GUICtrlSendMsg($hlst, $LVM_REDRAWITEMS, 0, 20)
$B_DESCENDING[$iSub] = Not $B_DESCENDING[$iSub]
EndFunc
Func _CtrlSel($hlst, $ilParam, ByRef $aDataArray);按住ctrl键点选item
If $bCtrlDown Then;ctrl键按下
$tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)
Local $iIndex = DllStructGetData($tInfo, "Item")
Local $iNewState = DllStructGetData($tInfo, "NewState")
If $iIndex > -1 And $iNewState = BitOR($LVIS_FOCUSED, $LVIS_SELECTED) Then
If $aDataArray[$iIndex] = 4096 Then
$ichked+=1
$aDataArray[$iIndex] = 8192;4096未选中 8192选中
Else
$ichked-=1
$aDataArray[$iIndex] = 4096;4096未选中 8192选中
EndIf
$tInfo = DllStructCreate($tagNMLVDISPINFO, $ilParam)
DllStructSetData($tInfo, "State", $aDataArray[$iIndex]);设置复选框状态
;====立刻刷新复选框显示状态 重绘$iIndex项
GUICtrlSendMsg($hlst, $LVM_REDRAWITEMS, $iIndex, $iIndex)
EndIf
EndIf
EndFunc
Func _LVN_GETDISPINFO($hlst, $ilParam, ByRef $aDataArray)
If Not IsArray($aDataArray) Then Return
$tInfo = DllStructCreate($tagNMLVDISPINFO, $ilParam)
$iIndex = Int(DllStructGetData($tInfo, "Item"))
$iSub = Int(DllStructGetData($tInfo, "SubItem"))
If BitAND(DllStructGetData($tInfo, "Mask"), $LVIF_IMAGE) And $iSub = 0 Then DllStructSetData($tInfo, "Image", 0);判断是否有LVIF_IMAGE属性,有则设置列图像。不设置_GUICtrlListView_SetImageList则无
If (BitAND(_GUICtrlListView_GetExtendedListViewStyle($hlst), $LVS_EX_CHECKBOXES) = $LVS_EX_CHECKBOXES) Then
;===============设置复选框信息
DllStructSetData($tInfo, "Mask", BitOR($LVIF_STATE, DllStructGetData($tInfo, "Mask")))
DllStructSetData($tInfo, "StateMask", $LVIS_STATEIMAGEMASK)
DllStructSetData($tInfo, "State", $aDataArray[$iIndex])
EndIf
DllStructSetData($tText, "Text", $aDataArray[$iIndex][$iSub]);列数据放入$tText结构
DllStructSetData($tInfo, "Text", DllStructGetPtr($tText));$tText结构的指针来设置列数据
DllStructSetData($tInfo, "TextMax", StringLen($aDataArray[$iIndex][$iSub]));设置列数据字串长
EndFunc
Func _StartItemEdit($hlst, $ilParam, ByRef $aDataArray)
$tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
$iIndex = DllStructGetData($tInfo, "Index")
$iSub = DllStructGetData($tInfo, "SubItem")
$x = DllStructGetData($tInfo, "X")
If ($iIndex <> -1) And ($iSub >= 0) And ($x > 16) Then;点击的x>16才响应原地编辑
$hActLst = $hlst
If _GUICtrlListView_EnsureVisible($hlst, $iIndex) Then GUICtrlSendMsg($hlst, $LVM_REDRAWITEMS, $iIndex, $iIndex + 1);确保列表视图项目可见
Local $alstPos = ControlGetPos($hGUI, "", $hlst)
$Item = $iIndex
$SubItem = $iSub
;==========计算编辑框坐标
Local $aRect = _GUICtrlListView_GetSubItemRect($hlst, $iIndex, $iSub)
Local $iEdit_X = $aRect + $alstPos + 4
Local $iEdit_Y = $aRect + $alstPos + 3
Local $iEdit_Width = _GUICtrlListView_GetColumnWidth($hlst, $iSub) - 1
Local $iEdit_Height = $aRect - $aRect
If $iSub = 0 Then
Local $i1 = 0, $i2 = 0
If (BitAND(_GUICtrlListView_GetExtendedListViewStyle($hlst), $LVS_EX_CHECKBOXES) = $LVS_EX_CHECKBOXES) Then $i1 = 17;判断是否有复选框
If _GUICtrlListView_GetImageList($hlst, 1) Then $i2 = 19;判断是否有分配图像列表到列表视图控件
$iEdit_X += ($i2 + $i1)
$iEdit_Width -= ($i2 + $i1)
EndIf
Local $iEdit = GUICtrlCreateInput($aDataArray[$iIndex][$iSub], $iEdit_X, $iEdit_Y, $iEdit_Width, $iEdit_Height, BitOR($WS_CHILD, $WS_VISIBLE, $ES_LEFT))
GUICtrlSetFont($iEdit, 11)
GUICtrlSetState($iEdit, $GUI_FOCUS)
$hEdit = GUICtrlGetHandle($iEdit)
_WinAPI_BringWindowToTop($hEdit)
_GUICtrlEdit_SetSel($hEdit, 0, -1) ;全选编辑框文字
Local $iEnter = GUICtrlCreateDummy()
$hEnter = GUICtrlGetHandle($iEnter)
GUISetAccelerators($aAccelKeys, $hGUI);在虚拟控件上绑定一个回车快捷按键
EndIf
EndFunc
Func _EndItemEdit($hlst, ByRef $aDataArray)
If ($Item < UBound($aDataArray, 1)) And ($SubItem < UBound($aDataArray, 2)) And ($hActLst == $hlst) Then
Local $sText = _GUICtrlEdit_GetText($hEdit)
_GUICtrlListView_SetItemText($hlst, $Item, $sText, $SubItem)
If IsHWnd($hEdit) Then _WinAPI_DestroyWindow($hEdit)
If IsHWnd($hEnter) Then _WinAPI_DestroyWindow($hEnter)
$hEnter = Null
$hEdit = Null
If ($Item >= 0) Then $aDataArray[$Item][$SubItem] = $sText
$Item = -1
$SubItem = 0
EndIf
EndFunc
Func _GetChkIndex($iChkState)
Local $aIndex = [-1], $j = 0
If $ichked = 0 Then Return $aIndex
If $iChkState = 8192 Then
ReDim $aIndex[$ichked]
Else
ReDim $aIndex
EndIf
For $i = 0 To UBound($aShowdata) -1
If $aShowdata[$i] == $iChkState Then
$aIndex[$j] = $i
$j+=1
EndIf
Next
Return $aIndex
EndFunc
Func __ClickListViewItem($hWnd, $iIndex, $baddX = False)
If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)
Local $tRECT = _GUICtrlListView_GetItemRectEx($hWnd, $iIndex, $LVIR_LABEL)
Local $tPoint = _WinAPI_PointFromRect($tRECT, True)
$tPoint = _WinAPI_ClientToScreen($hWnd, $tPoint)
Local $iX, $iY
_WinAPI_GetXYFromPoint($tPoint, $iX, $iY)
If $baddX Then $iX += DllStructGetData($tRECT, "Right")
Local $iMode = Opt("MouseCoordMode", 1)
Local $aPos = MouseGetPos()
MouseClick("left", $iX, $iY, 1, 0)
MouseMove($aPos, $aPos, 0)
Opt("MouseCoordMode", $iMode)
EndFunc
yhjfirst
发表于 2015-11-10 14:15:40
谢谢分享,正需要者呢
xulinghai
发表于 2015-11-11 09:09:46
感谢分享源码,新手下载学习。
athland5013
发表于 2015-11-14 06:26:42
看看~~~~~~~~~
wop3
发表于 2015-11-16 15:50:42
学习学习{:face (356):}
页:
1
2
3
4
[5]
6
7
8
9
10
11
12
13
14