Click here to Skip to main content
14,604,663 members

CCanvas - A Reusable Class to Draw a Simple Graph

Rate this:
4.62 (24 votes)
Please Sign up or sign in to vote.
4.62 (24 votes)
26 Feb 2009Public Domain
A reusable class for drawing a simple graph
Image 1

Introduction

Actually I am a little nervous to introduce this article. This is my first experience with MFC. Here I make a reusable class that is capable of drawing objects such as rectangle, ellipse, circle, and line by using GDI Device Context programming. The objects are selectable, moveable, and resizable. It is named CCanvas. I hope it will be useful for you. You can use it in your project that requires a simple graph editor.

Using the Code

Class Methods

Here are some public methods:

  • bool loadFile(char *fileName);

    Loads a file.

  • bool saveFile(char *fileName);

    Saves a file.

  • void set(CPoint ptStart, CPoint ptEnd);

    Retrieves start and end position when mouse is dragged.

  • set(int tool);

    Sets active tool: draw rectangle, draw ellipse, draw circle, or erase.

  • int update(CDC *dc);

    Updates window.

  • void store();

    Stores object into memory.

  • void drawGrid(CDC *dc, HWND hwnd, int gridsizeX, int gridsizeY)();

    Draw grids within specified size.

  • void setSnapToGrid(bool setting, int gridsizeX, int gridsizeY);

    Set snap-to-grid option within specified grid size.

How It Works

It works by handling these three important messages:

  • WM_LBUTTONDOWN - Start drawing, remember the origin position of the mouse pointer
  • WM_MOUSEMOVE - Here it tracks mouse movement, remember its current position
  • WM_LBUTTONUP - Finish drawing, store the newly created object into memory

How to Use

Let's say you have an SDI project, named Demo.

  • Add the file "canvas.h" to your DemoView.h:

    #include "canvas.h"
  • Add these variables to your DemoView.h:

    private:
        CCanvas m_canvas;
        CPoint m_ptStart;
        CPoint m_ptEnd;
  • Add these window messages to your DemoView.cpp:

    BEGIN_MESSAGE_MAP(CDemoView, CView)
        //{{AFX_MSG_MAP(CDemoView)
        ON_WM_MOUSEMOVE()
        ON_WM_LBUTTONUP()
        ON_WM_LBUTTONDOWN()
        //}}AFX_MSG_MAP
    END_MESSAGE_MAP()
  • Add these codes to your DemoView.cpp to handle those window messages:

    void CDemoView::OnDraw(CDC* dc)
    {
        CNiceDoc* pDoc = GetDocument();
        ASSERT_VALID(pDoc);
    
        m_canvas.update(dc);
    }
    
    BOOL CDemoView::PreCreateWindow(CREATESTRUCT& cs)
    {
        m_canvas.setSnapToGrid(true, 10, 10);
        return CView::PreCreateWindow(cs);
    }
    
    void CDemoView::OnMouseMove(UINT nFlags, CPoint point)
    {
        CView::OnMouseMove(nFlags, point);
    
        // Update end point while mouse is moving
        if (GetCapture() == this){
    	m_ptEnd = point;
    	Invalidate();
    	m_canvas.set(m_ptStart, m_ptEnd);
        }
    }
    
    void CDemoView::OnLButtonDown(UINT nFlags, CPoint point)
    {
        CView::OnLButtonDown(nFlags, point);
    
        // Get start point for drawing
        m_ptStart = m_ptEnd = point;SetCapture();
        m_canvas.set(m_ptStart, m_ptEnd);
    }
    
    void CDemoView::OnLButtonUp(UINT nFlags, CPoint point)
    {
        CView::OnLButtonUp(nFlags, point);
    
        // Get end point for drawing
        if (GetCapture() == this)
        {
            ReleaseCapture();
            m_ptEnd = point;
            Invalidate();
            m_canvas.store();
        }
    }

Loading and Saving Documents

Function members for loading and saving documents are called in class CDemoDoc that exists in file DemoDoc.h and DemoDoc.cpp. It is a pretty long explanation. You can see it yourself in the demo source code. Basically it is simply a "how you deal with CDocument."

Flickering Issue - Double Buffering

To get rid of the flickering issue, we can use the double buffering method. Look here. Follow the steps and you will see the flickering issue go away. The demo project attached with this article uses this method.

Points of Interest

This is my first MFC project and I am still improving it. I plan to add more features like:

  • More object shapes
  • Rotation
  • Ordering (backward and forward)
  • Select and move multiple objects
  • Coloring
  • Etc.

1st Update

I have fixed major bugs when creating vertical line. You cannot do anything to vertical line, it seems to be frozen. This is because of the incomplete mathematics equation I use in the code. I also added two new features: setSnapToGrid and drawGrid. I adapted code from Johan Rosengren for the drawGrid function. Don't worry, the rest is still original and kept to be as simple as it could be. Besides those things, now when you do resizing, the mouse cursor will change based on the resizing direction. The source is also converted to VC++ 2005. I think VC++6.0 has been abandoned.

