我正在使用辅助Scrollbar
进行一些手动滚动。我使用GetScrollInfo
API来获取Scrollbar
的跟踪位置。但是,当滚动结束时,轨道位置将恢复到其最后设定位置。因此,我使用SetScrollInfo
API在滚动结束后设置滚动信息,但之后只能在鼠标移动后直观地更新。我该怎么做才能解决这个问题?
ScrollUtility:
public class ScrollUtility
{
[DllImportAttribute("user32.dll")]
[PreserveSigAttribute()]
public static extern int SetScrollInfo(
IntPtr hWnd,
int fnBar,
ref SCROLLINFO si,
bool redraw
);
[DllImport("user32.dll")]
[PreserveSigAttribute()]
public static extern bool GetScrollInfo(
IntPtr hwnd,
int fnBar,
ref SCROLLINFO ScrollInfo
);
}
[Serializable, StructLayout(LayoutKind.Sequential)]
public struct SCROLLINFO
{
public uint cbSize;
public uint fMask;
public int nMin;
public int nMax;
public uint nPage;
public int nPos;
public int nTrackPos; // Ignored by setter
public override string ToString()
{
return cbSize + " " + fMask + " " + nMin + " " + nMax + " " + nPage + " " + nPos + " " + nTrackPos;
}
public const int SB_HORZ = 0x0000;
public const int SB_VERT = 0x0001;
public const int WM_HSCROLL = 0x0114;
public const int WM_VSCROLL = 0x0115;
public const int SB_THUMBPOSITION = 4;
public enum ScrollInfoMask : uint
{
SIF_RANGE = 0x1,
SIF_PAGE = 0x2,
SIF_POS = 0x4,
SIF_DISABLENOSCROLL = 0x8,
SIF_TRACKPOS = 0x10,
SIF_ALL = (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS)
}
}
Form1中:
public partial class Form1 : Form
{
private bool setOnStartUp = true; // Track position will not update if this is false
private bool setOnEndScroll = true; // Track position reverts to last set position if this is false, but still doesn't update visually if this is true until the mouse moves.
public Form1()
{
InitializeComponent();
if (setOnStartUp)
{
SCROLLINFO info = new SCROLLINFO
{
cbSize = (uint)Marshal.SizeOf(typeof(SCROLLINFO)),
fMask = (uint)SCROLLINFO.ScrollInfoMask.SIF_ALL,
nMax = 1000,
nMin = 0,
nPage = 50,
nPos = 500, // The middle of the scroll bar - just for testing
};
// Am I using the right handle?
ScrollUtility.SetScrollInfo(vScrollBar.Handle, SCROLLINFO.SB_VERT, ref info, true);
}
}
private void vScrollBar_Scroll(object sender, ScrollEventArgs e)
{
SCROLLINFO info = new SCROLLINFO
{
cbSize = (uint)Marshal.SizeOf(typeof(SCROLLINFO)),
fMask = (uint)SCROLLINFO.ScrollInfoMask.SIF_ALL
};
ScrollUtility.GetScrollInfo(vScrollBar.Handle, SCROLLINFO.SB_VERT, ref info);
label.Text = "Track: " + info.nTrackPos;
if (setOnEndScroll)
{
if (e.Type == ScrollEventType.EndScroll)
{
info.nPos = info.nTrackPos;
ScrollUtility.SetScrollInfo(vScrollBar.Handle, SCROLLINFO.SB_VERT, ref info, true);
}
}
}
}