Search code examples
c#c++canvasvisual-studio-2012drawing

Realising a drawing canvas in managed c++?


How can a drawing canvas be realised in managed C++ (C++/CLI). I want to be able to "draw" on a PictureBox object by leftclicking the mouse and simulatneous moving the mouse. The PictureBox is cleared with white color and i want to draw with Black pixels.


Solution

  • First of all, consider this an exception. While it's perfectly fine to ask for help with assignments and homework related stuff here (just make sure to mention it), you should really try to show some code or work you've done already. Don't just go like "I need some code, thanks." because that's not how this site is meant to work.

    Please don't just copy and paste this code. Understand it first, then use it or apply what you've learned to your own code.

    Back to the actual problem: There are multiple ways to approach this, but the basic concept is always the same (even if you try to create some vector drawing program). The following lines ommit classes and namespaces for readability. If you keep the standard using directives, this shouldn't be an issue for you (most stull will be in System.Drawing). Note that I'll implement everything directly into the form. You could as well create a custom user control for this (which might be the better/cleaner approach).

    First you'll need some control to actually display your drawing. Using the standard control PictureBox is perfectly fine for this. Next you'll need some image to actually draw to. Add a private Bitmap member to your user form. In this example we'll use the mouse cursor to draw a line. A line is always drawn between the previous position of the cursor and the current position. Due to this we'll have to store the previous position in a Point. Given the previous two points, you'll need the following two members somewhere in your form (or user control):

    private Bitmap bitmap;
    private Point oldPosition;
    

    In your form's Load event you'll have to create the Bitmap object. I'm also using Graphics to clear the Bitmap to white and then display it using the PictureBox:

    private void Form1_Load(object sender, EventArgs e)
    {
        bitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height);
        using (Graphics g = Graphics.FromImage(bitmap))
            g.Clear(Color.White);
        pictureBox1.Image = bitmap;
    }
    

    Next up, we'll have to reset the previous cursor position, whenever the user clicks somewhere in the PictureBox. For this I add a very simple MouseDown event to it:

    private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
    {
        oldPosition = e.Location;
    }
    

    Last but not least, the actual drawing happens in an MouseMove event. For this to work properly, you'll have to do one check and three working steps:

    • Determine whether the user actually wants to draw (is the left mouse button pressed?).
    • Draw the line into the bitmap.
    • Update the previous cursor position to the new position.
    • Display the results.

    The code for this could look like this:

    private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Left)
        {
            using (Graphics g = Graphics.FromImage(bitmap))
                g.DrawLine(Pens.Black, oldPosition, e.Location);
            oldPosition = e.Location;
            pictureBox1.Image = bitmap;
        }
    }
    

    If everything works as expected, you should be able to draw freehandedly on your PictureBox:

    Example form screenshot