Post List

레이블이 MFC인 게시물을 표시합니다. 모든 게시물 표시
레이블이 MFC인 게시물을 표시합니다. 모든 게시물 표시

2016년 2월 23일 화요일

Xtreame Toolkit Pro의 Chart Control의 class diagram

Xtreame Toolkit Pro의 Chart Control인 CXTPChartControl 사용시 알아야 할 class들 간의 상관관계를 Diagram으로 표시하였습니다.

전체다를 표시한건 아니고, 기본적으로 사용에 필요한 것들만 간추렸습니다.

XTPChart를 조금 사용해 본 소감은...
만들다 말았다는 느낌 ???

Mouse Click 이벤트 처리 같은거 ???NM_CLICK만 처리가 됩니다.
ButtonDown, ButtonUp 같은거 처리 안됩니다.
그냥 상속받아서 처리하세요.아래 글 참조하시면 됩니다.
분명 X-Argument로 날짜형식을 넣게는 되어 있는데,
AxisRange를 이용해서 SetViewMin/MaxValue로 범위를 지정하면....
제대로 안됩니다. double이나 CString 형으로는 잘 됩니다.
굳이 날짜형식으로 쓸려면 Series가 바뀔때마다 GetMin/MaxValue로 값을 얻어와서
그 값으로 계산을 해서 다시 
SetViewMin/MaxValue로 값을 넣어야 합니다.
자동으로 수정이 안됩니다. ;;;

Table 3.1
자세한 설명은 생략하겠습니다. 혹시나 Chart를 많이 안써보신 분들이 있을 수 있으니 대략적인 용어 및 뜻만 표기하겠습니다.
  • Title
    • Chart에 표시되는 명칭입니다.
  • Series
    • Chart에서 값을 나타내는 선을 나타냅니다.
    • 각 Point 들이 모여서 그 추이를 선으로 연결한 것입니다.
    • 각 Point는 X, Y 값의 2차원 값을 나타냅니다.
      • X 쪽을 Argument 라고 하며,
      • Y 쪽을 Value 라고 합니다.
  • Marker
    • Series 에 보면 각각의 Point를 눈에 띄게 좀 큰 점으로 표현한 것을 Marker라고 합니다.
  • Axis
    • X, Y 축 입니다.
  • Legend
    • 각 Series 들이 어떤 값을 나타내는지 Chart 한쪽에 색깔 별로 소개해 놓은 범주를 의미합니다.
  • ConstantLine
    • Chart 상의 특정 지점에 기준 선을 그어 놓는 경우가 있습니다.
      • 통계 관련 Chart의 경우 Y-Axis 상에 +- 1 sigma에 점선을 가로로 그어 놓는다던지 ...
      • X-Axis 상의 특정 시간안에 값들에 대해서 표시하기 위해서 세로로 그어 놓는 등...
위 그림은 Posting 목적으로 해상도를 줄여 놓았습니다.
원래 크기대로 보실려면 아래 Link를 눌러주세요.

2016년 2월 16일 화요일

사용자 정의 MFC Control의 Message 처리

사용자 정의 MFC Control의 Message 처리

CWnd를 상속받아서 사용자가 작성한 MFC Control의 메세지 처리하는 방법을 소개해드리겠습니다.
통상적으로 Dialog, View, FormView (앞으로 편의상 Dialog라 칭함)에 Control을 올려서 사용하는데, 그 구현자체를 Control안에서 하는 경우도 있지만,
해당 Control을 사용하고 있는 Dialog에서 구현을 해야하는 경우도 있습니다.
2개 이상의 Control을 같이 활용하려면 그렇게 해야 하죠.
Textbox에 숫자를 적어두고 Button을 눌렀을 경우 해당 숫자를 화면에 AfxMessageBox로 출력하는 경우  
해당 처리는 Button에서 하는게 아니라 Textbox와 Button을 가지고 있는 Dialog에서 하는게 편합니다.
3가지 방법이 있습니다.
  1. Message로 처리
  2. Command로 처리
  3. Notify로 처리
각각에 대해서 소개해 드리겠습니다.

준비사항

먼저 간단하게 Dialog 기반으로 MFC Application Project를 생성해주세요.
그런 다음 아래의 2개의 File을 추가합니다.
UserWnd.h
#pragma once
#include "afxwin.h"

