yamakawa 发表于 2017-9-5 14:42:37

回复 15# kk_lee69


    呵呵,,明白了。我继续折腾吧。。你觉得我用的风格怪异那是因为我不用custdraw,而是完全重绘的wm_drawitem,你这样改的话,wm_drawitem不响应了

kk_lee69 发表于 2017-9-5 14:48:26

回复 16# yamakawa

那就肯定要把
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]));設置列資料字串長

這段放在 你的 重繪的部分   是因為哪個風格可以影響重繪的部分呢??

kk_lee69 发表于 2017-9-5 14:51:09

本帖最后由 kk_lee69 于 2017-9-5 14:56 编辑

回复 16# yamakawa

找到了
你用
$lListView = GUICtrlCreateListView("Items|SubItems", 10, 10, 280, 180, BitOR($LVS_REPORT, $LVS_OWNERDRAWFIXED, $LVS_OWNERDATA))
這樣就可以了

你的重繪一樣有作用

把我前面的範例 風格改成這樣就可以了

   虛擬 LISTVIEW 的概念是LISTVIEW 只是皮所以 所有的資訊 可以從 陣列來的 就直接從陣列抓取

折腾好了 完成後記得分享一下

我看了一下如果你寫好了 這個 理論上 那些失去焦點變顏色的問題就不見了........

kk_lee69 发表于 2017-9-5 14:58:48

回复 16# yamakawa

如果我沒想錯的話    用我的範例後理論上總行數 用你的方法一樣可以取到 才對

kk_lee69 发表于 2017-9-5 15:01:48

回复 16# 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,棄用

取而代之的是 哪一段呢

yamakawa 发表于 2017-9-5 17:01:53

刚到家,浑身臭汗。。大概试了下,改风格,然后不停闪烁。。所以去掉wm_drawitem中绘图过程,OK,不闪了。。。可是设置的效果也没了。。。OMG。无解?

yamakawa 发表于 2017-9-5 20:55:01

回复 20# kk_lee69


    加了两个风格。。然后可以了。。notify不用 -155那个了#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include <WinAPI.au3>
#include <ButtonConstants.au3>
#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 $hGUI, $lListView, $hlListView, $rListView, $hrListView
Global $btn_test
Global $dataArray
For $i = 0 To 10000 - 1
        $dataArray[$i] = "Item " & $i + 1
        $dataArray[$i] = "SubItem " & $i + 1
Next

$hGUI = GUICreate("Test GUI", 650, 300)
;===第一个列表
$lListView = GUICtrlCreateListView("", 10, 10, 280, 180, BitOR($LVS_REPORT, $LVS_OWNERDRAWFIXED,$LVS_OWNERDATA));两个自绘属性都加上!
$hlListView = GUICtrlGetHandle(-1)
_GUICtrlListView_InsertColumn($hlListView, 1, "Item", 120)
_GUICtrlListView_InsertColumn($hlListView, 2, "SubItem", 120)
_GUICtrlListView_SetExtendedListViewStyle($hlListView, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT))
_GUICtrlListView_SetColumnWidth($hlListView, 0, 120)
_GUICtrlListView_SetColumnWidth($hlListView, 1, 120)
_GUICtrlListView_SetItemCount($lListView, UBound($dataArray))
;第二个列表
$rListView = GUICtrlCreateListView("", 310, 10, 280, 180)
$hrListView = GUICtrlGetHandle(-1)
_GUICtrlListView_SetExtendedListViewStyle($hrListView, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT))
_GUICtrlListView_InsertColumn($hrListView, 0, "隐藏列", 0)
_GUICtrlListView_InsertColumn($hrListView, 1, "列1", 120)
_GUICtrlListView_InsertColumn($hrListView, 2, "列2", 120)

