Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

An MFC Curve Control

0.00/5 (No votes)
19 Dec 2004 1  
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