|
I am not too familiar with Printing. How do I use the PrintGraph function?
Can you provide me with some sample codes?
Thanks
|
|
|
|
|
sorry I didn't want to post twice =(
|
|
|
|
|
i tried it with the following code pasted in the selfmade function of my view class, but all i get is an empty sheet of paper... =(
CPrintDialog dlgPrint(FALSE,PD_ALLPAGES,this);
if (dlgPrint.DoModal()==IDOK)
{
CDC dcPrint;
dcPrint.Attach(dlgPrint.GetPrinterDC());
DOCINFO myPrintJob;
myPrintJob.cbSize = sizeof(myPrintJob);
myPrintJob.lpszDocName = "My Printjob";
myPrintJob.lpszOutput = NULL;
myPrintJob.lpszDatatype = NULL;
myPrintJob.fwType = NULL;
if (dcPrint.StartDoc(&myPrintJob)>=0)
{
dcPrint.StartPage();
m_Graph[0].PrintGraph(&dcPrint);
dcPrint.EndPage();
dcPrint.EndDoc();
}
dcPrint.DeleteDC();
}
can anybody help?
|
|
|
|
|
i also tried
if ( pDC->IsPrinting() )
m_Graph[0].PrintGraph(pDC);
in the OnDraw function of my view class - same problem: all i get is an empty sheet of paper =(
|
|
|
|
|
I Have the same Problem. If you show in the Printgraph function, you will see that OnPaint function is used and in this function printing member of the DC is set to False.
I think, ( and I will test this), you must modify the function Printgraph and use a new function derived from on paint.
|
|
|
|
|
Sorry, but the new version indeed contains a printing bug.
In CXGraph::OnPaint replace everything above "clChartRect.left = clRect.left + m_nLeftMargin " with the following code :
CDCEx* pDC; <br />
CMemDC* pmdc = NULL;<br />
CPaintDC* pdc = new CPaintDC(this);<br />
CRect clRect, clChartRect;<br />
int nSaveDC;<br />
bool bMustDeleteDC = false;<br />
<br />
m_oldCursorPoint = CPoint(-1, -1);<br />
<br />
if (m_pPrintDC != NULL)<br />
{<br />
pDC = new CDCEx;<br />
pDC->Attach (m_pPrintDC->m_hDC);<br />
pDC->m_bPrinting = true;<br />
<br />
bMustDeleteDC = true;<br />
}<br />
else<br />
if(m_pDrawDC != NULL)<br />
pDC = (CDCEx*) m_pDrawDC;<br />
else<br />
{<br />
pDC = new CDCEx;<br />
bMustDeleteDC = true;<br />
}<br />
<br />
<br />
if (m_pPrintDC == NULL)<br />
{<br />
if (m_bDoubleBuffer)<br />
{<br />
pmdc = new CMemDC(pdc);<br />
pDC->Attach(pmdc->m_hDC);<br />
nSaveDC = pDC->SaveDC();<br />
pDC->m_bMono = false;<br />
pDC->m_bPrinting = false;<br />
pDC->m_bPrintPreview = false;<br />
}<br />
else<br />
{<br />
pDC->Attach(pdc->m_hDC);<br />
nSaveDC = pDC->SaveDC();<br />
pDC->m_bMono = false;<br />
pDC->m_bPrinting = false;<br />
pDC->m_bPrintPreview = false;<br />
}<br />
}<br />
<br />
m_oldCursorPoint = CPoint(-1, -1);<br />
<br />
if (pDC->m_bPrinting)<br />
clRect = m_clPrintRect;<br />
else <br />
GetClientRect(clRect);<br />
<br />
if (pDC->m_bMono)<br />
pDC->FillSolidRect(clRect, RGB(255,255,255));<br />
else<br />
pDC->FillSolidRect(clRect, m_crBackColor);<br />
Furthermore, replace erverything beginning with "pDC->RestoreDC(nSaveDC); " (at the end of the function) with :
if (nSaveDC)<br />
pDC->RestoreDC(nSaveDC);<br />
<br />
pDC->Detach();<br />
<br />
if (bMustDeleteDC && pDC)<br />
delete pDC;<br />
<br />
if (pmdc)<br />
delete pmdc;<br />
<br />
if (pdc)<br />
delete pdc;
Regards
Gunnar
|
|
|
|
|
many thanks, gunnar! it's a great tool you have written. best regards, greg.
|
|
|
|
|
printing preview still crashes. in debug mode VC6
|
|
|
|
|
|
When I do print preview, I only get a tiny graph on the up left corner? How do I fix that bug?
thanks
ahgu
|
|
|
|
|
I am not too familiar with Printing. How do I use the PrintGraph function?
Can you provide me with some sample codes?
Thanks
|
|
|
|
|
when i call create i get an unhandled exception
this is the line of code, modified slightly from the example.
m_Graph.Create(_T("XGraph"),_T(""), WS_CHILD|WS_VISIBLE, clRect, this, 1001);
i get the exceptiom
Unhandled exception at 0x1000b35e in testXGraph2.exe: 0xC0000005: Access violation reading location 0x00000020.
|
|
|
|
|
If you have the control inside a dialog you should relate it with an static control (a picture is ok) IDC_STATIC_PICTURE:
<br />
CWnd* pWnd = GetDlgItem(IDC_STATIC_PICTURE);<br />
pWnd->GetClientRect(clRect);<br />
m_Graph.Create(_T("XGraph"),_T(""), WS_CHILD|WS_VISIBLE, clRect, pWnd, IDC_STATIC_PICTURE);<br />
hope it helps,
Marc Soleda
|
|
|
|
|
i'm new to visual c++ and xgraph.
i keep getting the following error when i trying to implement a small demo of xgraph in a standard sdi app.
testXGraph2 error LNK2001: unresolved external symbol "public: virtual void __thiscall CtestXGraph2View::OnInitialUpdate(void)" (?OnInitialUpdate@CtestXGraph2View@@UAEXXZ)
i'm not sure what the problem is.
Also when i try to compile the demo program i get the following error
XGraphTest error LNK2019: unresolved external symbol "public: class CXGraphLabel & __thiscall CXGraph::InsertLabel(class ATL::CStringT<char,class strtraitmfc_dll<char,class="" atl::chtraitscrt<char=""> > >)" (?InsertLabel@CXGraph@@QAEAAVCXGraphLabel@@V?$CStringT@DV?$StrTraitMFC_DLL@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@@Z) referenced in function "protected: void __thiscall CPropertyView::OnInsertLabel(void)" (?OnInsertLabel@CPropertyView@@IAEXXZ)
and
XGraphTest error LNK2019: unresolved external symbol "public: void __thiscall CXGraphAxis::SetColorRange(int,double,double,unsigned long,unsigned long,class ATL::CStringT<char,class strtraitmfc_dll<char,class="" atl::chtraitscrt<char=""> > >,unsigned int)" (?SetColorRange@CXGraphAxis@@QAEXHNNKKV?$CStringT@DV?$StrTraitMFC_DLL@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@I@Z) referenced in function "public: void __thiscall CXGraphTestView::AddDataSerie(bool)" (?AddDataSerie@CXGraphTestView@@QAEX_N@Z)
any ideas with either of these two programs would be a great help.
|
|
|
|
|
try to paste your code in a sdi application with document-view support (a check box in step 1 of the app wizzard)
|
|
|
|
|
ok, thanks
solved most of the probs.
|
|
|
|
|
Rebuild Xgrapjic_src then you can get debug and release version.
You have to copy this two files to xgraphic-demo folder.
That is all.
|
|
|
|
|
Great work Gunnar & co!!
Is it possible to configure it to work like an oscilloscope? I mean, adding points dynamically and viewing just the last N points added.
Bye,
Marc.
|
|
|
|
|
This is the answer I note below...
Hi
Here is one solution for your reference.I guess that you want a dynamic chart in which X value is increasing with time and Y value is random or defined under your command.If it is,you can use setdata() to feed your requirements.
Following is some sample code FYI...
======================================================
void CXGraphDemoView::OnDrawChart()
{
// TODO: Add your command handler code here
// setup data
timer1=SetTimer(1000,10,NULL);
// m_Graph.GetXAxis(0).SetCurrentRange(-500,0,30);
}
void CXGraphDemoView::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
// for (int i = 0; i < VALCOUNT; i++)
if (nCount {
m_Values[nCount].fYVal = -85 + (( sin(nCount / 180.0 * 3.14115926) * 10));
m_Values[nCount].fXVal = nCount;
m_Graph.SetData (m_Values, nCount+1, 0, 0, 0);
m_Graph.GetYAxis(0).SetCurrentRange(-120,-40,10);
m_Graph.GetXAxis(0).SetCurrentRange(0,500,30);
if (nCount>500)
{
m_Graph.GetXAxis(0).SetCurrentRange(nCount-500,nCount,30);
}
m_Graph.Invalidate();
}
nCount++;
CView::OnTimer(nIDEvent);
}
void CXGraphDemoView::OnStopTimer()
{
// TODO: Add your command handler code here
if (timer1!=NULL)
{
KillTimer(timer1);
TRACE("Stopped.\n");
}
}
================================================================
At first you can allocate big enough array to contain your data(X/Y values) and initialized with zero.Then update the array values with pair of X/Y value and use SetData(,Count,) to increase count to update the graph data.You can get one dynamic chart floating with time.
Thanks for the author's great job!
Cheers!
Sam Zhao
|
|
|
|
|
Yeah, but there's a problem implied: the data buffer has to be so big or it has to increase dynamically and it's unavailable for an application running 24x7. I've modified your code to mantain and view a buffer of VALCOUNT elements:
<br />
void CXGraphDemoView::OnTimer(UINT nIDEvent) <br />
{<br />
bool bMoveRange = false;<br />
<br />
TDataPoint m_ValuesAux[VALCOUNT-1];<br />
if(nCount == VALCOUNT) <br />
{<br />
bMoveRange = true;<br />
nCount--;<br />
}<br />
if(bMoveRange)<br />
{<br />
memcpy(m_ValuesAux, &m_Values[1], sizeof(m_ValuesAux));
memcpy(m_Values, m_ValuesAux, sizeof(m_ValuesAux));<br />
}<br />
<br />
m_Values[nCount].fXVal = m_iGlobalCounter;<br />
m_Values[nCount].fYVal = ;<br />
<br />
m_Graph.SetData(m_Values, nCount+1, 0, 0, 0, false);<br />
<br />
if(bMoveRange)<br />
m_Graph.GetXAxis(0).SetCurrentRange(m_iGlobalCounter-VALCOUNT+1, m_iGlobalCounter,10); <br />
else<br />
m_Graph.GetXAxis(0).SetCurrentRange(0,VALCOUNT,10);<br />
<br />
<br />
nCount++;<br />
m_iGlobalCounter++;<br />
}<br />
Another item would be to disable the X-axis value labels. Can they be disabled?
Cheers,
Marc Soleda
|
|
|
|
|
Hi,
Yeah.You are right.Really this is a problem during floating chart.But I think the method that you dynamically increase the array size is not so efficient.As you know frequent memory reallocation such as realloc() is not recommended here.
From my side I am trying to implementing one floating chart versus time.I also need one big engough arry to contain the data.My idea is I create one function which is likely with C style funciton realloc().I named it ReNew() as following for your reference.
////////////////////////
template <class t="">
T* ReNew(T* p,long nSize,long nGranularity)
{
T* p1=new T[nSize+nGranularity];
memset(p1,0,nSize+nGranularity);
memcpy(p1,p,nSize);
delete[] p;//Is it necessary???Yeah.
return p1;
}
///////////////////////
In case that you have to increase you array size.You can prepare another big enough block to meet the increasing memory need.With one Granularity variable you can control the mem reallocation.You can do this in you data updating section which is a good place to control Mem need.
Cheers
Sam Zhao
|
|
|
|
|
Yeah, maybe in your case, that you need a historical view of data it's better but in my one, where I need the current view, it's enough to reorganize the array, copying the VALCOUNT-1 values to an auxiliar array. I'm not increasing the array size dynamically.
Cheers,
Marc Soleda
|
|
|
|
|
Whooo.....
I see...Really it is very different case that we face....I need one historical chart view of all the record.
Cheers.
Sam Zhao
|
|
|
|
|
1. precompiled header error
go to the "project" -> "settings" menu, choose "settings for all configurations", choose the "C/C++" screen and there the category "precompiled headers". select the second radio button for using precompiled headers autommaticly with the header "stdafx.h"
2. other build problems
try to build a "Win32 Release" or "Win32 Debug" instead of a "Win32 Unicode Release" or "Win32 Unicode Debug". For this go to "build" -> "set active configuration" menu and choose "XGRAPH - Win32 Release" or "XGRAPH - Win32 Debug"
3. doubleclick / properties bug:
search for "cbFillCurve" in CurveDlg.cpp, CurveDlg.h and resource.h, and comment out all the lines including this string.
4. background-redrawing bug:
go to XGRAPH.cpp, search for the string "pmdc = new CMemDC(pdc)" (should be about line 920), comment it out and add the four following lines insetead of it:
CRect empty, client;
GetClientRect( client );
empty.SetRectEmpty();
pmdc = new CMemDC(pdc, empty, client);
hope it could help. regards from Lake Constance, greg.
|
|
|
|
|
Hi,Sir
Thanks for your message!Under your steps I got successful results!
Cheers!
Sam Zhao
|
|
|
|
|