Quadtech Associates

Old MS Code


PROGRAM READ_MSD-DATA;
{====================================================================
  This Delphi unit contains routines to access and manipulate data 
    from Hewlett-Packard MSD Data Files.  Derived from published
      Hewlett-Packard documentation.  © Quadtech Associates, 1997.
=====================================================================}

unit Hpunit3;

interface

Uses StLArr,SysUtils, Dialogs;  //uses TurboPower SysTools StLArr
                                
Type
 Byte = 0 .. 255;
 String80 = String[80];  {for filenames}
 gTicType
 Int_File_Type = File of SmallInt;

 Header_Info_Type = Record
   File_num_Str : String[3];
   File_String : String[19];
   Data_name : String[61];
   Misc_info : String[61];
   Operator : String[29];
   Date_time : String[29];
   Inst_model : String[9];
   Inlet : String[9];
   Method_File : String[19];
   File_type : LongInt;
   Seq_index : SmallInt;
   Als_bottle : SmallInt;
   Replicate : SmallInt;
   Dir_ent_type : SmallInt;
   Dir_Offset : LongInt;
   Data_Offset : LongInt;
   Run_Tbl_Offset : LongInt;
   Norm_Offset : LongInt;
   Extra_Records : SmallInt;
   Num_Records : LongInt;
   Start_rTime : LongInt;
   End_rTime : LongInt;
   Max_Signal : LongInt;
   Min_Signal : LongInt;
  End;

 File_Header_Type = Record
   Info : Header_Info_Type;
   Filler: Packed Array [1..(512 - SizeOf (Header_Info_Type))]
           of Byte;
  End;

 Spec_Rec_Type = Record
   NumWds : SmallInt;
   RetTime : Longint;
   WdsLess3 : SmallInt;
   DataType : SmallInt;
   Status : SmallInt;
   NumPks : SmallInt;
   BasePk : Word;
   BaseAb : SmallInt;
  End;

 Mass_Abund_Type = Packed Record
   Mass : Word;
   Abund : Longint;
  End;

  Function SwapLong (Incoming:LongInt):LongInt;
  Function SwapDble (Incoming:Double):Double;
  Function Unpack (Incoming:Word):LongInt;
  Procedure Read_Data_Header (File_Name : String;
                              Var Data_Header : File_Header_Type);
  Procedure Get_Tic (File_Name:String; DirOff:LongInt;
                     NumRecs:LongInt);
  Procedure Get_Spec_Head (File_Name:String; DirOff:LongInt;
                           Var theRTime:LongInt;
                           Var SpecHead:Spec_Rec_Type;
                           Var TotAb:LongInt);
  Procedure Get_Spec_Data (File_Name:String; DirOff:LongInt;
                           SpecRecs:SmallInt;Caller:SmallInt);

implementation

{ ===================== Variable Declarations ==================== }

 Var
  Header : File_Header_Type;
  SwapInt : LongInt;
  TheDir_Offset : LongInt;
  Data_File : Int_File_Type;
  File_Name : String;
  Output_File_Name : String;
  NumRecs, DirOff: LongInt;
  SpecRecs : SmallInt;
  ThisArray: array [1..3] of LongInt;
  gTicType:TStLArray;
  MA,MD,ME:Array[1..1000] of Mass_Abund_Type;