#define WM_USER_WND            WM_USER + 10001          // User-defined Message (#1)

class CUserWnd : public CWnd
{
public:
    HWND m_hwndDlg = nullptr;                               // HWND of Parent Dialog (#2)

protected:
    DECLARE_MESSAGE_MAP()                                   // Message Map Macro (#3)
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);  // Mouse left button click event (#4)
};
  • #1 : 사용자 정의 메세지 입니다.
  • #2 : 메세지를 보낼려면 해당 메세지를 받을 Dialog의 pointer나 HWND값이 필요합니다.
    • HWND를 알고 있는 경우 : ::SendMessage(m_hwndDlg, 메세지, WPARAM, LPARAM);
    • Dialog의 pointer를 알고 있는 경우 : pointer->SendMessage(메세지, WPARAM, LPARAM);
  • #3 : Message Map을 사용할려면 헤더파일에 선언해줘야할 매크로 입니다.
  • #4 : 예제로 마우스 왼쪽 버튼을 눌렀을 경우 Dialog로 Message를 전달하기 위하여 해당 메세지를 사용했습니다.
UserWnd.cpp
#include "stdafx.h"
#include "UserWnd.h"

BEGIN_MESSAGE_MAP(CUserWnd, CWnd)                        // Message Map (#1)
    ON_WM_LBUTTONDOWN()                                  // Mouse left button click event (#2)
END_MESSAGE_MAP()

void CUserWnd::OnLButtonDown(UINT nFlags, CPoint point)  // Mouse left button click event (#3)
{
    HWND hWnd = GetSafeHwnd();

    if (hWnd == NULL) return;
    if (!::IsWindow(hWnd)) return;

    int nID = GetDlgCtrlID();

    if (m_hwndDlg != nullptr)
    {

    }

    CWnd::OnLButtonDown(nFlags, point);                  // Call Parent Function (#4)
}
  • #1 : Message Map 정의 부분입니다.
    • 첫번째 인자 : 해당 class를 적어줍니다.
    • 두번째 인자 : 부모 class를 적어줍니다. 해당 class 내에 적어주지 않은 메세지에 대해서는 부모 class에서 처리하게 됩니다.
      • 만약 CXTPChartControl을 상속받아서 만든 사용자 정의 Control일 경우 두번째 인자에 CXTPChartControl을 적어줘야 합니다.
  • #2 : MFC에서 미리 정의해놓은 것으로 마우스 왼쪽 버튼 눌렀을때 OnLButtonDown()을 실행하게 됩니다.
  • #3 : 사용자 정의 메세지를 보내기위해 필요한 값들 HWND, ControlID를 가지고 있습니다. if 구문 안에서 각각의 메세지 타입에 따른 구현이 달라집니다.
  • #4 : 부모 class에서 해당 메세지에 대한 동작을 계속 하도록 호출해 줍니다. 부모 class의 작업이 필요없다면 이 줄은 삭제하면 됩니다.
Resource.h
  • UserWnd의 Control ID를 생성해줍니다.
#define IDC_USER_WND                    10001
Dialog Header file (필자의 경우 UserCtrlMsgDlg.h)
  • UserWnd.h를 추가해 주세요.
#include "UserWnd.h"
  • CUserWnd 타입의 멤버를 선언해 주세요.
CUserWnd m_wndUser;
Dialog cpp file (필자의 경우 UserCtrlMsgDlg.cpp)
  • OnInitDialog() 에서 UserWnd를 생성해 줍니다.
// TODO: Add extra initialization here
m_wndUser.m_hwndDlg = GetSafeHwnd();
m_wndUser.Create(NULL, _T(""), WS_VISIBLE | WS_BORDER, CRect(0, 0, 100, 100), this, IDC_USER_WND);
이로서 준비는 끝났습니다.
위에서 언급한 3가지 방법 (Message, Notify, Command)에 대해서 어떤 방법으로 구현을 하더라도 이 준비과정은 똑같습니다.

1. Message 방식

  • Dialog에 해당 User Control을 1개만 사용할 경우 유용합니다.
  • Dialog에 Message로 전달하는 방식입니다.
  • return값을 받을수 있기 때문에 User Control에서 그 값에 따라 처리가 가능합니다.
  • 대신 Message 전달 이후 return값을 받아야 하므로 해당 처리가 끝날때까지 대기하게 됩니다.
  • Dialog에 같은 User Control이 여러 개 있을 경우 모두 같은 Message로 전달되므로, Parameter로 Control ID를 보내는 등의 방법을 사용하여 Dialog에서 처리하는 함수 내부에서 구분하여 사용해야 합니다.
