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;
}
}
}