using System; using System.Drawing; using System.Runtime.InteropServices; using System.Windows.Forms; namespace FastReport.Utils { partial class DrawUtils { [DllImport("user32.dll")] static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, DrawingOptions drawingOptions); const int WM_PRINT = 0x317; [Flags] enum DrawingOptions { PRF_CHECKVISIBLE = 0x01, PRF_NONCLIENT = 0x02, PRF_CLIENT = 0x04, PRF_ERASEBKGND = 0x08, PRF_CHILDREN = 0x10, PRF_OWNED = 0x20 } private static void FloodFill(Bitmap bmp, int x, int y, Color color, Color replacementColor) { if (x < 0 || y < 0 || x >= bmp.Width || y >= bmp.Height || bmp.GetPixel(x, y) != color) return; bmp.SetPixel(x, y, replacementColor); FloodFill(bmp, x - 1, y, color, replacementColor); FloodFill(bmp, x + 1, y, color, replacementColor); FloodFill(bmp, x, y - 1, color, replacementColor); FloodFill(bmp, x, y + 1, color, replacementColor); } /// /// Draws control to a bitmap. /// /// Control to draw. /// Determines whether to draw control's children or not. /// The bitmap. public static Bitmap DrawToBitmap(Control control, bool children) { Bitmap bitmap = new Bitmap(control.Width, control.Height); using (Graphics gr = Graphics.FromImage(bitmap)) { IntPtr hdc = gr.GetHdc(); DrawingOptions options = DrawingOptions.PRF_ERASEBKGND | DrawingOptions.PRF_CLIENT | DrawingOptions.PRF_NONCLIENT; if (children) options |= DrawingOptions.PRF_CHILDREN; SendMessage(control.Handle, WM_PRINT, hdc, options); gr.ReleaseHdc(hdc); } if (control is Form) { // form has round edges which are filled black (DrawToBitmap issue/bug). FloodFill(bitmap, 0, 0, Color.FromArgb(0, 0, 0), Color.White); FloodFill(bitmap, bitmap.Width - 1, 0, Color.FromArgb(0, 0, 0), Color.White); } return bitmap; } } }