Create a new MFC project with a Chart in Visual Studio 2010 and up

Accessing all the properties of an ActiveX control in a Visual C++ MFC project can be complicate to some developers. That’s what motivated me to write a quite detailed guide about how I created an MFC project with TeeChart v2014.0.0.1.
Here the step-by-step instructions:

 

– Create a new MFC project:

2014-07-09_1416

2014-07-09_1417

– Note I used “Dialog based” application type to make a simple project:

2014-07-09_1418

– Here it is the blank dialog we get:

2014-07-09_1419

– Drag a “TeeChart Pro ActiveX control v*”:

2014-07-09_1420

-Then we’ll have to create a variable to access the chart at runtime:

2014-07-09_1420_001

– Set a name to it (ie “mChart1”):

2014-07-09_1423

This action has created “tchart1.h” and “tchart1.cpp” in our solution.
However, if we build this project now, we get a few errors we need to fix.
The first three errors:

error C2365: ‘pmwNormal’ : redefinition; previous definition was ‘enumerator’ .\mfcaxtest\mfcaxtest\tchart1.h 1406 1 MFCAXTest
error C2365: ‘pmwInverted’ : redefinition; previous definition was ‘enumerator’ .\mfcaxtest\mfcaxtest\tchart1.h 1407 1 MFCAXTest
error C2365: ‘pmwNone’ : redefinition; previous definition was ‘enumerator’ .\mfcaxtest\mfcaxtest\tchart1.h 1409 1 MFCAXTest

We can fix them changing some defines at “tchart1.h”, where it says:

enum
{
pmwNormal = 0,
pmwInverted = 1,
pmwNone = 2
}EMouseWheelStyle;
enum
{
pmwNormal = 0,
pmwInverted = 1,
pmwNone = 2
}EMouseWheelStyle;

 

Change it for:

enum
{
pmwsNormal = 0,
pmwsInverted = 1,
pmwsNone = 2
}EMouseWheelStyle;
enum
{
pmwsNormal = 0,
pmwsInverted = 1,
pmwsNone = 2
}EMouseWheelStyle;

 

This error:

error C2365: ‘tsNone’ : redefinition; previous definition was ‘enumerator’ .\mfcaxtest\mfcaxtest\tchart1.h 1525 1 MFCAXTest

We can fix it changing some other defines at “tchart1.h”, where it says:

enum
{
tsNone = 0,
tsStacked = 1,
tsStacked100 = 2
}ETowerStacked;
enum
{
tsNone = 0,
tsStacked = 1,
tsStacked100 = 2
}ETowerStacked;

 

Change it for:

enum
{
twsNone = 0,
twsStacked = 1,
twsStacked100 = 2
}ETowerStacked;
enum
{
twsNone = 0,
twsStacked = 1,
twsStacked100 = 2
}ETowerStacked;

 

And this one:

error C2664: ‘CTchart1::CTchart1(const CTchart1 &)’ : cannot convert parameter 1 from ‘int’ to ‘const CTchart1 &’ .\mfcaxtest\mfcaxtest\mfcaxtestdlg.cpp 54 1 MFCAXTest

We can fix it removing the 0 argument at “MFCAXTestDlg.cpp”, where it says:

CMFCAXTestDlg::CMFCAXTestDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CMFCAXTestDlg::IDD, pParent)
, mChart1(0)
CMFCAXTestDlg::CMFCAXTestDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CMFCAXTestDlg::IDD, pParent)
, mChart1(0)

 

Change it for:

CMFCAXTestDlg::CMFCAXTestDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CMFCAXTestDlg::IDD, pParent)
, mChart1()
CMFCAXTestDlg::CMFCAXTestDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CMFCAXTestDlg::IDD, pParent)
, mChart1()

 

– Now, just to make things a bit more clean (so this is optional), add this to the “protected” section at “MFCAXTestDlg.h”:

void initChart();
void initChart();

 

Add this at the end of MFCAXTestDlg.cpp:

void CMFCAXTestDlg::initChart()
{
 
}
void CMFCAXTestDlg::initChart()
{

}

 

And call “initChart” at the end of “OnInitDialog”, still at “MFXAXTestDlg.cpp”:

BOOL CMFCAXTestDlg::OnInitDialog()
{
//...
 
// TODO: Add extra initialization here
 
initChart();
 
return TRUE; // return TRUE unless you set the focus to a control
}
BOOL CMFCAXTestDlg::OnInitDialog()
{
//...

// TODO: Add extra initialization here

initChart();

return TRUE; // return TRUE unless you set the focus to a control
}

 

At this point the project builds fine, and we have the “mChart1” variable but this variable doesn’t give us access to the chart properties and methods yet.

 

– Open the “Class Wizzard”:

2014-07-09_1624

– Select the “MFC Class From ActiveX Control…” option in the “Add” submenu:

2014-07-09_1621

– Select “TeeChart Pro ActiveX control v*” in the combobox and move “ITChart” to the “Generated classes” box:

2014-07-09_1622

This creates “CTChart.h” and “CTChart.cpp”. Now, at “MFCAXTestDlg.h”, change the “include”:

#include "tchart1.h"
#include "tchart1.h"

 

For this:

#include "CTChart.h"
#include "CTChart.h"

 

And also change “mChart1” declaration:

CTchart1 mChart1;
CTchart1 mChart1;

 

For this:

CTChart mChart1;
CTChart mChart1;

 

– Now you should be able to see the chart methods and properties for “mChart1”. Ie, at “MFCAXTestDlg.cpp”:

void CMFCAXTestDlg::initChart()
{
mChart1.AboutBox();
}
void CMFCAXTestDlg::initChart()
{
mChart1.AboutBox();
}

 

But you only see the properties and methods at the chart level. To get access to all the other classes, we still have to create and include the other required headers.

 

– Open again the “Class Wizard”. And this time select the “MFC Class From TypeLib…” option in the “Add” submenu:

2014-07-09_1432

– Move all the interfaces to the “Generated classes” (>> button):

2014-07-09_1432_001

Now a lot of headers have been added to the solution. But they include this line that will give us more problems:

#import "C:\\Program Files (x86)\\Steema Software\\TeeChart Pro v2014 ActiveX Control\\TeeChart2014.ocx" no_namespace
#import "C:\\Program Files (x86)\\Steema Software\\TeeChart Pro v2014 ActiveX Control\\TeeChart2014.ocx" no_namespace

 

So we have to use the “Quick Replace” function in Visual Studio (Ctrl+H) to replace the line above for this on the entire solution to remove it:

//#import "C:\\Program Files (x86)\\Steema Software\\TeeChart Pro v2014 ActiveX Control\\TeeChart2014.ocx" no_namespace
//#import "C:\\Program Files (x86)\\Steema Software\\TeeChart Pro v2014 ActiveX Control\\TeeChart2014.ocx" no_namespace

 

Now we use write the code we want for the chart initialization on “MFCAXTestDlg.cpp”. Ie:

//...
#include "CTitles.h"
#include "CAspect.h"
#include "CLegend.h"
#include "CSeries.h"
#include "CColorGridSeries.h"
#include "CPen0.h"
 
//...
 
void CMFCAXTestDlg::initChart()
{
    CTitles header = mChart1.get_Header();
    header.put_Caption(mChart1.get_Version());
 
    CAspect a = mChart1.get_Aspect();
    a.put_View3D(false);
 
    CLegend l = mChart1.get_Legend();
    l.put_Visible(false);
 
    mChart1.AddSeries(30);
    CSeries s = mChart1.Series(0);
    s.FillSampleValues(100);
    CColorGridSeries cgs = s.get_asColorGrid();
    CPen0 cgsPen = cgs.get_Pen();
    cgsPen.put_Visible(false);
}
//...
#include "CTitles.h"
#include "CAspect.h"
#include "CLegend.h"
#include "CSeries.h"
#include "CColorGridSeries.h"
#include "CPen0.h"

//...

void CMFCAXTestDlg::initChart()
{
	CTitles header = mChart1.get_Header();
	header.put_Caption(mChart1.get_Version());

	CAspect a = mChart1.get_Aspect();
	a.put_View3D(false);

	CLegend l = mChart1.get_Legend();
	l.put_Visible(false);

	mChart1.AddSeries(30);
	CSeries s = mChart1.Series(0);
	s.FillSampleValues(100);
	CColorGridSeries cgs = s.get_asColorGrid();
	CPen0 cgsPen = cgs.get_Pen();
	cgsPen.put_Visible(false);
}

Yeray Alonso

Developer and coffee master at Steema Software

Leave a Reply

Your email address will not be published. Required fields are marked *