UserWnd.cpp
OnLButtonDown 함수 내부에 아래와 같이 1줄을 추가
void CUserWnd::OnLButtonDown(UINT nFlags, CPoint point)
{
    HWND hWnd = GetSafeHwnd();

    if (hWnd == NULL) return;
    if (!::IsWindow(hWnd)) return;

    int nID = GetDlgCtrlID();

    if (m_hwndDlg != nullptr)
    {
        ::SendMessage(m_hwndDlg, WM_USER_WND, nID, NULL);
    }

    CWnd::OnLButtonDown(nFlags, point);
}
Dialog Header file (필자의 경우 UserCtrlMsgDlg.h)
Message를 처리할 함수를 선언해주세요.
afx_msg LRESULT OnUserWnd(WPARAM wParam, LPARAM lPraram);
Dialog cpp file (필자의 경우 UserCtrlMsgDlg.cpp)
Message Map에 아래 1줄을 추가해주세요.
ON_MESSAGE(WM_USER_WND, OnUserWnd)
  • ON_MESSAGE 경우 Message번호 와 실행할 함수를 인자로 설정해줍니다.
Command를 처리할 함수를 구현합니다.
LRESULT CUserCtrlMsgDlg::OnUserWnd(WPARAM wParam, LPARAM lPraram)
{
    int nID = (int)wParam; // 해당 ID를 비교해서 Control 구분 가능

    AfxMessageBox(_T("ON MESSAGE"));

    return TRUE;
}
이제 실행 후 왼쪽 상단의 검은색 선 안을 누르면 해당 메세지가 출력되는 것을 확인 할 수 있습니다.

2. Notify 방식

  • Dialog에 해당 User Control이 여러개 있고, 전달한 메세지 종류가 2가지 이상인 경우 유용합니다.
  • Dialog에 Notify로 알려주고 User Control은 계속 남은 처리를 진행합니다.
UserWnd.cpp
OnLButtonDown 함수 내부에 아래와 같이 NMHDR 선언과 SendMessage를 추가
void CUserWnd::OnLButtonDown(UINT nFlags, CPoint point)
{
    HWND hWnd = GetSafeHwnd();

    if (hWnd == NULL) return;
    if (!::IsWindow(hWnd)) return;

    int nID = GetDlgCtrlID();

    if (m_hwndDlg != nullptr)
    {
        NMHDR nmhdr;
        nmhdr.code = WM_USER_WND;
        nmhdr.idFrom = nID;
        nmhdr.hwndFrom = hWnd;
        ::SendMessage(m_hwndDlg, WM_NOTIFY, nID, (LPARAM)&nmhdr);
    }

    CWnd::OnLButtonDown(nFlags, point);
}
Dialog Header file (필자의 경우 UserCtrlMsgDlg.h)
Message를 처리할 함수를 선언해주세요.
afx_msg void OnNotyfyUserWnd(NMHDR* pNMHDR, LRESULT* pResult);
Dialog cpp file (필자의 경우 UserCtrlMsgDlg.cpp)
Message Map에 아래 1줄을 추가해주세요.
ON_NOTIFY(WM_USER_WND, IDC_USER_WND, OnNotyfyUserWnd)
  • ON_NOTIFY 경우 Message번호, Contril ID와 실행할 함수를 인자로 설정해줍니다.
Command를 처리할 함수를 구현합니다.
void CUserCtrlMsgDlg::OnNotyfyUserWnd(NMHDR* pNMHDR, LRESULT* pResult)
{
    AfxMessageBox(_T("ON NOTIFY"));
}

3. Command 방식

  • Dialog에 해당 User Control 별로 전달할 메세지가 1가지 밖에 없을 경우 유용합니다.
    • e.g. button의 경우 눌렀을 경우에만 메세지를 전달하면 되고, 나머지 경우는 전달하지 않아도 될 경우 유용합니다.
