Home | Downloads | Support | Buy Now | Top Users | Company
 
Instrumentation Pack
 
Components
Animation
AirGauge
AniLine
Annunciator
Gauge
Indicator
Knob
Led
Meter
NumberLED
Odometer
Percent
Selector
Slider
Toggle
Trend

Application
Comport Wizard

Bundled Products
OPCWare
HMITalk
 
Links
Developersdex
 

.NET | ActiveX | VCL

General | Web

  Some of users ask how to draw a discontinuous line on Trend control?
How does the evaluation edition work?
What shall I do when I get the licensed product?
I could not re-register the product when I re-install it?
Why to register a control?
How to register/unregister a control?
How do I load a picture property at run time?
How do I replace the evaluation control in the project with the licensed one, without change the project?
How to connect TREND ActiveX to a database?
Why the PrintPic method of Trend ActiveX can not work on some laser jet printers?
How can I load the ActiveX in Visual C++?
I am trying to create one of your components dynamically. It runs fine on my machine, but it can not work property on an end-user's  machine, I get a licensing error message. What am I doing wrong?
How do I use the AddXYArray method of the TREND activex in Visual C++?
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?
How to use the method GetValueFromBuf of Trend ActiveX to read data from the buffer?
How to set the positions of the two sliders on x axis of Trend ActiveX?
  Some of users ask how to draw a discontinuous line on Trend control?

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

How does the evaluation edition work?
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
What shall I do when I get the licensed product?
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
I could not re-register(unlock) the product when I re-install it?
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
Why to register a control?
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
How to register/unregister a control ?

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

How do I load a picture property at run time?

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

How do I replace the evaluation control in the project with the licensed one,without change the project?

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

How to connect TREND ActiveX to a database?
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
Why the PrintPic method of Trend ActiveX can not work on some laser jet printers?
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

How can I load the ActiveX control in Visual C++?
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

I am trying to create one of your components dynamically. It rus fine on my machine, but it can not work properly on an end-user's machine, I get a licensing error message. What am I doinig wrong?
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
How do I use the AddXYArray method of the TREND activex?
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

CSTSOFT All rights reserved.