{ ========================== PROCEDURES ============================ }

  Function SwapLong (Incoming:LongInt):LongInt;
   { This routine swaps type LongInt variables.  These variables 
     are all stored in reverse byte order.  
     Last Edited: Dec 2, 1995}
   type
    AType = Array[1..4] of Byte;
   var
    i,j:Integer;
    A1,A2:AType;
    L2: Longint;
   begin
     A1:=AType(Incoming);
     j:=4;
     for i:=1 to 4 do
      begin
       A2[j]:=A1[i];
       j:=j-1;
      end;
     L2 := LongInt(A2);
     SwapLong := L2;
   end;

 {===================================================================}
  Function SwapDble (Incoming:Double):Double;
   { This routine swaps type Double variables.  
     Last Edited: Dec 2, 1995.}
   type
    AType = array[1..8] of Byte;
   var
    i,j:Integer;
    A1,A2:AType;
   begin
     A1:=AType(Incoming);
     j:=8;
     for i:=1 to 8 do
      begin
       A2[j]:=A1[i];
       j:=j-1;
      end;
     SwapDble:=Double(A2);
   end;

 {===================================================================}
  Function Unpack (Incoming:Word):LongInt;
   { This routine is used to unpack HP Packed-Abundance values.  The
     HP Packed-Abundance value is in a 16-bit (unsigned) integer such
     that the two high-order bits are the scale and the remaining 14
     bits are the mantissa.  Then abundance = mantissa * (8 ^ scale).
     Last edited on June 7, 1997}
   var
    J : Integer;
   begin
     J:=HI(Incoming) DIV 64;
     Case J of
      0: J:=1;
      1: J:=8;
      2: J:=64;
      3: J:=512;
     end;
    Unpack := (Longint(HI(Incoming) AND 63)*256 + LO(Incoming))*J;
   end;

 {===================================================================}
  Procedure Read_Data_Header (File_Name : String;
                             Var Data_Header : File_Header_Type);
  {  This routine is used to assign file labels and read & store the
     Data Header information from the HP data file.
     Last edited December 2, 1995 }
  var
   Header_File : file of File_Header_Type;
   begin
    try
     Assign (Header_File, File_Name);
     Reset (Header_File);
     Read (Header_File, Data_Header);
     Close (Header_File)
    except
     MessageDlg('Error in accessing file.',
               mtInformation,[mbOk], 0);
     Close(Header_File);
     exit;
    end;
   end;

 {===================================================================}
  Procedure Get_Tic (File_Name:String; DirOff:LongInt;
                    NumRecs:LongInt);
{ Procedure to obtain the Tic data from the file.  These data are
  extracted from the directory records which also provides offset
  information for individual spectra.  There are 3 longints per record
  in the following order: (1)file offset; (2)RT;(3) Total abundance.
  Last edited Dec 6, 1995 }
  var
   Tic_File: file of SmallInt;
   TheEntry: array [1..2] of SmallInt;
   I, J, k:SmallInt;
  begin
   Assign (Tic_File, File_Name);
   Reset (Tic_File);
   Seek (Tic_File, DirOff - 1);
   If (Assigned(gTicType)) then gTicType.Free;
   gTicType := TStLArray.Create(NumRecs+1,SizeOf(ThisArray));
   gTicType.ElementsStorable := True;
   k:=0;
   for I:=1 to NumRecs do
    begin
     for J:= 1 to 3 do
      begin
       Read (Tic_File, TheEntry[1]);
       Read (Tic_File, TheEntry[2]);
       ThisArray[J]:= SwapLong(LongInt(TheEntry));
      end;
     gTicType.Put(i,ThisArray);
     k:=k+1;
     if k= 10 then
      begin
       k:=0;
       Form1.Label14.Caption:=IntToStr(I);
       Form1.Label14.Refresh;
      end;
    end;
   Close(Tic_File);
  end;

 {===================================================================}
  Procedure Get_Spec_Head (File_Name:String; DirOff:LongInt;
                           Var theRTime:LongInt;
                           Var SpecHead:Spec_Rec_Type;
                           Var TotAb:LongInt);
  { Procedure to recover a selected spectrums Header information. 
    This is then used by the Get_Spec_Data procedure below.
    Last edited  December 23, 1995 }
  var
   Spec_File: file of SmallInt;
   RTime: array [1..2] of SmallInt;
   tStr:String;
   RT:Single;
  begin
   Assign (Spec_File, File_Name);
   Reset (Spec_File);
   Seek (Spec_File, DirOff - 1);
   Read (Spec_File, SpecHead.NumWds);
   SpecHead.NumWds := Swap(SpecHead.NumWds);
   Read (Spec_File, RTime[1]);
   Read (Spec_File, RTime[2]);
   theRTime := SwapLong(Longint(RTime));
   Read (Spec_File, SpecHead.WdsLess3);
   SpecHead.WdsLess3 := Swap(SpecHead.WdsLess3);
   Read (Spec_File, SpecHead.DataType);
   SpecHead.DataType := Swap(SpecHead.DataType);
   Read (Spec_File, SpecHead.Status);
   SpecHead.Status := Swap(SpecHead.Status);
   Read (Spec_File, SpecHead.NumPks);
   SpecHead.NumPks := Swap(SpecHead.NumPks);
   SpecRecs := SpecHead.NumPks;
   Read (Spec_File, SmallInt(SpecHead.BasePk));
   SpecHead.BasePk := Swap(SpecHead.BasePk);
   Read (Spec_File, SpecHead.BaseAb);
   TotAb:=Unpack(Swap(SpecHead.BaseAb));
   Close (Spec_File);
   RT:=theRTime/60000;
  end;

 {===================================================================}
  Procedure Get_Spec_Data (File_Name:String; DirOff:LongInt;
                          SpecRecs:SmallInt; Caller:SmallInt);
  { Procedure to recover the mass & abundance information for a
    spectrum and store it in a typed-array (MA).  NOTE: the array
    dimensions here are only temporary.  This should be changed to
    dynamically alocate memory for the array on the heap using size
    information from the Get_Spec_Head call.
    Last edited on June 7, 1997 }
  var
   Spec_File: file of Word;
   I, Incoming : Word;
  begin
   Assign (Spec_File, File_Name);
   Reset (Spec_File);
   Seek (Spec_File, (DirOff-1) + SizeOf(Spec_Rec_Type) DIV 2);
   If Caller=0 then     {standard procs (Not MDA)}
    begin
     MA[0].Abund:=0;
     for I := 1 to SpecRecs do
      begin
       Read (Spec_File, Incoming);
       MA[I].Mass := Swap(Incoming);
       Read (Spec_File, Incoming);
       MA[I].Abund := Unpack(Swap(Incoming));
      end;
    end
   else If Caller=1 then       {MDA Call}
     for I := 1 to SpecRecs do
      begin
       Read (Spec_File, Incoming);
       MD[I].Mass := Swap(Incoming);
       Read (Spec_File, Incoming);
       MD[I].Abund := Unpack(Swap(Incoming));
      end
   else                        {EXTion call}
     for i:=1 to SpecRecs Do
       begin
       Read (Spec_File, Incoming);
       ME[I].Mass := Swap(Incoming);
       Read (Spec_File, Incoming);
       ME[I].Abund := Unpack(Swap(Incoming));
      end;
   Close (Spec_File);
  end;
 

