Последовательность обработчика событий не согласована для разных представлений дерева - PullRequest
0 голосов
/ 04 ноября 2019

Я работаю над приложением Excel VBA, которое содержит два элемента управления древовидной структуры, которые содержатся в одной пользовательской форме. Единственное различие между ними состоит в том, что Treeview1 имеет два уровня узлов, а Treeview2 имеет три уровня. Оба дерева используют одинаковые обработчики событий:

BeforeLabelEdit

MouseDown

MouseMove

NodeClick

OLEDragDrop

OLEDragOver

Когда пользователь щелкает мышью узел в treeview1, последовательность событий MouseDown, затем NodeClick. Однако для Treeview2, когда пользователь нажимает на узел, срабатывает только событие NodeClick. После некоторого тестирования я обнаружил, что если я добавлю обработчик события MouseUp для treeview2, он вызовет ПОСЛЕ события NodeClick. Похоже, событие MouseDown никогда не запускается.

Мне интересно, сталкивался ли кто-нибудь с подобной проблемой. Я могу закодировать это, но мне бы очень хотелось понять, почему это происходит. Я предполагаю, что есть кое-что, что я не понимаю о том, как запускаются триггеры событий.

Я использую MouseDown, чтобы захватить выбор мыши и кнопки, и NodeClick, чтобы идентифицировать выбранный узел. Первоначально я использовал обработчик событий MouseDown для (1) захвата нажатий клавиш / клавиш и (2) захвата выбранного узла с помощью функции HitTest. Однако hitTest не захватывал правильный узел, когда я тестировал свое приложение на другом компьютере. Казалось, проще добавить событие NodeClick EventHandler, чем пытаться кодировать обобщенный метод вычисления / преобразования пикселей на разных компьютерах.

Код довольно сложный, поэтому я просто включил обработчики MouseDown и NodeClick для каждого дерева.

Я использую 64-разрядную версию Windows10, версия 1903 и Office 365 (16.0.12026.20344). Я знаю, что в прошлом были проблемы с использованием элементов управления treeview в 64-битной среде, так может ли это быть связано?

Любые мысли очень ценятся.

Спасибо!

'=============================================================
'===== Event Handlers for Treeview 1 =========================
'=============================================================
Private Sub TreeView_LineItem_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As stdole.OLE_XPOS_PIXELS, ByVal y As stdole.OLE_YPOS_PIXELS)      
        gButton = Button
        gShift = Shift     
End Sub

Private Sub TreeView_LineItem_NodeClick(ByVal Node As MSComctlLib.Node)   
        Set gSelectedNode = Node
        If Not (gSelectedNode Is Nothing) Then
                If gShift = 0 Then
                        If gButton = 1 Then       'Left Mouse
                                Call Node_Enter(ControlPanel.TreeView_LineItem, gNodeCollLineItems, gNodeGraphLineItems, gSelectedNode)
                                Set prevSelectedNodeClick = gSelectedNode
                                Set prevSelectedNodeControl = Nothing
                                Set prevSelectedNodeShift = Nothing
                                ControlPanel.TreeView_LineItem.Refresh                                
                                If ControlPanel.Visible = False Then
                                        ControlPanel.Show vbModeless
                                End If       
                        ElseIf gButton = 2 Then   'Right Mouse
                                'Custom node selected for deletion
                                If gCustomLineItemDelete = True And gNumCustomLineItems > 1 Then
                                        Call DeleteCustomLineItemStep2(gSelectedNode, ControlPanel.TreeView_LineItem.Nodes)
                                        Application.Goto Reference:=wb.Sheets(1).Range("A1"), Scroll:=True
                                        gCustomLineItemDelete = False                                     
                                ElseIf gCustomLineItemModify = True And gNumCustomLineItems > 1 Then
                                        Call modifyCustomLineItemStep2(gSelectedNode, ControlPanel.TreeView_LineItem.Nodes)
                                        Application.Goto Reference:=wb.Sheets(1).Range("A1"), Scroll:=True
                                        gCustomLineItemModify = False                                                                      
                                        'Delete menu line item selected
                                ElseIf gCustomLineItemDelete = False Or gNumCustomLineItems = 1 Then
                                        If gNumCustomLineItems = 1 Then
                                                MsgBox "There are no custom line items"
                                        End If

                                        For Each cb In CommandBars
                                                If StrComp(cb.name, "LineItem") = 0 Then
                                                        cb.Delete
                                                End If
                                        Next

                                        If gCustomLineItemDelete = True Then
                                                GoTo endSub
                                        End If

                                        'Reset menu
                                        Set PopBar = CommandBars.Add(name:="LineItem", Position:=msoBarPopup, MenuBar:=False, Temporary:=True)
                                        Set Top_Menu = PopBar.Controls.Add(Type:=msoControlButton, before:=1, Temporary:=True)
                                        With Top_Menu
                                                .caption = "Clear LineItem Selections"
                                                .OnAction = "ClearLineItemCollections"
                                        End With


                                        PopBar.ShowPopup
                                End If
                        End If
                ElseIf gShift = 1 Then            'Shift
                        Call Node_Shift(ControlPanel.TreeView_LineItem, gNodeCollLineItems, gNodeGraphLineItems, gSelectedNode)
                        Set prevSelectedNodeShift = gSelectedNode
                        Set prevSelectedNodeControl = Nothing
                        Set prevSelectedNodeClick = Nothing
                        ControlPanel.TreeView_LineItem.Refresh
                        ControlPanel.Show vbModeless
                ElseIf gShift = 2 Then            'Cntl
                        Call Node_Control(ControlPanel.TreeView_LineItem, gNodeCollLineItems, gNodeGraphLineItems, gSelectedNode)
                        Set prevSelectedNodeControl = gSelectedNode
                        Set prevSelectedNodeClick = Nothing
                        Set prevSelectedNodeShift = Nothing
                        ControlPanel.TreeView_LineItem.Refresh                       
                        ControlPanel.Show vbModeless
                End If
        End If        
