C# WinC窗体中的SCROLLINFO PInvoke#
我正在编写一个带有滚动条的控件,我希望它的行为(就滚动条而言)像C# WinC窗体中的SCROLLINFO PInvoke#,c#,.net,winforms,scrollbar,pinvoke,C#,.net,Winforms,Scrollbar,Pinvoke,我正在编写一个带有滚动条的控件,我希望它的行为(就滚动条而言)像RichTextBox;i、 e.当钢筋“强制”时,我希望在必要时禁用钢筋。我有这个工作(某种程度上),但在构建项目之前,我不会在Windows窗体设计器中看到结果 代码: namespace WindowsFormsApplication1 { public class ScrollControl : Control { public const int WS_HSCROLL = 0x0010000
RichTextBox
;i、 e.当钢筋“强制”时,我希望在必要时禁用钢筋。我有这个工作(某种程度上),但在构建项目之前,我不会在Windows窗体设计器中看到结果
代码:
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
}
}
命名空间窗口窗体应用程序1
{
公共类滚动控件:控件
{
公共常数int WS_HSCROLL=0x00100000;
公共常数int WS_VSCROLL=0x00200000;
私人RichTextBoxScrollBars某人;
公共RichTextBoxScrollBars滚动条滚动条
{
得到
{
把这个还给某人;
}
设置
{
这是sb=值;
this.UpdateScrollBars();
}
}
受保护的重写CreateParams CreateParams
{
得到
{
CreateParams结果=base.CreateParams;
结果.Style |=WS|HSCROLL;
结果.Style |=WS|u VSCROLL;
返回结果;
}
}
私有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|u DISABLENOSCROLL;
}
if(this.ScrollBars==RichTextBoxScrollBars.ForcedHorizontal | | this.ScrollBars==RichTextBoxScrollBars.ForcedBoth)
{
maskH |=ScrollInfoMask.SIF|u DISABLENOSCROLL;
}
SCROLLINFO sV=新的SCROLLINFO();
SCROLLINFO sH=新的SCROLLINFO();
sV.cbSize=(uint)Marshal.SizeOf();
sH.cbSize=(uint)Marshal.SizeOf();
sV.fMask=(uint)maskV;
sH.fMask=(uint)maskH;
setScrolInfo(this.Handle,(int)dirV,ref sV,true);
setScrolInfo(this.Handle,(int)dirH,ref sH,true);
}
[DllImport(“user32.dll”)]
私有静态外部设置crollinfo(IntPtr hwnd,intfnbar,[In]ref SCROLLINFO lpsi,bool fRedraw);
}
[StructLayout(LayoutKind.Sequential)]
公共结构滚动信息
{
公共单位cbSize;
公共单位任务;
公共国际信息网;
公共int nMax;
公共单位网页;
公共非营利组织;
公共int nTrackPos;
}
公共枚举滚动信息掩码
{
应力强度因子范围=0x0001,
SIF_页面=0x0002,
SIF_POS=0x0004,
SIF_DISABLENOSCROLL=0x0008,
SIF_TRACKPOS=0x0010,
SIF_ALL=SIF_范围| SIF_页面| SIF_位置| SIF_轨迹位置
}
}
在这里,我构建了控件并将其加载到表单中(表单上填充16倍以清晰显示控件的边界)
在这里,我已经将ScrollBars属性设置为ForcedVertical,但是在构建解决方案之前,这个不会显示
这里我选择了ForcedBoth,同样,这个只在构建后显示
问题:
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
}
}
如何让设计器立即更新,以便在不需要不断构建的情况下查看更改
注意:
请原谅代码质量差(易变结构、可怕的名称等)-这只是一个演示
我也不想使用ScrollableControl
…这太糟糕了!我需要完成对滚动条的控制-就像Win32预期的那样
.Invalidate()
.Update()和.Refresh()
不起作用 最可能的情况是,您需要强制重新绘制控件,即在UpdateScrollBars
方法的末尾,添加Invalidate()代码>
编辑:以下内容适合我(在UpdateScrollBars
的末尾):
我想你必须重新创建窗口才能做到这一点。试着这样做:
public RichTextBoxScrollBars ScrollBars {
get {
return this.sb;
}
set {
this.sb = value;
this.RecreateHandle();
}
}
protected override void OnHandleCreated(EventArgs e) {
base.OnHandleCreated(e);
UpdateScrollBars();
}
不,试过了……也试过将它与Update()和Refresh()结合使用……什么都不起作用。@series0ne:你在原来的帖子中没有写过。考虑到这一点,否决权似乎并不公平。公平评论,道歉我找到了一个适合我的解决方案(VS 2013)。我编辑了我的答案。请让我知道这是否也适用于你。不:-(刷新();与.Invalidate();.Update();-我认为这比仅仅重新绘制表单要深入一点,因此无效、更新和刷新都不起作用。天哪……天才!先生,你应该得到一枚奖章!