Click here to Skip to main content
15,885,546 members
Articles / Programming Languages / C#
Tip/Trick

Creating a Simple "scratch card" Control in WinForms

Rate me:
Please Sign up or sign in to vote.
5.00/5 (16 votes)
21 Oct 2015CPOL2 min read 24.4K   668   16   11
A simple "scratch card" like control for Winforms, where the user can reveal the image by "scratching off" a cover

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:

C#
/// <summary>
/// The image we cover the "real" image with
/// </summary>
private Bitmap cover;
/// <summary>
/// When true, mouse movement removes the "cover" image
/// </summary>
private bool scratching = false;
/// <summary>
/// Last point the user scratched to
/// </summary>
private Point last = new Point(0, 0);

With a few simple property bases:

C#
/// <summary>
/// Image to reveal as the top is "scratched off"
/// </summary>
private Image _Image = null;
/// <summary>
/// Pen to scratch with - wider reveals more at a time.
/// </summary>
/// <remarks>
/// The colour of this pen *MUST* match the colour used in the Paint event
/// to set the Transparency for the "cover" image.
/// </remarks>
private Pen _ScratchPen = new Pen(Brushes.Red, 5.0F);
/// <summary>
/// Brush to fill the cover image with
/// </summary>
private Brush _CoverBrush = Brushes.LightGray;

And handles a couple of mouse events:

C#
/// <summary>
/// Mouse down - so start "scratching" from this point.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ScratchImage_MouseDown(object sender, MouseEventArgs e)
    {
    scratching = true;
    last = e.Location;
    }
/// <summary>
/// Mouse up - so stop "scratching"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ScratchImage_MouseUp(object sender, MouseEventArgs e)
    {
    scratching = false;
    }
/// <summary>
/// If we are scratching, draw on the cover so that the transparency layer lets
/// the real image show through.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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:

C#
/// <summary>
/// Creates an cover big enough to hide the "real" image
/// </summary>
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:

C#
/// <summary>
/// Paint the image and it's cover.
/// </summary>
/// <remarks>
/// We draw the "real image",
/// then we cover it with an image which contains a transparency layer.
/// The "scratched off" colour goes transparent,
/// and the real image can be seen through it.
/// </remarks>
/// <param name="sender"></param>
/// <param name="e"></param>
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

  • 2015-10-21 First version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
CEO
Wales Wales
Born at an early age, he grew older. At the same time, his hair grew longer, and was tied up behind his head.
Has problems spelling the word "the".
Invented the portable cat-flap.
Currently, has not died yet. Or has he?

Comments and Discussions

 
QuestionHow can I change the makeover color to a "non standard" color? Pin
Member 157176991-Mar-23 22:05
Member 157176991-Mar-23 22:05 
AnswerRe: How can I change the makeover color to a "non standard" color? Pin
OriginalGriff1-Mar-23 22:50
mveOriginalGriff1-Mar-23 22:50 
GeneralRe: How can I change the makeover color to a "non standard" color? Pin
Member 157176992-Mar-23 0:54
Member 157176992-Mar-23 0:54 
GeneralRe: How can I change the makeover color to a "non standard" color? Pin
OriginalGriff2-Mar-23 1:31
mveOriginalGriff2-Mar-23 1:31 
NewsConsulting problems Pin
hdgao2222211-Jun-16 22:03
hdgao2222211-Jun-16 22:03 
GeneralRe: Consulting problems Pin
OriginalGriff11-Jun-16 22:25
mveOriginalGriff11-Jun-16 22:25 
GeneralInteresting. Pin
Brisingr Aerowing21-Oct-15 10:13
professionalBrisingr Aerowing21-Oct-15 10:13 
QuestionMissing source...? Pin
Brian Pendleton21-Oct-15 2:02
Brian Pendleton21-Oct-15 2:02 
AnswerRe: Missing source...? Pin
OriginalGriff21-Oct-15 2:28
mveOriginalGriff21-Oct-15 2:28 
GeneralRe: Missing source...? Pin
Brian Pendleton21-Oct-15 2:32
Brian Pendleton21-Oct-15 2:32 
GeneralRe: Missing source...? Pin
OriginalGriff21-Oct-15 2:50
mveOriginalGriff21-Oct-15 2:50 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.