Skip to content

Commit

Permalink
-fix: PacketList Scrollbar bug
Browse files Browse the repository at this point in the history
There is a bug with ListBox in that moving the scrollbar by dragging with a mouse is broken if you have more than 64K items in the list.
I added a workaround for this by faking a scrollbar that is linked to the actual ListBox. To do this, I also had to further customize the ListBox by adding a ShowScrollBar property that allows to fully hide and disable it's vertical scrollbar.
  • Loading branch information
ZeromusXYZ committed Apr 15, 2023
1 parent 9680916 commit cd11ee3
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 30 deletions.
20 changes: 2 additions & 18 deletions VieweD/Forms/MainForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1358,15 +1358,7 @@ private static void FindNext(ViewedProjectTab project)
{
// Select index
project.PacketsListBox.SelectedIndex = i;
// Move to center
var iHeight = project.PacketsListBox.ItemHeight;
if (iHeight <= 0)
iHeight = 8;
var iCount = project.PacketsListBox.Size.Height / iHeight;
var tPos = i - (iCount / 2);
if (tPos < 0)
tPos = 0;
project.PacketsListBox.TopIndex = tPos;
project.CenterListBox();
project.PacketsListBox.Focus();
// We're done
return;
Expand Down Expand Up @@ -1866,15 +1858,7 @@ private void FindNextInvalid(ViewedProjectTab project)
{
// Select index
project.PacketsListBox.SelectedIndex = i;
// Move to center
var iHeight = project.PacketsListBox.ItemHeight;
if (iHeight <= 0)
iHeight = 8;
var iCount = project.PacketsListBox.Size.Height / iHeight;
var tPos = i - (iCount / 2);
if (tPos < 0)
tPos = 0;
project.PacketsListBox.TopIndex = tPos;
project.CenterListBox();
project.PacketsListBox.Focus();
// We're done
return;
Expand Down
58 changes: 56 additions & 2 deletions VieweD/Helpers/PacketList/FlickerFreeListBox.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Drawing;
using System;
using System.Drawing;
using System.Windows.Forms;

namespace VieweD.Helpers.PacketList
Expand Down Expand Up @@ -63,6 +64,59 @@ protected override void OnPaint(PaintEventArgs e)
}
base.OnPaint(e);
}
}

// Added code to hide vertical scrollbar if wanted
// https://stackoverflow.com/questions/13169900/hide-vertical-scroll-bar-in-listbox-control
private bool _mShowScroll;
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
if (!_mShowScroll)
cp.Style = cp.Style & ~0x200000;
return cp;
}
}

public bool ShowScrollbar
{
get { return _mShowScroll; }
set
{
if (value != _mShowScroll)
{
_mShowScroll = value;
if (IsHandleCreated)
RecreateHandle();
}
}
}

public int MaximumVisibleItems => Size.Height / (ItemHeight <= 0 ? 8 : ItemHeight);

/*
private const int WM_VSCROLL = 277; // Vertical scroll
private const int SB_ENDSCROLL = 8; // Ends scroll
public event EventHandler TopIndexChanged;
private int _oldTopIndex = 0;
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_VSCROLL) // && (m.WParam == (IntPtr)SB_ENDSCROLL))
{
if (m.WParam == (IntPtr)SB_ENDSCROLL)
{
if ((TopIndex != _oldTopIndex) && (TopIndexChanged != null))
{
TopIndexChanged(this, EventArgs.Empty);
_oldTopIndex = TopIndex;
}
}
}
base.WndProc(ref m);
}
*/
}
}
4 changes: 2 additions & 2 deletions VieweD/VieweD.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>disable</ImplicitUsings>
<AssemblyVersion>1.0.0.1</AssemblyVersion>
<FileVersion>1.0.0.1</FileVersion>
<AssemblyVersion>1.0.2.0</AssemblyVersion>
<FileVersion>1.0.2.0</FileVersion>
<PackageLicenseExpression>Unlicense</PackageLicenseExpression>
<Title>VieweD</Title>
<ApplicationIcon>resources\icons\found-it!.ico</ApplicationIcon>
Expand Down
95 changes: 87 additions & 8 deletions VieweD/engine/common/ViewedProjectTab.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
Expand All @@ -12,6 +13,7 @@
using System.Windows.Forms;
using System.Xml;
using Ionic.BZip2;
using Microsoft.VisualBasic.Devices;
using VieweD.Helpers.PacketList;

namespace VieweD.engine.common;
Expand All @@ -22,6 +24,9 @@ public class ViewedProjectTab : TabPage

// Visual Components
internal FlickerFreeListBox PacketsListBox { get; } = new();
private Panel ListBoxPanel { get; } = new();
internal VScrollBar PacketsListScrollBar { get; } = new();
private bool _isScrollingList = false;

// Project Settings
/// <summary>
Expand Down Expand Up @@ -130,18 +135,46 @@ public ViewedProjectTab()

#region CreatePacketListBox

