using System; using System.Drawing; namespace Mk0.Tools.ImageCropper { #region Enumerations public enum RasterOps { R2_BLACK = 1, R2_NOTMERGEPEN, R2_MASKNOTPEN, R2_NOTCOPYPEN, R2_MASKPENNOT, R2_NOT, R2_XORPEN, R2_NOTMASKPEN, R2_MASKPEN, R2_NOTXORPEN, R2_NOP, R2_MERGENOTPEN, R2_COPYPEN, R2_MERGEPENNOT, R2_MERGEPEN, R2_WHITE, R2_LAST } public enum BrushStyles { BS_SOLID = 0, BS_NULL = 1, BS_HATCHED = 2, BS_PATTERN = 3, BS_INDEXED = 4, BS_DIBPATTERN = 5, BS_DIBPATTERNPT = 6, BS_PATTERN8X8 = 7, BS_MONOPATTERN = 9 } public enum PenStyles { PS_SOLID = 0, PS_DASH = 1, PS_DOT = 2, PS_DASHDOT = 3, PS_DASHDOTDOT = 4 } #endregion public sealed class GDIWrap : IDisposable { #region Variables private Color _borderColor; private Color _fillColor; private int _lineWidth; private IntPtr _hdc, _oldBrush, _oldPen, _gdiPen, _gdiBrush; private BrushStyles _brushStyle; private PenStyles _penStyle; #endregion #region Constructors /// /// Initializes a new instance of the GDIWrap class. /// public GDIWrap() { // Set up for XOR drawing to begin with this._borderColor = Color.Transparent; this._fillColor = Color.Black; this._lineWidth = 2; this._brushStyle = BrushStyles.BS_NULL; this._penStyle = PenStyles.PS_SOLID; } #endregion #region Properties /// /// Gets or sets the current BrushColor /// public Color BrushColor { get { return _fillColor; } set { _fillColor = value; } } /// /// Gets or sets the current BrushStyle. Set to BS_NULL for no brush. /// public BrushStyles BrushStyle { get { return _brushStyle; } set { _brushStyle = value; } } /// /// Gets or sets the current PenColor. Set to Color.Transparent for a XOR line. /// public Color PenColor { get { return _borderColor; } set { _borderColor = value; } } /// /// Gets or sets the current PenStyle. /// public PenStyles PenStyle { get { return _penStyle; } set { _penStyle = value; } } /// /// Gets or sets the current PenWidth. /// public int PenWidth { get { return _lineWidth; } set { _lineWidth = value; } } #endregion #region Methods /// /// Draws a line with the pen that has been set by the user. Uses gdi32->MoveToEx and gdi32->LineTo /// /// Graphics object. You can use CreateGraphics(). /// Initial point of line. /// Termination point of line. public void DrawLine(Graphics g, Point p1, Point p2) { InitPenAndBrush(g); NativeMethods.MoveToEx(_hdc, p1.X, p1.Y, (IntPtr)null); NativeMethods.LineTo(_hdc, p2.X, p2.Y); Dispose(g); } /// /// Draws a rectangle with the pen and brush that have been set by the user. Uses gdi32->Rectangle /// /// Graphics object. You can use CreateGraphics(). /// The shape to draw. public void DrawRectangle(Graphics g, Rectangle myRect) { InitPenAndBrush(g); NativeMethods.Rectangle(_hdc, myRect.Left, myRect.Top, myRect.Right, myRect.Bottom); Dispose(g); } /// /// Draws an ellipse with the pen and brush that have been set by the user. Uses gdi32->Ellipse /// /// Graphics object. You can use CreateGraphics(). /// First corner of ellipse (if you imagine its size as a rectangle). /// Second corner of ellipse (if you imagine its size as a rectangle). public void DrawEllipse(Graphics g, Point p1, Point p2) { InitPenAndBrush(g); NativeMethods.Ellipse(_hdc, p1.X, p1.Y, p2.X, p2.Y); Dispose(g); } public void Dispose() { } private int GetRGBFromColor(Color fromColor) { return fromColor.ToArgb() & 0xFFFFFF; } /// /// Initializes the pen and brush objects. Stores the old pen and brush so they can be recovered later. /// /// private void InitPenAndBrush(Graphics g) { _hdc = g.GetHdc(); _gdiPen = NativeMethods.CreatePen(_penStyle, _lineWidth, GetRGBFromColor(PenColor)); _gdiBrush = NativeMethods.GetStockObject(5); // CreateSolidBrush(GetRGBFromColor(fillColor)); if (PenColor == Color.Transparent) NativeMethods.SetROP2(_hdc, (int)RasterOps.R2_XORPEN); _oldPen = NativeMethods.SelectObject(_hdc, _gdiPen); _oldBrush = NativeMethods.SelectObject(_hdc, _gdiBrush); } /// /// Reloads the old pen and brush. /// Deletes the pen that was created by InitPenAndBrush(g). /// Releases the handle to the device context and then disposes of the Graphics object. /// /// private void Dispose(Graphics g) { NativeMethods.SelectObject(_hdc, _oldBrush); NativeMethods.SelectObject(_hdc, _oldPen); NativeMethods.DeleteObject(_gdiPen); NativeMethods.DeleteObject(_gdiBrush); g.ReleaseHdc(_hdc); } #endregion internal static class NativeMethods { [System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")] internal static extern bool Ellipse(IntPtr hdc, int x1, int y1, int x2, int y2); [System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")] internal static extern bool Rectangle(IntPtr hdc, int X1, int Y1, int X2, int Y2); [System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")] internal static extern IntPtr MoveToEx(IntPtr hdc, int x, int y, IntPtr lpPoint); [System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")] internal static extern bool LineTo(IntPtr hdc, int x, int y); [System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")] internal static extern IntPtr CreatePen(PenStyles enPenStyle, int nWidth, int crColor); [System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")] internal static extern IntPtr CreateSolidBrush(int crColor); [System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")] internal static extern bool DeleteObject(IntPtr hObject); [System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")] internal static extern IntPtr SelectObject(IntPtr hdc, IntPtr hObject); [System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")] internal static extern IntPtr GetStockObject(int brStyle); [System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")] internal static extern int SetROP2(IntPtr hdc, int enDrawMode); } } }