找回密码
 加入
搜索
查看: 13784|回复: 57

[效率算法] kk请进。listview麻烦看看能不能改虚拟列表写法【已解决】

  [复制链接]
发表于 2017-9-5 10:44:55 | 显示全部楼层 |阅读模式
本帖最后由 yamakawa 于 2017-9-20 21:44 编辑

闲的蛋疼,用wm_drawitem消息重绘列表,然后不知道什么缘故,滚动条滚动过快,就会停止响应,网上说是消息响应过度,,,,郁闷的是找不到解决方法。。弄来弄去,变成个很奇怪的东西。。。你帮我看下。能不能改成虚拟列表方式加载?
#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include <WinAPI.au3>
#include <ButtonConstants.au3>
#include <GDIPlus.au3>
#NoTrayIcon
#cs
        autoit.com yamakawa
        测试环境 win10 x64
        autoit3 3.3.14.2
#ce
;版本判断
Local $verArray = StringSplit(@AutoItVersion, ".")
If $verArray[3] < 14 Then MsgBox(4096, "来自Autoit.com -Yamakawa的提示", "本段代码测试于 Autoit 3.3.14.2!" & @CRLF & @CRLF & @CRLF & "当前版本低于3.3.14.2 如果出现问题,请自行修改!")
;低于3.3.14.2则弹出提示。不兼容可能是版本问题

Global Const $ODT_LISTVIEW = 102
Global Const $ODA_DRAWENTIRE = 0x1
Global Const $ODA_SELECT = 0x2
Global Const $ODA_FOCUS = 0x4
Global Const $ODS_SELECTED = 0x0001

$hGUI = GUICreate("Test GUI", 650, 300)
;===第一个列表
$lListView = GUICtrlCreateListView("Items|SubItems", 10, 10, 280, 180, BitOR($LVS_REPORT, $LVS_OWNERDRAWFIXED))
$hlListView = GUICtrlGetHandle(-1)
_GUICtrlListView_SetExtendedListViewStyle($hlListView, $LVS_EX_FULLROWSELECT)
_GUICtrlListView_SetColumnWidth($hlListView, 0, 120)
_GUICtrlListView_SetColumnWidth($hlListView, 1, 120)

;计划填充进去的数据
Local $dataArray[10000][2]
For $i = 0 To 10000 - 1
        $dataArray[$i][0] = "Item " & $i + 1
        $dataArray[$i][1] = "SubItem " & $i + 1
Next

GUICtrlSendMsg($hlListView, $LVM_SETITEMCOUNT, 10000, 0) ;

;第二个列表
$rListView = GUICtrlCreateListView("", 310, 10, 280, 180)
$hrListView = GUICtrlGetHandle(-1)
_GUICtrlListView_SetExtendedListViewStyle($hrListView, $LVS_EX_FULLROWSELECT)

_GUICtrlListView_InsertColumn($hrListView, 0, "隐藏列", 0)
_GUICtrlListView_InsertColumn($hrListView, 1, "列1", 120)
_GUICtrlListView_InsertColumn($hrListView, 2, "列2", 120)


GUICtrlCreateLabel("双击左边列表项," & @CRLF & "如果当前项在右边列表不存在,则建立" & @CRLF & "如果当前项在右边列表存在,则删除", 10, 200)
GUICtrlCreateLabel("双击右边列表项-------------删除项目",320,200)
$do = GUICtrlCreateButton("text", 10, 250)
GUICtrlSetStyle(-1, BitOR($WS_TABSTOP, $BS_NOTIFY, $BS_OWNERDRAW)) ;
GUICtrlCreateLabel("←←←←←←←这个按钮感觉如何(我指的形状)", 50, 255)
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

GUIRegisterMsg($WM_DRAWITEM, "WM_DRAWITEM")

GUISetState()

For $i = 1 To 10000;这里填写什么都没用,都会被重绘掉,,,但是不写的话,,会取不到总行数?!
        _GUICtrlListView_AddItem($hlListView, "22")
        _GUICtrlListView_AddSubItem($hlListView, $i - 1, "222", 1)
