anythinging 发表于 2021-1-3 20:50:16

【已解决】关于使用多个listviewr遇到的问题

本帖最后由 anythinging 于 2021-1-4 11:46 编辑

前面经A版指点,采用2个listveiw,通过显示隐藏状态来切换表格显示。
1、遇到个大问题:修改任意一侧表格内内容,另一侧也会随着改变。
好象是需要升级_update()来解,自行尝试修改多次无果,只能向A版求助。
2、还有个小问题,左侧第1列的表格在双击后编辑状态窗口宽很多,没弄明白是什么原因。
3、另求证在_WM_NOTIFY,加入Case $hListView2响应listview2表格,是否是正确的方法?
#include <GUIConstantsEx.au3>
#include <GuiImageList.au3>
#include <GuiListView.au3>
#include <WindowsConstants.au3>
#include <GuiMenu.au3>

Global $gui, $list1, $list2
Global $hListView1,$hListView2,$listViewNum
Global $aItem


$gui = GUICreate($gui, 1000, 400)
$bt1 = GUICtrlCreateButton('切换1', 20, 270, 60, 20)
$bt2 = GUICtrlCreateButton('切换2', 100, 270, 60, 20)

Dim $iCombo = GUICtrlCreateCombo('', -100, -100)

list1()
list2()

GUISetState()

GUIRegisterMsg(0x004E, '_WM_NOTIFY') ;$WM_NOTIFY = 0x004E

Local $id1 = GUICtrlCreateDummy()
Local $aAccelKeys= [['{Enter}', $id1]]
GUISetAccelerators($aAccelKeys)

Func _UdpData()

      If Not IsArray($aItem) Then Return
      Local $sRd = GUICtrlRead($iCombo), $sData = ''
      ;_GUICtrlListView_SetItemText($hListView1, $aItem, $sRd, $aItem)      ;单listview

      Switch $listViewNum
                Case 1
                        _GUICtrlListView_SetItemText($hListView1, $aItem, $sRd, $aItem)      ;多listView
                Case 2
                        _GUICtrlListView_SetItemText($hListView2, $aItem, $sRd, $aItem)      ;多listView
                Case 3
      EndSwitch

      GUICtrlSetPos($iCombo, -1000, -100)
;~         MsgBox(262144,'','激活了快捷键',1)
EndFunc   ;==>_UdpData


While 1
      Switch GUIGetMsg()
                Case $GUI_EVENT_CLOSE
                        ExitLoop
                Case $bt1
                        GUICtrlSetState($list2, 32)
                        GUICtrlSetState($list1, 16)
                Case $bt2
                        GUICtrlSetState($list1, 32)
                        GUICtrlSetState($list2, 16)
                Case $list1
                        _GUICtrlListView_SortItems($list1, GUICtrlGetState($list1))

                Case $list2
                        _GUICtrlListView_SortItems($list2, GUICtrlGetState($list2))

                              Case $id1
                                        _UdpData()
      EndSwitch
WEnd

_GUICtrlListView_UnRegisterSortCallBack($list1)
_GUICtrlListView_UnRegisterSortCallBack($list2)

Func list1()
      $list1 = GUICtrlCreateListView("英文 1|英文 2|英文 3", 10, 10, 280, 180)
                Dim         $hListView1      = GUICtrlGetHandle(-1)
      _GUICtrlListView_AddItem($list1, 'aa')
      _GUICtrlListView_AddSubItem($list1, 0, 'bb', 1)
      _GUICtrlListView_AddSubItem($list1, 0, 'cc', 2)
      _GUICtrlListView_AddItem($list1, 'dd')
      _GUICtrlListView_AddSubItem($list1, 1, 'ee', 1)
      _GUICtrlListView_AddSubItem($list1, 1, 'ff', 2)
      _GUICtrlListView_RegisterSortCallBack($list1, 0)
EndFunc   ;==>list1

Func list2()
      $list2 = GUICtrlCreateListView("数字 1|数字 2|数字 3|数字 4", 510, 10, 280, 180)
                Dim         $hListView2      = GUICtrlGetHandle(-1)
      _GUICtrlListView_AddItem($list2, '11')
      _GUICtrlListView_AddSubItem($list2, 0, '22', 1)
      _GUICtrlListView_AddSubItem($list2, 0, '233', 2)
      _GUICtrlListView_AddSubItem($list2, 0, '144', 3)
      _GUICtrlListView_AddItem($list2, '55')
      _GUICtrlListView_AddSubItem($list2, 1, '66', 1)
      _GUICtrlListView_AddSubItem($list2, 1, '77', 2)
      _GUICtrlListView_AddSubItem($list2, 1, '88', 3)
      _GUICtrlListView_RegisterSortCallBack($list2, 1)