UserWnd.cpp
OnLButtonDown 함수 내부에 아래와 같이 1줄을 추가
void CUserWnd::OnLButtonDown(UINT nFlags, CPoint point)
{
    HWND hWnd = GetSafeHwnd();

    if (hWnd == NULL) return;
    if (!::IsWindow(hWnd)) return;

    int nID = GetDlgCtrlID();

    if (m_hwndDlg != nullptr)
    {
        ::SendMessage(m_hwndDlg, WM_COMMAND, nID, NULL);
    }

    CWnd::OnLButtonDown(nFlags, point);
}
Dialog Header file (필자의 경우 UserCtrlMsgDlg.h)
Command를 처리할 함수를 선언해주세요.
afx_msg void OnCommandUserWnd();
Dialog cpp file (필자의 경우 UserCtrlMsgDlg.cpp)
Message Map에 아래 1줄을 추가해주세요.
ON_COMMAND(IDC_USER_WND, OnCommandUserWnd)
  • ON_COMMAND의 경우 Control ID 와 실행할 함수를 인자로 설정해줍니다.
Command를 처리할 함수를 구현합니다.
void CUserCtrlMsgDlg::OnCommandUserWnd()
{
    AfxMessageBox(_T("ON COMMAND"));
}
이제 실행 후 왼쪽 상단의 검은색 선 안을 누르면 해당 메세지가 출력되는 것을 확인 할 수 있습니다.

2016년 2월 4일 목요일

Codejock Xtreme ToolkitPro Chart Control Tutorial (CXTPChartControl)

Codejock Xtreme ToolkitPro Chart Control Tutorial

ToolkitPro의 Chart Control 인 CXTPChartContorl의 간단한 사용법을 소개해 드리도록 하겠습니다.
기본적으로 ToolkitPro를 설치하고 환경설정하는 방법은 생략하겠습니다.
아래 Link를 참조해 주세요.
먼저 MFC Application Project를 생성하여 Dialog로 생성해 주세요.
image
image
물론 ToolkitPro를 사용하려면
stdafx.h에 ToolkitPro 헤더파일을 추가해 주세요.
#include <XTToolkitPro.h> 

1.Resource File (.rc)에서 Dialog Design에 찾아서 아래와 같이 Control을 타이핑

CONTROL         "Chart", IDC_CHARTCONTROL, "XTPChartControl", WS_TABSTOP, 7, 7, 245, 186

2. Resource.h에 추가

#define IDC_CHARTCONTROL                103
Resource View에서 마우스로 대충 크기 변환해주세요. 대충 아래와 같은 모양이 됩니다.
image
IDD_XTPCHARTSAMPLE_DIALOG DIALOGEX 0, 0, 427, 287
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "XTPChartSample"
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
    DEFPUSHBUTTON   "OK",IDOK,312,266,50,14
    PUSHBUTTON      "Cancel",IDCANCEL,370,266,50,14
    CONTROL         "Chart",IDC_CHARTCONTROL,"XTPChartControl",WS_TABSTOP,7,7,413,255
END

3. 컨트럴에 마우스 우 클릭 Add Variable 누른 뒤 그림대로 추가해주세요.

image
위와 같이 하지 않고 직접 코딩하여도 됩니다.
  • XTPChartSampleDlg.h
public:
    CXTPChartControl m_wndChartControl;
  • XTPChartSampleDlg.cpp
void CXTPChartSampleDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_CHARTCONTROL, m_wndChartControl);
}
모든 구현은 void InitChart();를 추가하여 여기다가 하겠습니다.
BOOL CXTPChartSampleDlg::OnInitDialog()에서 InitChart();를 호출하도록 해주세요.

4. 구현

어떤 작업을 하던지 Content 객체를 가져와서 작업을 해야 합니다.
CXTPChartContent* pContent = m_wndChartControl.GetContent();
  • Title 설정
// Title 설정
CXTPChartTitleCollection* pTitles = pContent->GetTitles();
CXTPChartTitle* pTitle = pTitles->Add(new CXTPChartTitle());
pTitle->SetText(_T("My Chart"));
  • Series에 Point 추가
// Series, Series Point 추가
CXTPChartSeriesCollection* pCollection = pContent->GetSeries();
CXTPChartSeries* pSeries = pCollection->Add(new CXTPChartSeries());

pSeries->SetStyle(new CXTPChartLineSeriesStyle());
CXTPChartSeriesPointCollection* pPoints = pSeries->GetPoints();

