找回密码
 加入
搜索
楼主: 298311657

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

 火... [复制链接]
发表于 2017-12-4 09:26:27 | 显示全部楼层
必须回复啊
发表于 2017-12-4 09:50:30 | 显示全部楼层
谢谢楼主分享。
发表于 2017-12-13 21:24:57 | 显示全部楼层
谢谢分享,研究一下
发表于 2017-12-17 15:50:43 | 显示全部楼层
现在回复算不算挖坟
发表于 2017-12-17 22:01:18 | 显示全部楼层
不错啊。很实用啊。。
发表于 2017-12-22 18:52:54 | 显示全部楼层
回复 1# 298311657


   
谢谢分享!!。。
发表于 2018-2-27 13:04:03 | 显示全部楼层
参考参考。。。。
发表于 2018-3-5 11:11:02 | 显示全部楼层
支持一下..
发表于 2018-3-5 12:35:19 | 显示全部楼层
回复 1# 298311657


    这个必须要学习一下~~~
发表于 2018-3-17 15:21:38 | 显示全部楼层
感谢楼主分享
发表于 2018-3-22 22:56:02 | 显示全部楼层
回复 1# 298311657

請問 圖標 可以加在SUBITEM 嗎
 楼主| 发表于 2018-3-26 18:10:05 | 显示全部楼层
回复 177# kk_lee69


使用下面的方法:
_GUICtrlListView_SetExtendedListViewStyle($hListView, BitOR($LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_SUBITEMIMAGES)); ++++++++++++++++++++++++允许显示子项目图像
这是完整示例:
#cs ____________________________________
    Au3 版本: 3.3.14.2
    脚本作者: CrossDoor
    电子邮件: [email]382869232@qq.com[/email]
    QQ/TM: 382869232
#ce _______________脚本开始_________________
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <GuiImageList.au3>
#include <WindowsConstants.au3>
#include <WinAPISys.au3>
#include <GuiEdit.au3>
#include <array.au3>

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

Global $hEdit, $Item = -1, $SubItem = 0

Local $tText = DllStructCreate("wchar Text[512]");建个结构,用来放listview列数据
Local $GUI, $hImage, $iITEM_COUNT = 10000
Local $sSomeString = ""
Local $aShowdata[$iITEM_COUNT][4]
For $i = 0 To $iITEM_COUNT - 1;初始化数组
    $aShowdata[$i][0] = "爷爷" & $i
    $aShowdata[$i][1] = "爸爸" & $i
    $aShowdata[$i][2] = "儿子" & $i
    $aShowdata[$i][3] = 4096;复选框状态 4096未选中 8192选中
Next

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, 294, $LVS_SHOWSELALWAYS + $LVS_OWNERDATA, $LVS_EX_GRIDLINES + $LVS_EX_FULLROWSELECT + $LVS_EX_DOUBLEBUFFER + $LVS_EX_CHECKBOXES)
_GUICtrlListView_SetExtendedListViewStyle($hListView, BitOR($LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_SUBITEMIMAGES)); ++++++++++++++++++++++++允许显示子项目图像

;设置列宽
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_SetIconSize($hImage, 32, 16); ++++++++++++++++++++++++设置图像列表大小
_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()

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][0] = "爷爷" & $i & "-" & $sSomeString
                $aShowdata[$i][1] = "爸爸" & $i & "-" & $sSomeString
                $aShowdata[$i][2] = "儿子" & $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][3] = 4096 Then
                            $aShowdata[$iIndex][3] = 8192;4096未选中 8192选中
                        Else
                            $aShowdata[$iIndex][3] = 4096;4096未选中 8192选中
                        EndIf
                        $tInfo = DllStructCreate($tagNMLVDISPINFO, $ilParam)
                        DllStructSetData($tInfo, "State", $aShowdata[$iIndex][3]);设置复选框状态
                        ;====立刻刷新复选框显示状态 重绘$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[0] + 4
                        Local $iEdit_Y = $aRect[1] + 3
                        Local $iEdit_Width = _GUICtrlListView_GetColumnWidth($hListView, $iSub) + 3
                        Local $iEdit_Height = $aRect[3] - $aRect[1] + 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);判断0列是否有LVIF_IMAGE属性,有则设置列图像

                    If (BitAND(_GUICtrlListView_GetExtendedListViewStyle($hListView), $LVS_EX_CHECKBOXES) = $LVS_EX_CHECKBOXES) And $iSub = 0 Then ;++++++++++++++++++++++++在0列设置复选框信息,同列也可以在子列设置复选框,但子列选中操作需另写代码
                        DllStructSetData($tInfo, "Mask", BitOR($LVIF_STATE,DllStructGetData($tInfo, "Mask")))
                        DllStructSetData($tInfo, "StateMask", $LVIS_STATEIMAGEMASK)
                        DllStructSetData($tInfo, "State", $aShowdata[$iIndex][3])
                    EndIf

                    DllStructSetData($tText, "Text", $aShowdata[$iIndex][$iSub]);列数据放入$tText结构
                    DllStructSetData($tInfo, "Text", DllStructGetPtr($tText));用$tText结构的指针来设置列数据
                    DllStructSetData($tInfo, "TextMax", StringLen($aShowdata[$iIndex][$iSub]));设置列数据长度

                    If BitAND(DllStructGetData($tInfo, "Mask"), $LVIF_IMAGE) And $iSub = 1 Then DllStructSetData($tInfo, "Image", 0); ++++++++++++++++++++++++判断是否子列1是否有LVIF_IMAGE属性,有则设置列图像,其它子列同理
            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
发表于 2018-4-2 00:09:16 | 显示全部楼层
回复 5# wangms

老大  有上線幫我看一下

关于listview虚表直接读取数据库的方法,求助修改范例成SQL的!!

官网有个范例 是listview虚表 直接拿SQLlite 的数据库 当作 listview虚表的数据 直接使用,这样的好处是 即使你的数据再多 也是分次 读取 就不会卡了
无奈 小弟 对于 SQLLITE的 UDF 实在没辙,我研究了半天 总是搞不懂原理
无法改成 把SQL DB 当作数据库来源的方法 ,所以上来求助

listview虚表 我已经很熟了  所以理论上不应该是我不会使用,只是以前的方法都是读进
数组  然后 利用数组 当作listview虚表 的数据源

只是最近遇到了 数据太多 读进数组太慢  想要改成 分次读取 分次秀出的方法

所以才把脑筋动到了 数据库上……

看看 可不可以給個範例
发表于 2018-4-2 10:44:40 | 显示全部楼层
这个要看看,谢谢楼主分享。
发表于 2018-4-3 12:49:55 | 显示全部楼层
这个好,看看怎么搞。
您需要登录后才可以回帖 登录 | 加入

本版积分规则

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

GMT+8, 2024-12-23 04:25 , Processed in 0.071792 second(s), 15 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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