ASE Home Page Products Download Purchase Support About ASE
ChartDirector Support
Forum HomeForum Home   SearchSearch

Message ListMessage List     Post MessagePost Message

  C++ ActiveX in Delphi; Exception setChart
Posted by Fabian on Feb-24-2012 19:40
Hi Peter,

I get an exception by calling setChart.

Chartdirector runs in an C++ ActiveX. Compiled in VS2005 on Windows 7.

"_control87(0x133F, 0xFFFF);" doesn't help!

I'm using "chartdir50.dll"

Any Idea?

  Re: C++ ActiveX in Delphi; Exception setChart
Posted by Peter Kwan on Feb-25-2012 02:56
Hi Fabian,

Just from this information, it is hard to diagnose what causes the problem.

The "_control87(0x133F, 0xFFFF);" is only applicable if the exception is a floating point exception. For your case, is it a floating point exeception or another exception? Do you have any stack trace or other more detail error information?

Have you tested your ActiveX control in another C++ program, or in VB6 or other ActiveX container? This can help to determine if the issue is in the ActiveX control itself, or is a compatibility issue with Delphi.

Regards
Peter Kwan

  Re: C++ ActiveX in Delphi; Exception setChart
Posted by Fabian on Feb-26-2012 01:28
Hi Peter,

it seems to be since I changed from VS2000 to VS2005.

I tested it in the microsoft ActiveX container and "setChart" returned immediately.

If my ActiveX runs in the Delphi container, I don't get any Exception message, but
"setchart" blocks and don't returned.

  Re: C++ ActiveX in Delphi; Exception setChart
Posted by Fabian on Feb-27-2012 23:58
Hi Peter,

do you have any idee or do you need further details?

  Re: C++ ActiveX in Delphi; Exception setChart
Posted by Peter Kwan on Feb-28-2012 01:02
Hi Fabian,

Actually, I am not sure which part of ChartDirector have you been ported to ActiveX, and how does it interact with Delphi.

The ChartDirector DLL "chartdir50.dll" does not have a setChart method. The setChart method is part of the MFC and QT sample code, implemented in CChartViewer.cpp and QChartViewer.cpp. So I think you should have the source code that implements setChart, and you probably have compiled it into your ActiveX control.

So one method to trouble-shoot the problem is to single step the code. You can set a breakpoint in setChart, and single step the code and examine the variables to see why it hang. See:

http://msdn.microsoft.com/en-us/library/w54zfak1(v=vs.80).aspx

You mentioned that it works in the microsoft ActiveX container, and you mentioned "it seems to be since I changed from VS2000 to VS2005". Do you mean the code works normally with Delphi if you use "VS2000" (actually, I am not aware there is a VS2000 at all)? This can help to determine if there is issue with incorrect code, or with incorrect compiler configuration.

As mentioned above, the ChartDirector DLL does not contain the setChart method or any MFC or QT control at all. (The MFC and QT controls are part of the sample code.) If your Delphi application is called the methods in the ChartDirector DLL (like creating an XYChart, setPlotArea, addLineLayer, etc), you may consider to write some code that generates a chart image in the hard disk (using BaseChart.makeChart). This can test if Delphi can interface with the ChartDirector DLL correctly. If it works, we can then focus on the part related to the sample code (the MFC or QT controls).

Hope this can help.

Regards
Peter Kwan

  Re: C++ ActiveX in Delphi; Exception setChart
Posted by Fabian on Feb-28-2012 02:29
Hi Peter,

thank you for your reply. I'm using ChartDirector Version 5.0 C++ Edition.
My ActiveX was written in C++.

In my ActiveX-Project is the ChartViewer class included. I'm using chartdirector in many
other projects and it worked fine. setChart is a function from CChartViewer which is
provided by chartdirector.

Yes, I mean the code works normally with Delphi if I use "VS2000".

On my computer (windows7) it worked fine - also compiled with VS2005, but on another
one (Microsoft Windows Server 2003 - Enterprise Edition - SP2) it doesn't work.
I found the position that causes the problem by adding some log functionalities.
=> the function "makeChart" in setChart doesn't return.


Below is a part of my code: ###################
XYChart *c = new XYChart(rc.Width(), rc.Height());
...
delete m_ChartViewer.getChart(); // => CChartViewer m_ChartViewer;
m_ChartViewer.setChart(c);
###############################
void CChartViewer::setChart(BaseChart *c)
{
...
if (0 != c)
{
// Output chart as Device Indpendent Bitmap with file headers
MemBlock m = c->makeChart(Chart::BMP);
...
}
...
}
#####################################

  Re: C++ ActiveX in Delphi; Exception setChart
Posted by Peter Kwan on Feb-28-2012 07:16
Hi Fabian,

