title: Highlight effect like snipping tool
body: <p>Im creating a new snipping tool similar to the windows 7 snipping tool.</p>
  
  <p>however I cant get the highlight effect working the same.</p>
  
  <p>for example, the snipping tool highlight works as follows: (The highlight is very bright on a white background, it looks like it has no transparency</p>
  
  <p><img src="https://i.stack.imgur.com/WbPLS.jpg" alt="enter image description here"></p>
  
  <p>and my snipping tool highlight looks as follows:</p>
  
  <p><img src="https://i.stack.imgur.com/o6Xfm.png" alt="enter image description here"></p>
  
  <p>Im sure the color used is the same (255,255,0) with an alpha channel of 110. if i decrease the transparency then it just overwrites the text below.</p>
  
  <p>my snip is applying the transparency over the top of the white, where as the windows snipping tool seems to blend it all better.</p>
  
  <p>What am i doing wrong here?</p>
  
  <p>the code I am using for my highlight annotation is:</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Drawing;
  using System.Linq;
  using System.Text;
  using System.Windows.Forms;
  
      namespace Sicon.Snipper.Annotations
      {
          /// &lt;summary&gt;
          /// Highlight Annotation
          /// &lt;/summary&gt;
          public class HighlightAnnotation : BaseAnnotation
          {
              #region Members
  
              protected Rectangle _selection = Rectangle.Empty;
              protected const int _transparancyAlpha = 110;
              private Brush _brush;
  
              #endregion Members
  
              #region Properties
  
              /// &lt;summary&gt;
              /// Gets or Sets the Brush
              /// &lt;/summary&gt;
              protected Brush Brush
              {
                  get { return _brush; }
                  set { _brush = value; }
              }
  
              /// &lt;summary&gt;
              /// Gets the Selection
              /// &lt;/summary&gt;
              public Rectangle Selection
              {
                  get { return _selection; }
                  protected set { _selection = value; }
              }
  
              #endregion Properties
  
              #region Constructors
  
              /// &lt;summary&gt;
              /// Constructor
              /// &lt;/summary&gt;
              /// &lt;param name="imageRef"&gt;Reference to the image&lt;/param&gt;
              public HighlightAnnotation(Image imageRef, Control host)
                  : base(imageRef, Pens.Yellow, host)
              {
                  this.Brush = new SolidBrush(
                                  Color.FromArgb(
                                  _transparancyAlpha,
                                  this.Pen.Color));
              }
  
              #endregion Constructors
  
              #region Methods
  
              /// &lt;summary&gt;
              /// Handles on Mouse down
              /// &lt;/summary&gt;
              /// &lt;param name="e"&gt;args&lt;/param&gt;
              public override void OnMouseDown(MouseEventArgs e)
              {
                  if (base.Enabled)
                  {
                      // Start the snip on mouse down
                      if (e.Button != MouseButtons.Left) return;
                      _startPoint = e.Location;
                      _selection = new Rectangle(e.Location, new Size(0, 0));
                  }
              }
  
              /// &lt;summary&gt;
              /// Handles Mouse Move
              /// &lt;/summary&gt;
              /// &lt;param name="e"&gt;args&lt;/param&gt;
              public override void OnMouseMove(MouseEventArgs e)
              {
                  if (base.Enabled)
                  {
                      // Modify the selection on mouse move
                      if (e.Button != MouseButtons.Left) return;
                      int x1 = Math.Min(e.X, _startPoint.X);
                      int y1 = Math.Min(e.Y, _startPoint.Y);
                      int x2 = Math.Max(e.X, _startPoint.X);
                      int y2 = Math.Max(e.Y, _startPoint.Y);
                      _selection = new Rectangle(x1, y1, x2 - x1, y2 - y1);
                  }
              }
  
              /// &lt;summary&gt;
              /// Handles on mouse up
              /// &lt;/summary&gt;
              /// &lt;param name="e"&gt;args&lt;/param&gt;
              public override void OnMouseUp(MouseEventArgs e)
              {
                  if (base.Enabled)
                  {
                      if (_selection.Width &lt;= 0 || _selection.Height &lt;= 0) return;
  
                      using (Graphics g = Graphics.FromImage(this.ImageRef))
                      {
                          Rectangle dest = new Rectangle(
                              TranslateCenterImageMousePosition(_startPoint),
                              _selection.Size);
  
                          g.FillRectangle(
                              this.Brush,
                              dest);
  
                      }
  
                      this.Enabled = false;
                  }
              }
  
              /// &lt;summary&gt;
              /// Hanles on paint
              /// &lt;/summary&gt;
              /// &lt;param name="g"&gt;graphics&lt;/param&gt;
              public override void OnPaint(System.Drawing.Graphics g)
              {
                  if (base.Enabled)
                      g.FillRectangle(this.Brush, _selection);
              }
  
              #endregion Methods
          }
      }
  </code></pre>
  
  <p><strong>UPDATE::</strong></p>
  
  <p>Ok, I have made a few changes, I like the idea of freehand drawing too, but the main reason im making this is to have nice tidy highlights etc.</p>
  
  <p>The issue I have now is that when i release the mouse button the rectangle gets drawn in black as image below. its almost there!</p>
  
  <p>GDI32.cs</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Runtime.InteropServices;
  using System.Text;
  
  namespace Sicon.Snipper.Tools
  {
      public static class GDI32
      {
          [DllImport("gdi32.dll")]
          public static extern int SetROP2(IntPtr hdc, int fnDrawMode);
  
          [DllImport("gdi32.dll")]
          public static extern IntPtr CreatePen(int fnPenStyle, int nWidth, uint crColor);
  
          [DllImport("gdi32.dll")]
          public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
  
          [DllImport("gdi32.dll")]
          public static extern bool DeleteObject(IntPtr hObject);
  
          [DllImport("gdi32.dll")]
          public static extern bool MoveToEx(IntPtr hdc, int X, int Y, IntPtr lpPoint);
  
          [DllImport("gdi32.dll")]
          public static extern bool LineTo(IntPtr hdc, int nXEnd, int nYEnd);
  
          [DllImport("gdi32.dll")]
          public static extern bool Rectangle(IntPtr hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
      }
  }
  </code></pre>
  
  <p>New Hightlight Annotation.cs</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Drawing;
  using System.Linq;
  using System.Text;
  using System.Windows.Forms;
  using Sicon.Snipper.Enums;
  using Sicon.Snipper.Tools;
  
  namespace Sicon.Snipper.Annotations
  {
      /// &lt;summary&gt;
      /// Highlight Annotation
      /// &lt;/summary&gt;
      public class HighlightAnnotation : BaseAnnotation
      {
          #region Members
  
          protected Rectangle _selection = Rectangle.Empty;
          protected const int _transparancyAlpha = 110;
          private ShapeEnum _shape = ShapeEnum.Rectangle;
          List&lt;Point&gt; points = new List&lt;Point&gt;();
          private const int PS_SOLID = 0;
          private const int R2_MASKPEN = 9;
          private const int R2_COPYPEN = 13;
  
          #endregion Members
  
          #region Properties
  
          /// &lt;summary&gt;
          /// Gets or Sets the Shape
          /// &lt;/summary&gt;
          public ShapeEnum Shape
          {
              get { return _shape; }
              set { _shape = value; }
          }
  
          /// &lt;summary&gt;
          /// Gets the Selection
          /// &lt;/summary&gt;
          public Rectangle Selection
          {
              get { return _selection; }
              protected set { _selection = value; }
          }
  
          #endregion Properties
  
          #region Constructors
  
          /// &lt;summary&gt;
          /// Constructor
          /// &lt;/summary&gt;
          /// &lt;param name="imageRef"&gt;Reference to the image&lt;/param&gt;
          public HighlightAnnotation(Image imageRef, Control host, ShapeEnum shape)
              : base(imageRef, new Pen(Color.Yellow, 16), host)
          {
              _shape = shape;
          }
  
          #endregion Constructors
  
          #region Methods
  
          /// &lt;summary&gt;
          /// Handles on Mouse down
          /// &lt;/summary&gt;
          /// &lt;param name="e"&gt;args&lt;/param&gt;
          public override void OnMouseDown(MouseEventArgs e)
          {
              if (base.Enabled)
              {
                  // Start the snip on mouse down
                  if (e.Button != MouseButtons.Left) return;
  
                  _startPoint = e.Location;
                  _selection = new Rectangle(e.Location, new Size(0, 0));
              }
          }
  
          /// &lt;summary&gt;
          /// Handles Mouse Move
          /// &lt;/summary&gt;
          /// &lt;param name="e"&gt;args&lt;/param&gt;
          public override void OnMouseMove(MouseEventArgs e)
          {
              if (base.Enabled)
              {
                  // Modify the selection on mouse move
                  if (e.Button != MouseButtons.Left) return;
  
                  //Add freehand points
                  points.Add(new Point(e.X, e.Y));
  
                  //Update selection rectangele
                  int x1 = Math.Min(e.X, _startPoint.X);
                  int y1 = Math.Min(e.Y, _startPoint.Y);
                  int x2 = Math.Max(e.X, _startPoint.X);
                  int y2 = Math.Max(e.Y, _startPoint.Y);
                  _selection = new Rectangle(x1, y1, x2 - x1, y2 - y1);
              }
          }
  
          /// &lt;summary&gt;
          /// Handles on mouse up
          /// &lt;/summary&gt;
          /// &lt;param name="e"&gt;args&lt;/param&gt;
          public override void OnMouseUp(MouseEventArgs e)
          {
              if (base.Enabled)
              {
                  if (_selection.Width &lt;= 0 || _selection.Height &lt;= 0) return;
  
                  using (Graphics g = Graphics.FromImage(this.ImageRef))
                  {
                      switch (this.Shape)
                      {
                          case ShapeEnum.Freehand:
  
                              DrawHighlight(g, points.ToArray());
  
                              break;
  
                          case ShapeEnum.Rectangle:
  
                              Rectangle dest = new Rectangle(
                                  TranslateCenterImageMousePosition(_startPoint),
                                  _selection.Size);
  
                              DrawRectange(g);
  
                              break;
  
                          default: return;
                      }
                  }
  
                  this.Enabled = false;
              }
          }
  
          /// &lt;summary&gt;
          /// Hanles on paint
          /// &lt;/summary&gt;
          /// &lt;param name="g"&gt;graphics&lt;/param&gt;
          public override void OnPaint(System.Drawing.Graphics g)
          {
              if (base.Enabled)
              {
                  switch (this.Shape)
                  {
                      case ShapeEnum.Freehand:
  
                          DrawHighlight(g, points.ToArray());
  
                          break;
  
                      case ShapeEnum.Rectangle:
  
                          DrawRectange(g);
  
                          break;
  
                      default: return;
                  }
              }
          }
  
          /// &lt;summary&gt;
          /// Draws a highlight
          /// &lt;/summary&gt;
          /// &lt;param name="g"&gt;graphics&lt;/param&gt;
          /// &lt;param name="usePoints"&gt;points to draw&lt;/param&gt;
          private void DrawHighlight(Graphics g, Point[] usePoints)
          {
              int useColor = System.Drawing.ColorTranslator.ToWin32(base.Pen.Color);
              IntPtr pen = GDI32.CreatePen(PS_SOLID, (int)base.Pen.Width, (uint)useColor);
              IntPtr hDC = g.GetHdc();
              IntPtr xDC = GDI32.SelectObject(hDC, pen);
              GDI32.SetROP2(hDC, R2_MASKPEN);
              for (int i = 1; i &lt;= usePoints.Length - 1; i++)
              {
                  Point p1 = usePoints[i - 1];
                  Point p2 = usePoints[i];
                  GDI32.MoveToEx(hDC, p1.X, p1.Y, IntPtr.Zero);
                  GDI32.LineTo(hDC, p2.X, p2.Y);
              }
              GDI32.SetROP2(hDC, R2_COPYPEN);
              GDI32.SelectObject(hDC, xDC);
              GDI32.DeleteObject(pen);
              g.ReleaseHdc(hDC);
          }
  
          /// &lt;summary&gt;
          /// Draws a rectangle
          /// &lt;/summary&gt;
          /// &lt;param name="g"&gt;Graphics&lt;/param&gt;
          private void DrawRectange(Graphics g)
          {
              Rectangle dest = new Rectangle(
                                  TranslateCenterImageMousePosition(_startPoint),
                                  _selection.Size);
  
              int useColor = System.Drawing.ColorTranslator.ToWin32(base.Pen.Color);
              IntPtr pen = GDI32.CreatePen(PS_SOLID, (int)base.Pen.Width, (uint)useColor);
              IntPtr hDC = g.GetHdc();
              IntPtr xDC = GDI32.SelectObject(hDC, pen);
              GDI32.SetROP2(hDC, R2_MASKPEN);
              GDI32.Rectangle(hDC, dest.Left, dest.Top, dest.Right, dest.Bottom);
              GDI32.SetROP2(hDC, R2_COPYPEN);
              GDI32.SelectObject(hDC, xDC);
              GDI32.DeleteObject(pen);
              g.ReleaseHdc(hDC);
          }
  
          #endregion Methods
      }
  }
  </code></pre>
  
  <p><img src="https://i.stack.imgur.com/BVWKZ.png" alt="enter image description here"></p>