Introduction
We all know how a scratch card works - even if we don't buy them - you take a coin, and you scrape off a coving to reveal a symbol beneath - if you have the right set of symbols, you win! But the covering means you can't tell before you start scraping.
This provides a control where the user can do the same thing with his mouse.
Background
This was an answer I posted to a question (How do you create a windows form application that works like a lottery scratch-and-win[^] - but someone decided that wasn't answerable, despite my answer being posted... :sigh: )
So I tidied up the code a little, made it a bit more flexible, and posted it here.
Using the Code
Add the User Control "ScratchImage
" to your project (change the namespace, probably) and compile.
Drag and drop an instance onto your form, and set the Image
property to a suitable image.
Run your app, and press the mouse button down on the cover surface, and drag to scratch the cover away.
How It Works
What it does is simple: the control has a couple of internal variables:
private Bitmap cover;
private bool scratching = false;
private Point last = new Point(0, 0);
With a few simple property bases:
private Image _Image = null;
private Pen _ScratchPen = new Pen(Brushes.Red, 5.0F);
private Brush _CoverBrush = Brushes.LightGray;
And handles a couple of mouse events:
private void ScratchImage_MouseDown(object sender, MouseEventArgs e)
{
scratching = true;
last = e.Location;
}
private void ScratchImage_MouseUp(object sender, MouseEventArgs e)
{
scratching = false;
}
private void ScratchImage_MouseMove(object sender, MouseEventArgs e)
{
if (scratching)
{
using (Graphics g = Graphics.FromImage(cover))
{
g.DrawLine(_ScratchPen, last, e.Location);
}
last = e.Location;
Invalidate();
}
}
It also fills the "cover
" with a solid colour:
private void MakeCover()
{
if (cover != null) cover.Dispose();
cover = new Bitmap(Width, Height);
using (Graphics g = Graphics.FromImage(cover))
{
g.FillRegion(_CoverBrush, new Region(new Rectangle(0, 0, Width, Height)));
}
}
Then, all it has to do is draw the two images via the Paint
event:
private void ScratchImage_Paint(object sender, PaintEventArgs e)
{
if (Image != null)
{
e.Graphics.DrawImage(Image, 0, 0, Width, Height);
cover.MakeTransparent(_ScratchPen.Color);
e.Graphics.DrawImage(cover, 0, 0, Width, Height);
}
}
That's it! There are a couple of other properties to make it more flexible, it has DoubleBuffered
set to make it work properly, and it recreates the cover image on resize, but that's about all.
While the user is "scratching" with the mouse, that draws onto the "cover
" image in a specific color of pen - which defaults to Red - which is treated as the Transparency colour when the cover is drawn over the base image. So everything drawn in Red on the cover becomes see-though and the image below becomes visible through the cover where the user held the mouse down to "scratch".
History