pPoints->Add(new CXTPChartSeriesPoint(0, 3));
pPoints->Add(new CXTPChartSeriesPoint(1, 1));
pPoints->Add(new CXTPChartSeriesPoint(2, 2));
pPoints->Add(new CXTPChartSeriesPoint(3, 0.5));
실행시키면 다음과 같은 화면이 나옵니다.
image
여기에서 Series를 하나 더 추가해 보겠습니다.
CXTPChartSeries* pS2 = pCollection->Add(new CXTPChartSeries());
pSeries->SetName(_T("Series2"));

pS2->SetStyle(new CXTPChartLineSeriesStyle());
CXTPChartSeriesPointCollection* pPoints = pS2->GetPoints();

pPoints->Add(new CXTPChartSeriesPoint(0, 2));
pPoints->Add(new CXTPChartSeriesPoint(1, 0.5));
pPoints->Add(new CXTPChartSeriesPoint(2, 3));
pPoints->Add(new CXTPChartSeriesPoint(3, 1));
image
Series의 Label을 설정하려면 다음과 같이 하면 됩니다.
소숫점 1자리까지 나오게 하는 예제 입니다.
// SeriesLabel의 설정
for (int i = 0; i < pCollection->GetCount(); i++)
{
    CXTPChartSeriesLabel* pLabel = pCollection->GetAt(i)->GetStyle()->GetLabel();
    pLabel->GetFormat()->SetCategory(xtpChartNumber);
    pLabel->GetFormat()->SetDecimalPlaces(1); // 소숫점 표시
}
image
Point Label 자체를 안보이게 하려면 다음 문장을 추가하면 됩니다.
pLabel->SetVisible(FALSE);
image
  • 범주 보이게 하기
pContent->GetLegend()->SetVisible(TRUE);
image
  • Series의 통계값 계산
아래와 같은 함수들을 지원해줘서 통계값을 쉽게 계산할 수 있습니다. Min, Max등의 다양한 함수가 많습니다.
double dArithmeticMean = pPoints->GetArithmeticMean(0);
double dVariance = pPoints->GetVariance(0);
double dStd = pPoints->GetStandardDeviation(0);
  • 축(AXIS 설정)
// Axis 설정
//CXTPChartDiagram2D* pDiagram = DYNAMIC_DOWNCAST(CXTPChartDiagram2D, pCollection->GetAt(0)->GetDiagram());
CXTPChartDiagram* pDiagram = pCollection->GetAt(0)->GetDiagram();
CXTPChartDiagram2D* pD2D = DYNAMIC_DOWNCAST(CXTPChartDiagram2D, pDiagram);

CXTPChartAxis *pAxisX = pD2D->GetAxisX();

CXTPChartAxisTitle* pTitle = pAxisX->GetTitle();

pTitle->SetText(_T("X-Argument"));
pTitle->SetVisible(TRUE);

CXTPChartAxis *pAxisY = pD2D->GetAxisY();

CXTPChartAxisTitle* pTitle2 = pAxisY->GetTitle();

pTitle2->SetText(_T("Y-Value"));
pTitle2->SetVisible(TRUE);
image
  • Series Marker 안보이게 하기
for (int i = 0; i < pCollection->GetCount(); i++)
{
    CXTPChartPointSeriesStyle* pStyle = (CXTPChartPointSeriesStyle*)pCollection->GetAt(i)->GetStyle();
    pStyle->GetMarker()->SetVisible(FALSE);
    //pStyle->GetMarker()->SetSize(20); // Maeker Size 조정
    //pStyle->GetMarker()->SetType(xtpChartMarkerCircle); // enum XTPChartMarkerType 
}
image
  • 마우스 휠을 이용한 Zoom 허용 및 Scroll 허용
pD2D->SetAllowZoom(TRUE);   // 마우스 휠을 이용한 Zoom 허용
pD2D->SetAllowScroll(TRUE); // Scroll 허용
image
  • Chart Image 저장
m_wndChartControl.SaveAsImage(_T("D:\\A.PNG"),CSize(600,400));
image

위 설명한 내용의 Full Source