// Virtual Scrollbar that is added to fix the default ListBox scrollbar behavior
// There is a issue with the OG ListBox that the scrollbar breaks when you have more than 65536 items
PacketsListScrollBar.Parent = this;
PacketsListScrollBar.Location = new Point(this.Width - 16, 0);
PacketsListScrollBar.Size = new Size(16, this.Height);
PacketsListScrollBar.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Right;
// PacketsListScrollBar.Dock = DockStyle.Right;
PacketsListScrollBar.Minimum = 0;
PacketsListScrollBar.Maximum = 1;
PacketsListScrollBar.ValueChanged += PacketListScrollBar_ValueChanged;

// This intermediate Panel is required so that the below ListBox is getting sized correctly
ListBoxPanel.Parent = this;
ListBoxPanel.BorderStyle = BorderStyle.None;
ListBoxPanel.Location = new Point(0, 0);
ListBoxPanel.Size = new Size(this.Width - 16, this.Height);
ListBoxPanel.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
// ListBoxPanel.Dock = DockStyle.Fill;
// ListBoxPanel.BackColor = Color.CadetBlue;

// Set ListBox Position
PacketsListBox.Parent = this;
PacketsListBox.Parent = ListBoxPanel;
PacketsListBox.Location = new Point(0, 0);
PacketsListBox.Size = new Size(this.Width, this.Height);
PacketsListBox.Size = new Size(ListBoxPanel.Width, ListBoxPanel.Height);
PacketsListBox.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
PacketsListBox.Dock = DockStyle.Fill;
ReloadPacketListColorsFromSettings();
PacketsListBox.DrawMode = DrawMode.OwnerDrawFixed;

PacketsListBox.DrawItem += PacketsListBox_DrawItem;
PacketsListBox.SelectedIndexChanged += PacketsListBox_SelectedIndexChanged;
PacketsListBox.DoubleClick += PacketsListBox_DoubleClick;

PacketsListBox.MouseWheel += PacketsListBox_MouseWheel;

// PacketsListBox.TopIndexChanged += PacketListBox_TopIndexChanged;


PacketsListBox.ShowScrollbar = false; // Hide scrollbar

#endregion

#region CreatePopupMenu
Expand Down Expand Up @@ -222,6 +255,42 @@ public ViewedProjectTab()
OnProjectDataChanged();
}

public void UpdateScrollBarValue()
{
if (_isScrollingList)
return;

_isScrollingList = true;
try
{
PacketsListScrollBar.Minimum = 0;
PacketsListScrollBar.Maximum = PacketsListBox.Items.Count;
PacketsListScrollBar.Value = PacketsListBox.TopIndex;
}
catch
{
// Ignore
}
_isScrollingList = false;
}

private void PacketListScrollBar_ValueChanged(object? sender, EventArgs e)
{
if (_isScrollingList)
return;

_isScrollingList = true;
try
{
PacketsListBox.TopIndex = PacketsListScrollBar.Value;
}
catch
{
// Ignore
}
_isScrollingList = false;
}

private void PmPLEditParser_Click(object? sender, EventArgs e)
{
EditCurrentPacketRule();
Expand All @@ -242,14 +311,11 @@ private void PmPLResetFilter_Click(object? sender, EventArgs e)
internal void CenterListBox()
{
// Move to center
var iHeight = PacketsListBox.ItemHeight;
if (iHeight <= 0)
iHeight = 8;
var iCount = PacketsListBox.Size.Height / iHeight;
var tPos = PacketsListBox.SelectedIndex - (iCount / 2);
var tPos = PacketsListBox.SelectedIndex - (PacketsListBox.MaximumVisibleItems / 2);
if (tPos < 0)
tPos = 0;
PacketsListBox.TopIndex = tPos;
UpdateScrollBarValue();
}

private void PmPLShowIncomingOnly_Click(object? sender, EventArgs e)
Expand Down Expand Up @@ -632,6 +698,7 @@ public void PopulateListBox(int selectIndex = -1)
private void PacketsListBox_SelectedIndexChanged(object? sender, EventArgs e)
{
PacketsListBox.Invalidate();
UpdateScrollBarValue();
if ((PacketsListBox.SelectedIndex >= 0) && (PacketsListBox.Items[PacketsListBox.SelectedIndex] is BasePacketData pd))
{
CurrentSyncId = pd.SyncId;
Expand Down Expand Up @@ -1791,8 +1858,20 @@ public bool ImportFromVpxStream(Stream fileStream, bool isCompressed, bool inclu
}
catch (Exception e)
{
Console.WriteLine(e);
Debug.WriteLine(e);
return false;
}
}

private void PacketsListBox_MouseWheel(object? sender, MouseEventArgs e)
{
var hasShift = ModifierKeys.HasFlag(Keys.Shift);
var hasControl = ModifierKeys.HasFlag(Keys.Control);
var itemDelta = e.Delta * SystemInformation.MouseWheelScrollLines / 120;
if (hasShift || hasControl)
itemDelta *= PacketsListBox.MaximumVisibleItems;
PacketsListBox.TopIndex -= itemDelta;
UpdateScrollBarValue();
}

}

0 comments on commit cd11ee3

Please sign in to comment.