Next

While 1
        Switch GUIGetMsg()
                Case -3
                        Exit
                Case $do
                        MsgBox(0, "", "你点击了按钮!", 0, $hGUI)

        EndSwitch
WEnd

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 $rListView
                        If $iCode <> $NM_DBLCLK Then Return $GUI_RUNDEFMSG
                        $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
                                        Local $index = DllStructGetData($tInfo, "Index")
                                                                                        _GUICtrlListView_DeleteItem($rListView, $index)

                Case $lListView
                        
                        Switch $iCode
                                Case $NM_DBLCLK
                                        $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
                                        Local $index = DllStructGetData($tInfo, "Index")
                                        Local $newIndex = _GUICtrlListView_FindText($rListView, String($lListView & "," & $index))
                                        If $newIndex <> -1 Then
                                                _GUICtrlListView_DeleteItem($rListView, $newIndex)
                                        Else
                                                $newIndex = _GUICtrlListView_AddItem($hrListView, String($lListView & "," & $index))
                                                For $i = 0 To UBound($dataArray, 2) - 1
                                                        _GUICtrlListView_AddSubItem($hrListView, $newIndex, $dataArray[$index][$i], $i + 1)
                                                Next
                                        EndIf
                                        Return 0
                        EndSwitch
        EndSwitch
        Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func WM_DRAWITEM($hWnd, $Msg, $wParam, $lParam)
        Local $tagDRAWITEMSTRUCT, $iBrushColor, $cID, $itmID, $itmAction, $itmState, $hItm, $hDC, $bSelected, $oldColor
        $tagDRAWITEMSTRUCT = DllStructCreate( _
                        "uint cType;" & _ 
                        "uint cID;" & _ 
                        "uint itmID;" & _ 
                        "uint itmAction;" & _ 
                        "uint itmState;" & _ 
                        "hwnd hItm;" & _ 
                        "handle hDC;" & _ 
                        "long itmRect[4];" & _ 
                        "ulong_ptr itmData" _ 
                        , $lParam)
        $cID = $tagDRAWITEMSTRUCT.cID
        $itmID = $tagDRAWITEMSTRUCT.itmID
        $hItm = $tagDRAWITEMSTRUCT.hItm
        $hDC = $tagDRAWITEMSTRUCT.hDC
        If $tagDRAWITEMSTRUCT.cType <> $ODT_LISTVIEW Then Return $GUI_RUNDEFMSG ;重绘的控件类型
        If $tagDRAWITEMSTRUCT.itmAction <> $ODA_DRAWENTIRE Then Return $GUI_RUNDEFMSG ;全部重绘

        
        ;>====设置选中项文字颜色
        $txtcolor = BitAND($tagDRAWITEMSTRUCT.itmState, $ODS_SELECTED) = $ODS_SELECTED ? 0xffffff : 0x000000
        _WinAPI_SetTextColor($hDC, $txtcolor)
        ;<=====

        ;>=========
        Local $tRect = DllStructGetPtr($tagDRAWITEMSTRUCT, "itmRect") ;====这个学习了。。
;~ Local $tRect = DllStructCreate($tagRect,DllStructGetPtr($tagDRAWITEMSTRUCT, "itmRect"));====这样也可以。好处是可以修改
        $iBrushColor = BitAND($tagDRAWITEMSTRUCT.itmState, $ODS_SELECTED) = $ODS_SELECTED ? 0xff7bcc : 0xffffff ;上色
        Local $aBrush = _WinAPI_CreateSolidBrush($iBrushColor)
        Local $aBrushOld = _WinAPI_SelectObject($hDC, $aBrush)
        _WinAPI_FillRect($hDC, $tRect, $aBrush)
        _WinAPI_SelectObject($hDC, $aBrushOld)
        _WinAPI_DeleteObject($aBrush)
        ;<=====画背景
        
        ;如果用这段代码,那上面直接写的数据会在,但是滚动条滚动太快,程序就宕机了
