Skip to content

MyTabControl.vb

Single change in this file

Removed the early-exit guard at the top of HandletabMouseClick. The full reasoning is in the HandletabMouseClick Early-Exit bug fix doc — this page is the file-level reference.

What was removed

Removed lines

Dim pageViewInfo As BaseTabPageViewInfo = TryCast(
    pr.GetValue(TabPages(TabPages.Count - 1), Nothing),
    BaseTabPageViewInfo)
If pageViewInfo Is Nothing Then
    Exit Sub
End If
Dim nLine As Integer = pageViewInfo.Bounds.Location.Y

Four problems with this block: 1. The nLine variable was never read after assignment. 2. The early-exit bailed on the entire handler when the last tab's PageViewInfo was unset — even though we may be hit-testing a different tab. 3. The inner loop already does If pageViewInfo Is Nothing Then Continue For — so the early-exit was a redundant first line of defense at the wrong granularity. 4. The exit was mode-blind: it fired even in the PulseDevTools.PDS.UsingNewLookMenu = True branch which doesn't depend on Bounds at all.

What was added

A single declaration line and a comment block:

' Note: previously bailed out here if the LAST tab's PageViewInfo
' was Nothing, but that incorrectly suppressed right-click handling
' on every tab whenever a single tab hadn't been laid out yet
' (e.g. immediately after a user switch and a redraw cycle).
' The per-page Nothing check inside the loop below is sufficient.
Dim pageViewInfo As BaseTabPageViewInfo

pageViewInfo is now declared once and assigned inside the loop on each iteration. The behavior of the inner loop is unchanged.

Full patched method

Public Sub HandletabMouseClick(ByVal e As System.Windows.Forms.MouseEventArgs)
    ' JLN 5/15/2024

    If TabPages.Count = 0 Then Exit Sub

    Dim pr As PropertyInfo = GetType(MyTabPage).GetProperty(
        "PageViewInfo",
        BindingFlags.NonPublic Or BindingFlags.Instance)
    ' Note: previously bailed out here if the LAST tab's PageViewInfo
    ' was Nothing, but that incorrectly suppressed right-click handling
    ' on every tab whenever a single tab hadn't been laid out yet
    ' (e.g. immediately after a user switch and a redraw cycle).
    ' The per-page Nothing check inside the loop below is sufficient.
    Dim pageViewInfo As BaseTabPageViewInfo

    For i As Integer = 0 To TabPages.Count - 1

        pageViewInfo = TryCast(pr.GetValue(TabPages(i), Nothing), BaseTabPageViewInfo)
        If pageViewInfo Is Nothing Then
            Continue For
        End If
        Dim AdjustedPageBounds As New Rectangle
        AdjustedPageBounds.X = pageViewInfo.Bounds.X
        AdjustedPageBounds.Y = pageViewInfo.Bounds.Y
        AdjustedPageBounds.Width = pageViewInfo.Bounds.Width
        AdjustedPageBounds.Height = 21

        If PulseDevTools.PDS.UsingNewLookMenu = True Then  'JLN
            TabPages(i).Focus()

            If e.Button = MouseButtons.Right Then
                CType(TabPages(i), MyTabPage).ShowContextMenu(PointToScreen(e.Location))
            ElseIf e.Button = MouseButtons.Middle AndAlso CType(TabPages(i), MyTabPage).m_SplitContainer IsNot Nothing Then
                If CType(TabPages(i), MyTabPage).m_SplitContainer.PanelVisibility = SplitPanelVisibility.Panel2 Then
                    CType(TabPages(i), MyTabPage).m_SplitContainer.PanelVisibility = SplitPanelVisibility.Both
                Else
                    CType(TabPages(i), MyTabPage).m_SplitContainer.PanelVisibility = SplitPanelVisibility.Panel2
                End If
            End If
            Exit Sub

        Else
            If AdjustedPageBounds.Contains(e.Location) Then
                TabPages(i).Focus()

                If e.Button = MouseButtons.Right Then
                    CType(TabPages(i), MyTabPage).ShowContextMenu(PointToScreen(e.Location))
                ElseIf e.Button = MouseButtons.Middle AndAlso CType(TabPages(i), MyTabPage).m_SplitContainer IsNot Nothing Then
                    If CType(TabPages(i), MyTabPage).m_SplitContainer.PanelVisibility = SplitPanelVisibility.Panel2 Then
                        CType(TabPages(i), MyTabPage).m_SplitContainer.PanelVisibility = SplitPanelVisibility.Both
                    Else
                        CType(TabPages(i), MyTabPage).m_SplitContainer.PanelVisibility = SplitPanelVisibility.Panel2
                    End If
                End If
                Exit Sub
            End If
        End If
    Next

End Sub

What did not change

  • The two flow branches (UsingNewLookMenu = True vs Else) are unchanged.
  • The hit-test (AdjustedPageBounds.Contains(e.Location)) is unchanged.
  • The Focus() / ShowContextMenu / middle-button split panel toggle calls are unchanged.
  • The other HandletabMouseClick callsite (MyTabControl_MouseClick(...) Handles Me.MouseClick) is unchanged.

Test coverage

See HandletabMouseClick Early-Exit — Test plan.