yamakawa 发表于 2017-9-5 10:44:55

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

本帖最后由 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 < 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
For $i = 0 To 10000 - 1
        $dataArray[$i] = "Item " & $i + 1
        $dataArray[$i] = "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;" & _
                        "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], $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

kk_lee69 发表于 2017-9-5 11:43:51

回复 1# yamakawa

研究看看   不過要抽空上班中 ~~ 呵呵

kk_lee69 发表于 2017-9-5 11:51:22

回复 1# yamakawa

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

你現在的問題是 第一個 出問題 還是....第二個LISTVIEW

yamakawa 发表于 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

kk_lee69 发表于 2017-9-5 12:02:54

回复 4# yamakawa

yamakawa 发表于 2017-9-5 12:28:27

回复 5# kk_lee69


    ?????什么意思?我那个代码现在已经不会宕机了。。。如果用注释掉的会挂

yamakawa 发表于 2017-9-5 12:30:08

回复 5# kk_lee69


就是说如果不用虚拟列表就会挂。。。但是用了以后,无法设置行数。。得填充

kk_lee69 发表于 2017-9-5 13:37:13

回复 4# yamakawa

用虛擬的 總行數 不就是 陣列(數組)的行數嗎??

kk_lee69 发表于 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,棄用
;~

那麼 哪一段又得拿掉呢??

kk_lee69 发表于 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


這段如果只是為了得到總行數那就不用寫因為 就是 陣列(數組) 的行數 不是??

yamakawa 发表于 2017-9-5 13:42:19

回复 10# kk_lee69


    你试试,,注释这个界面就没内容了

yamakawa 发表于 2017-9-5 13:43:13

回复 9# kk_lee69


    这段代码下面那些拿掉

yamakawa 发表于 2017-9-5 13:44:51

回复 9# kk_lee69


    另外,drawtext的第二个参数得处理下,,不用数组而是直接从listview获取

yamakawa 发表于 2017-9-5 13:49:38

回复 10# kk_lee69


    还有个很好玩的地方,,,界面刚启动你就去点击列表,你会发现,会变色,这说明程序空闲?但是去点击左下角那个按钮,你会发现要等一段时间才会弹出提示框 这说明程序没运行到这,,,,那为什么还会变色呢?

kk_lee69 发表于 2017-9-5 14:27:39

回复 11# yamakawa

請看以下的範例

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

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

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

1. 你少為TXT 宣告一個存放位置
Global $tText = DllStructCreate("wchar Text");建個結構,用來放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 < 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");建個結構,用來放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
For $i = 0 To 10000 - 1
      $dataArray[$i] = "Item " & $i + 1
      $dataArray[$i] = "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;" & _
                        "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], $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
页: [1] 2 3 4
查看完整版本: kk请进。listview麻烦看看能不能改虚拟列表写法【已解决】