;~ ;========重新填充数据,
;~         For $i = 0 To _GUICtrlListView_GetColumnCount($hItm)
;~                 Local $iItmRect = DllStructCreate($tagRect)
;~                 If $i Then $iItmRect.top = $i ;这句啥意思还不理解。。。。。。怎么想来想去好像是列索引的意思???可是这个结构中不是指的top么??
;~                 DllCall('user32.dll', 'int', 'SendMessage', 'hwnd', $hItm, 'uint', $LVM_GETSUBITEMRECT, 'wparam', $itmID, 'lparam', DllStructGetPtr($iItmRect))
;~                 $iItmRect.left = $i ? $iItmRect.left + 5 : $iItmRect.left + 10 ;首项缩进10,其他缩进5
;~                 _WinAPI_DrawText($hDC, $dataArray[$itmID][$i], $iItmRect, $DT_LEFT)
;~         Next
;~ ;============好像会导致bug,弃用
;~
        For $i = 0 To _GUICtrlListView_GetColumnCount($hItm) - 1
                ConsoleWrite("当前项是 :" & $itmID & "子项是 " & $i & @CRLF)
                If $i = 0 Then
                        Local $iItmRect = DllStructCreate($tagRect)
                        DllCall('user32.dll', 'int', 'SendMessage', 'hwnd', $hItm, 'uint', $LVM_GETSUBITEMRECT, 'wparam', $itmID, 'lparam', DllStructGetPtr($iItmRect))
                        $iItmRect.left += 10
                        _WinAPI_DrawText($hDC, $dataArray[$itmID][0], $iItmRect, $DT_LEFT)
                Else
                        Local $iItmRect = DllStructCreate($tagRect)
                        $iItmRect.top = $i
                        DllCall('user32.dll', 'int', 'SendMessage', 'hwnd', $hItm, 'uint', $LVM_GETSUBITEMRECT, 'wparam', $itmID, 'lparam', DllStructGetPtr($iItmRect))
                        $iItmRect.left += 5
                        _WinAPI_DrawText($hDC, $dataArray[$itmID][$i], $iItmRect, $DT_LEFT)
                EndIf
        Next

        Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_DRAWITEM
发表于 2017-9-5 11:43:51 | 显示全部楼层
回复 1# yamakawa

研究看看   不過要抽空  上班中 ~~ 呵呵
发表于 2017-9-5 11:51:22 | 显示全部楼层
回复 1# yamakawa

你的第一個 LISTVIEW 就是虛擬的  第二個不是.....

你現在的問題是 第一個 出問題 還是....第二個LISTVIEW
 楼主| 发表于 2017-9-5 12:00:27 | 显示全部楼层
我的问题是
 GUICtrlSendMsg($hlListView, $LVM_SETITEMCOUNT, 100, 0) ;
 _GUICtrlListView_SetItemCount($lListView, 10000)
这两个都获取不到行数
要傻乎乎的先填充才可以得到行数。。
For $i = 1 To 10000 ;这里填写什么都没用,都会被重绘掉,,,但是不写的话,,会取不到总行数?!
        _GUICtrlListView_AddItem($hlListView, "22")
        _GUICtrlListView_AddSubItem($hlListView, $i - 1, "222", 1)
Next
发表于 2017-9-5 12:02:54 | 显示全部楼层
回复 4# yamakawa

本帖子中包含更多资源

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

×
 楼主| 发表于 2017-9-5 12:28:27 | 显示全部楼层
回复 5# kk_lee69


    ?????什么意思?我那个代码现在已经不会宕机了。。。如果用注释掉的会挂
 楼主| 发表于 2017-9-5 12:30:08 | 显示全部楼层
回复 5# kk_lee69


就是说如果不用虚拟列表就会挂。。。但是用了以后,无法设置行数。。得填充
发表于 2017-9-5 13:37:13 | 显示全部楼层
回复 4# yamakawa