PROGRAM SCIEXAPI-IIIREAD;

{The purpose of this program is to read original Sciex API III   }
{quantitation data files (zipd)collected on the Macintosh system }
{(with Motorola CPU). Compiled in ThinkPASCAL for the Macintosh  }
{on  April 23, 1993.  © Quadtech Associates, 1993.               }

CONST
 BASE = 128;
 KEEP_ON = 1;
 QUIT = 2;

VAR
 gEndit, gIsOpen: boolean;
 gResFile, gHor, gVer, gCnt, gSrcFile: Integer;
 gNMass, gNScans: Integer;
 gtheWindow: WindowPtr;
 gReply: SFReply;
 gRect: Rect;
 gS: str255;

{----------------------- PROCEDURES ----------------------- }

PROCEDURE Windowlnit;
BEGIN
 gtheWindow := GetNewWindow(Base, NIL, WindowPtr(-1));
 ShowWindow(gtheWindow);
 SetPort(gtheWindow);
 InitCursor;
 gEndit:=false;
END;

{This procedure calls a filename and stores the filename and volume }
{reference numbers in a global record accessed as gReply.fName and  }
{gReply.vRefNum, respectively. The typelist is set to ZIPD to access}
{only ZIPD Sciex Data File types, and the numtypes is set to 1      }

{---------------------------------------------------------}
PROCEDURE GetFileName (VAR replyPtr: SFReply);
VAR
 Apoint: Point;
 typelist: SFTypeList;
 numtypes: integer;