You mentioned the code "blocks" and doesn't return. I assume it means your application essentially hangs. Also, the problem only occurs with Delphi on certain Windows OS using certain Visual Studio versions.

When the code "blocks", is the CPU utilization close to 100% or 0%? If it is close to 100%, it is more likely to be an infinite loop or due to invalid parameters (like creating a chart with 10000 x 1000000 pixels). If it is close to 0%, it may be an I/O issue.

For your charting code, I assume it is entirely in C++, and run continuously (without breaking out to run some Delphi code in the middle, etc). For a first step, I suggest replace your charting code with the following code (the "Simple Bar Chart" sample code).

     // The data for the bar chart
    double data[] = {85, 156, 179.5, 211, 123};

    // The labels for the bar chart
    const char *labels[] = {"Mon", "Tue", "Wed", "Thu", "Fri"};

    // Create a XYChart object of size 250 x 250 pixels
    XYChart *c = new XYChart(250, 250);

    // Set the plotarea at (30, 20) and of size 200 x 200 pixels
    c->setPlotArea(30, 20, 200, 200);

    // Add a bar chart layer using the given data
    c->addBarLayer(DoubleArray(data, sizeof(data)/sizeof(data[0])));

    // Set the labels on the x axis.
    c->xAxis()->setLabels(StringArray(labels, sizeof(labels)/sizeof(labels[0])));

    c->makeChart(Chart::BMP);

    // Output the chart
    c->makeChart("c:\\\\simplebar.png");


In the above code, everything is hard coded, so we eliminate the risk of having invalid data. We still make the makeChart call, but no MFC or setChart is used. This eliminates the risk in difference in MFC. The entire code is continuous within no other code in between, and this eliminates the uncertainty with other code. The code does produce an output "c:\\\\simplebar.png", so you can see if it works or not.

Also, I assume your code is a desktop application (as opposed to a server based application, as the server application may run under a special non-user account with different security settings and may not be able to access the GUI subsystem).

If the above code works, trying using exactly the same code (with everything hard coded and no other code in between), but instead of makeChart, calls setChart.

If even the above code hangs with near 0% CPU utilization, you may want to monitor the I/O access to see if it blocks. (On Windows 2003 Server, which is a server OS, may be different I/O access security settings from a normal desktop machines.) ChartDirector access font files, and may check for the license file (unless you use setLicenseCode to set the license key first.) You may use the Microsoft ProcessMonitor (http://technet.microsoft.com/en-us/sysinternals/bb896645) to log all File I/O access from your process to see if there are any error.

Regards
Peter Kwan

  Re: C++ ActiveX in Delphi; Exception setChart
Posted by Fabian on Feb-28-2012 15:23
Hi Peter,

Thank you for your support! I followed your suggestion and found the problem.

****************
CRect rcChart;
m_ChartViewer.GetWindowRect(&rcChart);
XYChart *c = new XYChart(rcChart.Width(), rcChart.Height());
c->setPlotArea(60, 70, rcChart.Width()-100, rcChart.Height()-180);
****************

rcChart is to the beginning 17220x32754. I can't understand why this happening, but these
causes the problem!

I don't know why it do by compiling with VS2000 and on my machine compiled with VS2005,
but the main thing is it do. ;)

Or do you have any idee, Peter?

cheers,
Fabian

  Re: C++ ActiveX in Delphi; Exception setChart
Posted by Peter Kwan on Feb-28-2012 23:45
Hi Fabian,

Your code attempts to get the size of the m_ChartViewer, and then use it as the size of the XYChart.

For this to work, your code must have somewhat set the size of the m_ChartViewer before attempting to get its size (otherwise the size is initialized and can be random numbers). Have you verified that the size of m_ChartViewer is in fact set before you tried to get it? When you set the size of m_ChartViewer, please verify if they are set correctly. (If your code really sets the size to 17220x32754, then you will of course obtain 17220x32754.)

Also, the GetWindowRect is not guaranteed to be successful. According to Microsoft documentation, it should return a BOOL value to indicate if it is successful, and you can use getLastError to check what is the error. In your case, your code does not check for error, so there is a chance that the GetWindowRect is not successful.

From experience, different versions of Visual Studio comes with different versions of MFC. The operation of different versions of MFC are not the same. In particular, the sequence of MFC events may be different. If you set the m_ChartViewer size in one event, and draw the chart in another event, you must make sure the former event occurs first, followed by the latter event in all versions of MFC. And of course, you must make sure the code executes only after the Window has been created, and the MFC variable m_ChartViewer is bound to the actual control.

Regards
Peter Kwan

  Re: C++ ActiveX in Delphi; Exception setChart
Posted by Fabian on Feb-29-2012 00:41
Hi Peter,

thank you so much for your support!!!

I will do some review over my code...

Fabian