用虛擬的 總行數 不就是 陣列(數組)的行數嗎??
发表于 2017-9-5 13:39:11 | 显示全部楼层
回复 6# yamakawa

你的意思是 要用這段??

        ;如果用這段代碼,那上面直接寫的資料會在,但是捲軸滾動太快,程式就宕機了
;~ ;========重新填充數據,
;~         For $i = 0 To _GUICtrlListView_GetColumnCount($hItm)
;~                 Local $iItmRect = DllStructCreate($tagRect)
;~                 If $i Then $iItmRect.top = $i ;這句啥意思還不理解。。。。。。怎麼想來想去好像是列索引的意思???可是這個結構中不是指的top麼??
;~                 DllCall('user32.dll', 'int', 'SendMessage', 'hwnd', $hItm, 'uint', $LVM_GETSUBITEMRECT, 'wparam', $itmID, 'lparam', DllStructGetPtr($iItmRect))
;~                 $iItmRect.left = $i ? $iItmRect.left + 5 : $iItmRect.left + 10 ;首項縮進10,其他縮進5
;~                 _WinAPI_DrawText($hDC, $dataArray[$itmID][$i], $iItmRect, $DT_LEFT)
;~         Next
;~ ;============好像會導致bug,棄用
;~

那麼 哪一段又得拿掉呢??
发表于 2017-9-5 13:41:15 | 显示全部楼层
回复 4# yamakawa

For $i = 1 To 10000 ;这里填写什么都没用,都会被重绘掉,,,但是不写的话,,会取不到总行数?!

        _GUICtrlListView_AddItem($hlListView, "22")

        _GUICtrlListView_AddSubItem($hlListView, $i - 1, "222", 1)

Next


這段如果只是為了得到總行數  那就不用寫  因為 就是 陣列(數組) 的行數 不是??
 楼主| 发表于 2017-9-5 13:42:19 | 显示全部楼层
回复 10# kk_lee69


    你试试,,注释这个界面就没内容了
 楼主| 发表于 2017-9-5 13:43:13 | 显示全部楼层
回复 9# kk_lee69


    这段代码下面那些拿掉
 楼主| 发表于 2017-9-5 13:44:51 | 显示全部楼层
回复 9# kk_lee69


    另外,drawtext的第二个参数得处理下,,不用数组而是直接从listview获取
 楼主| 发表于 2017-9-5 13:49:38 | 显示全部楼层
回复 10# kk_lee69


    还有个很好玩的地方,,,界面刚启动你就去点击列表,你会发现,会变色,这说明程序空闲?但是去点击左下角那个按钮,你会发现要等一段时间才会弹出提示框 这说明程序没运行到这,,,,那为什么还会变色呢?
发表于 2017-9-5 14:27:39 | 显示全部楼层
回复 11# yamakawa

請看以下的範例

你說  必須要填值  雖然會被蓋掉

你說 不信我註釋掉  就不會有內容出現

那是因為 你少了幾個東西   請看下面範例

1. 你少為TXT 宣告一個存放位置
Global $tText = DllStructCreate("wchar Text[256]");建個結構,用來放listview列資料

2. 你的風格有點怪 換成我的就可以
$lListView = GUICtrlCreateListView("Items|SubItems", 10, 10, 280, 180, BitOR($LVS_REPORT, $LVS_SHOWSELALWAYS, $LVS_OWNERDATA), $LVS_EX_GRIDLINES + $LVS_EX_FULLROWSELECT + $LVS_EX_DOUBLEBUFFER )

3.  GUICtrlSendMsg($lListView, $LVM_SETITEMCOUNT, 10000, 0) ;
這個位置 要用控件ID $lListView 而不是 句柄