History

  • 31st January, 2009: Initial version
  • 25th February, 2009: 1st update 

License

This article, along with any associated source code and files, is licensed under A Public Domain dedication

Share

About the Author

auralius manurung
Student
Indonesia Indonesia
http://kataauralius.com/

Comments and Discussions

 
QuestionCan we add free hand drawing in this project? Pin
gawadepd1-Jun-16 20:01
Membergawadepd1-Jun-16 20:01 
GeneralMy vote of 3 Pin
liujichao3-Nov-10 3:41
Memberliujichao3-Nov-10 3:41 
QuestionDoes CCanvas function on CScrollView ? Pin
mesajflaviu28-Jun-10 6:27
Membermesajflaviu28-Jun-10 6:27 
AnswerRe: Does CCanvas function on CScrollView ? Pin
auralius manurung2-Jul-10 16:08
Memberauralius manurung2-Jul-10 16:08 
GeneralGreat Job Pin
xox_c0bra_xox25-Jul-09 18:41
Memberxox_c0bra_xox25-Jul-09 18:41 
GeneralRe: Great Job Pin
auralius manurung26-Jul-09 7:19
Memberauralius manurung26-Jul-09 7:19 
Questionwhat is DRAWCLI from microsoft? Pin
Southmountain2-May-09 19:03
MemberSouthmountain2-May-09 19:03 
AnswerRe: what is DRAWCLI from microsoft? Pin
auralius manurung15-May-09 14:54
Memberauralius manurung15-May-09 14:54 
QuestionCan it support PrintPreview? Pin
maplewang27-Feb-09 18:30
Membermaplewang27-Feb-09 18:30 
AnswerRe: Can it support PrintPreview? Pin
auralius manurung1-Mar-09 18:45
Memberauralius manurung1-Mar-09 18:45 
GeneralDrawCLI Pin
prcarp27-Feb-09 5:49
Memberprcarp27-Feb-09 5:49 
Hi Auralius,
I was wondering if you saw the DrawCLI code that came as a sample with VC6. It has a very similar look and feel even though it uses MDI instead of SDI. Microsoft's DrawCLI sample also breaks the shapes out into separate class objects which makes expansion in that direction more palatable. You might want to consider that rather than lumping all the shapes into your canvas class.

Thanks for CP the contribution. Although I have been doing C/C++ coding for over 20 years, I still like reading the beginner articles because I am still open to the possibility of doing something better. Smile | :)

-Paul
GeneralRe: DrawCLI Pin
auralius manurung1-Mar-09 18:44
Memberauralius manurung1-Mar-09 18:44 
GeneralMy vote is 5 Pin
tyjiang26-Feb-09 22:38
Membertyjiang26-Feb-09 22:38 
GeneralRe: My vote is 5 Pin
auralius manurung27-Feb-09 0:17
Memberauralius manurung27-Feb-09 0:17 
GeneralHello Auralius Pin
Jerry Evans4-Feb-09 1:25
MemberJerry Evans4-Feb-09 1:25 
GeneralRe: Hello Auralius Pin
auralius manurung4-Feb-09 16:14
Memberauralius manurung4-Feb-09 16:14 
GeneralMy vote of 2 Pin
Country Man3-Feb-09 5:33
MemberCountry Man3-Feb-09 5:33 
GeneralRe: My vote of 2 Pin
merano3-Feb-09 7:18
Membermerano3-Feb-09 7:18 
GeneralRe: My vote of 2 Pin
auralius manurung3-Feb-09 11:52
Memberauralius manurung3-Feb-09 11:52 
GeneralRe: My vote of 2 Pin
Tim Craig26-Feb-09 17:31
MemberTim Craig26-Feb-09 17:31 
GeneralRe: My vote of 2 Pin
auralius manurung27-Feb-09 0:31
Memberauralius manurung27-Feb-09 0:31 
GeneralRe: My vote of 2 Pin
maplewang24-May-09 16:29
Membermaplewang24-May-09 16:29 
GeneralMy vote of 2 Pin
Tomas Rapkauskas3-Feb-09 0:24
MemberTomas Rapkauskas3-Feb-09 0:24 
GeneralRe: My vote of 2 Pin
Emilio Garavaglia3-Feb-09 4:43
MemberEmilio Garavaglia3-Feb-09 4:43 
GeneralRe: My vote of 2 Pin
auralius manurung3-Feb-09 12:32
Memberauralius manurung3-Feb-09 12:32 

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.

Article
Posted 1 Feb 2009

Tagged as

Stats

76.1K views
4.5K downloads
45 bookmarked