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