Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WinC窗体中的SCROLLINFO PInvoke#_C#_.net_Winforms_Scrollbar_Pinvoke - Fatal编程技术网

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();-我认为这比仅仅重新绘制表单要深入一点,因此无效、更新和刷新都不起作用。天哪……天才!先生,你应该得到一枚奖章!