|
|
|
|
|
|
|
|
In fact,
you can implement this function by setting
multiple Variables, for example, you can
use 2 lines to simulate a discontinuous line.
Back to
Top |
|
|
|
|
|
|
You
can download a evaluation edition of the activex
control from this site and fully test it in your
project, it can be used freely for 60 days.
The evaluation edition is fully functional and
project compatible with the licensed edition.
Back to Top |
|
|
|
|
|
|
We will provide
a zip files(*.exe), it includes licensed control,
register information, register tools, example
project of VB and VC and demo. You can upzip it
and run the register tools(reigster.exe), and
register(unlock) the product with the register
information provided, then it is ok. A *.lic file
will be created and saved in the same directory
of your disk, please don't remove and edit it.
Back to Top |
|
|
|
|
|
|
You should delete all files
and information of the product if you will unregister
the product. The product can been registered(unlocked)
successfully when it is original state. In a simple
way, you can delete the old *.lic file and register(unlock)
it again. Back
to Top |
|
|
|
|
|
|
In order to let applications
use a new component, it need to be registered. This
simply means that you have to inform the OS telling
to look at the component file, in the directory
where it is placed. It is responsibility of the
OS to recognize the control and its exported properties
and methods in order to let other applications
access them. Back
to Top |
|
|
|
|
|
|
There
are several ways to register a control:
by
the use of the REGSVR32.EXE program, you can find
it in windows system directory:
to register a control
you simply have to digit the following command:
REGSVR32 D:\MyDirectory\meter.ocx and to unregister a
control:
REGSVR32/u D:\MyDirectory\meter.ocx
by use of the REGCTRLS.EXE
program, you can download it from this site.
Download 18KB
by using the ActiveX Control
Test Container: Start the program (it is part
of the Visual Studio Tools), select "File",
"Register cotrols..." from the menu.
You will see the follwing dialog box, which can
be used to register and unregister controls.
by
using other programs or directly via operating
system calls.
Back
to Top |
|
|
|
|
|
|
For Visual Basic:
The proper way to set pictures at run time is as follows:
Set Object.Picture = LoadPicture("c:\abc.bmp")
For Visual C++:
The following sample code illustrates how to use a dialog box to locate a picture at run-time and load the picture into the Trend's BackPicture property. The sample code assumes that the user clicks a button to launch the directory dialog. This method will work with any of the picture properties. Of course, you do not have to use the dialog box and can skip a great deal of this code if unnecessary. Pictures can be loaded at design time quite easily - without all this extra code! Pictures loaded at design time are compiled into the executable.
HRESULT _AfxCreateStreamOnFile(LPCTSTR pszPath, LPSTREAM* ppstm,LONG* plSize)
{
ASSERT(pszPath != NULL);
ASSERT(ppstm != NULL);
*ppstm = NULL;
if (plSize != NULL)
*plSize = 0;
CFileStatus fstatus;
CFile file;
HRESULT hr = E_FAIL;
LONG cb;
if (file.Open(pszPath, CFile::modeRead) &&
file.GetStatus(pszPath, fstatus) &&
((cb = fstatus.m_size) != -1))
{
HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, cb);
LPVOID pvData = NULL;
if (hGlobal != NULL)
{
if ((pvData = GlobalLock(hGlobal)) != NULL)
{
BOOL bRead = (file.ReadHuge(pvData, cb) == (ULONG)cb);
GlobalUnlock(hGlobal);
if (bRead && SUCCEEDED(hr = CreateStreamOnHGlobal(hGlobal, TRUE, ppstm)))
{
ASSERT(*ppstm != NULL);
if (plSize != NULL)
*plSize = fstatus.m_size;
hr = S_OK;
}
}
if (FAILED(hr))
GlobalFree(hGlobal);
}
else
hr = E_OUTOFMEMORY;
}
else
hr = E_ACCESSDENIED;
return hr;
}
void CVCDemoDlg::OnBitmapBUTTON()
{
CString strFilter, strTitle;
strFilter.LoadString(AFX_IDS_PICTUREFILTER);
strTitle.LoadString(AFX_IDS_PICTUREBROWSETITLE);
CFileDialog fdlg(TRUE, NULL, NULL,
OFN_FILEMUSTEXIST |
OFN_HIDEREADONLY |
OFN_PATHMUSTEXIST,
strFilter);
fdlg.m_ofn.lpstrTitle = strTitle;
int nResult = fdlg.DoModal();
SetFocus();
if (nResult != IDOK)
return;
CString strPath = fdlg.GetPathName();
LPSTREAM pstm = NULL;
LONG lSize;
HRESULT hr;
if (FAILED(hr = _AfxCreateStreamOnFile(strPath, &pstm, &lSize)))
{
UINT idsText;
CString strText;
CString strCaption;
switch (GetScode(hr))
{
case E_OUTOFMEMORY:
idsText = AFX_IDP_PICTURETOOLARGE;
break;
case E_ACCESSDENIED:
idsText = AFX_IDP_PICTURECANTOPEN;
break;
default:
idsText = AFX_IDP_PICTUREREADFAILED;
break;
}
AfxFormatString1(strText, idsText, strPath);
strCaption.LoadString(AFX_IDS_PICTURE_PPG_CAPTION);
MessageBox(strText, strCaption, MB_OK | MB_ICONEXCLAMATION);
SetFocus();
return;
}
ASSERT(pstm != NULL);
LPPICTURE pPict;
if (SUCCEEDED(OleLoadPicture(pstm, lSize, FALSE, IID_IPicture, (LPVOID *)&pPict)))
{
ASSERT(pPict != NULL);
LPPICTUREDISP pPictDisp = NULL;
if(SUCCEEDED(pPict->QueryInterface(IID_IPictureDisp,(LPVOID*)&pPictDisp)))
{
ASSERT(pPictDisp != NULL);
m_Trend1.SetRefBackPicture(pPictDisp); //Set backpicture for the control
pPictDisp->Release();
}
pPict->Release();
}
else
{
CString strText;
CString strCaption;
AfxFormatString1(strText, AFX_IDP_PICTURECANTLOAD, strPath);
strCaption.LoadString(AFX_IDS_PICTURE_PPG_CAPTION);
MessageBox(strText, strCaption, MB_OK | MB_ICONEXCLAMATION);
SetFocus();
}
pstm->Release();
}
Back to Top
|
|
|
|
|
|
|
For Visual Basic:
The evaluation version is project compatible with the licensed one.
Unregister the evaluation activex.
Register the licensed version activex.
Open your old project include the evaluation version, the old control will be replaced automatically.
Save the project.
IF the old version of the activex is not compatible with the newer version.
Unregister the old activex.
Register the new activex.
Open your project include the old activex, the form include the old one will not be loaded normally.
Delete the form include the old activex without save.
Select the new activex in the component list.
Add the form again, the old activex will be replaced with the new one.
Save the form.
For Visual C++:
Unregister the evaluation activex.
Register the licensed version activex.
Open your old project include the evaluation version, a message box pop up, warning some actrivex can not be instantiated.
Select the FileView page in your project workspace.
Delete generated .cpp and .h of the evaluation control, for instance _trend.cpp,font.cpp,picture.cpp,_trend.h,font.h,picture.h.
Delete these files from your project directory.
Execute menu "Add to project"->Compoent and Controls,add the licensed control to your project.
Drop new licensed control into your dialog.
Close and save your project.
Open .rc file with notepad, locate the dialog resources description,replace the classid of the evaluation with the classid of the licensed
control,Save the .rc file.
Open .dsw file with notepad.
Delete the classid of the evaluation control. Save the .dsw file.
Reopen your project.It is OK.
Back to Top |
|
|
|
|
|
Many users want to connect Trend activex to a database,for instance *.mdb, the sample code will do the trick!
DownLoad the example
Private Sub cmdLoadFromDatabase_Click()
Dim Db As Database, Rs As Recordset
Dim SQLTab As String
Dim Value As Double
Dim Time1 As Date
Trend1.ClearAll 'Clear the Trend ActiveX
SQLTab = "SELECT * FROM " & "ValueTab3sec10min" & " WHERE PointName = 'aa1' " & "ORDER BY ID" 'Set the table
Set Db = Workspaces(0).OpenDatabase("c:\TrendDemo\sec.mdb") 'Open a database
Set Rs = Db.OpenRecordset(SQLTab) 'Open the recordset
Rs.MoveLast
Time1 = Rs.Fields("Time") 'Get Max value of the X axis
Trend1.XMax = CDbl(Time1) 'Convert time datatype to double
Rs.MoveFirst
Time1 = Rs.Fields("Time") 'Get Min value of the X axis
Trend1.XMin = CDbl(Time1)
Trend1.SetXDisplay Trend1.XMin, Trend1.XMax 'Set the display area
Do While Not Rs.EOF 'Add all recorde to the trend
Value = Rs.Fields("Value")
Time1 = Rs.Fields("Time")
Trend1.AddXY 0, CDbl(Time1), Value
Rs.MoveNext
Loop
Rs.Close
Db.Close 'Close the database
Trend1.Refresh 'Refresh the Trend, in this case you should set the AutoRedraw property to FALSE
End Sub
Back to Top |
|
|
|
|
|
|
Some users reported the PrintPic method of Trend ActiveX can not work on some laser jet printers. We have got
this error and found these printers have trouble in supporting a standard windows API.
But the reason is not clear,may be caused by printer driver.
We have provided a solution. Directly output the Image to printer instead of using the PrintPic method.
VB Example:
Private Sub cmdPrint_Click()
Printer.PaintPicture Trend1.Image, 0, 0
End Sub
If you use Visual C++,please use the hDC property and StrechBlt function to output the Image to printer.
void CTrendDlg::OnPrint()
{
//Create the printer's dc
CPrintDialog pd(FALSE);
pd.GetDefaults();
HDC hdc = pd.CreatePrinterDC();
DOCINFO DI;
DI.cbSize = sizeof(DOCINFO);
DI.fwType = 0;
DI.lpszDatatype = NULL;//"Trend Chart";
DI.lpszDocName = "Trend Chart";
DI.lpszOutput = NULL;
RECT rctTrend;
::GetWindowRect((HWND)m_Trend1.GetHWnd(), &rctTrend);
long nWidth = rctTrend.right - rctTrend.left;
long nHeight = rctTrend.bottom - rctTrend.top;
//Adjust the picture size to the printer
int nScreenW = GetDeviceCaps((HDC)m_Trend1.GetHDC(), LOGPIXELSX);
int nScreenH = GetDeviceCaps((HDC)m_Trend1.GetHDC(), LOGPIXELSY);
int nPrintW = GetDeviceCaps(hdc, LOGPIXELSX);
int nPrintH = GetDeviceCaps(hdc, LOGPIXELSY);
float fRateX = float(nScreenW) / nPrintW;
float fRateY = float(nScreenH) / nPrintH;
StartDoc(hdc, (LPDOCINFO)&DI);
StartPage(hdc);
//::BitBlt(hdc, 0, 0, rctTrend.right - rctTrend.left, rctTrend.bottom - rctTrend.top, (HDC)m_Trend1.GetHDC(), 0, 0, SRCCOPY);
::StretchBlt(hdc, 0, 0,int(nWidth / fRateX) , int(nHeight / fRateY), (HDC)m_Trend1.GetHDC(), 0, 0, nWidth, nHeight, SRCCOPY);
EndPage(hdc);
EndDoc(hdc);
DeleteDC(hdc);
}
Back to Top |
|
|
|
|
|
|
|
If you only use the OCX in the dialog box |
|
Click the ResourceView tab to choose the resource edit.
Double-click the dialog's name to edit the dialog.
Right-click the dialog and choose Insert ActiveX Control... from the pop-up menu.
Choose the Control from the ActiveX control list and click OK.
Then insert the control into the dialog. |
If you want to use the OCX in your project |
|
Load the project.
Choose menu Project|Add To Project|Components and Controls...
Open the Registered ActiveX Control gallery.
Choose the Control and click Insert.
Visual C++ will generate several classes of the control,such as CMeter.
Then you can define variable of the type as CMeter. |
Back to Top
|
|
|
|
|
|
|
Normally, instantiation can be performed at design time by simply placing the component on a dialog rather than trying to "Create" the control dynamically at run time. However, there are occassions when developers are creating dialogs at run time and placing components on them. If you are doing something like this and absolutely cannot instantiate the component in your design environment, contact us and we can provide a new version - but only if you are NOT developing a container. If you are designing a true ActiveX container, then you will need to discuss a royalty arrangement with us.
Back to Top |
|
|
|
|
|
This sample will do the trick!
void CTrendDemoDlg::OnTimer(UINT nIDEvent)
{
double x,y,v[10][2];
int i=0;
VARIANT vArray;
SAFEARRAY *pArray;
//Speed
switch (Speed)
{
case 0: //normal
x += 0.1;
y = 8 * sin(x) + 3 * cos(x * 0.5);
m_Trend1.AddY(0, y);
break;
case 1: //fast
for(i=0;i<15;i++)
{
x += 0.1;
y = 8 * sin(x) + 3 * cos(x * 0.5);
m_Trend1.AddY(0, y);
}
break;
case 2: //really fast
pArray = (SAFEARRAY *) new char[sizeof(SAFEARRAY) + sizeof(SAFEARRAYBOUND)];
pArray->cDims = 2;
pArray->cbElements = 8;
pArray->rgsabound[0].cElements = 10;
pArray->rgsabound[0].lLbound = 0;
pArray->rgsabound[1].cElements = 2;
pArray->rgsabound[1].lLbound = 0;
pArray->pvData = (void *) v;
vArray.vt = VT_ARRAY | VT_R8;
vArray.parray = pArray;
for(i=0;i<10;i++)
{
x += 0.1;
v[i][0] = x * 10.;
v[i][1] = 7 * sin(x) + 4 * cos(x * 0.5);
}
m_Trend1.AddXYArray(0, &vArray);
break;
}
CDialog::OnTimer(nIDEvent);
}
Back to Top |
|
|
|
Why the Icon is not displayed on the AcitveX Panel when I use the menu Component->Import ActiveX Control in Delphi6/7 and C++Builder? |
|
|
Step by step:
1.Select menu Tools->Environment Options->Type Library.
2.Select "Ignore special CoClass Flags When Importing" item.
3.Select "Can Create" item.
4.Try to import the ActiveX, you will see the icon of the ActiveX control.
If you have already imported the control, please delete the two files .dcr and .pas in the Imports directory of Delphi first. Note: if you use Delphi6 , you need update to Delphi Update2, same as C++Builder.
Back to Top |
|
|
How to use the method GetValueFromBuf of Trend ActiveX to read data from the buffer? |
|
|
VB Exmaple:
Private Sub GetDataFromBuf()
Dim X As Double, Y As Double
Dim CurBufIndex As Integer
Dim i As Integer Trend1.VarID = 0
CurBufIndex = Trend1.VarLatestBufIndex
For i = 0 To CurBufIndex
Trend1.GetXYValueFromBuf 0, i, X, Y
MsgBox "X=" + CStr(X) + " Y=" + CStr(Y)
Next
End Sub
VC++ Exmaple:
void CTrend_getvalueDlg::OnButton2()
{
// TODO: Add your control notification handler code here
double x, y;
int CurBufIndex;
int i;
char temp[100];
m_Trend1.SetVarID(0);
CurBufIndex = m_Trend1.GetVarLatestBufIndex();
for(i = 0;i<=CurBufIndex;i++)
{
m_Trend1.GetXYValueFromBuf(0, i, &x, &y);
sprintf(temp,"x=%f, y=%f",x,y);
MessageBox(temp);
}
}
Back to Top
|
|
|
How to set the positions of the two sliders on x axis of Trend ActiveX? |
|
|
Some of users do not know how to set the positions of the two sliders on x axis. Actually the positions of the two sliders are determined by four properties: XMin, XDisplayMin, XMax and XDisplayMax.
XMin and XDisplayMin determine the position of left slider.
XMax and XDisplayMax determine the position of right slider.
XMax is increased automatically in realtime mode that usually keeps the latest x value. Do be careful to alter it (for example, you can set it to a value bigger than the latest x, otherwise some points will not be visible).
Back to Top
|
|
|
|
|
|