End Sub


'=============================================================
'===== Event Handlers for Treeview 2 =========================
'=============================================================
Private Sub TreeView_Segment_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As stdole.OLE_XPOS_PIXELS, ByVal y As stdole.OLE_YPOS_PIXELS)

  gShift = Shift
  gButton = Button       

End Sub

Private Sub TreeView_Segment_NodeClick(ByVal Node As MSComctlLib.Node)        
        set gSelectedNode = Node

        gShift = Shift
        gButton = Button

        If Not (gSelectedNode Is Nothing) Then
                If gShift = 0 Then
                        If gButton = 1 Then      'left mouse                                
                                Call Node_Enter(ControlPanel.TreeView_Segment, gNodeCollSegments, gNodeGraphSegments, gSelectedNode)
                                Set prevSelectedNodeClick = gSelectedNode
                                Set prevSelectedNodeControl = Nothing
                                Set prevSelectedNodeShift = Nothing
                                If ControlPanel.TreeView_Segment.SelectedItem <> gSelectedNode Then
                                        ControlPanel.TreeView_Segment.SelectedItem = gSelectedNode
                                        ControlPanel.TreeView_Segment.DropHighlight = gSelectedNode
                                End If
                                ControlPanel.TreeView_Segment.Refresh                               

                        ElseIf gButton = 2 Then  'Right Mouse
                                For Each cb In CommandBars
                                        If StrComp(cb.name, "Segment") = 0 Then
                                                cb.Delete
                                        End If
                                Next

                                Set PopBar = CommandBars.Add(name:="Segment", Position:=msoBarPopup, MenuBar:=False, Temporary:=True)
                                Set Top_Menu = PopBar.Controls.Add(Type:=msoControlButton, before:=1, Temporary:=True)
                                With Top_Menu
                                        .caption = "Clear Segment Selections"
                                        .OnAction = "ClearSegmentCollections"
                                End With

                                PopBar.ShowPopup
                        End If
                ElseIf gShift = 1 Then           'Shift                       
                        Call Node_Shift(ControlPanel.TreeView_Segment, gNodeCollSegments, gNodeGraphSegments, gSelectedNode)
                        Set prevSelectedNodeShift = gSelectedNode
                        Set prevSelectedNodeControl = Nothing
                        Set prevSelectedNodeClick = Nothing
                        If ControlPanel.TreeView_Segment.SelectedItem <> gSelectedNode Then  
                                ControlPanel.TreeView_Segment.DropHighlight = Nothing  
                        End If
                        ControlPanel.TreeView_Segment.Refresh   
                        ControlPanel.Show vbModeless
                ElseIf gShift = 2 Then           'Cntl              
                        Call Node_Control(ControlPanel.TreeView_Segment, gNodeCollSegments, gNodeGraphSegments, gSelectedNode)
                        Set prevSelectedNodeControl = gSelectedNode
                        Set prevSelectedNodeClick = Nothing
                        Set prevSelectedNodeShift = Nothing
                        If ControlPanel.TreeView_Segment.SelectedItem <> gSelectedNode Then
                                ControlPanel.TreeView_Segment.SelectedItem = gSelectedNode
                        End If
                        ControlPanel.TreeView_Segment.Refresh                       
                        ControlPanel.Show vbModeless
                End If
        End If

endSub:
End Sub


Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...