BEGIN
 Apoint.h := 100;
 Apoint.v := 100;
 typelist[0] := 'ZIPD';
 numtypes := 1;
 SFGetFile(Apoint, ", NIL, numtypes, typelist, NIL, replyPtr);
END;

{---------------------------------------------------------}
PROCEDURE DoError (msg: STRING; theSrc: Integer);
VAR
 err: OSerr;
 dummy: longint;
BEGIN
  Moveto(150, 350);
  WriteDraw('ERROR: ', msg);
  CloseResFile(gResFile);
  {dangerous to FSClose a closed file so test if open & if so Close}
  IF gIsOpen THEN
    dummy := FSClose(theSrc);
  err := NoteAlert(129, NIL);
  Halt;
END;

{---------------------------------------------------------}
PROCEDURE MoveIt (VAR VSet: Integer; VAR HSet: Integer;
                      VI, HI:Integer);
BEGIN
 VSet := VSet + VI;
 HSet := HSet + HI;
 Moveto(HSet, VSet);
END;

{Procedure to access mass intensity data}
{---------------------------------------------------------}
PROCEDURE GetData;
TYPE
 RealPtr = ^Real;
VAR
 DataPtr: RealPtr;
 Offset, Buff: Longint;
 i, j: Integer;
 A: ARRAY[1..8] OF Real;
 err: OSerr;
 watch: cursHandle;
BEGIN
  if NOT gIsOpen then
   BEGIN
    gEndIt;
    Exit;
   END;
  watch := GetCursor(4);
  SetCursor(watch^^);
  {set Buffer size and data offset based on # of masses}
  Buff := Sizeof(Real);
  Offset := Sizeof(Real) * gNMass;
  Ptr(DataPtr) := NewPtr(Sizeof(Real));
  {Process each scan in file}
  FOR i:= 1 TO gNScans DO
   BEGIN
    FOR j:= 1 TO gNMass DO
     {read each MRM mass pair into DataPtr and copy to array}
     BEGIN
      err := FSRead(gSrcFile, Buff, Ptr(DataPtr));
      A[j] := DataPtr^;
      {---------------------------------------}
      {A[j] is an element in an array of Reals}
      { process data here - print,store, etc  }
      {---------------------------------------}
     END;
   END;
END;

{Main routine here.  Declares three Record types for the 4 resources }
{accessed: GRUP, HEAD, and STAT (TEXT doesn't need a Record structure}
{Additional types are declared for STATArrayType(a 23 element array  }
{of StatType)and a ScanIndex Type which is declared but not used in  }
{this program.  The Resources are accessed sequentially and a Handle }
{is assigned which is then doubly dereferenced to access the records.}
{After printing the relevant data in each section, the Handle is     }
{released and the next resource is accessed.                         }

{---------------------------------------------------------}
PROCEDURE DoFile;
 TYPE
  GroupType = RECORD
    StartTime: Longint;
    StepSize: Real;
    ScanType: Integer;
    FirstScan: Integer;
    NumScans: Integer;
    NumMasses:Integer;
    MaxTicScan: Integer;
    TicMax: Real;
   END;
  HeadType = RECORD
    Name: PACKED ARRAY[1..20] OF Char;
    OrigiD: PACKED ARRAY[1..6] OF Char;
    Day: Integer;
    Month: Integer;
    Year: Integer;
    totScans: Integer;
    beginTime: Longint;
    lastTime: Longint;
   END;
  ScanIndex = RECORD
    offset: Longint;
    startTime: Real;
   END;
  StatType = RECORD
    ShortName: PACKED ARRAY[1..6] OF Char;
    LongName: PACKED ARRAY[1..32] OF Char;
    Flag: Integer;
    Value: Real;
   END;
  StatArrayType = ARRAY[1..23] OF StatType;
  DataArray = ARRAY[1..100] OF Real;
VAR
  i,j,z,err,srcFile,dummy,ScanT:Integer;
  VSet, HSet, VI, HI, theFlag: Integer;
  offset: Longint;
  Step, SSD, ScanRate, theValue: Real;
  fGroup: GroupType;
  fHead: HeadType;
  fStat: StatArrayType;
  fScan: Scanindex;
  theResult, DType: integer;
  S, S1: STRING;
  theString: STRING[6];
  theDate, theTime: Str255;
  UseIt: StatType;
  testC: PACKED ARRAY[1 ..4] OF Char;
  theS: ARRAY[1..8] OF STRING;
  bufSize, headerSize, runTime: longint;
  ResH, docText, IHandle: Handle;
  fGroupHandle, fHeadHandle, fStatHandle, fScanHandle: Handle;
  fGroupPtr: ^GroupType;
  fHeadPtr: ^HeadType;
  fStatPtr: ^StatArrayType;
  fScanPtr: ^Scan Index;
  DataPtr: ^DataArray;
  MI: DataArray;
  IRect, r1: Rect;
BEGIN
{Call GetFileName and store the selected file. The filename and      }
{volume reference number are displayed. Then Open the file and return}
{a file handle in srcFile. Error checking is through the returned    }
{value. The current volume must be set before accessing the resource }
{fork (only the data fork has been opened at this point). Then check }
{size of the file with the GetEOF function and store the result in   }
{bufSize of type longint.  Open the resource fork with a file handle }
{returned in gResFile and process selected resources.                }

 GetFileName(gReply);
 IF gReply.good <> True THEN
  Halt;
 s := concat('Filename: ', gReply.fName);
 gHor := 20;
 gVer := 20;
 moveto(gHor, gVer);
 SetRect(r1, 5, 5, 600, 500);
 EraseRect(r1);
 TextMode(srcCopy);
 WriteDraw(s);
 gVer := gVer + 20;
 moveto(gHor, gVer);
 I:= (FSOpen(gReply.fName, gReply.vRefNum, gsrcFile));
 IF I <> 0 THEN
  BEGIN
   IF i = -43 THEN
     Halt
   ELSE
    BEGIN
     si := concat('Cannot open file. Error Code: ', Stringof(i));
     DoError(sl, gsrcFile);
    END;
  END;
{File was opened without error - first set the File Open variable}
 gIsOpen := True;
 err := SetVol(NIL, gReply.vRefNum);
 IF err <> 0 THEN
  BEGIN
   s := concat(' in call to SetVol. Error number was ',
        Stringof(err));
   DoError(s, gsrcFile);
  END;
{SetVol Occured without error}
 err := GetEOF(gsrcFile, bufSize);
 IF err = 0 THEN
  BEGIN
   si := Stringof(bufSize);
   s := concat('Data Fork Size: ', si, bytes');
   WriteDraw(s);
  END
 ELSE
  BEGIN
   s := concat(' in call to GetEOF. Error number was ',
        Stringof(err));
   DoError(s, gsrcFile);
  END;
{GetEOF occured without error}
gResFile := OpenResFile(gReply.fName);
IF gResFile = -1 THEN
 BEGIN
  s := ('in call to OpenResFile.'); DoError(s, gsrcFile);
 END;
ResH := GetResource('TEXT', 1001);
{Note: in ZIPD files 1000 is generic; the others refer to periods - }
{e.g. 1001,1002, etc.  This program accesses only one period, 1001  }
IF ResH <> NIL THEN
 BEGIN
  SetRect(gRect, 10, 60, 300, 400);
  {Need to lock this rascal first}
  HLock(ResH);
  TextBox(Ptr(ResH^), GetHandleSize(ResH), gRect, 0);
  HUnlock(ResH);
  ReleaseResource(ResH);
 END
ELSE
 DoError(' in Accessing TEXT Resource', gsrcFile);
ResH := GetResource('GRUP', 1001);
IF ResH <> NIL THEN
 BEGIN
  HLock(ResH);
   {Coerce the fGroupPtr to a Pointer type and assign to}
   {dereferenced ResH Handle}
  Ptr(fGroupPtr) := ResH^;
   {assign pointer to fGroup}
  fGroup := GroupType(fGroupPtr^);
   {can now access fields in the fGroup Record}
  Step := (fGroup.StepSize);
  ScanT := fGroup.ScanType;
  CASE fGroup.ScanType OF
    17:  theS[2] := 'Q1 MI';
    18:  theS[2] := 'Q3 MI';
    19:  theS[2] := 'MRM';
  OTHERWISE
    {must be a spectrum scantype so can't use MacQuan}
    theS[2] := 'Not Quantifiable';
  END;
  IF fGroup.ScanType = 19 THEN
   {MRM. So correct for Parent-Daughter pair in Numlons count}
    gNMass := fGroup.NumMasses DIV 2
  ELSE
   gNMass := fGroup.NumMasses;
  gNScans := fGroup.NumScans;
  HUnlock(ResH);
  ReleaseResource(ResH);
  Vset := 60;
  HSet := 300;
  VI := 16;
  HI := 0;
  MoveIt(VSet, HSet, VI, HI);
  WriteDraw('Step Size: ', Step : 4 : 3);
  MoveIt(VSet, HSet, VI, HI);
  WriteDraw('Type of Analysis: ',theS[2]);
  MoveIt(VSet, HSet, VI, HI);
  WriteDraw('Number of Ions Monitored: ', gNMass : 2);
  MoveIt(VSet, HSet, VI, HI);
  WriteDraw('Total Scans: ', gNScans);
  gVer := VSet;
 END
ELSE
 DoError(' in Accessing GROUP Resource', gsrcFile);
ResH := GetResource('HEAD', 1000);
IF ResH <> NIL THEN
 BEGIN
  HLock(ResH);
    {same as above}
  Ptr(fHeadPtr) := ResH^;
  fHead := Headtype(fHeadPtr^);
  SSD := fHead.lastTime / fHead.totScans;
  ScanRate := fHead.totScans / fHead.lastTime;
  runTime := fHead.lastTime;
  IUDateString(fHead.beginTime, longdate, theDate);
  IUTimeString(fHead.beginTime, False, theTime);
  HUnlock(ResH);
  ReleaseResource(ResH);
  Vset := 0;
  HSet := 300;
  VI := 20;
  HI := 0;
  MoveIt(VSet, HSet, VI, HI);
  WriteDraw('Date of Analysis:   the Date);
  MoveIt(VSet, HSet, VI, HI);
  WriteDraw('Time of Analysis:   theTime);
  VSet := gVer;
  MoveIt(VSet, HSet, VI, HI);
  WriteDraw('Run Time (seconds): ', RunTime : 5);
  VI := 16;
  MoveIt(VSet, HSet, VI, HI);
  WriteDraw('Scans per second: ScanRate : 5 : 1);
  MoveIt(VSet, HSet, VI, HI);
  WriteDraw('Single scan duration: ', SSD : 5 : 2, ' seconds');
  MoveIt(VSet, HSet, VI, HI);
 END
ELSE
 DoError(' in Accessing HEAD Resource', gsrcFile);
ResH := GetResource('STAT', 1000);
  {Note - only one STAT (State File) Resource -- so 1000}
IF ResH <> NIL THEN
 BEGIN
  HLock(ResH);
  Ptr(fStatPtr) := ResH^;
  fStat := StatArrayType(fStatPtr^);
  HSet := 260;
  gVer := Vset;
  FOR i:=1 TO 8 DO
   BEGIN
    UseIt := fStat[i];
    MoveIt(VSet, HSet, VI, HI);
    CASE i OF
     2, 7, 8:
       WriteDraw(UseIt.shortName : 3, ' ', UseIt.Value : 8 : 2);
    OTHERWISE
       WriteDraw(UseIt.shortName : 2, '   ', UseIt.Value : 8 : 2);
    END;
   END;
  HSet := 370;
  VSet := gVer;
  FOR i:= 9 TO 16 DO
   BEGIN
    UseIt := fStat[i];
    MoveIt(VSet, HSet, VI, HI);
    CASE i OF
     13, 14:
      WriteDraw(UseIt.shortName :3, ' ',UseIt.Value :8 :2);
    OTHERWISE
      WriteDraw(UseIt.shortName :2, ' ',UseIt.Value :8 :2);
    END;
   END;
  HSet := 480;
  VSet := gVer;
  FOR i:= 17 TO 23 DO
   BEGIN
    UseIt := fStat[i];
    MoveIt(VSet, HSet, VI, HI);
    CASE i OF
     19:
      {This is the CC which is entered as a 4 byte Packed Array of}
      {Char - however, reading it here as a Real. So 'calculate' the}
      {true result based on the float value}
      BEGIN
       IF UseIt.Value > 2e-09 THEN
         UseIt.Value := 10
       ELSE
         UseIt.Value := 1;
       WriteDraw(UseIt.shortName : 2, '   ', UseIt.Value
      END;
     20:
       CASE ScanT OF
         19, 22, 23, 24:
         {This is MRM, Daughter, Parent or Constant Neutral}
         {'cheating' again here to show the 'proper' output}
           WriteDraw(UseIt.shortName : 2, '  Ar');
         OTHERWISE
           WriteDraw(UseIt.shortName : 2, '  OFF');
       END; {Case of ScanT}
         22, 23:
           WriteDraw(UseIt.shortName : 3, ' ', UseIt.Value : 8 : 2);
         OTHERWISE
          WriteDraw(UseIt.shortName : 2, '   ', UseIt.Value : 8 : 2);
       END;
     END;
    HUnlock(ResH);
    ReleaseResource(ResH);
  END
ELSE
  DoError(' in Accessing STAT Resource', gsrcFile);
CloseResFile(gResFile);
GetData;
{close and end program}
IF gIsOpen THEN
 BEGIN
  gIsOpen := False;
  err := FSClose(gsrcFile);
  gEndIt;
 END;
END;
{---------------------------------------------------------}
PROCEDURE GetEvent;
 BEGIN
  WHILE NOT gEndit DO
   BEGIN
    DoFile;
   END;
 END;
{==========================MAIN===========================}
BEGIN
  Windowinit;
  GetEvent;
END.
    
   
Back

Copyright © 2019 Quadtech Associates, Inc.