public class ControlImage { #region API [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] 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 ScrollBarInfoFlags { 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) } public enum ScrollBarRequests { SB_LINEUP = 0, SB_LINELEFT = 0, SB_LINEDOWN = 1, SB_LINERIGHT = 1, SB_PAGEUP = 2, SB_PAGELEFT = 2, SB_PAGEDOWN = 3, SB_PAGERIGHT = 3, SB_THUMBPOSITION = 4, SB_THUMBTRACK = 5, SB_TOP = 6, SB_LEFT = 6, SB_BOTTOM = 7, SB_RIGHT = 7, SB_ENDSCROLL = 8 } [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern int GetScrollInfo(IntPtr hwnd, int bar, ref SCROLLINFO si); [DllImport("user32")] public static extern int SetScrollPos(IntPtr hWnd, int nBar, int nPos, bool Rush); [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, int lParam); [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern IntPtr SendMessage(HandleRef hWnd, int msg, IntPtr wParam, IntPtr lParam); [DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)] public static extern bool BitBlt(HandleRef hDC, int x, int y, int nWidth, int nHeight, HandleRef hSrcDC, int xSrc, int ySrc, int dwRop); #endregion private ControlImage() { } private static int verticalScrollBarWidth = SystemInformation.VerticalScrollBarWidth; private static int horizontalScrollBarHeight = SystemInformation.HorizontalScrollBarHeight; /// <summary> /// 支持呈现到指定的位图。 /// </summary> public static void DrawToBitmap(Control control, Bitmap bitmap, Rectangle targetBounds) { if (bitmap == null) { throw new ArgumentNullException("bitmap"); } if (((targetBounds.Width <= 0) || (targetBounds.Height <= 0)) || ((targetBounds.X < 0) || (targetBounds.Y < 0))) { throw new ArgumentException("targetBounds"); } Bitmap image = new Bitmap(control.Width, control.Height, bitmap.PixelFormat); using (Graphics graphics = Graphics.FromImage(image)) { IntPtr hdc = graphics.GetHdc(); SendMessage(new HandleRef(control, control.Handle), 0x317, hdc, (IntPtr)30); using (Graphics graphics2 = Graphics.FromImage(bitmap)) { IntPtr handle = graphics2.GetHdc(); BitBlt(new HandleRef(graphics2, handle), 0, 0, control.Width, control.Height, new HandleRef(graphics, hdc), targetBounds.X, targetBounds.Y, 0xcc0020); graphics2.ReleaseHdcInternal(handle); } graphics.ReleaseHdcInternal(hdc); } } /// <summary> /// 获取图形 有滚动截图功能 /// </summary> public static Bitmap GetImage(Control control) { Point scrollMaxInfo = GetScrollPoint(control); Size controlMaxSize = GetControlSize(control, scrollMaxInfo); Bitmap bitmap = new Bitmap(controlMaxSize.Width, controlMaxSize.Height); if (scrollMaxInfo.IsEmpty) { DrawToBitmap(control, bitmap, new Rectangle(0, 0, control.Width, control.Height)); return bitmap; } Graphics g = Graphics.FromImage(bitmap); Bitmap tempBitmap = new Bitmap(control.Width - verticalScrollBarWidth, control.Height - horizontalScrollBarHeight); int stepWidth = GetScrollNumber(control.Width - verticalScrollBarWidth, scrollMaxInfo.X); int stepHeight = GetScrollNumber(control.Height - horizontalScrollBarHeight, scrollMaxInfo.Y); int widthPos = 0; int heightPos = 0; MoveBar(0, 0, control); for (int i = 0; i < stepWidth; i++) { heightPos = 0; MoveBar(1, 0, control); for (int z = 0; z < stepHeight; z++) { control.DrawToBitmap(tempBitmap, new Rectangle(0, 0, control.Width - verticalScrollBarWidth, control.Height - horizontalScrollBarHeight)); g.DrawImage(tempBitmap, widthPos, heightPos); MoveBar(1, control.Height - horizontalScrollBarHeight + heightPos, control); heightPos = GetScrollPoint(1, control); } MoveBar(0, control.Width - verticalScrollBarWidth + widthPos, control); widthPos = GetScrollPoint(0, control); } g.Dispose(); tempBitmap.Dispose(); return bitmap; } /// <summary> /// 获取目前滚动条位置 /// </summary> /// <param name="bar"></param> /// <param name="control"></param> /// <returns></returns> private static int GetScrollPoint(int bar, Control control) { SCROLLINFO scrollInfo = new SCROLLINFO(); scrollInfo.cbSize = (uint)Marshal.SizeOf(scrollInfo); scrollInfo.fMask = (uint)ScrollBarInfoFlags.SIF_ALL; GetScrollInfo(control.Handle, bar, ref scrollInfo); return scrollInfo.nPos; } /// <summary> /// 获取循环几次获得图形 /// </summary> private static int GetScrollNumber(int controlNumber, int scrollMaxInfoNumber) { return (int)Math.Ceiling(scrollMaxInfoNumber / (double)controlNumber) + 1; } /// <summary> /// 获得控件不需要滚动条的宽和高(最终图形大小) /// </summary> private static Size GetControlSize(Control control, Point scrollMaxInfo) { return new Size(control.Size.Width + scrollMaxInfo.X - verticalScrollBarWidth, control.Size.Height + scrollMaxInfo.Y - horizontalScrollBarHeight); } /// <summary> /// 获取控件滚动条数据 /// </summary> private static Point GetScrollPoint(Control control) { verticalScrollBarWidth = SystemInformation.VerticalScrollBarWidth; horizontalScrollBarHeight = SystemInformation.HorizontalScrollBarHeight; Point maxScroll = new Point(); SCROLLINFO scrollInfo = new SCROLLINFO(); scrollInfo.cbSize = (uint)Marshal.SizeOf(scrollInfo); scrollInfo.fMask = (uint)ScrollBarInfoFlags.SIF_ALL; GetScrollInfo(control.Handle, 1, ref scrollInfo); if ((int)scrollInfo.nPage == 0) { maxScroll.Y = 0; verticalScrollBarWidth = 0; } else { maxScroll.Y = scrollInfo.nMax - (int)scrollInfo.nPage; } GetScrollInfo(control.Handle, 0, ref scrollInfo); if ((int)scrollInfo.nPage == 0) { maxScroll.X = 0; horizontalScrollBarHeight = 0; } else { maxScroll.X = scrollInfo.nMax - (int)scrollInfo.nPage; } return maxScroll; } /// <summary> /// 移动控件滚动条位置 /// </summary> private static void MoveBar(int bar, int nPose, Control control) { if (bar == 0) { SetScrollPos(control.Handle, 0, nPose, true); SendMessage(control.Handle, 0x0114, (int)ScrollBarRequests.SB_THUMBPOSITION, 0); } else { SetScrollPos(control.Handle, 1, nPose, true); SendMessage(control.Handle, 0x0115, (int)ScrollBarRequests.SB_THUMBPOSITION, 0); } } }
转载于:https://www.cnblogs.com/hdl217/articles/2131884.html