4. 你少了 顯示處理的部分
Case -150, -177 ;$LVN_GETDISPINFOA = -150, $LVN_GETDISPINFOW = -177   請求顯示資料
        If Not IsArray($dataArray) Then Return
        $tInfo = DllStructCreate($tagNMLVDISPINFO, $ilParam)
        $iIndex = Int(DllStructGetData($tInfo, "Item"))
        $iSub = Int(DllStructGetData($tInfo, "SubItem"))

        DllStructSetData($tText, "Text", $dataArray[$iIndex][$iSub]);列資料放入$tText結構
        DllStructSetData($tInfo, "Text", DllStructGetPtr($tText));$tText結構的指標來設置列資料
        DllStructSetData($tInfo, "TextMax", StringLen($dataArray[$iIndex][$iSub]));設置列資料字串長




#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include <WinAPI.au3>
#include <ButtonConstants.au3>
#include <GDIPlus.au3>
#NoTrayIcon
#cs
        autoit.com yamakawa
        測試環境 win10 x64
        autoit3 3.3.14.2
#ce
;版本判斷
Local $verArray = StringSplit(@AutoItVersion, ".")
If $verArray[3] < 14 Then MsgBox(4096, "來自Autoit.com -Yamakawa的提示", "本段代碼測試於 Autoit 3.3.14.2!" & @CRLF & @CRLF & @CRLF & "當前版本低於3.3.14.2 如果出現問題,請自行修改!")
;低於3.3.14.2則彈出提示。不相容可能是版本問題

Global Const $ODT_LISTVIEW = 102
Global Const $ODA_DRAWENTIRE = 0x1
Global Const $ODA_SELECT = 0x2
Global Const $ODA_FOCUS = 0x4
Global Const $ODS_SELECTED = 0x0001
;-----------------------------------------------------------------------------------------------------------------增加部分
Global $tText = DllStructCreate("wchar Text[256]");建個結構,用來放listview列資料
;-------------------------------------------------------------------------------------------------------------------------

$hGUI = GUICreate("Test GUI", 650, 300)
;===第一個列表
;$lListView = GUICtrlCreateListView("Items|SubItems", 10, 10, 280, 180, BitOR($LVS_REPORT, $LVS_OWNERDRAWFIXED))
$lListView = GUICtrlCreateListView("Items|SubItems", 10, 10, 280, 180, BitOR($LVS_REPORT, $LVS_SHOWSELALWAYS, $LVS_OWNERDATA), $LVS_EX_GRIDLINES + $LVS_EX_FULLROWSELECT + $LVS_EX_DOUBLEBUFFER )
$hlListView = GUICtrlGetHandle(-1)
;_GUICtrlListView_SetExtendedListViewStyle($hlListView, $LVS_EX_FULLROWSELECT)
_GUICtrlListView_SetColumnWidth($hlListView, 0, 120)
_GUICtrlListView_SetColumnWidth($hlListView, 1, 120)

;計畫填充進去的資料
Local $dataArray[10000][2]
For $i = 0 To 10000 - 1
        $dataArray[$i][0] = "Item " & $i + 1
        $dataArray[$i][1] = "SubItem " & $i + 1
Next

;GUICtrlSendMsg($hlListView, $LVM_SETITEMCOUNT, 10000, 0) ;
GUICtrlSendMsg($lListView, $LVM_SETITEMCOUNT, 10000, 0) ;

;第二個列表
$rListView = GUICtrlCreateListView("", 310, 10, 280, 180)
$hrListView = GUICtrlGetHandle(-1)
_GUICtrlListView_SetExtendedListViewStyle($hrListView, $LVS_EX_FULLROWSELECT)

_GUICtrlListView_InsertColumn($hrListView, 0, "隱藏列", 0)
_GUICtrlListView_InsertColumn($hrListView, 1, "列1", 120)
_GUICtrlListView_InsertColumn($hrListView, 2, "列2", 120)


GUICtrlCreateLabel("按兩下左邊列表項," & @CRLF & "如果當前項在右邊列表不存在,則建立" & @CRLF & "如果當前項在右邊列表存在,則刪除", 10, 200)
GUICtrlCreateLabel("按兩下右邊列表項-------------刪除項目",320,200)
$do = GUICtrlCreateButton("text", 10, 250)
GUICtrlSetStyle(-1, BitOR($WS_TABSTOP, $BS_NOTIFY, $BS_OWNERDRAW)) ;
GUICtrlCreateLabel("←←←←←←←這個按鈕感覺如何(我指的形狀)", 50, 255)
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

