개발/MFC

[스크랩]실시간 그래프

FA1976 2017. 6. 20. 15:51

[출처 :  http://blog.daum.net/pg365/126 ]


C++로 로봇 프로그램을 하다보면 센서에서 실시간으로 들어오는 데이터를 연속적으로 모니터링 할 필요가 있습니다. 이때 유용한 컨트롤이 OscopeCtrl 입니다. OscopeCtrl은 오실로스코프(oscilloscope) 컨트롤의 약어로서 실시간으로 들어오는 데이터를 오실로스코프와 같이 표시한다는 의미에서 붙인 이름인것 같습니다. 실제로 이 컨트롤은 제가 만든것이 아니라 emule project에 있던 파일을 떼어와서 사용하기 편하게 약간 가공한 것입니다. Emule project (http://www.emule-project.net/)에 가시면 실제 이 컨트롤을 포함한 emule 전체 소스코드를 다운받을 수 있습니다.

 

아래의 두 파일이 OscopeCtrl을 만들기 위한 소스코드 입니다. CWnd 클래스를 상속하여 만들어 졌기때문에, 생성하고 사용하는 방법은 CWnd 클래스와 동일합니다. 추가로 오실로스코프의 기능을 구현하기 위한 함수들이 구현되어 있습니다.

 

OScopeCtrl.cpp

OScopeCtrl.h


 

아래는 이 컨트롤을 VisualStudio C++ 2008에서 사용하기 위한 방법입니다. 먼저 오실로스코프 컨트롤을 표시하기 위한 대화상자에 Picture Control을 아이디 IDC_STATIC_RT_GRAPH 로 추가하고 위치와 크기를 맞춰 줍니다. 그리고 대화상자의 *Dlg.h 파일에서 OScopeCtrl.h 파일을 인클루드 하고 COScopeCtrl 컨트롤의 객체 포인터를 선언해 둡니다.

 

//  COScopeCtrl의 헤더 파일 인클루드
#include "OScopeCtrl.h"

...

class *Dlg : public CDialog
{
    ...
    // COScopeCtrl 컨트롤의 객체 포인터를 선언
    COScopeCtrl *_rtGraph;

    ...
};

 

이제 *Dlg.cpp 파일에서 WM_TIMER 이벤트와 WM_DESTROY 이벤트를 수행할 함수를 만들고 다음과 같이 소스코드를 추가합니다. on InitDialog() 함수에서는 IDC_STATIC_RT_GRAPH 컨트롤의 위치와 크기를 얻어와서 그 위치에다가 오실로스코프 컨트롤을 생성합니다. 그리고 x,y 축의 타이틀, 각 그래프의 레이블과 색상을 설정합니다. on InitDialog() 함수의 마지막에서는 타이머 이벤트를 기동하여 주기적으로 그래프가 업데이트 되도록 합니다.

 


BOOL *Dlg::OnInitDialog()
{
    ...

    // 오실로스코프 컨트롤이 위치할 영역 가져오기
    CRect rtGraph;
    GetDlgItem(IDC_STATIC_RT_GRAPH)->GetWindowRect(rtGraph);

    ScreenToClient(rtGraph);

    // 오실로스코프 컨트롤을 생성하고 설정한다.
    _rtGraph = new COScopeCtrl(3);      //cos,sin,tan 3개의 그래프 예약
    _rtGraph->Create(WS_VISIBLE | WS_CHILD, rtGraph, this, IDC_STATIC_RT_GRAPH);
    _rtGraph->SetRanges(-3., 3.);
    _rtGraph->autofitYscale = true;
    _rtGraph->SetYUnits("Value");
    _rtGraph->SetXUnits("Time");
    _rtGraph->SetLegendLabel("cos(t)", 0);
    _rtGraph->SetLegendLabel("sin(t)", 1);
    _rtGraph->SetLegendLabel("tan(t)", 2);
    _rtGraph->SetPlotColor(RGB(255,0,0), 0);
    _rtGraph->SetPlotColor(RGB(0,255,0), 1);
    _rtGraph->SetPlotColor(RGB(0,0,255), 2);
    _rtGraph->InvalidateCtrl();

    // 오실로스코프 컨트롤을 그리기 위한 타이머 이벤트 활성화
    SetTimer (1000, 10, NULL);

    ...
}

void *Dlg::OnTimer(UINT_PTR nIDEvent)
{
    if(nIDEvent==1000) {
        double t = (double)GetTickCount ()/1000.;

        double value[3] = {cos(t), sin(t), tan(t) };

        _rtGraph->AppendPoints(value);
    }

    CDialog::OnTimer(nIDEvent);
}

void *Dlg::OnDestroy()
{
    CDialog::OnDestroy();

    // 오실로스코프 컨트롤 삭제
    delete _rtGraph;
}

 

아래 예제 프로젝트를 참조하시기 바랍니다. 예제 프로젝트에서는 10ms마다 sin, cos, tan 그래프를 그리도록 되어있습니다.

 

RtGraph.zip


 

예제 프로젝트를 실행한 화면입니다.

 


그래프의 선 굵기가 너무 얇아서 안보이는 경우엔

아래 코드에서 숫자 "3"을 조정하시면 됩니다.. 첨부 소스코드엔 0으로 되어 있음.


void COScopeCtrl::SetPlotColor(COLORREF color, int iTrend)

{

m_PlotData[iTrend].crPlotColor = color;

m_PlotData[iTrend].penPlot.DeleteObject();

m_PlotData[iTrend].penPlot.CreatePen(PS_SOLID, 3, m_PlotData[iTrend].crPlotColor);

//InvalidateCtrl();

}

'개발 > MFC' 카테고리의 다른 글

Warning C4996  (0) 2017.04.28
MFC 타이틀바 없앤뒤 이동하기  (0) 2017.04.28
MFC 타이틀바 없애기  (0) 2017.04.28
MFC 테두리 없애기  (0) 2017.04.28
MFC 그룹박스 테두리 색상 적용  (0) 2017.04.28
MFC 다이얼로그 접기 펴기  (0) 2017.04.24
MFC 에디트 컨트롤 색상  (0) 2017.04.21
MFC 윈도우 스타일 적용  (0) 2017.04.21