1. 程式人生 > >C#獲取滾動條的相關資訊

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+繪圖重疊的現象。