Click here to Skip to main content
15,867,453 members
Articles / Desktop Programming / MFC
Article

An MFC Curve Control

Rate me:
Please Sign up or sign in to vote.
4.90/5 (38 votes)
19 Dec 20044 min read 100.8K   10.1K   117   19
An article on a curve control.

Sample Image - curvectrl.jpg

Introduction

  • Derived from CWnd, easy to use
  • Fits width and height of drawing rect
  • Zooming in and out
  • Mouse coordinates tracing
  • Single/multiple selected by clicking mouse button
  • Cross-line tracing mouse
  • Add or delete a point of a curve by clicking mouse button
  • Edit vertical value of a point of a curve by moving mouse with button down
  • Easy to move, shift or mirror one curve
  • Notify control’s owner when curve changing
  • Owner determines whether to modify curve data by return values of message handle functions
  • Unicode support
  • Compiles under Windows 2000, VC 6.0 with warning level 4

Background

Recently, I wanted to visualize data in one of my applications. I had searched from Internet and downloaded some curve controls. Most of them are beautiful and work well, but none works as I want it to be. After reading source code of some controls, I decided to develop one curve control which would meet my application’s requirements.

Classes

CCurve

CCurve class, derived from CObject is used to store data and curve properties. It does not perform data adding or deleting.

  • void ShowCurve(BOOL bShow = TRUE);
  • BOOL IsVisible();

    Sets/gets visualization.

  • void Select(BOOL bSelect = TRUE);
  • BOOL IsSelected

    Sets/gets selected.

  • BOOL SetCurveName(CString& strName);
  • CString GetCurveName();

    Sets/gets curve name.

  • void SetCurveColor(COLORREF color);
  • COLORREF GetCurveColor();

    Sets/gets curve line color.

  • void SetCurveStyle(int iStyle);
  • int GetCurveStyle();

    Sets/gets curve line style.

  • void SetCurveWidth(int nWidth);
  • int GetCurveWidth();

    Sets/gets curve line width.

  • float Distance(const CPoint& pt1, const CPoint& pt2);

    Gets distance between two points.

  • BOOL IsPointNearCurve(const CPoint& point, int& iIndex);

    Whether the point is near the curve.

CCurveCtrl

  • BOOL Create(const RECT& rect, CWnd* parent, UINT nID,DWORD dwStyle = WS_CHILD | WS_BORDER | WS_TABSTOP | WS_VISIBLE);

    Creates control, where rect is the dimensions. Refer to MSDN.

  • int AddCurve(const CString& strName, COLORREF color = RGB(0, 0, 0), int iStyle = PS_SOLID, int nWidth = 1);

    Adds one curve to control.

  • BOOL AddData(const CString& strName, float fHori, float fVert);
  • BOOL AddData(CCurve* pCurve, float fHori, float fVert);

    Adds data to a curve by index or object pointer.

  • BOOL AddCurveData(const CString& strName, const CArray< float, float >& ArrHori, const CArray< float, float >& ArrVert);

    Adds one curve and data at the same time.

  • CCurve* GetCurve(int iIndex);
  • CCurve* GetCurve(const CString& strName);

    Gets a curve object’s pointer by its index in CCurveCtrl or its name.

  • int GetIndex(const CCurve* pCurve);

    Gets a curve’s index in CCurveCtrl by pointer.

  • BOOL Remove(int index);
  • BOOL Remove(const CString& strName);
  • void RemoveAll();

    Removes a curve or all of the curves in CCurveCtrl.

  • int GetCurveCount();

    Gets total count of curves.

  • int GetSelectedCount();

    Gets count of selected curves.

  • void Move(BOOL bLeft);
  • void MovePage(BOOL bLeft);

    Moves all curves and coordinate scales left or right (will not modify data).

  • void CurveLeft(CCurve* pCurve, float fLen); void CurveRight(CCurve* pCurve, float fLen);

    Shifts a curve left or right (will modify data of the curve).

  • void MirrorHori(CCurve* pCurve, float fMid);

    Mirrors a curve in horizontal.

  • void MirrorVert(CCurve* pCurve, float fMid);

    Mirrors a curve in vertical.

  • void Restore();

    Shows all points of all curves.

  • BOOL Zoom(BOOL bIn);

    Zooms in (bIn: TRUE) or zooms out (bIn: FALSE).

  • void SetHoriLabel(CString& str);
  • CString GetHoriLabel();

    Sets/gets horizontal label.

  • void SetVertLabel(CString& str);
  • CString GetVertLabel();

    Sets/gets vertical label.

  • void ShowCross(BOOL bShow);
  • BOOL IsShowCross();

    Whether to show cross lines.

  • void SetMargin(const CRect& rect);
  • CRect GetMargin();

    Sets/gets margin left to show title, etc.

  • void EnableEdit(BOOL bEdit);
  • BOOL CanEditCurve();

    Whether can edit curve data by using mouse.

  • void SetGridLineStyle(int iStyle);
  • int GetGridLineStyle();

    Sets/gets style of grid line in background.

