I will try to describe as I use teechart in the project.
I catch sometime access violation error in this simple example, when restart thread with OnBnClickedCap192() and OnBnClickedStopcap192() function
Code: Select all
//i have formview class
//---------------- file ContView.h --------------------------------------------------
#pragma once
#include "tchart\tchart.h"
class CContView : public CFormView
{
DECLARE_DYNCREATE(CContView)
protected:
CContView(); // protected constructor used by dynamic creation
virtual ~CContView();
public:
enum { IDD = IDD_CONTROL_VIEW };
CTChart m_ctrlChart1;
CWinThread *wtPlotProc;
static UINT uiPlotProc(LPVOID param);//plot PSD 4096 poitns
afx_msg void OnBnClickedCap192();
afx_msg void OnBnClickedStopcap192();
}
//----------------------- file ContView.cpp ------------------------------------------------
#include "ContView.h"
//tchart include
#include "tchart\TeeChartDefines.h"
#include "tchart\Aspect.h"
#include "tchart\Axis.h"
#include "tchart\Axes.h"
#include "tchart\Areaseries.h"
#include "tchart\Arrowseries.h"
#include "tchart\Axisarrowtool.h"
#include "tchart\Axislabels.h"
#include "tchart\Axistitle.h"
#include "tchart\LineSeries.h"
#include "tchart\Brush.h"
#include "tchart\Canvas.h"
#include "tchart\environment.h"
#include "tchart\Marks.h"
#include "tchart\Pen.h"
#include "tchart\PointSeries.h"
#include "tchart\Pointer.h"
#include "tchart\Scroll.h"
#include "tchart\Series.h"
#include "tchart\Strings.h"
#include "tchart\TeeFunction.h"
#include "tchart\titles.h"
#include "tchart\teefont.h"
#include "tchart\valuelist.h"
#include "tchart\wall.h"
#include "tchart\Zoom.h"
#include "tchart\export.h"
#include "tchart\jpegexport.h"
#include "tchart\gifexport.h"
void CContView::OnInitialUpdate()
{
m_ctrlChart1.RemoveAllSeries();
m_ctrlChart1.GetEnvironment().SetMouseWheelScroll(false);
m_ctrlChart1.GetAspect().SetView3D(false);
m_ctrlChart1.GetAxis().GetBottom().SetAutomaticMaximum(FALSE);
m_ctrlChart1.GetAxis().GetBottom().SetAutomaticMinimum(FALSE);
m_ctrlChart1.GetAxis().GetLeft().SetAutomaticMaximum(TRUE);
m_ctrlChart1.GetAxis().GetLeft().SetAutomaticMinimum(TRUE);
m_ctrlChart1.GetAxis().GetBottom().SetMaximum(65000);
m_ctrlChart1.GetAxis().GetBottom().SetMinimum(-65000);
m_ctrlChart1.GetAxis().GetLeft().SetMinimum(-130);
m_ctrlChart1.GetAxis().GetLeft().SetMaximum(0);
}
//start func
void CContView::OnBnClickedCap192()
{
if (wtPlotProc==NULL)
wtPlotProc = AfxBeginThread(uiPlotProc,this);
}
//stop func
void CContView::OnBnClickedStopcap192()
{
//wait while stoped uiPlotProc
SetEvent(hPlotEvents[1]);
if (wtPlotProc!=NULL)
{
waitWithMessageLoop(this->wtPlotProc->m_hThread,0);
wtPlotProc=NULL;
}
}
//plot thread function
UINT CContView::uiPlotProc(LPVOID param)
{
CContView *pdlg = static_cast<CContView *>(param);//pointer on form
if (pdlg == NULL || !pdlg->IsKindOf(RUNTIME_CLASS(CContView)))
return 1; // if pdlg is not valid
ResetEvent(pdlg->hPlotEvents[1]);
int iFFTSize = (4096);
const double dHz = 48000/iFFTSize;
//init variable used for messages loop
bool bDone = false;
DWORD dwResult,dwResult1,dwResult2,dwResult3;
//array ------------------------------------------
COleSafeArray XValues;
COleSafeArray YValues;
double xVal[FFT_SIZ];
SAFEARRAYBOUND rgsabound[1];
rgsabound[0].lLbound = 0;
rgsabound[0].cElements = iFFTSize;
XValues.Clear();YValues.Clear();
XValues.Create(VT_R8, 1, rgsabound);
YValues.Create(VT_R8, 1, rgsabound);
long icur;
// Initialize them with values...
for(long index=0; index<iFFTSize; index++)
{
double CV=0;
double val;
if (index <iFFTSize/2)
{
icur = (index+iFFTSize/2);
val =(index*dHz);
xVal[icur]=val;
XValues.PutElement(&icur, &val);
YValues.PutElement(&icur, & CV);
}
else
{
icur = (index-iFFTSize/2);
val = ((_REAL)(index-iFFTSize)*dHz);
xVal[icur]=val;
XValues.PutElement(&icur, &val);
YValues.PutElement(&icur, & CV);
}
};
pdlg->m_ctrlChart1.RemoveAllSeries();
pdlg->m_ctrlChart1.AddSeries(scLine);
pdlg->m_ctrlChart1.AddSeries(scLine);
pdlg->m_ctrlChart1.AddSeries(scPoint);
pdlg->m_ctrlChart1.Series(0).SetShowInLegend(false);
pdlg->m_ctrlChart1.Series(0).SetColor(RGB(0,100,200));
pdlg->m_ctrlChart1.Series(0).GetAsLine().GetLinePen().SetWidth(1);
pdlg->m_ctrlChart1.Series(1).SetShowInLegend(false);
pdlg->m_ctrlChart1.Series(1).SetColor(RGB(200,20,0));
pdlg->m_ctrlChart1.Series(1).GetAsLine().GetLinePen().SetWidth(2);
pdlg->m_ctrlChart1.Series(2).SetShowInLegend(false);
pdlg->m_ctrlChart1.Series(2).SetColor(RGB(20,200,20));
pdlg->m_ctrlChart1.Series(2).GetAsPoint().GetPointer().SetStyle(psCircle);
pdlg->m_ctrlChart1.Series(2).GetAsPoint().GetPointer().SetHorizontalSize(3);
pdlg->m_ctrlChart1.Series(2).GetAsPoint().GetPointer().SetVerticalSize(3);
pdlg->m_ctrlChart1.Series(2).AddXY(2048,0,"",RGB(20,200,20));
pdlg->m_ctrlChart1.Series(0).SetName("Series0");
pdlg->m_ctrlChart1.Series(0).AddArray(iFFTSize,YValues,XValues);
pdlg->m_ctrlChart1.Series(1).AddArray(iFFTSize,YValues,XValues);
pdlg->m_ctrlChart1.GetExport().GetAsGIF().SetColorReduction(rmNetscape);
pdlg->m_ctrlChart1.GetExport().GetAsGIF().SetDitherMode(dmNearest);
pdlg->m_ctrlChart1.GetExport().GetAsGIF().SetHeight(444);
pdlg->m_ctrlChart1.GetExport().GetAsGIF().SetWidth(545);
pdlg->SendDlgItemMessage(IDC_DIFMASK_ED,WM_SETTEXT,NULL,(LPARAM)"int");
//----------------------------------------
dwResult2 = WaitForSingleObject(pdlg->hPlotEvents[1],INFINITE);
if (dwResult2 == (WAIT_OBJECT_0 + 0))
{
bDone=true;
}
return 0;
}
//wait thread exit
BOOL waitWithMessageLoop(HANDLE hEvent, DWORD dwTimeout)
{
DWORD dwRet;
do
{
dwRet = ::MsgWaitForMultipleObjects(1, &hEvent, FALSE, INFINITE, QS_ALLINPUT);
if (dwRet != WAIT_OBJECT_0)
{
MSG msg;
while (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
} while ((dwRet != WAIT_OBJECT_0) && (dwRet != WAIT_FAILED));
return TRUE;
}