GUIRegisterMsg($WM_DRAWITEM, "WM_DRAWITEM")

GUISetState()

;For $i = 1 To 10000;這裡填寫什麼都沒用,都會被重繪掉,,,但是不寫的話,,會取不到總行數?!
;        _GUICtrlListView_AddItem($hlListView, "22")
;        _GUICtrlListView_AddSubItem($hlListView, $i - 1, "222", 1)
;Next

While 1
        Switch GUIGetMsg()
                Case -3
                        Exit
                Case $do
                        MsgBox(0, "", "你點擊了按鈕!", 0, $hGUI)

        EndSwitch
WEnd

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 $rListView
                        If $iCode <> $NM_DBLCLK Then Return $GUI_RUNDEFMSG
                        $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
                                        Local $index = DllStructGetData($tInfo, "Index")
                                                                                        _GUICtrlListView_DeleteItem($rListView, $index)

                Case $lListView
                        
                        Switch $iCode
                                Case $NM_DBLCLK
                                        $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
                                        Local $index = DllStructGetData($tInfo, "Index")
                                        Local $newIndex = _GUICtrlListView_FindText($rListView, String($lListView & "," & $index))
                                        If $newIndex <> -1 Then
                                                _GUICtrlListView_DeleteItem($rListView, $newIndex)
                                        Else
                                                $newIndex = _GUICtrlListView_AddItem($hrListView, String($lListView & "," & $index))
                                                For $i = 0 To UBound($dataArray, 2) - 1
                                                        _GUICtrlListView_AddSubItem($hrListView, $newIndex, $dataArray[$index][$i], $i + 1)
                                                Next
                                        EndIf
                                        Return 0
                                                                ;----------------------------------------------------------------------------------------------------                
                                                                Case -150, -177 ;$LVN_GETDISPINFOA = -150, $LVN_GETDISPINFOW = -177   請求顯示資料
                                                                        If Not IsArray($dataArray) Then Return
                                                                        $tInfo = DllStructCreate($tagNMLVDISPINFO, $ilParam)
                                                                        $iIndex = Int(DllStructGetData($tInfo, "Item"))
                                                                        $iSub = Int(DllStructGetData($tInfo, "SubItem"))

                                                                        DllStructSetData($tText, "Text", $dataArray[$iIndex][$iSub]);列資料放入$tText結構
                                                                        DllStructSetData($tInfo, "Text", DllStructGetPtr($tText));$tText結構的指標來設置列資料
                                                                        DllStructSetData($tInfo, "TextMax", StringLen($dataArray[$iIndex][$iSub]));設置列資料字串長
                                                                                
                        EndSwitch
        EndSwitch
        Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func WM_DRAWITEM($hWnd, $Msg, $wParam, $lParam)
        Local $tagDRAWITEMSTRUCT, $iBrushColor, $cID, $itmID, $itmAction, $itmState, $hItm, $hDC, $bSelected, $oldColor
        $tagDRAWITEMSTRUCT = DllStructCreate( _
                        "uint cType;" & _ 
                        "uint cID;" & _ 
                        "uint itmID;" & _ 
                        "uint itmAction;" & _ 
                        "uint itmState;" & _ 
                        "hwnd hItm;" & _ 
                        "handle hDC;" & _ 
                        "long itmRect[4];" & _ 
                        "ulong_ptr itmData" _ 
                        , $lParam)
        $cID = $tagDRAWITEMSTRUCT.cID
        $itmID = $tagDRAWITEMSTRUCT.itmID
        $hItm = $tagDRAWITEMSTRUCT.hItm
        $hDC = $tagDRAWITEMSTRUCT.hDC
        If $tagDRAWITEMSTRUCT.cType <> $ODT_LISTVIEW Then Return $GUI_RUNDEFMSG ;重繪的控制項類型
        If $tagDRAWITEMSTRUCT.itmAction <> $ODA_DRAWENTIRE Then Return $GUI_RUNDEFMSG ;全部重繪

        
        ;>====設置選中項文字顏色
        $txtcolor = BitAND($tagDRAWITEMSTRUCT.itmState, $ODS_SELECTED) = $ODS_SELECTED ? 0xffffff : 0x000000
        _WinAPI_SetTextColor($hDC, $txtcolor)
        ;<=====

        ;>=========
        Local $tRect = DllStructGetPtr($tagDRAWITEMSTRUCT, "itmRect") ;====這個學習了。。