Notifications

Following notify messages will be sent to control’s owner window (parent or not) if curve selected/ deselected or data modified by mouse operation:

  • CVN_MVALUE_ADD - a point added to curve.
  • CVN_MVALUE_CHANG - Y value of a point changing.
  • CVN_MVALUE_DELETE - a point deleted.
  • CVN_CURVE_SELECTED - a curve is selected.
  • CVN_CURVE_CANCELSELECT - a curve is deselected.
  • CVN_CURVE_SELECTNONE - deselected all curves.

Struct

typedef struct tagNM_CURVECTRL {
       NMHDR  hdr;      // curve object pointer
       void*  pCurve;   // curve object pointer
       int    iIndex;                                   
       float  fHori;    // horizontal value where cursor is
       float  fVert;    // vertical value where cursor is
} NM_CURVECTRL;

Note the iIndex member: it is the index of the point in the curve if the message sent to owner is CVN_MVALUE_ADD, CVN_MVALUE_CHANGE or CVN_MVALUE_DELETE; it is the index of the curve in CCurveCtrl if the message sent to owner is CVN_CURVE_SELECTED, CVN_CURVE_CANCELSELECT or CVN_CURVE_SELECTNONE.

Usage

Following steps demonstrate how to use CCurveCtrl in a dialog-based application:

  1. Add curvectrl.h and curvectrl.cpp into your project;
  2. Add a CCurveCtrl pointer member to your CDialog class:
    CCurveCtrl*  m_pCurveCtrl;

    And also add include statement:

    #include "CurveCtrl.h"
  3. Set m_pCurveCtrl as NULL in your dialog construction functions:
    m_pCurveCtrl = NULL;

    Add control’s resource ID to your resource.h file, such as:

    #define ID_CURVE_CONTROL   9999

    In your CDialog::OnInitDialog(), add statements as following:

    if (NULL == m_pCurveCtrl)
    {
        m_pCurveCtrl = new CCurveCtrl;
        m_pCurveCtrl->Create(CRect(10, 10, 200, 200),    
                             this, 
                             ID_CURVE_CONTROL);    // resorce ID
                             m_pCurveCtrl->SetMargin(CRect(70, 50, 50, 50));
    }
  4. Add one curve and data as following:
    CString  strName(TestOne);
    m_pCurveCtrl->AddCurve(strName, RGB(255, 0, 0));
    
    for (float f = 0.0f; f < 6.28f; f += 0.1f)
    {
        m_pCurveCtrl->AddData(strTitle, 
                             (m_nCurveCount) * f, 
                             100.f * float(sin(f)));
    }
    m_pCurveCtrl->Invalidate();

    If you want to add/delete or edit points with mouse operation, you must call:

    m_pCurveCtrl->EnableEdit(TRUE);

    Control’s owner will receive notify message, and if the return values of the messages is not 0 (>0 or <0), the edit or selection /deselection attempts will be rejected.

    For example, to handle the message of CVN_MVALUE_CHANG, add a handler in your dialog source file: 

    BEGIN_MESSAGE_MAP(CTestCurveDlg, CDialog)
             ... ...
    ON_NOTIFY(CVN_MVALUE_CHANG, ID_CURVE_CONTROL, OnCurveMouseModify)
    END_MESSAGE_MAP()
     
    // message handle function
    void CTestCurveDlg::OnCurveMouseModify(NMHDR *pNotifyStruct, LRESULT* pResult)
    {
        NM_CURVECTRL* pItem = (NM_CURVECTRL*)pNotifyStruct;
        CCurve* pCurve = (CCurve*)pItem->pCurve;
        CString str;
        str.Format("%s: index: %d, %.1f, %.1f", 
                            pCurve->GetCurveName(), 
                            pItem->iIndex, 
                            pItem->fHori, 
                            pItem->fVert);
        TRACE(str);
        // Uncomment following statement if to reject changing
        // *pResult = 1;
    }

