Skip to content

Commit

Permalink
Don't use Marshal.SizeOf for SCROLLINFO (#4819)
Browse files Browse the repository at this point in the history
  • Loading branch information
JeremyKuhne authored Apr 21, 2021
1 parent 29cd684 commit 7ecc0cf
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 42 deletions.
7 changes: 4 additions & 3 deletions src/System.Windows.Forms/src/System/Windows/Forms/Control.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7803,15 +7803,16 @@ private void OnSetScrollPosition(object sender, EventArgs e)
OnInvokedSetScrollPosition(sender, e);
}

internal virtual void OnInvokedSetScrollPosition(object sender, EventArgs e)
internal unsafe virtual void OnInvokedSetScrollPosition(object sender, EventArgs e)
{
if (!(this is ScrollableControl) && !IsMirrored)
{
var si = new User32.SCROLLINFO
User32.SCROLLINFO si = new()
{
cbSize = (uint)Marshal.SizeOf<User32.SCROLLINFO>(),
cbSize = (uint)sizeof(User32.SCROLLINFO),
fMask = User32.SIF.RANGE
};

if (User32.GetScrollInfo(this, User32.SB.HORZ, ref si).IsTrue())
{
si.nPos = (RightToLeft == RightToLeft.Yes) ? si.nMax : si.nMin;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -310,17 +310,18 @@ public double Zoom
}
}

private int AdjustScroll(Message m, int pos, int maxPos, bool horizontal)
private unsafe int AdjustScroll(Message m, int pos, int maxPos, bool horizontal)
{
switch ((User32.SBH)PARAM.LOWORD(m.WParam))
{
case User32.SBH.THUMBPOSITION:
case User32.SBH.THUMBTRACK:
var si = new User32.SCROLLINFO
User32.SCROLLINFO si = new()
{
cbSize = (uint)Marshal.SizeOf<User32.SCROLLINFO>(),
cbSize = (uint)sizeof(User32.SCROLLINFO),
fMask = User32.SIF.TRACKPOS
};

User32.SB direction = horizontal ? User32.SB.HORZ : User32.SB.VERT;
if (User32.GetScrollInfo(m.HWnd, direction, ref si).IsTrue())
{
Expand Down Expand Up @@ -745,19 +746,20 @@ private void SetPositionNoInvalidate(Point value)
User32.SetScrollPos(this, User32.SB.VERT, position.Y, BOOL.TRUE);
}

internal void SetVirtualSizeNoInvalidate(Size value)
internal unsafe void SetVirtualSizeNoInvalidate(Size value)
{
virtualSize = value;
SetPositionNoInvalidate(position); // Make sure it's within range

var info = new User32.SCROLLINFO
User32.SCROLLINFO info = new()
{
cbSize = (uint)Marshal.SizeOf<User32.SCROLLINFO>(),
cbSize = (uint)sizeof(User32.SCROLLINFO),
fMask = User32.SIF.RANGE | User32.SIF.PAGE,
nMin = 0,
nMax = Math.Max(Height, virtualSize.Height) - 1,
nPage = (uint)Height
};

User32.SetScrollInfo(this, User32.SB.VERT, ref info, BOOL.TRUE);

info.fMask = User32.SIF.RANGE | User32.SIF.PAGE;
Expand Down
53 changes: 28 additions & 25 deletions src/System.Windows.Forms/src/System/Windows/Forms/ScrollBar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -587,33 +587,35 @@ public override string ToString()
return s + ", Minimum: " + Minimum + ", Maximum: " + Maximum + ", Value: " + Value;
}

protected void UpdateScrollInfo()
protected unsafe void UpdateScrollInfo()
{
if (IsHandleCreated && Enabled)
if (!IsHandleCreated || !Enabled)
{
var si = new User32.SCROLLINFO
{
cbSize = (uint)Marshal.SizeOf<User32.SCROLLINFO>(),
fMask = User32.SIF.ALL,
nMin = _minimum,
nMax = _maximum,
nPage = (uint)LargeChange
};

if (RightToLeft == RightToLeft.Yes)
{
// Reflect the scrollbar position horizontally on an Rtl system
si.nPos = ReflectPosition(_value);
}
else
{
si.nPos = _value;
}
return;
}

si.nTrackPos = 0;
User32.SCROLLINFO si = new()
{
cbSize = (uint)sizeof(User32.SCROLLINFO),
fMask = User32.SIF.ALL,
nMin = _minimum,
nMax = _maximum,
nPage = (uint)LargeChange
};

User32.SetScrollInfo(this, User32.SB.CTL, ref si, BOOL.TRUE);
if (RightToLeft == RightToLeft.Yes)
{
// Reflect the scrollbar position horizontally on an Rtl system
si.nPos = ReflectPosition(_value);
}
else
{
si.nPos = _value;
}

si.nTrackPos = 0;

User32.SetScrollInfo(this, User32.SB.CTL, ref si, BOOL.TRUE);
}

private void WmReflectScroll(ref Message m)
Expand All @@ -622,7 +624,7 @@ private void WmReflectScroll(ref Message m)
DoScroll(type);
}

private void DoScroll(ScrollEventType type)
private unsafe void DoScroll(ScrollEventType type)
{
// For Rtl systems we need to swap increment and decrement
if (RightToLeft == RightToLeft.Yes)
Expand Down Expand Up @@ -689,11 +691,12 @@ private void DoScroll(ScrollEventType type)

case ScrollEventType.ThumbPosition:
case ScrollEventType.ThumbTrack:
var si = new User32.SCROLLINFO
User32.SCROLLINFO si = new()
{
cbSize = (uint)Marshal.SizeOf<User32.SCROLLINFO>(),
cbSize = (uint)sizeof(User32.SCROLLINFO),
fMask = User32.SIF.TRACKPOS
};

User32.GetScrollInfo(this, User32.SB.CTL, ref si);

if (RightToLeft == RightToLeft.Yes)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,20 +269,21 @@ public bool Visible
}
}

internal void UpdateScrollInfo()
internal unsafe void UpdateScrollInfo()
{
if (_parent is not null && _parent.IsHandleCreated && _visible)
{
var si = new User32.SCROLLINFO
User32.SCROLLINFO si = new()
{
cbSize = (uint)Marshal.SizeOf<User32.SCROLLINFO>(),
cbSize = (uint)sizeof(User32.SCROLLINFO),
fMask = User32.SIF.ALL,
nMin = _minimum,
nMax = _maximum,
nPage = _parent.AutoScroll ? (uint)GetPageSize(_parent) : (uint)LargeChange,
nPos = _value,
nTrackPos = 0
};

User32.SetScrollInfo(_parent, Orientation, ref si, BOOL.TRUE);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -927,13 +927,14 @@ protected virtual Point ScrollToControl(Control activeControl)
return new Point(xCalc, yCalc);
}

private int ScrollThumbPosition(User32.SB fnBar)
private unsafe int ScrollThumbPosition(User32.SB fnBar)
{
var si = new User32.SCROLLINFO
User32.SCROLLINFO si = new()
{
cbSize = (uint)Marshal.SizeOf<User32.SCROLLINFO>(),
cbSize = (uint)sizeof(User32.SCROLLINFO),
fMask = User32.SIF.TRACKPOS
};

User32.GetScrollInfo(this, fnBar, ref si);
return si.nTrackPos;
}
Expand Down
5 changes: 3 additions & 2 deletions src/System.Windows.Forms/src/System/Windows/Forms/TreeView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2778,11 +2778,12 @@ private unsafe void CustomDraw(ref Message m)
{
Rectangle bounds = node.RowBounds;

var si = new User32.SCROLLINFO
User32.SCROLLINFO si = new()
{
cbSize = (uint)Marshal.SizeOf<User32.SCROLLINFO>(),
cbSize = (uint)sizeof(User32.SCROLLINFO),
fMask = User32.SIF.POS
};

if (User32.GetScrollInfo(this, User32.SB.HORZ, ref si).IsTrue())
{
// need to get the correct bounds if horizontal scroll bar is shown.
Expand Down

0 comments on commit 7ecc0cf

Please sign in to comment.