home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 14 / CDACTUAL.iso / cdactual / demobin / share / program / Pascal / TVDMX.ZIP / DMXGIZMA.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1993-04-01  |  19.7 KB  |  792 lines

  1.  
  2. {■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■}
  3. {                            }
  4. {    DMXGIZMA  --constants, variables and functions    }
  5. {    tvDMX     --data editing project (ver 2.x)    }
  6. {                            }
  7. {    Copyright (c) 1992,93   Randolph Beck        }
  8. {                P.O. Box  56-0487    }
  9. {                Orlando, FL 32856    }
  10. {                CIS:  72361,753        }
  11. {                            }
  12. {■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■}
  13.  
  14. Unit DMXGIZMA;
  15.  
  16. {$V-,X+,O+,D+,B-,R- }
  17.  
  18. interface
  19.  
  20. uses  Objects, Drivers, Views, Dialogs, App, RSet;
  21.  
  22. {$DEFINE tvDMX2A }
  23.  
  24. const
  25.     { tvDMX commands }
  26.     cmDMX        = FirstCmdNum;  { defined in RSET.PAS }
  27.  
  28.     cmDMX_RollCall    = cmDMX +  1;
  29.     cmDMX_Ack        = cmDMX +  2;
  30.     cmDMX_FieldAltered    = cmDMX +  3;
  31.     cmDMX_Draw        = cmDMX +  4;
  32.     cmDMX_DrawData    = cmDMX +  5;
  33.     cmDMX_Lock        = cmDMX +  6;
  34.     cmDMX_LockData    = cmDMX +  7;
  35.     cmDMX_Unlock    = cmDMX +  8;
  36.     cmDMX_UnlockData    = cmDMX +  9;
  37.     cmDMX_FixSize    = cmDMX + 10;
  38.     cmDMX_SetupRecord    = cmDMX + 11;
  39.     cmDMX_WrongKey    = cmDMX + 12;
  40.  
  41.     cmDMX_ZeroizeField    = cmDMX + 13;
  42.     cmDMX_ZeroizeRecord    = cmDMX + 14;
  43.  
  44.     cmDMX_Enter        = cmDMX + 15;
  45.     cmDMX_Left        = cmDMX + 16;
  46.     cmDMX_Right        = cmDMX + 17;
  47.     cmDMX_Home        = cmDMX + 18;
  48.     cmDMX_End        = cmDMX + 19;
  49.  
  50.     cmDMX_goto        = cmDMX + 20;
  51.  
  52.     cmDMX_NextRow    = cmDMX + 21;
  53.     cmDMX_Up        = cmDMX + 22;
  54.     cmDMX_Down        = cmDMX + 23;
  55.     cmDMX_PgUp        = cmDMX + 24;
  56.     cmDMX_PgDn        = cmDMX + 25;
  57.     cmDMX_ScreenTop    = cmDMX + 26;
  58.     cmDMX_ScreenBottom    = cmDMX + 27;
  59.     cmDMX_Top        = cmDMX + 28;
  60.     cmDMX_Bottom    = cmDMX + 29;
  61.  
  62.     cmDMX_DoubleClick    = cmDMX + 30;  { mouse was double-clicked }
  63.     cmDMX_RecIndClicked    = cmDMX + 31;  { record indicator was clicked }
  64.     cmDMX_Reset        = cmDMX + 32;  { tvDMXCOL: reset size of collection }
  65.     cmDMX_ScrollBarChanged = cmDMX+33; { updates the TDmxLabels views }
  66.  
  67.     cmPRN_NewPage    = cmDMX + 40;  { tvDMXREP: broadcast before new page }
  68.     cmPRN_EndPage    = cmDMX + 41;  { tvDMXREP: broadcast before page end }
  69.     cmPRN_SetOptions    = cmDMX + 42;  { tvDMXREP: open options window }
  70.     cmPRN_LineFeed    = cmDMX + 43;  { tvDMXREP: line feed to printer }
  71.     cmPRN_FormFeed    = cmDMX + 44;  { tvDMXREP: form feed to printer }
  72.     cmPRN_Reset        = cmDMX + 45;  { tvDMXREP: reset printer }
  73.  
  74.     cmUserScreen    = cmDMX + 51;  { tvGizma: invokes User Screen }
  75.     cmToggleSound    = cmDMX + 52;  { tvGizma: toggles BeepOn }
  76.     cmToggleVideo    = cmDMX + 53;  { tvGizma: toggles video mode }
  77.     cmBeep        = cmDMX + 54;  { tvGizma: beeps if BeepOn is TRUE }
  78.     cmChime        = cmDMX + 55;  { tvGizma: broadcast every 30 minutes }
  79.  
  80.  
  81.     { tvDMX view registration numbers }
  82.     rnDMX        = FirstRegNum;  { defined in RSET.PAS }
  83.  
  84.     rnLtdFrame        = rnDMX +  1;    { RegisterTVGIZMA }
  85.     rnLtdWindow        = rnDMX +  2;
  86.  
  87.     rnDmxExtLabels    = rnDMX +  3;    { RegisterTVDMX }
  88.     rnDmxLabels        = rnDMX +  4;
  89.     rnDmxFLabels    = rnDMX +  5;
  90.     rnDmxMLabels    = rnDMX +  6;
  91.     rnDmxRecInd        = rnDMX +  7;
  92.     rnDmxScroller    = rnDMX +  8;
  93.     rnDmxEditor        = rnDMX +  9;
  94.  
  95.     rnDmxHexInd        = rnDMX + 10;    { RegisterTVDMXHEX }
  96.  
  97.     rnDmxEditDlg    = rnDMX + 11;    { RegisterSTDDMX }
  98.     rnInputFields    = rnDMX + 12;
  99.     rnDmxViewer        = rnDMX + 13;
  100.     rnDmxWindow        = rnDMX + 14;
  101.  
  102.     rnDmxCollectView    = rnDMX + 15;    { RegisterTVDMXCOL }
  103.     rnDmxCollector    = rnDMX + 16;
  104.     rnDmxCollectViewWin    = rnDMX + 17;
  105.     rnDmxCollectorWin    = rnDMX + 18;
  106.  
  107.     rnDmxStreamBuf    = rnDMX + 19;    { RegisterTVDMXBUF }
  108.     rnDmxExpBuf        = rnDMX + 20;
  109.     rnDmxExpRecInd    = rnDMX + 21;
  110.     rnDmxBufWin        = rnDMX + 22;
  111.     rnDmxExpBufWin    = rnDMX + 23;
  112.  
  113.     rnDmxForm        = rnDMX + 24;    { RegisterDMXFORMS }
  114.     rnDmxDlgForm    = rnDMX + 25;
  115.  
  116.  
  117.     cDMX        = #06#07#05#05#01#02;
  118.              {  |  |  |  |  |  | }
  119.   {  1 normal fields -------+  |  |  |  |  | }
  120.   {  2 normal selected field --+  |  |  |  | }
  121.   {  3 read-only selected field --+  |  |  | }
  122.   {  4 locked field -----------------+  |  | }
  123.   {  5 delimiter -----------------------+  | }
  124.   {  6 border -----------------------------+ }
  125.  
  126.  
  127.     accNormal    =    0;
  128.     accReadOnly  =    1;
  129.     accHidden    =    2;
  130.     accSkip      =    4;
  131.     accDelimiter =    8;
  132.  
  133.     accSpecA     =  $20;
  134.     accSpecB     =  $40;
  135.     accSpecC     =  $80;
  136.  
  137.     showTRUE     :  char  =   '■';  { TRUE indicator  }
  138.     showFALSE    :  char  =   ' ';  { FALSE indicator }
  139.     showOVERFLOW :  char  =   '*';  { overflow indicator for numbers }
  140.     showDecPt     :  char  =   '.';  { decimal point display }
  141.  
  142.  
  143.     fldSTR        =   'S';  { string field }
  144.     fldSTRNUM        =   '#';  { numeric string field }
  145.     fldCHAR        =   'C';  { character field }
  146.     fldCHARNUM        =   '0';  { numeric character field }
  147.     fldCHARVAL        =   'N';  { dbase formatted numeric field }
  148.     fldBYTE        =   'B';  { byte field }
  149.     fldSHORTINT        =   'J';  { shortint field }
  150.     fldWORD        =   'W';  { word field }
  151.     fldINTEGER        =   'I';  { integer field }
  152.     fldLONGINT        =   'L';  { longint field }
  153.     fldREALNUM        =   'R';  { real number field  (uses TREALNUM) }
  154.     fldBOOLEAN        =   'X';  { boolean value field }
  155.     fldHEXVALUE        =   'H';  { hexadecimal numeric entry }
  156.     fldENUM        =   ^E;   { enumerated field }
  157.     fldBLOb        =   ^M;   { unformatted data field }
  158.  
  159.     fldZEROMOD        =   'Z';  { zero modifier }
  160.     fldCONTRACTION    =   '`';  { limit of visible text }
  161.  
  162.     fldAPPEND        =   ^G;   { append from pointer }
  163.     fldSITEMS        =   ^I;   { link to chain of TSItem templates }
  164.  
  165.  
  166.   { Complex fields: }
  167.  
  168.     fldDATE      =  ' WW-'^F^Z + ^U+char(12) + ^P+char(2) +
  169.              #0'ZW-'^Z + ^U+char(31) +
  170.              #0'ZZZW '^Z^F + ^P+char(-6) +
  171.              #0 + ^P+char(4);
  172.  
  173.     fldTIME      =  ' WW:'^F^Z + ^U+char(23) +
  174.              #0'ZW '^Z + ^U+char(59) +
  175.              #0'W'^F^H#0;  { seconds are hidden }
  176.  
  177.     fldDATETIME  =  ' WW-'^F^Z + ^U+char(12) + ^P+char(2) +
  178.              #0'ZW-'^Z + ^U+char(31) +
  179.              #0'ZZZW '^Z^F + ^P+char(-6) +
  180.               '\' + ^P+char(4) +
  181.               ' WW:'^F^Z + ^U+char(23) +
  182.              #0'ZW:'^Z   + ^U+char(59) +
  183.              #0'ZW '^Z^F + ^U+char(59);  { seconds are not hidden }
  184.  
  185.     fldNDATE     =  { dBASE-formatted date field }
  186.             ' NN-'^Z^F^V'0' + ^P+char(4) +
  187.              #0'ZN-'^Z^V'0' +
  188.              #0'ZZZN '^Z^F^V'0' + ^P+char(-8) +
  189.              #0^P + char (4);
  190.  
  191.     CurrentCurPos : integer = 0;
  192.  
  193.  
  194. type
  195.     pDMXfieldrec = ^tDMXfieldrec;
  196.     tDMXfieldrec =  RECORD    { these records describe each field for tvDMX }
  197.     Next,Prev    :  pDMXfieldrec;
  198.     access        :  byte;    { read-only, hidden, skip, accSpecX }
  199.     fieldnum    :  byte;    { 1..totalfields (0=none) }
  200.     screentab    :  integer;    { virtual column num. }
  201.     columnwid    :  byte;    { width of field column }
  202.     shownwid    :  byte;    { visible width of column }
  203.     typecode    :  char;    { 's', 'r', etc. }
  204.     fillvalue    :  char;    { #0 or ' ' }
  205.     upperlimit    :  byte;    { maximum value limit }
  206.     showzeroes    :  boolean;    { display zero values }
  207.     truelen        :  byte;    { unformatted text length }
  208.     parenthesis    :  boolean;    { '('/')' characters }
  209.     decimals    :  byte;    { decimal point }
  210.     fieldsize    :  integer;    { sizeof (datatype) }
  211.     datatab        :  integer;    { position in record }
  212.     template    :  pstring;    { field template }
  213.     end;
  214.  
  215.  
  216.     showcodes    = (showanyway, shownegative, showregular);
  217.     showset    =  set of showcodes;    { used when displaying fields }
  218.  
  219.     DmxIDstr    =  string [8];        { contracted template string }
  220.  
  221.  
  222.   function  InitAppendFields (ATemplate : pstring) : DmxIDstr;
  223.     { initialize a pointer to more field templates }
  224.  
  225.   function  InitBlobField (Len : integer; AccMode,Default : byte) : DmxIDstr;
  226.     { initialize an unformatted data field }
  227.  
  228.   function  InitEnumField (ShowZ : boolean;  AccMode,Default : byte;
  229.                AItems : PSItem) : DmxIDstr;
  230.     { initialize a tvDMX enum field list }
  231.  
  232.   function  InitTSItemFields (ATemplates : PSItem) : DmxIDstr;
  233.     { initialize a chain of TSItem templates }
  234.  
  235.   procedure DisposeSItems (AItems : PSItem);
  236.     { dispose a chain of TSItems }
  237.  
  238.   function  ReadSItems (var S : TStream) : PSItem;
  239.     { reads strings from a pick list }
  240.  
  241.   procedure WriteSItems (var S : TStream; Items : PSItem);
  242.     { writes strings to a pick list }
  243.  
  244.   function  MaxItemStrLen (AItems : PSItem) : integer;
  245.     { returns the maximum length of the strings in a pick list }
  246.  
  247.   function  SItemsLen (S : PSItem) : integer;
  248.     { returns the cumulative length of the strings in a pick list }
  249.  
  250.   function  DmxStrLen (S : string)  : integer;
  251.     { returns the length of the visible portions of a tvDMX template string }
  252.  
  253.   function  FieldString (fieldrec  : pDMXfieldrec;
  254.              Show : showset;  var DataRec )  : string;
  255.     { returns a display string from a tvDMX field record }
  256.  
  257.  
  258. implementation
  259.  
  260.  
  261.   { ══════════════════════════════════════════════════════════════════════ }
  262.  
  263.  
  264. function  InitAppendFields (ATemplate : pstring) : DmxIDstr;
  265. var  S : DmxIDstr;
  266. begin
  267.   S := fldAPPEND + #0#0#0#0#0#0#0;
  268.   Move (ATemplate, S [2], 4);
  269.   InitAppendFields := S;
  270. end;
  271.  
  272.  
  273. function  InitBlobField (Len : integer; AccMode,Default : byte) : DmxIDstr;
  274. var  S : DmxIDstr;
  275. begin
  276.   S := fldBLOb + #0#0#0#0#0 + chr (AccMode) + chr (Default);
  277.   Move (Len, S [2], sizeof (Len));
  278.   InitBlobField := S;
  279. end;
  280.  
  281.  
  282. function  InitEnumField (ShowZ : boolean; AccMode,Default : byte;
  283.              AItems : PSItem) : DmxIDstr;
  284. var  S : DmxIDstr;
  285. begin
  286.   S := fldENUM + #0#0#0#0 + char (ShowZ) + chr (AccMode) + chr (Default);
  287.   Move (AItems, S [2], 4);
  288.   InitEnumField := S;
  289. end;
  290.  
  291.  
  292. function  InitTSItemFields (ATemplates : PSItem) : DmxIDstr;
  293. var  S : DmxIDstr;
  294. begin
  295.   S := fldSITEMS + #0#0#0#0#0#0#0;
  296.   Move (ATemplates, S [2], 4);
  297.   InitTSItemFields := S;
  298. end;
  299.  
  300.  
  301. procedure DisposeSItems (AItems : PSItem);
  302. var  P : PSItem;
  303. begin
  304.   While (AItems <> nil) do
  305.     begin
  306.     P := AItems^.Next;
  307.     If (AItems^.Value <> nil) then DisposeStr (AItems^.Value);
  308.     Dispose (AItems);
  309.     AItems := P;
  310.     end;
  311. end;
  312.  
  313.  
  314. function  ReadSItems (var S : TStream) : PSItem;
  315. var  P,P1 : PSItem;
  316.      n    : integer;
  317. begin
  318.   P1 := nil;
  319.   S.Read (n, sizeof (n));
  320.   While (S.Status = stOK) and (n > 0) do
  321.     begin
  322.     If (P1 = nil) then
  323.       begin
  324.       New (P1);
  325.       P := P1;
  326.       end
  327.      else
  328.       begin
  329.       New (P^.Next);
  330.       P := P^.Next;
  331.       end;
  332.     P^.Value := S.ReadStr;
  333.     P^.Next  := nil;
  334.     Dec (n);
  335.     end;
  336.   ReadSItems := P1;
  337. end;
  338.  
  339.  
  340. procedure WriteSItems (var S : TStream; Items : PSItem);
  341. var  P : PSItem;
  342.      n : integer;
  343. begin
  344.   P := Items;
  345.   n := 0;
  346.   While (P <> nil) do
  347.     begin
  348.     Inc (n);
  349.     P := P^.Next;
  350.     end;
  351.   S.Write (n, sizeof (n));
  352.   While (Items <> nil) do
  353.     begin
  354.     S.WriteStr (Items^.Value);
  355.     Items := Items^.Next;
  356.     end;
  357. end;
  358.  
  359.  
  360. function  MaxItemStrLen (AItems : PSItem) : integer;
  361. var  len : integer;
  362. begin
  363.   len := 0;
  364.   While (AItems <> nil) do
  365.     begin
  366.     If (AItems^.Value <> nil) and (length (AItems^.Value^) > len) then
  367.       len := length (AItems^.Value^);
  368.     AItems := AItems^.Next;
  369.     end;
  370.   MaxItemStrLen := len;
  371. end;
  372.  
  373.  
  374. function  SItemsLen (S : PSItem) : integer;
  375. var  Len : integer;
  376. begin
  377.   Len := 0;
  378.   While (S <> nil) do
  379.     begin
  380.     If (S^.Value <> nil) then Inc (Len, length (S^.Value^));
  381.     S := S^.Next;
  382.     end;
  383.   SItemsLen := Len;
  384. end;
  385.  
  386.  
  387.   { ══════════════════════════════════════════════════════════════════════ }
  388.  
  389.  
  390. function  DmxStrLen (S : string)  : integer;
  391. var  i,Len,Wid,Ttl    : integer;
  392.      h            : boolean;
  393.  
  394.     procedure ResetDelimiter (D : boolean);
  395.     begin
  396.       If not h then
  397.     begin
  398.     If (Wid = 0) then Inc (Ttl, Len) else Inc (Ttl, Wid);
  399.     end;
  400.       If D then Inc (Ttl);
  401.       Len := 0;
  402.       Wid := 0;
  403.       h   := FALSE;
  404.     end;
  405.  
  406. begin
  407.   h   := FALSE;
  408.   Ttl := 0;
  409.   Len := 0;
  410.   Wid := 0;
  411.   i   := 0;
  412.   While (i < length (S)) do
  413.     begin
  414.     Inc (i);
  415.     Case S [i] of
  416.       '~':
  417.     begin
  418.     Inc (i);
  419.     While (S [i] <> '~') and (i < length (S)) do
  420.       begin
  421.       Inc (Len);
  422.       Inc (i);
  423.       end;
  424.     end;
  425.       ^C, ^P, ^U, ^V:    Inc (i);
  426.       ^H:        h := TRUE;
  427.       ^D:
  428.     begin
  429.     ResetDelimiter (TRUE);
  430.     Inc (i);
  431.     end;
  432.       fldCONTRACTION:    Wid := Len;
  433.       fldENUM:
  434.     begin
  435.     ResetDelimiter (FALSE);
  436.     Inc (Len, MaxItemStrLen (PSItem (S [i+1])));
  437.     Inc (i, sizeof (DmxIDstr) - 1);
  438.     end;
  439.       fldBLOb:
  440.     begin
  441.     ResetDelimiter (FALSE);
  442.     Inc (i, sizeof (DmxIDstr) - 1);
  443.     end;
  444.       fldAPPEND:
  445.     begin
  446.     ResetDelimiter (FALSE);
  447.     Inc (Len, DmxStrLen (pstring (S [i+1])^));
  448.     Inc (i, sizeof (DmxIDstr) - 1);
  449.     end;
  450.       #0,'\','|','│','║':
  451.     begin
  452.     ResetDelimiter (S [i] <> #0);
  453.     end;
  454.       ^A..^Z:    begin  end;
  455.      else    Inc (Len);
  456.       end;
  457.     end;
  458.   ResetDelimiter (FALSE);
  459.   DmxStrLen := Ttl;
  460. end;
  461.  
  462.  
  463.   { ══════════════════════════════════════════════════════════════════════ }
  464.  
  465.  
  466. function  FieldString (fieldrec    : pDMXfieldrec;
  467.                Show    : showset;  var DataRec )  : string;
  468. var  i,j,Len    :  integer;
  469.      C        :  char;
  470.      Numbers    :  boolean;
  471.      ItsBlank    :  boolean;
  472.      Q        :  boolean;
  473.      A,T    :  string;
  474.      R        :  TREALNUM;
  475.      Items    :  PSItem;
  476.  
  477.      Data    :  pointer;
  478.      DataBool    :  pboolean    absolute Data;
  479.      DataByte    :  pbyte    absolute Data;
  480.      DataShort    :  pshortint    absolute Data;
  481.      DataInt    :  pinteger    absolute Data;
  482.      DataWord    :  pword    absolute Data;
  483.      DataLong    :  plongint    absolute Data;
  484.      DataReal    :  PREALNUM    absolute Data;
  485.      DataStr    :  pstring    absolute Data;
  486.  
  487.     function  HexByte (Number : byte)  : string;
  488.     const bts  : array [0..15] of char = '0123456789ABCDEF';
  489.     begin
  490.       HexByte := bts [(Number shr 4) and $0F] + bts [Number and $0F]
  491.     end;
  492.  
  493.     function  BlankField  : boolean;
  494.     var  i : word;
  495.     begin
  496.       BlankField := TRUE;
  497.       If Len > 0 then
  498.     For i := 0 to pred (fieldrec^.fieldsize) do
  499.       If DataStr^ [i] <> #0 then BlankField := FALSE;
  500.     end;
  501.  
  502.     function  CheckBlank (Zero : boolean) :  boolean;
  503.     begin
  504.       If (Zero) and not ((fieldrec^.showzeroes) or (showanyway in Show)) then
  505.     begin
  506.     fillchar (A [1], Len, ' ');
  507.     A [0]       := chr (Len);
  508.     ItsBlank   := TRUE;
  509.     CheckBlank := TRUE;
  510.     end
  511.        else
  512.     CheckBlank := FALSE;
  513.     end;
  514.  
  515.     procedure FormNum (sign : boolean);
  516.     { length of A[] must equal Len + 1 }
  517.     var  i,j : integer;
  518.      cc  : char;
  519.     begin
  520.       With fieldrec^ do
  521.     begin
  522.     If sign and (shownegative in Show) then
  523.       begin
  524.       i := 1;
  525.       While (A [i] = ' ') do Inc (i);
  526.       If (i > 1) then A [pred (i)] := '-';
  527.       end;
  528.     If (parenthesis) then
  529.       begin
  530.       If sign then
  531.         begin
  532.         T [pos ('(', T)] := ' ';
  533.         T [pos (')', T)] := ' ';
  534.         end
  535.        else
  536.         begin
  537.         A [pos ('-', A)] := ' ';
  538.         If length (A) > succ (Len) then Delete (A, 1,1);
  539.         end;
  540.       end;
  541.     If (A [1] <> ' ') then
  542.       begin
  543.       fillchar (A [1], Len, showOVERFLOW);
  544.       A [0] := chr (Len);
  545.       end
  546.      else
  547.       begin
  548.       Delete (A, 1,1);
  549.       Numbers := TRUE;
  550.       end;
  551.     end;
  552.     end;
  553.  
  554.  
  555. begin
  556.   With fieldrec^ do
  557.     begin
  558.     If (fieldrec = nil) or (access and accHidden <> 0) then
  559.       begin
  560.       FieldString := '';
  561.       Exit;
  562.       end;
  563.     If (template = nil) or (columnwid = 0) then
  564.       begin
  565.       If typecode <> #0 then FieldString := typecode else FieldString := '';
  566.       Exit;
  567.       end;
  568.     If (upcase (typecode) = fldENUM) then
  569.       begin
  570.       fillchar (T [1], columnwid, ' ');
  571.       T [0] := chr (columnwid);
  572.       end
  573.      else
  574.       T  := template^;
  575.     If (fieldsize = 0) then
  576.       begin
  577.       FieldString := T;
  578.       Exit;
  579.       end;
  580.     Data := ptr (seg (DataRec), ofs (DataRec) + datatab);
  581.     Len  := truelen;
  582.     Numbers  := FALSE;
  583.     ItsBlank := FALSE;
  584.     Q     := FALSE;
  585.     C     := upcase (typecode);
  586.     Case C of
  587.  
  588.       fldSTR, fldSTRNUM:            { 'S'/'#' }
  589.     begin
  590.     If DataStr^ <> '' then
  591.       For i := 1 to length (DataStr^) do
  592.         If ord (DataStr^[i]) and $DF <> 0 then Q := TRUE;
  593.     If not CheckBlank (not Q) then
  594.       begin
  595.       fillchar (A [1], Len, ' ');
  596.       Move (DataStr^[1], A [1], length (DataStr^));
  597.       A [0] := chr (Len);
  598.       end;
  599.     end;
  600.  
  601.       fldCHAR, fldCHARNUM:        { 'C'/'0' }
  602.     begin
  603.     If Len > 0 then
  604.       For i := 0 to pred (Len) do
  605.         If ((ord (DataStr^[i]) and $DF) <> 0) then Q := TRUE;
  606.     If not CheckBlank (not Q) then
  607.       begin
  608.       Move (Data^, A [1], Len);
  609.       A [0] := chr (Len);
  610.       end;
  611.     end;
  612.  
  613.       fldCHARVAL:            { 'N' }
  614.     begin
  615.     A [0] := chr (fieldsize);
  616.     Move (Data^, A [1], fieldsize);
  617.     Val (A, R, i);
  618.     If i <> 0 then R := 0.0;
  619.     If not CheckBlank (R = 0.0) then
  620.       begin
  621.       If decimals > 0 then
  622.         begin
  623.         Str (R:(Len + 2):decimals, A);
  624.         Delete (A, (Len + 2) - decimals, 1);
  625.         end
  626.        else
  627.         Str (R:(Len + 1):0, A);
  628.       FormNum (R >= 0);
  629.       end;
  630.     end;
  631.  
  632.       fldBYTE:                { 'B' }
  633.     If not CheckBlank (DataByte^ = 0) then
  634.       begin
  635.       Str (DataByte^:(Len + 1), A);
  636.       FormNum (TRUE);
  637.       end;
  638.  
  639.       fldSHORTINT:            { 'J' }
  640.     If not CheckBlank (DataShort^ = 0) then
  641.       begin
  642.       Str (DataShort^:(Len + 1), A);
  643.       FormNum (DataShort^ >= 0);
  644.       end;
  645.  
  646.       fldWORD:                { 'W' }
  647.     If not CheckBlank (DataWord^ = 0) then
  648.       begin
  649.       Str (DataWord^:(Len + 1), A);
  650.       FormNum (TRUE);
  651.       end;
  652.  
  653.       fldINTEGER:            { 'I' }
  654.     If not CheckBlank (DataInt^ = 0) then
  655.       begin
  656.       Str (DataInt^:(Len + 1), A);
  657.       FormNum (DataInt^ >= 0);
  658.       end;
  659.  
  660.       fldLONGINT:            { 'L' }
  661.     If not CheckBlank (DataLong^ = 0) then
  662.       begin
  663.       Str (DataLong^:(Len + 1), A);
  664.       FormNum (DataLong^ >= 0);
  665.       end;
  666.  
  667.       fldREALNUM:            { 'R' }
  668.     If not CheckBlank (DataReal^ = 0.0) then
  669.       begin
  670.       If decimals > 0 then
  671.         begin
  672.         Str (DataReal^:(Len + 2):decimals, A);
  673.         Delete (A, (Len + 2) - decimals, 1);
  674.         end
  675.        else
  676.         Str (DataReal^:(Len + 1):0, A);
  677.       If (abs (DataReal^) > 1e35) then
  678.         begin
  679.         A := '**********************************';
  680.         If (DataReal^ < 0.0) then A [1] := '-';
  681.         end;
  682.       FormNum (DataReal^ >= 0);
  683.       end;
  684.  
  685.       fldBOOLEAN:            { 'X' }
  686.     begin
  687.     If (Len = 0) then
  688.       begin
  689.       If DataBool^ then A := '' else ItsBlank := TRUE;
  690.       end
  691.      else
  692.       begin
  693.       If not CheckBlank (not DataBool^) then
  694.         begin
  695.         If DataBool^ then
  696.           fillchar (A [1], Len, showTRUE)
  697.          else
  698.           fillchar (A [1], Len, showFALSE);
  699.         A [0] := chr (Len);
  700.         end;
  701.       end;
  702.     end;
  703.  
  704.       fldHEXVALUE:            { 'H' }
  705.     If not CheckBlank (BlankField) then
  706.       begin
  707.       A  := '';
  708.       For i := 0 to pred (fieldsize) do A := hexbyte (ord (DataStr^ [i])) + A;
  709.       If (length (A) > Len) then Delete (A, 1,1);
  710.       end;
  711.  
  712.       fldENUM:                { ^P  }
  713.     If not CheckBlank (DataByte^ = 0) then
  714.       begin
  715.       A  := '';
  716.       Items := PSItem (template);
  717.       i     := DataByte^;
  718.       While (i > 0) do
  719.         begin
  720.         Dec (i);
  721.         If (Items <> nil) then Items := Items^.Next else i := 0;
  722.         end;
  723.       If (Items <> nil) and (Items^.Value <> nil) and (Items^.Value^ <> '') then
  724.         begin
  725.         Move (Items^.Value^ [1], T [1], length (Items^.Value^));
  726.         end;
  727.       end;
  728.       end;  { case of C }
  729.  
  730.     If ItsBlank then
  731.       begin
  732.       fillchar (T [1], length (T), ' ');
  733.       end
  734.      else
  735.       If A <> '' then
  736.     begin
  737.     j  := length (A);
  738.     Q  := (fieldrec^.decimals > 0);
  739.     For i := length (T) downto 1 do
  740.       begin
  741.       If Q and (showanyway in Show) and (j <= CurrentCurPos) then Q := FALSE;
  742.       If (ord (T [i]) and $FE = 0) then
  743.         begin
  744.         If j > 0 then
  745.           begin
  746.           If Q then If (A [j] = '0') then A [j] := ' ' else Q := FALSE;
  747.           If (T [i] = #0) or (A [j] > ' ') then
  748.         T [i] := A [j]
  749.            else
  750.         begin
  751.         T [i] := '0';
  752.         Q := FALSE;
  753.         end;
  754.           Dec (j);
  755.           end;
  756.         end
  757.        else
  758.         begin
  759.         If Q and (T [i] = showDecPt) then
  760.           begin
  761.           Q := FALSE;
  762.           T [i] := ' ';
  763.           end;
  764.         If Numbers and (T [i] = ',') then
  765.           begin
  766.           If (j <= 0) then T [i] := ' '
  767.            else
  768.         begin
  769.         If (A [j] in [' ','-']) then
  770.           begin
  771.           T [i] := A [j];
  772.           Dec (j);
  773.           end;
  774.         end;
  775.           end;
  776.         end;
  777.       end;
  778.     end;
  779.     end;
  780.  
  781.   CurrentCurPos := 0;
  782.   FieldString := T;
  783.  
  784. end;  { FieldString() }
  785.  
  786.  
  787.   { ══════════════════════════════════════════════════════════════════════ }
  788.  
  789.  
  790.  
  791. End.
  792.