天天看點

C#擷取滾動條的相關資訊

        C#很多控件都有滾動條屬性,我們也可以自己手動添加滾動條到控件(具體的例子見MSDN)。

        本文主要是擷取滾動條的一些資訊,例如滾動條滑塊的大小,滾動條按鈕塊的大小。根據這些資訊,使用者能夠自己計算出滑塊的任意偏移位置。當然了,微軟為我們提供了一個AutoScrollPosition屬性,能夠友善的計算出滑塊的位移。下面我們調用user32.dll裡的API來擷取滾動條資訊。

#region 擷取滾動條的資訊

        public const uint ObjidHscroll = 0xFFFFFFFA;  //水準滾動條

        public const uint ObjidVscroll = 0xFFFFFFFB;  //垂直滾動條

        [DllImport("user32.dll", SetLastError = true, EntryPoint = "GetScrollBarInfo")]

        private static extern int GetScrollBarInfo(IntPtr hWnd,

            uint idObject, ref Scrollbarinfo psbi);

      //滾動條的具體資訊

        public struct Scrollbarinfo

        {

            public int cbSize;

            public Rect rcScrollBar;

            public int dxyLineButton;

            public int xyThumbTop;  //滑塊資訊(滑塊的Top或Left坐标)

            public int xyThumbBottom; 滑塊的Bottom或Right坐标

            public int reserved;

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]

            public int[] rgstate;

        }

        public struct Rect

        {

            public int Left;

            public int Top;

            public int Right;

            public int Bottom;

        }

        #endregion

     定義好上面的資訊好,我們隻需要簡單的調用GetScrollBarInfo()函數即可。具體如下:

                    var info = new Scrollbarinfo();

                    var info_v = new Scrollbarinfo();

                    info.cbSize = Marshal.SizeOf(info);

                    var res_h = GetScrollBarInfo(this.Handle, ObjidHscroll, ref info); //水準滾動條資訊

                    var res_v = GetScrollBarInfo(this.Handle, ObjidVscroll, ref info_v); //垂直滾動條資訊

                    int sc = info.xyThumbBottom - info.xyThumbTop;   //這個就是滑塊的大小

     根據這些資訊以及滑塊的NewValue和OldValue計算出大概的偏移,這種做法主要是為了自己設定滾動條屬性才采用的。如果要計算滾動條的偏移隻需要記錄上次的

AutoScrollPosition和目前的AutoScrollPosition,然後做差即可得到準确的偏移。

    現在假設有這樣的一種情況:使用者在UserControl上用GDI+繪制很多圖形(矩形,橢圓......),但是客戶區域不夠存放整個畫布,此時為了能夠浏覽整個畫布,此時我們可以添加滾動條,方法如下:

      this.AutoScroll = true; //自動滾動條屬性

      this.AutoScrollMinSize = new Size(virtual_x, virtual_y); //設定虛拟區域的大小,可以了解為畫布的大小

然後在滑動滾動條時更新畫布上的所有圖形的Location,如:

int offset_h = currentMovePosition.X - lastMovePosition.X;  //currentMovePosition表示目前AutoScrollPosition,lastMovePosition表示上次AutoScrollPosition

得到水準滾動條的滑動距離

UserControl.Location=new Point(UserControl.Location.X+offset_h,UserControl.Location.Y)   

垂直方向同理可以計算出,這樣整個畫布都能預覽處理,不會出現GDI+繪圖重疊的現象。

c#