;~ Local $tRect = DllStructCreate($tagRect,DllStructGetPtr($tagDRAWITEMSTRUCT, "itmRect"));====這樣也可以。好處是可以修改
        $iBrushColor = BitAND($tagDRAWITEMSTRUCT.itmState, $ODS_SELECTED) = $ODS_SELECTED ? 0xff7bcc : 0xffffff ;上色
        Local $aBrush = _WinAPI_CreateSolidBrush($iBrushColor)
        Local $aBrushOld = _WinAPI_SelectObject($hDC, $aBrush)
        _WinAPI_FillRect($hDC, $tRect, $aBrush)
        _WinAPI_SelectObject($hDC, $aBrushOld)
        _WinAPI_DeleteObject($aBrush)
        ;<=====畫背景
        
        ;如果用這段代碼,那上面直接寫的資料會在,但是捲軸滾動太快,程式就宕機了
;~ ;========重新填充數據,
;~         For $i = 0 To _GUICtrlListView_GetColumnCount($hItm)
;~                 Local $iItmRect = DllStructCreate($tagRect)
;~                 If $i Then $iItmRect.top = $i ;這句啥意思還不理解。。。。。。怎麼想來想去好像是列索引的意思???可是這個結構中不是指的top麼??
;~                 DllCall('user32.dll', 'int', 'SendMessage', 'hwnd', $hItm, 'uint', $LVM_GETSUBITEMRECT, 'wparam', $itmID, 'lparam', DllStructGetPtr($iItmRect))
;~                 $iItmRect.left = $i ? $iItmRect.left + 5 : $iItmRect.left + 10 ;首項縮進10,其他縮進5
;~                 _WinAPI_DrawText($hDC, $dataArray[$itmID][$i], $iItmRect, $DT_LEFT)
;~         Next
;~ ;============好像會導致bug,棄用
;~
        For $i = 0 To _GUICtrlListView_GetColumnCount($hItm) - 1
                ConsoleWrite("當前項是 :" & $itmID & "子項是 " & $i & @CRLF)
                If $i = 0 Then
                        Local $iItmRect = DllStructCreate($tagRect)
                        DllCall('user32.dll', 'int', 'SendMessage', 'hwnd', $hItm, 'uint', $LVM_GETSUBITEMRECT, 'wparam', $itmID, 'lparam', DllStructGetPtr($iItmRect))
                        $iItmRect.left += 10
                        _WinAPI_DrawText($hDC, $dataArray[$itmID][0], $iItmRect, $DT_LEFT)
                Else
                        Local $iItmRect = DllStructCreate($tagRect)
                        $iItmRect.top = $i
                        DllCall('user32.dll', 'int', 'SendMessage', 'hwnd', $hItm, 'uint', $LVM_GETSUBITEMRECT, 'wparam', $itmID, 'lparam', DllStructGetPtr($iItmRect))
                        $iItmRect.left += 5
                        _WinAPI_DrawText($hDC, $dataArray[$itmID][$i], $iItmRect, $DT_LEFT)
                EndIf
        Next

        Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_DRAWITEM
您需要登录后才可以回帖 登录 | 加入

本版积分规则

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

GMT+8, 2024-11-17 00:03 , Processed in 0.086782 second(s), 20 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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