void CXTPChartSampleDlg::InitChart()
{
    // Content를 이용해서 Chart의 Title, Series, Legends등의 설정이 가능
    CXTPChartContent* pContent = m_wndChartControl.GetContent();
    if (!pContent) return;

    pContent->GetLegend()->SetVisible(TRUE);

    // Title 설정
    CXTPChartTitleCollection* pTitles = pContent->GetTitles();
    if (pTitles)
    {
        CXTPChartTitle* pTitle = pTitles->Add(new CXTPChartTitle());
        if (pTitle)
        {
            pTitle->SetText(_T("My Chart"));
        }
    }

    // Series, Series Point 추가
    CXTPChartSeriesCollection* pCollection = pContent->GetSeries();
    if (pCollection)
    {
        CXTPChartSeries* pSeries = pCollection->Add(new CXTPChartSeries());
        if (pSeries)
        {
            pSeries->SetName(_T("Series1"));
            pSeries->SetStyle(new CXTPChartLineSeriesStyle());
            CXTPChartSeriesPointCollection* pPoints = pSeries->GetPoints();
            if (pPoints)
            {
                pPoints->Add(new CXTPChartSeriesPoint(0, 3));
                pPoints->Add(new CXTPChartSeriesPoint(1, 1));
                pPoints->Add(new CXTPChartSeriesPoint(2, 2));
                pPoints->Add(new CXTPChartSeriesPoint(3, 0.5));

                double dArithmeticMean = pPoints->GetArithmeticMean(0);
                double dStd = pPoints->GetStandardDeviation(0);

            }
        }

        CXTPChartSeries* pS2 = pCollection->Add(new CXTPChartSeries());
        if (pS2)
        {
            pS2->SetName(_T("Series2"));
            pS2->SetStyle(new CXTPChartLineSeriesStyle());
            CXTPChartSeriesPointCollection* pPoints = pS2->GetPoints();
            if (pPoints)
            {
                pPoints->Add(new CXTPChartSeriesPoint(0, 2));
                pPoints->Add(new CXTPChartSeriesPoint(1, 0.5));
                pPoints->Add(new CXTPChartSeriesPoint(2, 3));
                pPoints->Add(new CXTPChartSeriesPoint(3, 1));
            }
        }

        // SeriesLabel의 설정
        for (int i = 0; i < pCollection->GetCount(); i++)
        {
            CXTPChartSeriesLabel* pLabel = pCollection->GetAt(i)->GetStyle()->GetLabel();
            pLabel->GetFormat()->SetCategory(xtpChartNumber);
            pLabel->GetFormat()->SetDecimalPlaces(1); // 소숫점 표시
            pLabel->SetVisible(FALSE);
        }

        // Axis 설정
        //CXTPChartDiagram2D* pDiagram = DYNAMIC_DOWNCAST(CXTPChartDiagram2D, pCollection->GetAt(0)->GetDiagram());
        CXTPChartDiagram* pDiagram = pCollection->GetAt(0)->GetDiagram();
        CXTPChartDiagram2D* pD2D = DYNAMIC_DOWNCAST(CXTPChartDiagram2D, pDiagram);
        if (pD2D)
        {
            CXTPChartAxis *pAxisX = pD2D->GetAxisX();
            if (pAxisX)
            {
                CXTPChartAxisTitle* pTitle = pAxisX->GetTitle();
                if (pTitle)
                {
                    pTitle->SetText(_T("X-Argument"));
                    pTitle->SetVisible(TRUE);
                }
            }

            CXTPChartAxis *pAxisY = pD2D->GetAxisY();
            if (pAxisX)
            {
                CXTPChartAxisTitle* pTitle = pAxisY->GetTitle();
                if (pTitle)
                {
                    pTitle->SetText(_T("Y-Value"));
                    pTitle->SetVisible(TRUE);
                }
            }
        }

        // Marker 안보이게 하기
        for (int i = 0; i < pCollection->GetCount(); i++)
        {
            CXTPChartPointSeriesStyle* pStyle = (CXTPChartPointSeriesStyle*)pCollection->GetAt(i)->GetStyle();
            pStyle->GetMarker()->SetVisible(FALSE);
            //pStyle->GetMarker()->SetSize(20); // Maeker Size 조정
            //pStyle->GetMarker()->SetType(xtpChartMarkerCircle); // enum XTPChartMarkerType 
        }

        pD2D->SetAllowZoom(TRUE);   // 마우스 휠을 이용한 Zoom 허용
        pD2D->SetAllowScroll(TRUE); // Scroll 허용

        m_wndChartControl.SaveAsImage(_T("D:\\A.PNG"),CSize(600,400));
    }
}

예제 소스