Delphi Example Program


{ *************************************************************}

{ ** 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.