alwaystick
发表于 2015-10-17 11:33:52
ddddddddddddddddd
ncxj
发表于 2015-10-18 07:48:50
很有深度的话题,学习
pchome2000
发表于 2015-10-18 22:09:30
学习下,。…………。…。…。………… 非常有用………………
烧卖
发表于 2015-10-19 11:19:37
谢谢楼主分享 学习学习
kk_lee69
发表于 2015-10-22 22:20:51
回复 1# 298311657
樓主 在請教個問題 ~~~
如何抓取到 複選框 打勾的東西呢??
kk_lee69
发表于 2015-10-22 23:24:15
回复 1# 298311657
在請教一下 樓主
我在 106-109行加入
_GUICtrlListView_SetItemSelected($hListView,$iIndex,True,True)
的判斷 可達到 勾選 就 Selected Item,取消勾選 就取消 Selected
但是 當我勾選 五個以後 按到 LISTVIEW就會變成 只有ㄧ行高亮,其他的有勾選的 就 不會有高亮
如何可以達到 勾選 與 Selected達到一致呢??
298311657
发表于 2015-10-22 23:53:29
回复 36# kk_lee69
你要清楚对于已经勾选的数据,判定它的选择状态是通过勾选框,而不是通过选中行。
我不能理解你为什么要让所有勾选的行都处于选中状态,这是没有必要的。
如果你非要这样做,那么系统自带的listview控件无法达到你的要求,你可以自己去实现一个listview控件来达成目的。
kk_lee69
发表于 2015-10-23 00:09:14
本帖最后由 kk_lee69 于 2015-10-23 00:23 编辑
回复 37# 298311657
我能理解 複選框 與 選中行 是兩件事情.....
但是 我是通常是寫類似ERP 的資料庫軟件,因此 站在使用者的角度 他會希望的 就是 操作上的便利
有人希望 用勾選的這樣不用按鍵盤
有人覺得 可以 按 CTRL +加滑鼠 取選中
但是 對於 程式設計者來說我只是想提供兩種方式 讓大家都滿意,但是 不會希望 兩種方式不同步
因為這樣我後續的程式 必須要寫兩套判斷
簡單的說 LISTVIEW 不透過 複選框 當然也可以複選,所以 在我的角度看來....複選框的目的 只是為了提供 使用者 多一種 勾選的方式風格而以.........所以會希望同步
所以才想說 能不能達到這個.........
很感謝樓主提供這麼好的 範例....... LISTVIEW 編輯 或者 把LISTVIEW 內容按滑鼠右鍵 複製 貼上 外加 可以讓LISTVIEW 變顏色 等等的........這些我現在都已經OK 了......
您的 LISTVIEW 幫助我很大的~~~~ 再次感謝!!
kk_lee69
发表于 2015-10-23 00:19:22
回复 37# 298311657
對了 樓主 您提到.........我不能理解你为什么要让所有勾选的行都处于选中状态,这是没有必要的。
原因有二
1. 複選框勾選了後面 跟著高亮 這樣是不是選了幾筆 都很清楚 ㄧ目暸然
2. 複選框選了3筆資料...... 結果 USER 點擊了一筆資料高亮 ......那這樣是算三筆資料 還是一筆資料,在使用者的角度 可能會產生錯亂
因此 這邊又 產生了 另外個一個問題 請教 樓主:
能夠讓 滑鼠 點擊到 其中某一筆資料的時候 不高亮嗎?? 連INDEX 都不要高亮?? 如果這樣 搭配 複選框,這樣也是一個解決方法.....
298311657
发表于 2015-10-23 00:25:49
回复 35# kk_lee69
#cs ____________________________________
Au3 版本: 3.3.14.2
脚本作者: CrossDoor
电子邮件: 382869232@qq.com
QQ/TM: 382869232
#ce _______________脚本开始_________________
#PRE_UseX64=n
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <GuiImageList.au3>
#include <WindowsConstants.au3>
#include <WinAPISys.au3>
#include <WinAPI.au3>
#include <GuiEdit.au3>
#include <array.au3>
Global $B_DESCENDING ; 排序用数组
Global $hEdit, $Item = -1, $SubItem = 0
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_COMMAND, "WM_COMMAND")
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
$hGUI = GUICreate("ListView虚表 加载[" & $iITEM_COUNT & "]数据 复选框 原地编辑例子 By_Crossdoor", 500, 350)
$hListView = GUICtrlCreateListView("Item1|nSubItem1|nSubItem2", 2, 2, 494, 296, $LVS_SHOWSELALWAYS + $LVS_OWNERDATA, $LVS_EX_GRIDLINES + $LVS_EX_FULLROWSELECT + $LVS_EX_DOUBLEBUFFER + $LVS_EX_CHECKBOXES)
;设置列宽
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
$iMsg = GUIGetMsg()
Switch $iMsg
Case -3
ExitLoop
Case $Button1
$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()
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
#forceref $hWnd, $iMsg, $iwParam
Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $tInfo, $s
$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_CLICK;单击
$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
$tInfo = DllStructCreate($tagNMLVDISPINFO, $ilParam)
DllStructSetData($tInfo, "State", $aShowdata[$iIndex]);设置复选框状态
;====立刻刷新复选框显示状态 重绘$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才响应原地编辑
$Item = $iIndex
$SubItem = $iSub
;==========计算编辑框坐标
Local $aRect = _GUICtrlListView_GetSubItemRect($hListView, $iIndex, $iSub)
Local $iEdit_X = $aRect + 4
Local $iEdit_Y = $aRect + 3
Local $iEdit_Width = _GUICtrlListView_GetColumnWidth($hListView, $iSub) + 3
Local $iEdit_Height = $aRect - $aRect + 3
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
$hEdit = GUICtrlCreateInput($aShowdata[$iIndex][$iSub], $iEdit_X, $iEdit_Y, $iEdit_Width, $iEdit_Height, BitOR($WS_CHILD, $WS_VISIBLE, $ES_LEFT))
GUICtrlSetFont($hEdit, 12)
GUICtrlSetState($hEdit, $GUI_FOCUS)
$hEdit = GUICtrlGetHandle($hEdit)
Send("{RIGHT}") ;方向 →
;~ _GUICtrlEdit_SetSel($hEdit, 0, -1) ;全选编辑框文字
HotKeySet("{ENTER}", "_EndItemEdit");设置热键响应回车
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_COMMAND($hWnd, $Msg, $wParam, $lParam)
$iIDFrom = _WinAPI_LoWord($wParam)
$iCode = _WinAPI_HiWord($wParam)
Switch $lParam
Case $hEdit
Switch $iCode
Case $EN_KILLFOCUS
_EndItemEdit()
Case $EN_UPDATE
EndSwitch
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)
_WinAPI_DestroyWindow($hEdit)
If ($Item >= 0) Then
$aShowdata[$Item][$SubItem] = $sText
GUICtrlSendMsg($hListView, $LVM_ENSUREVISIBLE, 1, 0)
GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 0, 20)
EndIf
$Item = -1
$SubItem = 0
HotKeySet("{ENTER}");取消回车热键
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
298311657
发表于 2015-10-24 23:07:24
本帖最后由 298311657 于 2015-10-24 23:41 编辑
回复 39# 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
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虚表 加载[" & $iITEM_COUNT & "]数据 复选框 原地编辑例子 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
$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, $s
$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, $iIndex
$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 $NM_CLICK;单击
$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
$tInfo = DllStructCreate($tagNMLVDISPINFO, $ilParam)
DllStructSetData($tInfo, "State", $aShowdata[$iIndex]);设置复选框状态
;====立刻刷新复选框显示状态 重绘$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才响应原地编辑
$Item = $iIndex
$SubItem = $iSub
;==========计算编辑框坐??
Local $aRect = _GUICtrlListView_GetSubItemRect($hListView, $iIndex, $iSub)
Local $iEdit_X = $aRect + 4
Local $iEdit_Y = $aRect + 3
Local $iEdit_Width = _GUICtrlListView_GetColumnWidth($hListView, $iSub) + 3
Local $iEdit_Height = $aRect - $aRect + 3
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
$hEdit = GUICtrlCreateInput($aShowdata[$iIndex][$iSub], $iEdit_X, $iEdit_Y, $iEdit_Width, $iEdit_Height, BitOR($WS_CHILD, $WS_VISIBLE, $ES_LEFT))
GUICtrlSetFont($hEdit, 12)
GUICtrlSetState($hEdit, $GUI_FOCUS)
$hEdit = GUICtrlGetHandle($hEdit)
Send("{RIGHT}") ;方向右键
;~ _GUICtrlEdit_SetSel($hEdit, 0, -1) ;全选编辑框文字
HotKeySet("{ENTER}", "_EndItemEdit");设置热键响应回车
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
_EndItemEdit()
Case $EN_UPDATE
EndSwitch
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)
_WinAPI_DestroyWindow($hEdit)
If ($Item >= 0) Then
$aShowdata[$Item][$SubItem] = $sText
GUICtrlSendMsg($hListView, $LVM_ENSUREVISIBLE, 1, 0)
GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 0, 20)
EndIf
$Item = -1
$SubItem = 0
HotKeySet("{ENTER}");取消回车热键
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-10-25 02:18:19
本帖最后由 kk_lee69 于 2015-10-25 02:40 编辑
回复 41# 298311657
感谢!! 楼主的回复太感动了!! 还为了我的 又写了一段范例给我
可能是两岸的关系,所以有些语词表示 大家可能会误解意思 跟不容易了解
您的案例其实是我想要的ㄧ半而已.........
您的这个案例 也是我最近ㄧ直苦恼的问题......引发了自行定义颜色的问题
不知道是否方便看一下
我的ㄧ个发问 http://www.autoitx.com/thread-50282-1-1.html
您上面的案例 我测试也会有ㄧ样的情况 就是您的 上色是以
If $aShowdata[$iIndex] = 4096 Then
DllStructSetData($tCustDraw, 'clrTextBk', 0xFFFFFF);BGR格式颜色值
Else
DllStructSetData($tCustDraw, 'clrTextBk', 0xF7D3AD);BGR格式颜色值
EndIf
当我直接改变 $aShowdata[$iIndex] 的值,程序并不会马上改变 也必须要缩小放大 颜色才会是对的
如何 能做到 改变了 数组的值 颜色就会跟着改呢??
至于前面的问题用 图片表示 可能会清楚点
至于 这些图片怎么来的小弟 有测试出来一个解决的方法.......兹附上 小弟修改后的代码
#cs ____________________________________
Au3 版本: 3.3.14.2
脚本作者: CrossDoor
电子邮件: 382869232@qq.com
QQ/TM: 382869232
#ce _______________脚本开始_________________
#PRE_UseX64=n
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <GuiImageList.au3>
#include <WindowsConstants.au3>
#include <WinAPISys.au3>
#include <GuiEdit.au3>
#include <array.au3>
Global $hEditCheck=0
Global $B_DESCENDING ; 排序用数组
Global $hEdit, $Item = -1, $SubItem = 0
Local $tText = DllStructCreate("wchar Text");建个结构,用来放listview列数据
Local $GUI, $hImage
;Local $iITEM_COUNT = 4194304, $aShowdata[$iITEM_COUNT];注意数组最大项目数为2^24(16777216),所以此处$iITEM_COUNT = 4194304为二维数组$aShowdata最大行数
Local $iITEM_COUNT = 1304, $aShowdata[$iITEM_COUNT];注意数组最大项目数为2^24(16777216),所以此处$iITEM_COUNT = 4194304为二维数组$aShowdata最大行数
Local $sSomeString = ""
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
$hGUI = GUICreate("ListView虚表 加载[" & $iITEM_COUNT & "]数据 复选框 原地编辑例子 By_Crossdoor", 500, 350)
$hListView = GUICtrlCreateListView("Item1|nSubItem1|nSubItem2|nSubItem3", 2, 2, 494, 294, $LVS_SHOWSELALWAYS + $LVS_OWNERDATA, $LVS_EX_GRIDLINES + $LVS_EX_FULLROWSELECT + $LVS_EX_DOUBLEBUFFER + $LVS_EX_CHECKBOXES)
;设置列宽
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);分配图像列表到列表视图控件
$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 = 13 Then GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 0, $i)
$aShowdata[$i] = "爷爷" & $i
$aShowdata[$i] = "爸爸" & $i
$aShowdata[$i] = "儿子" & $i
$aShowdata[$i] = 4096;复选框状态 4096未选中 8192选中
Next
While 1
$iMsg = GUIGetMsg()
Switch $iMsg
Case -3
ExitLoop
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
_ArrayDisplay($aShowdata)
; $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()
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
#forceref $hWnd, $iMsg, $iwParam
Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $tInfo, $s
$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_CLICK;单击
$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
$aShowdata[$iIndex] = 8192;4096未选中 8192选中
_GUICtrlListView_SetItemSelected($hListView,$iIndex,True,True)
Else
$aShowdata[$iIndex] = 4096;4096未选中 8192选中
_GUICtrlListView_SetItemSelected($hListView,$iIndex,False,True)
EndIf
$tInfo = DllStructCreate($tagNMLVDISPINFO, $ilParam)
DllStructSetData($tInfo, "State", $aShowdata[$iIndex]);设置复选框状态
;====立刻刷新复选框显示状态 重绘$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才回应原地编辑
$Item = $iIndex
$SubItem = $iSub
;==========计算编辑框坐标
Local $aRect = _GUICtrlListView_GetSubItemRect($hListView, $iIndex, $iSub)
Local $iEdit_X = $aRect + 4
Local $iEdit_Y = $aRect + 3
Local $iEdit_Width = _GUICtrlListView_GetColumnWidth($hListView, $iSub) + 3
Local $iEdit_Height = $aRect - $aRect + 3
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
$hEdit = _GUICtrlEdit_Create($hWnd, $aShowdata[$iIndex][$iSub], $iEdit_X, $iEdit_Y, $iEdit_Width, $iEdit_Height, BitOR($WS_CHILD, $WS_VISIBLE, $ES_AUTOHSCROLL, $ES_LEFT))
_WinAPI_SetFocus($hEdit)
Send("{RIGHT}")
_GUICtrlEdit_SetSel($hEdit, 0, -1)
HotKeySet("{ENTER}", "_EndItemEdit");设置热键回应回车
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属性,有则设置列图像
If (BitAND(_GUICtrlListView_GetExtendedListViewStyle($hListView), $LVS_EX_CHECKBOXES) = $LVS_EX_CHECKBOXES) AND _GUICtrlListView_GetItemSelected($hListView,$iIndex)=1 Then
;===============设置复选框信息
DllStructSetData($tInfo, "Mask", BitOR($LVIF_STATE, DllStructGetData($tInfo, "Mask")))
DllStructSetData($tInfo, "StateMask", $LVIS_STATEIMAGEMASK)
DllStructSetData($tInfo, "State", 8192)
$aShowdata[$iIndex] = 8192
Else
DllStructSetData($tInfo, "Mask", BitOR($LVIF_STATE, DllStructGetData($tInfo, "Mask")))
DllStructSetData($tInfo, "StateMask", $LVIS_STATEIMAGEMASK)
DllStructSetData($tInfo, "State", 4096)
$aShowdata[$iIndex] = 4096
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_COMMAND($hWnd, $Msg, $wParam, $lParam)
$iIDFrom = _WinAPI_LoWord($wParam)
$iCode = _WinAPI_HiWord($wParam)
Switch $lParam
Case $hEdit
Switch $iCode
Case $EN_KILLFOCUS
_EndItemEdit()
Case $EN_UPDATE
EndSwitch
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)
_WinAPI_DestroyWindow($hEdit)
If ($Item >= 0) Then
$aShowdata[$Item][$SubItem] = $sText
GUICtrlSendMsg($hListView, $LVM_ENSUREVISIBLE, 1, 0)
GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 0, 20)
EndIf
$Item = -1
$SubItem = 0
HotKeySet("{ENTER}");取消回车热键
EndIf
EndFunc ;==>_EndItemEdit
kk_lee69
发表于 2015-10-25 02:25:41
本帖最后由 kk_lee69 于 2015-10-25 02:38 编辑
回复 41# 298311657
能夠 直接用按鈕 發消息給WM_NOTIF 讓她重新繪製 LISTVIEW 嗎
298311657
发表于 2015-10-25 09:06:34
本帖最后由 298311657 于 2015-10-25 09:09 编辑
回复 43# kk_lee69
数据改变后,要立即显示,需向控件发送$LVM_REDRAWITEMS消息,让控件立即刷新显示数据。
;====立刻刷新$iIndex-1到iIndex+20的项
GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, $iIndex - 1, $iIndex + 20)
你的测试代码改成这样即可
Case $Button1
$aShowdata = 8192
$aShowdata = 8192
GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 3, 7)
kk_lee69
发表于 2015-10-25 12:31:08
回复 44# 298311657
感謝樓主~~ 這樣一來 虛擬 LISTVIEW 的功能就齊全了~~~
其實~~ 懂得 虛擬 LISTVIEW之後 我覺得它比 標準的 LISTVIEW 好用多了~~~
除了快以外 最大的優勢是 只要改變 陣列(數組) 的內容~~~ 就是改變 LISTVIEW 的內容了
页:
1
2
[3]
4
5
6
7
8
9
10
11
12