EndFunc   ;==>list2



Func _WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
      #forceref $hWnd, $iMsg, $iwParam
      Local $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
      Switch DllStructGetData($tNMHDR, 'hWndFrom')
                Case $hListView1
                        $listViewNum = 1
                                                Switch DllStructGetData($tNMHDR, 'Code')
                                                      Case -2
                                                                If IsArray($aItem) Then
                                                                              _UdpData()
                                                                Else
                                                                              Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
                                                                              Local $index = DllStructGetData($tInfo, 'Index')
                                                                              Local $SubItem = DllStructGetData($tInfo, 'SubItem')
                                        If $SubItem = 2 Then
                                                Local $context = GUICtrlCreateContextMenu(GUICtrlCreateDummy())
                                                Dim $hMenu = GUICtrlGetHandle($context)
                                                GUICtrlCreateMenuItem('男', $context)
                                                GUICtrlCreateMenuItem('女', $context)
                                                Local $iid = _GUICtrlMenu_TrackPopupMenu($hMenu, $gui, -1, -1, 1, 1, 2)
                                                If $iid Then _GUICtrlListView_SetItemText($hListView1, $index, _GUICtrlMenu_GetItemText($hMenu, $iid, False), 2)
                                        EndIf
                                                                EndIf
                                                      Case -3
                                                                        Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
                                                                        Local $index = DllStructGetData($tInfo, 'Index')
                                                                        Local $SubItem = DllStructGetData($tInfo, 'SubItem')
                                                                        Dim $aItem = 0
                                                                        If Not StringRegExp($SubItem, "^(0|1|2)[      DISCUZ_CODE_0      ]quot;) Then Return 'GUI_RUNDEFMSG'
                                                                        Local $aRect = _GUICtrlListView_GetSubItemRect($hListView1, $index, $SubItem)

                                                                        Dim $aItem = [$index, $SubItem]
                                                                        Local $sDef

                                                                        Local $sData = _GUICtrlListView_GetItemText($hListView1, $index, $SubItem)

                                                                        GUICtrlSetPos($iCombo      , $aRect + 4                , $aRect + 12                ,$aRect - $aRect)
                                                                        GUICtrlSetData($iCombo, '|' & $sData & '|' & $sDef, $sData)

                                                                        GUICtrlSetState($iCombo, 256)

                        EndSwitch

                              Case $hListView2
                                        $listViewNum = 2
                                           Switch DllStructGetData($tNMHDR, 'Code')
                                                      Case -2
                                                                If IsArray($aItem) Then
                                                                              _UdpData()
                                                                Else
                                                                              Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
                                                                              Local $index = DllStructGetData($tInfo, 'Index')
                                                                              Local $SubItem = DllStructGetData($tInfo, 'SubItem')
                                        If $SubItem = 3 Then
                                                Local $context = GUICtrlCreateContextMenu(GUICtrlCreateDummy())
                                                Dim $hMenu = GUICtrlGetHandle($context)
                                                GUICtrlCreateMenuItem('男', $context)
                                                GUICtrlCreateMenuItem('女', $context)
                                                Local $iid = _GUICtrlMenu_TrackPopupMenu($hMenu, $gui, -1, -1, 1, 1, 2)
                                                If $iid Then _GUICtrlListView_SetItemText($hListView2, $index, _GUICtrlMenu_GetItemText($hMenu, $iid, False), 3)
                                        EndIf
                                                                EndIf

                                                      Case -3
                                                                        Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
                                                                        Local $index = DllStructGetData($tInfo, 'Index')
                                                                        Local $SubItem = DllStructGetData($tInfo, 'SubItem')
                                                                        Dim $aItem = 0
                                                                         If Not StringRegExp($SubItem, "^(0|1|2)[      DISCUZ_CODE_0      ]quot;) Then Return 'GUI_RUNDEFMSG'
                                                                        Local $aRect = _GUICtrlListView_GetSubItemRect($hListView2, $index, $SubItem)

                                                                        Dim $aItem = [$index, $SubItem]
                                                                        Local $sDef
                                                                        Local $sData = _GUICtrlListView_GetItemText($hListView2, $index, $SubItem)

                                                                        GUICtrlSetPos($iCombo      , $aRect + 504                , $aRect + 12                ,$aRect - $aRect)
                                                                        GUICtrlSetData($iCombo, '|' & $sData & '|' & $sDef, $sData)
                                                                        GUICtrlSetState($iCombo, 256)
                        EndSwitch


      EndSwitch
EndFunc   ;==>_WM_NOTIFY






afan 发表于 2021-1-3 21:59:25

1、是因为你把之前代码的 Dim $aItem = 0 删了。
2、左侧第1列获取的是整行,需要减去子项坐标。
3、列表2的需求与1高度雷同,因此只需定义一个函数调用,将不同的部分以变量变更的形式代入。

afan 发表于 2021-1-3 21:52:33


#include <GuiListView.au3>
#include <GuiMenu.au3>

Global $gui, $list1, $list2
Global $hListView1, $hListView2, $listViewNum
Global $aItem

$gui = GUICreate($gui, 1000, 400)
$bt1 = GUICtrlCreateButton('切换1', 20, 270, 60, 20)
$bt2 = GUICtrlCreateButton('切换2', 100, 270, 60, 20)
Dim $iCombo = GUICtrlCreateCombo('', -100, -100)
list1()
list2()
Local $context = GUICtrlCreateContextMenu(GUICtrlCreateDummy())
Dim $hMenu = GUICtrlGetHandle($context)
GUICtrlCreateMenuItem('男', $context)
GUICtrlCreateMenuItem('女', $context)
GUISetState()

GUIRegisterMsg(0x004E, '_WM_NOTIFY') ;$WM_NOTIFY = 0x004E
Local $id1 = GUICtrlCreateDummy()
Local $aAccelKeys = [['{Enter}', $id1]]
GUISetAccelerators($aAccelKeys)

While 1
        Switch GUIGetMsg()
                Case -3
                        ExitLoop
                Case $bt1
                        GUICtrlSetState($list2, 32)
                        GUICtrlSetState($list1, 16)
                Case $bt2
                        GUICtrlSetState($list1, 32)
                        GUICtrlSetState($list2, 16)
                Case $list1
                        _GUICtrlListView_SortItems($list1, GUICtrlGetState($list1))
                Case $list2
                        _GUICtrlListView_SortItems($list2, GUICtrlGetState($list2))
                Case $id1
                        _UdpData()
        EndSwitch
WEnd
_GUICtrlListView_UnRegisterSortCallBack($list1)
_GUICtrlListView_UnRegisterSortCallBack($list2)

Func list1()
        $list1 = GUICtrlCreateListView("英文 1|英文 2|英文 3", 10, 10, 280, 180)
        Dim $hListView1 = GUICtrlGetHandle(-1)
        _GUICtrlListView_AddItem($list1, 'aa')
        _GUICtrlListView_AddSubItem($list1, 0, 'bb', 1)
        _GUICtrlListView_AddSubItem($list1, 0, 'cc', 2)
        _GUICtrlListView_AddItem($list1, 'dd')
        _GUICtrlListView_AddSubItem($list1, 1, 'ee', 1)
        _GUICtrlListView_AddSubItem($list1, 1, 'ff', 2)
        _GUICtrlListView_RegisterSortCallBack($list1, 0)
EndFunc   ;==>list1

Func list2()
        $list2 = GUICtrlCreateListView("数字 1|数字 2|数字 3|数字 4", 510, 10, 280, 180)
        Dim $hListView2 = GUICtrlGetHandle(-1)
        _GUICtrlListView_AddItem($list2, '11')
        _GUICtrlListView_AddSubItem($list2, 0, '22', 1)
        _GUICtrlListView_AddSubItem($list2, 0, '233', 2)
        _GUICtrlListView_AddSubItem($list2, 0, '144', 3)
        _GUICtrlListView_AddItem($list2, '55')
        _GUICtrlListView_AddSubItem($list2, 1, '66', 1)
        _GUICtrlListView_AddSubItem($list2, 1, '77', 2)
        _GUICtrlListView_AddSubItem($list2, 1, '88', 3)
        _GUICtrlListView_RegisterSortCallBack($list2, 1)
EndFunc   ;==>list2

Func _UdpData()
        If Not IsArray($aItem) Then Return
        Local $sRd = GUICtrlRead($iCombo), $sData = ''
        ;_GUICtrlListView_SetItemText($hListView1, $aItem, $sRd, $aItem)      ;单listview
        Switch $listViewNum
                Case 1
                        _GUICtrlListView_SetItemText($hListView1, $aItem, $sRd, $aItem) ;多listView
                Case 2
                        _GUICtrlListView_SetItemText($hListView2, $aItem, $sRd, $aItem) ;多listView
                Case 3
        EndSwitch
        GUICtrlSetPos($iCombo, -1000, -100)
        Dim $aItem = 0
EndFunc   ;==>_UdpData

Func _WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
        #forceref $hWnd, $iMsg, $iwParam
        Local $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
        Switch DllStructGetData($tNMHDR, 'hWndFrom')
                Case $hListView1
                        $listViewNum = 1
                        __LVWMsg($tNMHDR, $ilParam)

                Case $hListView2
                        $listViewNum = 2
                        __LVWMsg($tNMHDR, $ilParam)
        EndSwitch
EndFunc   ;==>_WM_NOTIFY

Func __LVWMsg($tNMHDR, $ilParam)
        Local $hLVW = $hListView2, $iXAdd = 514, $MenuSubIx = 3
        If $listViewNum = 1 Then
                $hLVW = $hListView1
                $iXAdd = 14
                $MenuSubIx = 2
        EndIf
        Switch DllStructGetData($tNMHDR, 'Code')
                Case -2
                        If IsArray($aItem) Then
                                _UdpData()
                        Else
                                Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
                                Local $index = DllStructGetData($tInfo, 'Index')
                                If $index = -1 Then Return
                                Local $SubItem = DllStructGetData($tInfo, 'SubItem')
                                If $SubItem = $MenuSubIx Then
                                        Local $iid = _GUICtrlMenu_TrackPopupMenu($hMenu, $gui, -1, -1, 1, 1, 2)
                                        If $iid Then _GUICtrlListView_SetItemText($hLVW, $index, _GUICtrlMenu_GetItemText($hMenu, $iid, False), $MenuSubIx)
                                EndIf
                        EndIf
                Case -3
                        Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
                        Local $index = DllStructGetData($tInfo, 'Index')
                        If $index = -1 Then Return
                        Local $SubItem = DllStructGetData($tInfo, 'SubItem')
                        Dim $aItem = 0
                        If Not StringRegExp($SubItem, "^(0|1|2)$") Then Return ;'GUI_RUNDEFMSG'
                        Local $aRect = _GUICtrlListView_GetSubItemRect($hLVW, $index, $SubItem)
                        Dim $aItem = [$index, $SubItem]
                        Local $sDef
                        Local $sData = _GUICtrlListView_GetItemText($hLVW, $index, $SubItem)
                        Local $iW = $aRect - $aRect
                        If $SubItem = 0 Then
                                Local $aRect1 = _GUICtrlListView_GetSubItemRect($hLVW, $index, 1)
                                $iW = $aRect1 - $aRect
                        EndIf
                        GUICtrlSetPos($iCombo, $aRect + $iXAdd, $aRect + 12, $iW)
                        GUICtrlSetData($iCombo, '|' & $sData & '|' & $sDef, $sData)
                        GUICtrlSetState($iCombo, 256)
        EndSwitch
EndFunc   ;==>__LVWMsg

anythinging 发表于 2021-1-3 22:31:46

加了Dim $aItem = 0,A版代码果然无敌于天下!
怪自己没完全理解好,Dim $aItem = 0居然这么重要。
本以为A版的示例看的差不多了,看来还要继续学习。


另外请教A版,如果功能差很多的话,在 _WM_NOTIFY中,通过switch
Case $hListView1
Case $hListView2
Case $hListView3
Case $hListViewN ......................
可以这样用吗?有没有什么隐患?

anythinging 发表于 2021-1-3 22:43:45

本帖最后由 anythinging 于 2021-1-3 22:46 编辑

万事皆有因,刚检查了之前的代码,
之所以原来一直没发现第一列宽度的问题,是因为第1列一直用的是序号,进而侥幸的成功避开了宽度的坑。
直到今天,终于掉进去了。感谢A版解答,又要学习A版新发的代码了。

afan 发表于 2021-1-4 00:47:51

anythinging 发表于 2021-1-3 22:31
加了Dim $aItem = 0,A版代码果然无敌于天下!
怪自己没完全理解好,Dim $aItem = 0居然这么重要。
本以 ...

怎么用都可以,没什么隐患,只要满足自己编写习惯
页: [1]
查看完整版本: 【已解决】关于使用多个listviewr遇到的问题