簡體   English   中英

從WinForms C#調用SCROLLINFO PInvoke

[英]SCROLLINFO PInvoke from WinForms C#

我正在使用滾動條編寫控件,並且希望它的行為(就滾動條而言)像RichTextBox 即當欄是“強制的”時,我希望它們被禁用,直到它們變得必要為止。 我有這種工作(有點),但是在構建項目之前,我看不到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填充以清楚顯示控件的邊界)

圖片1

在這里,我已經將ScrollBars屬性設置為ForcedVertical,但是直到我構建解決方案時它才會顯示

圖片2

在這里,我再次選擇了ForcedBoth,它在構建后顯示

圖片3

題:

如何使設計器立即更新,以便可以在不需要持續構建的情況下查看更改?

注意:

請原諒糟糕的代碼質量(可變結構,可怕的名稱等)-這只是一個演示!

我也不想使用ScrollableControl ...太爛了! 我需要對ScrollBars進行完全控制-Win32的預期方式!

.Invalidate() .Update().Refresh()不起作用!

我認為您必須重新創建窗口才能執行此操作。 嘗試這種方式:

public RichTextBoxScrollBars ScrollBars {
  get {
    return this.sb;
  }
  set {
    this.sb = value;
    this.RecreateHandle();
  }
}

protected override void OnHandleCreated(EventArgs e) {
  base.OnHandleCreated(e);
  UpdateScrollBars();
}

最有可能的是,您需要強制重畫控件,即,在UpdateScrollBars方法的末尾添加Invalidate(); UpdateScrollBars

編輯:以下對我UpdateScrollBars (在UpdateScrollBars ):

Invalidate();
Update();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM