{ *************************************************************}
{ ** Description: Delphi example building one graph }
{ ** with the Real-Time Graphics Tools for Windows }
{ *************************************************************}
{Main work unit for program}
{ Delphi Unit file which supplies the TForm1
interface to autoscrx.pas }
unit Unit5;
interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes,
Graphics, Controls, Forms, Dialogs, Menus, ExtCtrls;
type
TForm1 = class(TForm)
MainMenu1: TMainMenu;
Start1: TMenuItem;
Timer1: TTimer;
procedure FormDestroy(Sender: TObject);
procedure Start1Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses autoscrx;
{$R *.DFM}
procedure TForm1.FormDestroy(Sender: TObject);
begin
WM_DestroyGraph;
end;
procedure TForm1.Start1Click(Sender: TObject);
begin
MM_CreateGraph(Form1.Handle, hinstance );
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
TimerRoutine;
end;
end.
{ Main work unit for program}
{$F+}
unit Autoscrx;
interface
uses WinTypes, WinProcs, messages,qcwin,qcwrt, rthook;
{ Exports }
procedure MM_CreateGraph (thwnd:HWND; tinst:THANDLE);
procedure WM_DestroyGraph;
procedure TimerRoutine;
implementation
{$R rtdemo}
const
ncount: INTEGER = 0;
NT = 2;
var
thData: HDATA; { handle to dynamic data set }
pDynGrDesc :PGRAPH_DEF; { pointer to graph descriptor }
hTags: HGLOBAL; { handle to tag names }
{ Forward Referenced functions }
procedure StartGraphs1 (pPageDesc:PPAGE_DEF); far; forward;
procedure DrawP1G1 (pGrDesc:PGRAPH_DEF;
thdc:HDC); far; forward;
procedure MM_CreateGraph (thwnd:HWND; tinst:THANDLE);
begin
{ page is created in the current window }
WGCreatePage (PAGE1, thwnd, tInst, AUTOBARS,
@StartGraphs1, PageMenu, C_LIGHTGRAY, MM_PROPORT,
0, PAGE_FULL, 0, 0, 780, 580);
end;
procedure WM_DestroyGraph;
begin
WRCleanup (TRUE); { clean up charting tools memory }
PostQuitMessage (0);
end;
procedure StartGraphs1 (pPageDesc:PPAGE_DEF);
begin
{ Initialize graph }
pDynGrDesc:= WGCreateGraph (pPageDesc,
@DrawP1G1,
{ points to function which builds graph }
0.005, 0.005, { window relative position }
0.995, 0.995,
C_LIGHTGRAY,
C_BLACK,
1); { border width in pixels }
end;
{ Builds the graph using Q-C Windows Charting Calls }
procedure DrawP1G1 (pGrDesc:PGRAPH_DEF; thdc:HDC);
var
hScr: array[0..AS_NH-1] of HGOBJ;
lpTags: LPSTR;
nLineColor: array[0..NT-1] of INTEGER;
nTraces :INTEGER;
i:INTEGER;
rLow, rHigh, rSetpoint :realtype;
rSampleInt, rRelResetInt:realtype;
begin
nTraces:= NT;
{ allocate global array for tags }
hTags:= GlobalAlloc (GHND, nTraces * TAGLEN);
lpTags:= GlobalLock (hTags);
{ initialize tags (channel names) }
lstrcpy (lpTags , Tank Level);
lstrcpy (lpTags + TAGLEN, Steam Flow);
{ define dynamic data set }
thData:= WRDefineDynDataSet (Auto Scroll,
nTraces, { # of traces }
volts, { units string }
lpTags, { tag names }
0); { no history buffer }
WGRaiseGraph (pGrDesc, RC_HIGH);
{ assign line colors }
for i:= 1 to nTraces - 1 do
nLineColor[i]:= (i mod 15) + 1;
{ set current font to Arial, 16 points, bold, italic }
WGSetTextByName (C_GREEN, Arial, 16,
TEXT_BOLD or TEXT_ITAL);
rSampleInt:= 0.1; { time between samples := 0.1 s }
rRelResetInt:= 0.8; { reset back 20 MOD }
rSetpoint:= 0.0; { set point value }
rHigh:= 1.5; { high alarm limit }
rLow:= - 1.75; { low alarm limit }
{ create an auto scroll graph }
WRSetAutoScrollGraph (pGrDesc, {graph descriptor }
thData, { handle to dynamic data set }
rSampleInt, { sample interval }
rRelResetInt, { relative reset }
- 2.0, 2.0, { minimum AND maximum values }
10.0, { range of independent variable }
GOD_SUBT_SCLINE, { scrolling lines }
2, { 2 digits after decimal point }
rSetpoint, { set point value }
rHigh, { high alarm value }
rLow, { low alarm value }
Seconds, { dependent axis title }
C_WHITE, { plotting area color }
@nLineColor, { line colors }
TRUE, { display dynamic values as text }
@hScr); { handles to individual objects }
{ are returned in this array }
GlobalFree (hTags); { free tags array }
end;
{ *** Timer routine simulates new data. ***}
procedure TimerRoutine;
var
rArg:realtype;
rNewVals: array[0..1] of realtype;
begin
{ if the graph window exists, continue }
if (not WGIsDescValid (pDynGrDesc)) then exit;
WGStart;
rArg:= M_PI * nCount;
{ new values }
rNewVals [0]:= sin (rArg / 1000) * 1.5 ;
rNewVals [1]:= cos (rArg / 333.0) * 1.3;
{ update the data set }
WRUpdateData (thData, @rNewVals, pDynGrDesc);
ncount:= ncount + 1;
if (nCount > 1000) then
nCount:= 0;
end;
begin
pDynGrDesc:= nil;
end.