Post List

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

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월 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));
    }
}

예제 소스

2015년 4월 8일 수요일

XTPReportControl 사용 가이드 ( Xtreme Toolkit Pro : Report Control )

* 본격적인 내용에 앞서...

예전에 C# Project를 진행할 당시에 DevExpress 에 관련한 한글로 된 자료가 없어서,
Naver Blog에 관련 기능들을 정리한 적이 있습니다. ( http://icysword.blog.me )

MFC에서 사용할 만한 UI Component 중 가장 많이 사용하는 것으로 Codejock 의 eXtream Toolkit Pro (XTP) 를 꼽을 수 있습니다.
하지만, 이 녀석은 C# 같이 마우스로 찍. 찍. 찍. 해서 사용이 안되서 사용이 힘들더군요.
한글로 된 사용설명 또한 찾기 힘들구요. (아에 없는 듯 합니다. ㅠㅠ)

XTP 의 모든 Component 들의 사용 가이드는 만들 수 없더라도, 제가 사용했던 것들에 대해서는 정리해서 올릴 예정입니다.

그리고 제가 어떤 방법으로 이렇게 사용이 가능했는지에 대한 설명도 같이 드리겠습니다.

XTP의 설치 및 Visual Studio 에서의 설정은 제 Blog에 이미 설명해 놓았으니 넘어가겠습니다.

http://devluna.blogspot.kr/search/label/XtremeToolkit

위 Link에서 관련 글들의 확인이 가능합니다.

* XTPReportControl

Report Control 은 List를 Column 단위로 관리하면서 Record를 Row로 표현하는데 좋은 Control 입니다.
Grid와는 조금 다릅니다.

먼저 필자는 XTP 16.2 버전을 설치했으며,
Visual Studio 2010을 사용했습니다.

XTP 16.2가 VS2012까지밖에 지원하지 않아서,
Visual Studio 2015 CTP에서 MFC Project를 VS2010 용으로 생성하여서 진행하였습니다.

이제부터 예제를 통해서 사용법을 설명해 드리겠습니다.

1. Project 생성

  MFC Application ProjectDialog를 선택하여 생성하였습니다.
(Project Wizard 목록에는 Toolkit Pro용 Project도 있지만, 좀 더 일반적인 방법으로 접근하고자 MFC Application Project로 진행하였습니다.)
  Project 명은 XTPReportTest 로 하였으며,
  세부 설정은 다음 그림과 같이 하고 바로 Finish를 눌렀습니다.



당연히 Project를 만들었으면, 일단 F5를 눌러서 정상적으로 빌드가 되어서 Dialog가 뜨는지 확인을 하였습니다.

2. XTP 설정

stdafx.h 파일을 열어서 적당한 위치에 XTP용 해더파일을 추가하였습니다.

#include <XTToolkitPro.h>

그런 다음 다시 F7을 눌러서 빌드를 실행하였습니다.
빌드 출력창에 XTP 관련된 내용이 나오는 것을 확인하고, 빌드가 성공적으로 된것까지 확인을 하였습니다.

3. Dialog에 XTPReportControl 올리기

 MFC의 Dialog 편집창에서 마우스로 처리가 불가능합니다.
 (제가 모르는 것일 수도 있으니, 혹시 하는법 아시는분 계시면 알려주시면 감사하겠습니다.)

 그래서 저는 XTP 설치시 같이 설치되는 Sample Project를 보고 거기서 관련 Code들을 보고 적용하였습니다.

resource.h 파일을 열어서 ReportControl의 ID를 생성합니다.

#define IDR_MAINFRAME                        128
#define IDM_ABOUTBOX                         0x0010
#define IDD_ABOUTBOX                         100
#define IDS_ABOUTBOX                         101
#define IDD_XTPREPORTTEST_DIALOG             102
#define IDC_REPORT                           103

103번으로 추가하였습니다.

그런 다음 리소스 파일 (XTPReportTest.rc)을 Code보기로 열어봅니다.



파일 안에서 Dialog 디자인 관련 부분을 찾아서 ReportControl을 한줄 추가 합니다.

IDD_XTPREPORTTEST_DIALOG DIALOGEX  0, 0, 320, 200
STYLE DS_SHELLFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_THICKFRAME | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "XTPReportTest"
FONT 8, "MS Shell Dlg"
BEGIN
    DEFPUSHBUTTON   "OK",IDOK,209,179,50,14
    PUSHBUTTON      "Cancel",IDCANCEL,263,179,50,14
    CTEXT           "TODO: Place dialog controls here.",IDC_STATIC,10,96,300,8
    CONTROL          "", IDC_REPORT, "XTPReport", WS_TABSTOP, 10,10,300,150, WS_EX_STATICEDGE
END

그리고 쓸데없는 TEXT 한줄은 지웠습니다.

Dialog 해더 파일 (XTPReportTestDlg.h) 을 열어서 ReportControl을 멤버변수로 선언해 주시구요.

CXTPReportControl m_wndReport;

cpp 파일 (XTPReportTestDlg.cpp) 을 열어서 Control 과 멤버 변수를 연결시켜 줍니다.

void CXTPReportTestDlg::DoDataExchange(CDataExchange* pDX)
{
        CDialogEx::DoDataExchange(pDX);
        DDX_Control(pDX, IDC_REPORT, m_wndReport);
}

그런 다음 F5를 눌러서 실행해 봅니다.
정상적으로 따라오셨으면 Dialog가 실행됩니다.



화면에 텅빈 ReportControl이 추가된 것이 확인가능합니다.
크기나 이동은 이제 리소스 편집창에서 마우스로 가능합니다.

4. XTPReportControl 의 Column 설정

먼저 해더 파일을 열어서 Column을 enum으로 정의하였습니다.

enum REPORT_COLUMN
{
   COLUMN_ID = 0,
   COLUMN_NAME,
   COLUMN_ADDR,
   COLUMN_GRADE
};

cpp파일을 열어서

BOOL CXTPReportTestDlg::OnInitDialog()

안에다가 다음과 같이 Column을 설정합니다.

m_wndReport.ModifyStyle(0, WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_TABSTOP);
m_wndReport.GetReportHeader()->AllowColumnRemove(FALSE);

m_wndReport.AddColumn(new CXTPReportColumn(COLUMN_ID, _T("ID"), 200));
m_wndReport.AddColumn(new CXTPReportColumn(COLUMN_NAME, _T("Name"), 200));
m_wndReport.AddColumn(new CXTPReportColumn(COLUMN_ADDR, _T("Addr"), 200));
m_wndReport.AddColumn(new CXTPReportColumn(COLUMN_GRADE, _T("Grade"), 200, TRUE, -1, FALSE, FALSE));

Column의 Width는 모두 200으로 하였으며, 마지막 줄인 COLUMN_GRADE는 화면에 보이지 않게 설정하였습니다.

다시 F5를 눌러서 제대로 반영되었는지 확인해 봅니다.




5. Record Data 등록

위 Column을 등록한 바로 아래에 다음과 같이 예제 Record들을 등록해 봅시다.

auto AddReport = [&](CString p_sID, CString p_sName, CString p_sAddr, CString p_sGrade)
{
   CXTPReportRecord* pRecord = m_wndReport.AddRecord(new CXTPReportRecord());
   pRecord->AddItem(new CXTPReportRecordItemText(p_sID));
   pRecord->AddItem(new CXTPReportRecordItemText(p_sName));
   pRecord->AddItem(new CXTPReportRecordItemText(p_sAddr));
   pRecord->AddItem(new CXTPReportRecordItemText(p_sGrade));
};

AddReport(_T("ID001"), _T("Yun Seok-joon"), _T("Sangam-dong"), _T("VVIP"));
AddReport(_T("ID002"), _T("Luna Star"), _T("Sky"), _T("Star"));
AddReport(_T("ID003"), _T("Demilune"), _T("Universe"), _T("Dark"));

m_wndReport.Populate();

다시 F5를 눌러서 실행하면 Record들이 등록된 것을 확인 할 수 있습니다.

6. 관련 동작 (Event) 등록하기

XTPReportControl에서 동작가능한 Event 들은 XTP 설치시 같이 설치되는 Document에서 확인이 가능합니다.
Online Help를 실행하여 Report Control 아래에 있는 Macros 를 보면 관련 내용들이 나옵니다.



위 화면에서 Ctrl + F 를 눌러서 Click으로 검색해보면, XTP_NM_REPORT_LBUTTONDOWN 이라는 Event 를 찾을 수 있습니다.
아래 설명에 시키는대로 하면 마우스 클릭 이벤트에 대해서 처리가 가능합니다.
(이번 예제에서는 다루지 않겠습니다.)


다시 SELECT로 검색을 해보았습니다.
XTP_NM_REPORT_SELCHANGED 라는 매크로가 검색되었습니다.
선택된 Record가 변경되었을 때 실행되는 Event 입니다.
이 것을 한번 적용해 보겠습니다.



먼저 해더파일을 열어서
afx_msg void OnReportSelChanged(NMHDR* pNMHDR, LRESULT*);
라는 이벤트 함수를 추가합니다.

// Generated message map functions
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnReportSelChanged(NMHDR* pNMHDR, LRESULT*);
DECLARE_MESSAGE_MAP()

그런 다음 cpp파일을 열어서 Message Map에 관련 내용을 추가 한 뒤

BEGIN_MESSAGE_MAP(CXTPReportTestDlg, CDialogEx)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_NOTIFY(XTP_NM_REPORT_SELCHANGED, IDC_REPORT, OnReportSelChanged)
END_MESSAGE_MAP()

관련 함수를 구현합니다.

afx_msg void CXTPReportTestDlg::OnReportSelChanged(NMHDR* pNMHDR, LRESULT*)
{
    CXTPReportRow* pRow = m_wndReport.GetFocusedRow();
    CXTPReportRecord* pRecord = pRow->GetRecord();
    CXTPReportRecordItem* pItem = pRecord->GetItem(COLUMN_GRADE);
    CString sGrade = pItem->GetCaption();

    AfxMessageBox(sGrade);
}

내용은 선택된 Record에서 우리가 숨긴 Grade 정보를 팝업창으로 보여주는 코드입니다.

위 함수 내용의 5줄을 그냥 한줄로도 표현이 됩니다.

AfxMessageBox(m_wndReport.GetFocusedRow()->GetRecord()->GetItem(COLUMN_GRADE)->GetCaption());

예전에는 아래와 같이 한 줄로 표현하는게 멋있어 보였습니다.
그것보다도 왠지 따로 명시적으로 변수로 선언을 안하니깐 메모리도 절약될것 같고...
하지만 지금은 오히려 아래가 더 병맛같이 보이네요.
(병맛같지만 왠지 멋있어 ? 뭐 그런 ???)
디버깅도 더 힘들구요.
위와 같이 따로따로 명시적으로 선언을 하면 디버깅시 훨씬 편리합니다.
그리고, 명시적으로 선언한다고 메모리를 더 잡아먹거나 그러진 않습니다.
시대가 어느 시댄데... 컴파일러가 어련히 알아서 잘 해주겠죠.

그리고 F5를 눌러서 실행하면 아래와 같이 선택된 레코드의 Grade가 보여집니다.



이상으로 XTPReportControl 사용 가이드에 대한 설명은 마치겠습니다.