Refer to sample application TestCurve if you want more information.

History

  • V1.0, 19 September 2004

    CCurve, CCurveCtrl first released.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Team Leader
China China
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionHow do I get the coordinates on the curve? Pin
Member 1373617213-May-18 20:55
Member 1373617213-May-18 20:55 
QuestionHave some questions about AddCurve! Pin
Micheal_liu2-Aug-12 15:18
Micheal_liu2-Aug-12 15:18 
AnswerRe: Have some questions about AddCurve! Pin
Micheal_liu2-Aug-12 16:18
Micheal_liu2-Aug-12 16:18 
GeneralExcellent Pin
sisixiao12-Mar-11 14:26
sisixiao12-Mar-11 14:26 
GeneralJust what I needed Pin
Tom Guidarelli16-Nov-10 10:41
Tom Guidarelli16-Nov-10 10:41 
GeneralMy vote of 5 Pin
liuhuizhen25-Sep-10 15:05
liuhuizhen25-Sep-10 15:05 
Generalgood job Pin
batsword5-Aug-10 21:38
batsword5-Aug-10 21:38 
Questionhow to run? Pin
bitichong11-Mar-10 20:45
bitichong11-Mar-10 20:45 
AnswerHide the graph control Pin
vaughn.Huang2-Mar-10 4:25
vaughn.Huang2-Mar-10 4:25 
Questionneed help about using Curve Control with a doc/view application Pin
vaughn.Huang14-Nov-09 18:28
vaughn.Huang14-Nov-09 18:28 
AnswerRe: need help about using Curve Control with a doc/view application Pin
Sunjoy Chen16-Nov-09 22:26
Sunjoy Chen16-Nov-09 22:26 
GeneralRe: need help about using Curve Control with a doc/view application Pin
vaughn.Huang17-Nov-09 1:00
vaughn.Huang17-Nov-09 1:00 
Generalthanks! Pin
zyzqtu14-Sep-09 23:39
zyzqtu14-Sep-09 23:39 
Generalthanks,man! Pin
akaterry29-May-09 17:06
akaterry29-May-09 17:06 
GeneralThank you ! A little pity Pin
jn_xutao9-Jan-06 20:10
jn_xutao9-Jan-06 20:10 
GeneralSave and load curve Pin
thanhthuy_vnvtasgdja24-Jan-05 21:35
thanhthuy_vnvtasgdja24-Jan-05 21:35 
Generalvery nice! thank you! Pin
fredpu20-Dec-04 5:28
fredpu20-Dec-04 5:28 
GeneralFiles not Found Pin
Piccinano19-Dec-04 5:24
Piccinano19-Dec-04 5:24 
GeneralRe: Files not Found Pin
Sunjoy Chen19-Dec-04 14:59
Sunjoy Chen19-Dec-04 14:59 

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.