$btn_test = GUICtrlCreateButton("text", 10, 250)
GUICtrlSetStyle(-1, BitOR($WS_TABSTOP, $BS_NOTIFY, $BS_OWNERDRAW)) ; Set the ownerdrawn flag
GUICtrlCreateLabel("←←←←←←←这个按钮感觉如何(我指的形状)", 50, 255)

GUIRegisterMsg($WM_DRAWITEM, "WM_DRAWITEM")
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUISetState()

While 1
        Switch GUIGetMsg()
                Case -3
                        Exit
                Case $btn_test
                        MsgBox(0, "", "do is clicked", 0, $hGUI)
        EndSwitch
WEnd

Func WM_DRAWITEM($hWnd, $Msg, $wParam, $lParam)
        Local $tagDRAWITEMSTRUCT, $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")) ;====这样也可以。好处是可以修改
        Local $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) - 1
                Local $iItmRect = DllStructCreate($tagRect)
                If $i Then $iItmRect.top = $i
                DllCall('user32.dll', 'int', 'SendMessage', 'hwnd', $hItm, 'uint', $LVM_GETSUBITEMRECT, 'wparam', $itmID, 'lparam', DllStructGetPtr($iItmRect))
                $iItmRect.left += $i ? 5 : 10
                _WinAPI_DrawText($hDC, $dataArray[$itmID][$i], $iItmRect, $DT_LEFT)
        Next
        Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_DRAWITEM

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")
                        If _GUICtrlListView_DeleteItem($iIDFrom, $index) Then
                                If _GUICtrlListView_GetItemCount($iIDFrom) > _GUICtrlListView_GetCounterPage($iIDFrom) Then
                                        _GUICtrlListView_SetItemSelected($hrListView, $index - 1)
                                Else
                                        _GUICtrlListView_SetItemSelected($hrListView, $index)
                                EndIf
                        EndIf
                        Return $GUI_RUNDEFMSG
                Case $lListView
                Switch $iCode
                                Case $NM_DBLCLK
                                        $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
                                        Local $index = DllStructGetData($tInfo, "Index")
                                        If $index = -1 Then Return $GUI_RUNDEFMSG
                                        Local $newIndex = _GUICtrlListView_FindText($hrListView, String($lListView & "," & $index))
                                        If $newIndex <> -1 Then
                                                _GUICtrlListView_DeleteItem($hrListView, $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
                                                _GUICtrlListView_EnsureVisible($hrListView, $newIndex)
                                                _GUICtrlListView_SetItemSelected($hrListView, $newIndex)
                                        EndIf
                                        Return 0
                        EndSwitch
                        Return $GUI_RUNDEFMSG
        EndSwitch
        Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

kk_lee69 发表于 2017-9-5 22:37:07

回复 22# yamakawa

酷喔非常流暢

可以請教 這樣子 完全自繪 的用意 跟好處是甚麼嗎??

yamakawa 发表于 2017-9-6 10:04:13

回复 23# kk_lee69


    和custdraw相比,这个做法的好处是,完全控制,可以修改显示过程的一切

kk_lee69 发表于 2017-9-8 11:47:24

回复 24# yamakawa

這個 可以繪製 INPUT框嗎??有辦法重新繪製 INPUT框嗎??

yamakawa 发表于 2017-9-8 22:48:52

回复 25# kk_lee69


    WM_DRAWITEM message
Sent to the parent window of an owner-drawn button, combo box, list box, or menu when a visual aspect of the button, combo box, list box, or menu has changed.

好像不行

chzj589 发表于 2017-9-12 16:53:41

回复 26# yamakawa
你22楼的例子,读取速度很快。
能修改为左键点击LISTVIEW连续选中状态,
我对自绘还不会,想要修改,不知从那里下手

yamakawa 发表于 2017-9-12 18:18:51

回复 27# chzj589

这个么#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include <WinAPI.au3>
#include <ButtonConstants.au3>
Opt('GUIOnEventMode', 1)

#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 $hGUI, $lListView, $hlListView, $rListView, $hrListView,$idAddSingleSel, $idDelSingleSel
Global $btn_test
Global $dataArray
For $i = 0 To 10000 - 1
        $dataArray[$i] = "Item " & $i + 1
        $dataArray[$i] = "SubItem " & $i + 1
Next

$hGUI = GUICreate("Test GUI", 650, 300)
        GUISetOnEvent(-3, '_Exit')

;===第一个列表
$lListView = GUICtrlCreateListView("", 10, 10, 280, 180, BitOR($LVS_REPORT, $LVS_OWNERDRAWFIXED, $LVS_OWNERDATA)) ;两个自绘属性都加上!
$hlListView = GUICtrlGetHandle(-1)
_GUICtrlListView_InsertColumn($hlListView, 1, "Item", 120)
_GUICtrlListView_InsertColumn($hlListView, 2, "SubItem", 120)
_GUICtrlListView_SetExtendedListViewStyle($hlListView, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT))
_GUICtrlListView_SetColumnWidth($hlListView, 0, 120)
_GUICtrlListView_SetColumnWidth($hlListView, 1, 120)
_GUICtrlListView_SetItemCount($lListView, UBound($dataArray))
;第二个列表
$rListView = GUICtrlCreateListView("", 310, 10, 280, 180)
$hrListView = GUICtrlGetHandle(-1)
_GUICtrlListView_SetExtendedListViewStyle($hrListView, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT))
_GUICtrlListView_InsertColumn($hrListView, 0, "隐藏列", 0)
_GUICtrlListView_InsertColumn($hrListView, 1, "列1", 120)
_GUICtrlListView_InsertColumn($hrListView, 2, "列2", 120)


        ; Subclass ListView to receive keyboard/mouse messages
        $pListViewFunc = DllCallbackGetPtr(DllCallbackRegister("ListViewFunc", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr"))
        _WinAPI_SetWindowSubclass($hlListView, $pListViewFunc, 0, 0) ; $iSubclassId = 0, $pData = 0

        ; Add/del single selection
        $idAddSingleSel = GUICtrlCreateDummy()
        GUICtrlSetOnEvent(-1, '_AddSingleSel')
        $idDelSingleSel = GUICtrlCreateDummy()
        GUICtrlSetOnEvent(-1, '_DelSingleSel')


GUIRegisterMsg($WM_DRAWITEM, "WM_DRAWITEM")
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUISetState()

While 1
        Switch GUIGetMsg()
                Case -3
                        Exit
        EndSwitch
WEnd


Func ListViewFunc($hWnd, $iMsg, $wParam, $lParam, $iSubclassId, $pData)

        If $iMsg = $WM_LBUTTONDOWN Then

                Switch $wParam
                        Case 0x0001
                                If _GUICtrlListView_GetSelectedCount($hlListView) Then
                                        Local $aHit = _GUICtrlListView_HitTest(GUICtrlGetHandle($lListView), BitAND($lParam, 0xFFFF), BitShift($lParam, 16))
                                        If Not (@error Or $aHit = -1) Then
                                                If _GUICtrlListView_GetItemSelected($hlListView, $aHit) Then
                                                        GUICtrlSendToDummy($idDelSingleSel, $aHit)
                                                Else
                                                        GUICtrlSendToDummy($idAddSingleSel, $aHit)
                                                EndIf
                                        EndIf
                                        Return 0
                                EndIf
                        Case 0x0009
                                Return 0
                EndSwitch
        ElseIf $iMsg = $WM_KILLFOCUS Then
                ConsoleWrite("WM_KILLFOCUS" & @CRLF)
        Else
                Local $result = DllCall("comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam)
                If Not @error Then
                        Return $result
                Else
                        Return
                EndIf
        EndIf
       
       
        Local $result = DllCall("comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam)
        If Not @error Then
                Return $result
        Else
                Return
        EndIf
        #forceref $iSubclassId, $pData
EndFunc   ;==>ListViewFunc

Func _AddSingleSel()
        Local $iItem = GUICtrlRead($idAddSingleSel)
        _GUICtrlListView_SetItemSelected($hlListView, $iItem, True)
        _GUICtrlListView_SetItemFocused($hlListView, $iItem)
EndFunc   ;==>_AddSingleSel
Func _DelSingleSel()
        Local $iItem = GUICtrlRead($idDelSingleSel)
        _GUICtrlListView_SetItemSelected($hlListView, $iItem, False)
        _GUICtrlListView_SetItemFocused($hlListView, $iItem)
EndFunc   ;==>_DelSingleSel
Func _Exit()
        _WinAPI_RemoveWindowSubclass($hlListView, $pListViewFunc, 0)
        GUIDelete()
        Exit
EndFunc   ;==>_Exit

Func _WinAPI_SetWindowSubclass($hWnd, $pSubclassProc, $idSubClass, $pData = 0)
        Local $aRet = DllCall('comctl32.dll', 'bool', 'SetWindowSubclass', 'hwnd', $hWnd, 'ptr', $pSubclassProc, 'uint_ptr', $idSubClass, _
                        'dword_ptr', $pData)
        If @error Then Return SetError(@error, @extended, 0)
        ; If Not $aRet Then Return SetError(1000, 0, 0)

        Return $aRet
EndFunc   ;==>_WinAPI_SetWindowSubclass
Func _WinAPI_RemoveWindowSubclass($hWnd, $pSubclassProc, $idSubClass)
        Local $aRet = DllCall('comctl32.dll', 'bool', 'RemoveWindowSubclass', 'hwnd', $hWnd, 'ptr', $pSubclassProc, 'uint_ptr', $idSubClass)
        If @error Then Return SetError(@error, @extended, False)
        Return $aRet
EndFunc   ;==>_WinAPI_RemoveWindowSubclass


Func WM_DRAWITEM($hWnd, $Msg, $wParam, $lParam)
        Local $tagDRAWITEMSTRUCT, $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

        ;>=========
;~         Local $tRect = DllStructGetPtr($tagDRAWITEMSTRUCT, "itmRect") ;====这个学习了。。
        Local $tRect = DllStructCreate($tagRect, DllStructGetPtr($tagDRAWITEMSTRUCT, "itmRect")) ;====这样也可以。好处是可以修改
        Local $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)
        ;<=====画背景
        ;>====设置选中项文字颜色
        $txtcolor = BitAND($tagDRAWITEMSTRUCT.itmState, $ODS_SELECTED) = $ODS_SELECTED ? 0xffffff : 0x000000
        _WinAPI_SetTextColor($hDC, $txtcolor)
        ;<=====
        ;回填数据
        For $i = 0 To _GUICtrlListView_GetColumnCount($hItm) - 1
                Local $iItmRect = DllStructCreate($tagRect)
                If $i Then $iItmRect.top = $i
                DllCall('user32.dll', 'int', 'SendMessage', 'hwnd', $hItm, 'uint', $LVM_GETSUBITEMRECT, 'wparam', $itmID, 'lparam', DllStructGetPtr($iItmRect))
                $iItmRect.left += $i ? 5 : 10
                _WinAPI_DrawText($hDC, $dataArray[$itmID][$i], $iItmRect, $DT_LEFT)
        Next
        Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_DRAWITEM

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")
                        If _GUICtrlListView_DeleteItem($iIDFrom, $index) Then
                                If _GUICtrlListView_GetItemCount($iIDFrom) > _GUICtrlListView_GetCounterPage($iIDFrom) Then
                                        _GUICtrlListView_SetItemSelected($hrListView, $index - 1)
                                Else
                                        _GUICtrlListView_SetItemSelected($hrListView, $index)
                                EndIf
                        EndIf
                        Return $GUI_RUNDEFMSG
                Case $lListView
                        Switch $iCode
                                Case $NM_DBLCLK
                                        $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
                                        Local $index = DllStructGetData($tInfo, "Index")
                                        If $index = -1 Then Return $GUI_RUNDEFMSG
                                        Local $newIndex = _GUICtrlListView_FindText($hrListView, String($lListView & "," & $index))
                                        If $newIndex <> -1 Then
                                                _GUICtrlListView_DeleteItem($hrListView, $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
                                                _GUICtrlListView_EnsureVisible($hrListView, $newIndex)
                                                _GUICtrlListView_SetItemSelected($hrListView, $newIndex)
                                        EndIf
                                        Return 0
                        EndSwitch
                        Return $GUI_RUNDEFMSG
        EndSwitch
        Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

chzj589 发表于 2017-9-12 18:42:54

回复 28# yamakawa

是的。谢谢!
怎么没想到:$pListViewFunc = DllCallbackGetPtr(DllCallbackRegister("ListViewFunc", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr"))
_WinAPI_SetWindowSubclass($hlListView, $pListViewFunc, 0, 0) ; $iSubclassId = 0, $pData = 0

; Add/del single selection
$idAddSingleSel = GUICtrlCreateDummy()
GUICtrlSetOnEvent(-1, '_AddSingleSel')
$idDelSingleSel = GUICtrlCreateDummy()
GUICtrlSetOnEvent(-1, '_DelSingleSel')

Func ListViewFunc($hWnd, $iMsg, $wParam, $lParam, $iSubclassId, $pData)

        If $iMsg = $WM_LBUTTONDOWN Then

                Switch $wParam
                        Case 0x0001
                                If _GUICtrlListView_GetSelectedCount($hlListView) Then
                                        Local $aHit = _GUICtrlListView_HitTest(GUICtrlGetHandle($lListView), BitAND($lParam, 0xFFFF), BitShift($lParam, 16))
                                        If Not (@error Or $aHit = -1) Then
                                                If _GUICtrlListView_GetItemSelected($hlListView, $aHit) Then
                                                        GUICtrlSendToDummy($idDelSingleSel, $aHit)
                                                Else
                                                        GUICtrlSendToDummy($idAddSingleSel, $aHit)
                                                EndIf
                                        EndIf
                                        Return 0
                                EndIf
                        Case 0x0009
                                Return 0
                EndSwitch
        ElseIf $iMsg = $WM_KILLFOCUS Then
                ConsoleWrite("WM_KILLFOCUS" & @CRLF)
        Else
                Local $result = DllCall("comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam)
                If Not @error Then
                        Return $result
                Else
                        Return
                EndIf
        EndIf


        Local $result = DllCall("comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam)
        If Not @error Then
                Return $result
        Else
                Return
        EndIf
        #forceref $iSubclassId, $pData
EndFunc   ;==>ListViewFunc

Func _AddSingleSel()
        Local $iItem = GUICtrlRead($idAddSingleSel)
        _GUICtrlListView_SetItemSelected($hlListView, $iItem, True)
        _GUICtrlListView_SetItemFocused($hlListView, $iItem)
EndFunc   ;==>_AddSingleSel
Func _DelSingleSel()
        Local $iItem = GUICtrlRead($idDelSingleSel)
        _GUICtrlListView_SetItemSelected($hlListView, $iItem, False)
        _GUICtrlListView_SetItemFocused($hlListView, $iItem)
EndFunc   ;==>_DelSingleSel

chzj589 发表于 2017-9-14 09:25:49

回复 28# yamakawa

读取Excel显示在:$lListView = GUICtrlCreateListView("", 10, 10, 280, 180, BitOR($LVS_REPORT, $LVS_OWNERDRAWFIXED,$LVS_OWNERDATA))
出现第一行空白,折腾了一天,没办法调整。怪事。

页: 1 [2] 3 4
查看完整版本: kk请进。listview麻烦看看能不能改虚拟列表写法【已解决】