WinForms C# 中的 SCROLLINFO PInvoke
SCROLLINFO PInvoke from WinForms C#
我正在编写一个带滚动条的控件,我希望它的行为(就滚动条而言)像 RichTextBox
;即当条形图为 "Forced" 时,我希望它们在必要时被禁用。我有这个工作(有点),但在构建项目之前我没有在 Windows Forms Designer 中看到结果。
代码:
namespace WindowsFormsApplication1
{
public class ScrollControl : Control
{
public const int WS_HSCROLL = 0x00100000;
public const int WS_VSCROLL = 0x00200000;
private RichTextBoxScrollBars sb;
public RichTextBoxScrollBars ScrollBars
{
get
{
return this.sb;
}
set
{
this.sb = value;
this.UpdateScrollBars();
}
}
protected override CreateParams CreateParams
{
get
{
CreateParams result = base.CreateParams;
result.Style |= WS_HSCROLL;
result.Style |= WS_VSCROLL;
return result;
}
}
private void UpdateScrollBars()
{
ScrollOrientation dirH = ScrollOrientation.HorizontalScroll;
ScrollInfoMask maskH = ScrollInfoMask.SIF_ALL;
ScrollOrientation dirV = ScrollOrientation.VerticalScroll;
ScrollInfoMask maskV = ScrollInfoMask.SIF_ALL;
if (this.ScrollBars == RichTextBoxScrollBars.ForcedVertical || this.ScrollBars == RichTextBoxScrollBars.ForcedBoth)
{
maskV |= ScrollInfoMask.SIF_DISABLENOSCROLL;
}
if(this.ScrollBars == RichTextBoxScrollBars.ForcedHorizontal || this.ScrollBars == RichTextBoxScrollBars.ForcedBoth)
{
maskH |= ScrollInfoMask.SIF_DISABLENOSCROLL;
}
SCROLLINFO sV = new SCROLLINFO();
SCROLLINFO sH = new SCROLLINFO();
sV.cbSize = (uint)Marshal.SizeOf<SCROLLINFO>();
sH.cbSize = (uint)Marshal.SizeOf<SCROLLINFO>();
sV.fMask = (uint)maskV;
sH.fMask = (uint)maskH;
SetScrollInfo(this.Handle, (int)dirV, ref sV, true);
SetScrollInfo(this.Handle, (int)dirH, ref sH, true);
}
[DllImport("user32.dll")]
private static extern int SetScrollInfo(IntPtr hwnd, int fnBar, [In] ref SCROLLINFO lpsi, bool fRedraw);
}
[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;
}
public enum ScrollInfoMask
{
SIF_RANGE = 0x0001,
SIF_PAGE = 0x0002,
SIF_POS = 0x0004,
SIF_DISABLENOSCROLL = 0x0008,
SIF_TRACKPOS = 0x0010,
SIF_ALL = SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS
}
}
在这里,我已经构建了控件并将其加载到表单中(表单上的 16x 填充以清楚地显示控件的边界)
在这里,我已将 ScrollBars 属性 设置为 ForcedVertical,但是在构建解决方案之前不会显示
这里我选择了ForcedBoth,同样,这个只在构建
后显示
问题:
如何让 Designer 立即更新,以便我可以看到我的更改而无需不断构建?
注:
请原谅糟糕的代码质量(可变结构、可怕的名称等)- 这只是一个演示!
我也不想用ScrollableControl
...太烂了!我需要 COMPLETE 控制 ScrollBars - Win32 预期的方式!
.Invalidate()
.Update()
和 .Refresh()
不工作!
很可能,您需要强制重绘控件,即在 UpdateScrollBars
方法的末尾添加 Invalidate();
.
编辑:以下对我有用(在 UpdateScrollBars
末尾):
Invalidate();
Update();
我认为您必须重新创建 window 才能做到这一点。试试这样:
public RichTextBoxScrollBars ScrollBars {
get {
return this.sb;
}
set {
this.sb = value;
this.RecreateHandle();
}
}
protected override void OnHandleCreated(EventArgs e) {
base.OnHandleCreated(e);
UpdateScrollBars();
}
我正在编写一个带滚动条的控件,我希望它的行为(就滚动条而言)像 RichTextBox
;即当条形图为 "Forced" 时,我希望它们在必要时被禁用。我有这个工作(有点),但在构建项目之前我没有在 Windows Forms Designer 中看到结果。
代码:
namespace WindowsFormsApplication1
{
public class ScrollControl : Control
{
public const int WS_HSCROLL = 0x00100000;
public const int WS_VSCROLL = 0x00200000;
private RichTextBoxScrollBars sb;
public RichTextBoxScrollBars ScrollBars
{
get
{
return this.sb;
}
set
{
this.sb = value;
this.UpdateScrollBars();
}
}
protected override CreateParams CreateParams
{
get
{
CreateParams result = base.CreateParams;
result.Style |= WS_HSCROLL;
result.Style |= WS_VSCROLL;
return result;
}
}
private void UpdateScrollBars()
{
ScrollOrientation dirH = ScrollOrientation.HorizontalScroll;
ScrollInfoMask maskH = ScrollInfoMask.SIF_ALL;
ScrollOrientation dirV = ScrollOrientation.VerticalScroll;
ScrollInfoMask maskV = ScrollInfoMask.SIF_ALL;
if (this.ScrollBars == RichTextBoxScrollBars.ForcedVertical || this.ScrollBars == RichTextBoxScrollBars.ForcedBoth)
{
maskV |= ScrollInfoMask.SIF_DISABLENOSCROLL;
}
if(this.ScrollBars == RichTextBoxScrollBars.ForcedHorizontal || this.ScrollBars == RichTextBoxScrollBars.ForcedBoth)
{
maskH |= ScrollInfoMask.SIF_DISABLENOSCROLL;
}
SCROLLINFO sV = new SCROLLINFO();
SCROLLINFO sH = new SCROLLINFO();
sV.cbSize = (uint)Marshal.SizeOf<SCROLLINFO>();
sH.cbSize = (uint)Marshal.SizeOf<SCROLLINFO>();
sV.fMask = (uint)maskV;
sH.fMask = (uint)maskH;
SetScrollInfo(this.Handle, (int)dirV, ref sV, true);
SetScrollInfo(this.Handle, (int)dirH, ref sH, true);
}
[DllImport("user32.dll")]
private static extern int SetScrollInfo(IntPtr hwnd, int fnBar, [In] ref SCROLLINFO lpsi, bool fRedraw);
}
[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;
}
public enum ScrollInfoMask
{
SIF_RANGE = 0x0001,
SIF_PAGE = 0x0002,
SIF_POS = 0x0004,
SIF_DISABLENOSCROLL = 0x0008,
SIF_TRACKPOS = 0x0010,
SIF_ALL = SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS
}
}
在这里,我已经构建了控件并将其加载到表单中(表单上的 16x 填充以清楚地显示控件的边界)
在这里,我已将 ScrollBars 属性 设置为 ForcedVertical,但是在构建解决方案之前不会显示
这里我选择了ForcedBoth,同样,这个只在构建
后显示问题:
如何让 Designer 立即更新,以便我可以看到我的更改而无需不断构建?
注:
请原谅糟糕的代码质量(可变结构、可怕的名称等)- 这只是一个演示!
我也不想用ScrollableControl
...太烂了!我需要 COMPLETE 控制 ScrollBars - Win32 预期的方式!
.Invalidate()
.Update()
和 .Refresh()
不工作!
很可能,您需要强制重绘控件,即在 UpdateScrollBars
方法的末尾添加 Invalidate();
.
编辑:以下对我有用(在 UpdateScrollBars
末尾):
Invalidate();
Update();
我认为您必须重新创建 window 才能做到这一点。试试这样:
public RichTextBoxScrollBars ScrollBars {
get {
return this.sb;
}
set {
this.sb = value;
this.RecreateHandle();
}
}
protected override void OnHandleCreated(EventArgs e) {
base.OnHandleCreated(e);
UpdateScrollBars();
}