home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 14 / CDACTUAL.iso / cdactual / demobin / share / program / Pascal / TVDMX.ZIP / SAMPLES.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1993-03-31  |  25.8 KB  |  868 lines

  1.  
  2. {■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■}
  3. {                            }
  4. {    SAMPLES   --Multi-window sample demo program    }
  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. Program SAMPLES;
  15.  
  16. { This program was written to demonstrate various data structures.  You can
  17.   examine the field templates and copy some portions into WORKSHOP.PAS for
  18.   your own experiments.
  19.  
  20.   The design of some of these record structures may seem pointless since
  21.   they are intended only to demonstrate the interface mechanism.
  22.  
  23.   The "Account" window is the simplest example here.  It's somewhat bland,
  24.   but most programmers will only require simple data structures like this.
  25.  
  26.   The "Payroll" window is a larger data window.  It demonstrates the 'Z'
  27.   template code, which forces the display of leading zeroes in that field.
  28.   Its last three fields are marked as READ-ONLY (with the ^R code).  These
  29.   are entered automatically by the virtual methods in object TDmxPayroll,
  30.   which overrides TDmxEditor.  Unlike "Accounts" and "Busy", this window is
  31.   a regular TWindow type.
  32.  
  33.   The "Busy" window uses a more complex template string.  Note the heavy use
  34.   of control codes, and that the last field in the main window is Read-Only.
  35.   One of the integer fields is marked as a "skip" field (that means that the
  36.   cursor will not land on it).
  37.  
  38.   The DateTime type is used here, with fldDATETIME, fldDATE, and fldTIME
  39.   constants --as defined in the DMXGIZMA unit.  Its Year, Month and Day are
  40.   swapped by codes in the fldDATETIME and fldDATE string to place it in its
  41.   more familiar Month-Day-Year order.  An enumerated field is now used for
  42.   the date portion, although its corresponding dialog box does not.
  43.  
  44.  
  45.   Three other views are available from the menu:  "Hex" is a tvDMX-driven
  46.   hex-byte editor using the same data as Busy window;  and "Dialog" is a
  47.   dialog box that uses tvDMX descendants for individual field input, using
  48.   the data in the current window at the current record.  A dialog window
  49.   may also be actuated by double-clicking a record with a mouse.
  50.  
  51.   The data in most windows can be reported to file SAMPLES.OUT, using the
  52.   objects in unit tvDMXREP.PAS.
  53.  
  54.   (See file TVDMXHEX.PAS for the code used in the hexadecimal byte editor.)
  55.  }
  56.  
  57. {$V-,X+ }
  58.  
  59. uses
  60.     Dos, { required to define DateTime type }
  61.     Objects, Drivers, Views, Menus, Dialogs, App, MsgBox,
  62.     RSet, DmxGizma, tvGizma, tvDMX, StdDMX, tvDmxHex, tvDmxRep;
  63.  
  64. const
  65.     cmHasDialog   =  103;
  66.  
  67.     cmAccounts    =  111;
  68.     cmPayroll     =  112;
  69.     cmBusyWin     =  113;
  70.     cmHexWin      =  114;
  71.     cmDialog      =  116;
  72.     cmRecDialog   =  117;
  73.     cmPrint      =  118;
  74.  
  75.     cmNoCmd       = 1000;
  76.  
  77.     hcDeskTop      = 1100;
  78.     hcAccounts      = 1100;
  79.     hcPayroll      = 1200;
  80.     hcBusyWin      = 1300;
  81.     hcHexWin      = 1400;
  82.     hcDialogs      = 4000;
  83.     hcMenus      = 5000;
  84.  
  85.     hcReadOnly    = 1500;
  86.     hcEnumField      = 1501;
  87.  
  88.  
  89.       { Data presentation template for the "Accounts" window.
  90.         The data structure is declared as "TAccount" in the TYPE section.
  91.        }
  92.  
  93.     AccountLabel : string =
  94.         ' Transaction          Debit        Credit      [?] ';
  95.  
  96.     AccountInfo  : string =
  97.     ' SSSSSSSSSSSSSSSS`SSSSSSSSSS| rrr,rrr.zz  | rrr,rrr.zz  | [x] ';
  98.  
  99.       { Note that the '`' character marks the end of the visible field.
  100.        }
  101.  
  102.  
  103.  
  104.       { Data presentation template for the "Payroll" window.
  105.     The data structure is declared as "TPayroll" in the TYPE section.
  106.     The last three fields are marked READ-ONLY, and are automatically
  107.     entered by the virtual methods in object TDmxPayroll.
  108.        }
  109.  
  110.     _PayrollLblA  = ' Employee                ID     Earnings       FICA        FITW        SITW   ';
  111.     _PayrollInfo  = ' ssssssssssssssssssssss| ZZW ║ $rr,rrr.zz | $r,rrr.zz '^R'| $r,rrr.zz '^R'| $r,rrr.zz '^R;
  112.     _PayrollLblB  = ' (dollar amounts are dependent upon Earnings)';
  113.  
  114.     PayrollLabelA :  string [length (_PayrollLblA)]  =  _PayrollLblA;
  115.     PayrollInfo   :  string [length (_PayrollInfo)]  =  _PayrollInfo;
  116.     PayrollLabelB :  string [length (_PayrollLblB)]  =  _PayrollLblB;
  117.  
  118.  
  119.  
  120.       { The Busy Window's template uses many of the special options.  Since
  121.         it uses an enumerated field, the template was defined in the method
  122.         that instantiates these windows.
  123.        }
  124.  
  125.     _BusyLabel    =
  126.     ' Name                  SSN             Balance      Start Date   Time   <A>  [B]   Pointer       Value     RO ';
  127.  
  128.     BusyLabel     :  string [length (_BusyLabel)] =  _BusyLabel;
  129.  
  130.  
  131.     MaxRecordNum  =   49;
  132.  
  133.  
  134. type
  135.     PAccount      = ^TAccount;
  136.     PPayroll      = ^TPayroll;
  137.     PBusyData      = ^TBusyData;
  138.  
  139.  
  140.     TAccount      =  RECORD
  141.     Account    :  string [26];
  142.     Debit    :  real;
  143.     Credit    :  real;
  144.     Status    :  boolean;
  145.     end;
  146.  
  147.  
  148.     TPayroll      =  RECORD
  149.     Employee :  string [22];
  150.     ID     :  word;
  151.     Earnings :  real;
  152.     FICA     :  real;  { READ-ONLY }
  153.     FITW     :  real;  { READ-ONLY }
  154.     SITW     :  real;  { READ-ONLY }
  155.     end;
  156.  
  157.  
  158.     TBusyData      =  RECORD
  159.     Marker        :  byte;    { HIDDEN field }
  160.     Name        :  string [30];
  161.     SSN        :  string [9];
  162.     realfield1    :  real;
  163.     DT        :  datetime;
  164.     intfield0    :  integer;    { READ-ONLY }
  165.     intfield1    :  integer;
  166.     ptrfield    :  pointer;
  167.     realfield2    :  real;
  168.     hextwo        :  byte;    { READ-ONLY }
  169.     end;
  170.  
  171.  
  172.     PDmxEditTbl       = ^TDmxEditTbl;
  173.     PDmxEditTblWin = ^TDmxEditTblWin;
  174.  
  175.  
  176.     TDmxEditTbl     =  OBJECT (TDmxEditor)
  177.       function  GetHelpCtx : word;  VIRTUAL;
  178.       procedure HandleEvent (var Event : TEvent);  VIRTUAL;
  179.     end;
  180.  
  181.  
  182.     TDmxEditTblWin  =  OBJECT (TDmxWindow)
  183.       procedure InitDMX (ATemplate : string;  var AData;
  184.              ALabels, ARecInd : PDmxLink;
  185.              BSize  : longint);  VIRTUAL;
  186.     end;
  187.  
  188.  
  189.     PDmxPayroll    = ^TDmxPayroll;
  190.  
  191.     TDmxPayroll       =  OBJECT (TDmxEditTbl)
  192.       procedure EvaluateField;  VIRTUAL;
  193.       procedure ZeroizeField (Whole :boolean; Field :pDMXfieldrec);  VIRTUAL;
  194.       procedure RecalcRecord;
  195.     end;
  196.  
  197.  
  198.     PMyStatusLine  = ^TMyStatusLine;
  199.     TMyStatusLine  =  OBJECT (TStatusLine)
  200.       function  Hint (AHelpCtx : word) : string;  VIRTUAL;
  201.     end;
  202.  
  203.  
  204.     TAppN       =  OBJECT (TAppPrn)  { from tvDMXREP.PAS }
  205.     end;
  206.  
  207.     TMyApp       =  OBJECT (TAppN)
  208.       constructor Init;
  209.       procedure Idle;  VIRTUAL;
  210.       procedure HandleEvent (var Event : TEvent);  VIRTUAL;
  211.       procedure InitMenuBar;     VIRTUAL;
  212.       procedure InitStatusLine;  VIRTUAL;
  213.       procedure AccountWindow;
  214.       procedure PayrollWindow;
  215.       procedure BusyWindow;
  216.       procedure HexWindow;
  217.       procedure AccountDialog (P : PDmxEditTbl);
  218.       procedure PayrollDialog (P : PDmxPayroll);
  219.       procedure BusyDialog (P : PDmxEditTbl);
  220.     end;
  221.  
  222.  
  223. var
  224.     Accounts    :  array [0..MaxRecordNum] of TAccount;
  225.     Payroll    :  array [0..MaxRecordNum] of TPayroll;
  226.     BusyData    :  array [0..MaxRecordNum] of TBusyData;
  227.  
  228.  
  229.   procedure InitializeData;  forward;  { for the sample data }
  230.  
  231.  
  232.   { ══ TMyStatusLine ═════════════════════════════════════════════════════ }
  233.  
  234.  
  235. function  TMyStatusLine.Hint (AHelpCtx : word) : string;
  236. begin
  237.   Case AHelpCtx of
  238.     hcDragging:  Hint := #24#25#26#27' Move  Shift-'#24#25#26#27' Resize  '#17#196#217' Done  Esc Cancel';
  239.     hcReadOnly:  Hint := '(Read-Only field)';
  240.     hcEnumField: Hint := '(Use "+" or "-")';
  241.    else         Hint := '';
  242.     end;
  243. end;
  244.  
  245.  
  246.   { ══ TDmxEditTbl ═══════════════════════════════════════════════════════ }
  247.  
  248.  
  249. function  TDmxEditTbl.GetHelpCtx : word;
  250. begin
  251.   If (CurrentField^.typecode = fldENUM) then
  252.     GetHelpCtx := hcEnumField
  253.   else
  254.   If (CurrentField^.access and accReadOnly <> 0) then
  255.     GetHelpCtx := hcReadOnly
  256.   else
  257.     GetHelpCtx := hcNoContext;
  258. end;
  259.  
  260.  
  261. procedure TDmxEditTbl.HandleEvent (var Event : TEvent);
  262. begin
  263.   TDmxEditor.HandleEvent (Event);
  264.   With Event do
  265.     If (What = evCommand) then
  266.       begin
  267.       Case Command of
  268.     cmDialog,cmDMX_DoubleClick:
  269.       Message (Application, evCommand, cmRecDialog, @Self);
  270.     cmHasDialog:
  271.       begin end;  { just clear the event }
  272.        else    Exit;
  273.     end;
  274.       ClearEvent (Event);
  275.       end;
  276. end;
  277.  
  278.  
  279.   { ══ TDmxEditTblWin ════════════════════════════════════════════════════ }
  280.  
  281.  
  282. procedure TDmxEditTblWin.InitDMX (ATemplate : string;  var AData;
  283.                   ALabels, ARecInd : PDmxLink;
  284.                   BSize  : longint);
  285. { To override TDmxEditor (as does object TDmxEditTbl above), you could
  286.   override a TDmxWindow object to insert the new object.  This window
  287.   type is used for the "Accounts" and "Busy" windows.  (The "Payroll"
  288.   window uses a regular TWindow type.)
  289.  }
  290. var  R    : TRect;
  291. begin
  292.   GetExtent (R);
  293.   R.Grow (-1,-1);
  294.   If ALabels <> nil then Inc (R.A.Y, ALabels^.Size.Y);
  295.   DMX := New (PDmxEditTbl, Init (ATemplate, AData, BSize, R,
  296.         ALabels, ARecInd,
  297.         StandardScrollBar (sbHorizontal+ sbHandleKeyboard),
  298.         StandardScrollBar (sbVertical  + sbHandleKeyboard)));
  299.   Insert (DMX);
  300. end;
  301.  
  302.  
  303.   { ══ TDmxPayroll ═══════════════════════════════════════════════════════ }
  304.  
  305.  
  306. procedure TDmxPayroll.EvaluateField;
  307. { virtual method called after a field is edited...
  308.   -- It updates the three READ-ONLY fields when field 3 is modified.
  309.  }
  310. begin
  311.   TDmxEditTbl.EvaluateField;
  312.   If (CurrentField^.fieldnum = 3) and FieldAltered then RecalcRecord;
  313. end;
  314.  
  315.  
  316. procedure TDmxPayroll.ZeroizeField (Whole : boolean; Field : pDMXfieldrec);
  317. { virtual method called to clear a field...
  318.   -- The program will still operate properly without overriding this method,
  319.      but the READ-ONLY fields would not react until the user changes fields.
  320.  }
  321. begin
  322.   TDmxEditTbl.ZeroizeField (Whole, Field);
  323.   If (Field^.fieldnum = 3) then RecalcRecord;
  324. end;
  325.  
  326.  
  327. procedure TDmxPayroll.RecalcRecord;
  328. { new method to follow up on changes }
  329. begin
  330.   With Payroll [CurrentRecord] do
  331.     begin
  332.     FICA  := Earnings * 0.075;
  333.     FITW  := Earnings * 0.28;
  334.     SITW  := Earnings * 0.05;
  335.     end;
  336.   RedrawRecord := TRUE;  { forces entire record to be redrawn }
  337. end;
  338.  
  339.  
  340.   { ══ TMyApp ════════════════════════════════════════════════════════════ }
  341.  
  342.  
  343. constructor TMyApp.Init;
  344. begin
  345.   TAppN.Init;
  346.   MenuBar^.HelpCtx := hcMenus;
  347.   DeskTop^.HelpCtx := hcDeskTop;
  348.   InitializeData;  { initialize the sample data }
  349.  
  350.   { Open the first 5 selections }
  351.   AccountWindow;
  352.   PayrollWindow;
  353.   BusyWindow;
  354.   HexWindow;
  355.  
  356.   DeskTop^.SelectNext (FALSE);  { change back to account window }
  357.  
  358.   MessageBox (^C'Sample Data Editors'^M^M^C'tvDMX (c) 1993  Randolph Beck',
  359.         nil, mfInformation + mfOKButton);
  360.  
  361. end;
  362.  
  363.  
  364. procedure TMyApp.Idle;
  365. begin
  366.   TAppN.Idle;
  367.   If (Message (DeskTop, evCommand, cmHasDialog, @Self) <> nil) then
  368.     EnableCommands ([cmDialog,cmPrint])
  369.    else
  370.     begin
  371.     DisableCommands ([cmDialog]);
  372.     If (Message (DeskTop, evCommand, cmDMX_RollCall, @Self) <> nil) then
  373.       EnableCommands ([cmPrint])
  374.      else
  375.       DisableCommands ([cmPrint]);
  376.     end;
  377. end;
  378.  
  379.  
  380. procedure TMyApp.HandleEvent (var Event : TEvent);
  381.  
  382.     procedure DoRecDialog;
  383.     var  P : PDmxEditTbl;
  384.     begin
  385.       P := Event.InfoPtr;
  386.       If (P <> nil) then
  387.     begin
  388.     If (P^.WorkingData = @Accounts) then AccountDialog (P)
  389.     else
  390.     If (P^.WorkingData = @Payroll)  then PayrollDialog (PDmxPayroll (P))
  391.     else
  392.     If (P^.WorkingData = @BusyData) then BusyDialog (P);
  393.     end;
  394.     end;
  395.  
  396.     procedure PrintingNewPage;
  397.     var  S : string;
  398.     begin
  399.       S := PWindow (PDmxReport (Event.InfoPtr)^.DMX^.Owner)^.Title^;
  400.       PDmxReport (Event.InfoPtr)^.PrintStr ('SAMPLES:  Data from ' + S);
  401.       PDmxReport (Event.InfoPtr)^.NewLine;
  402.       PDmxReport (Event.InfoPtr)^.NewLine;
  403.     end;
  404.  
  405. begin
  406.   TAppN.HandleEvent (Event);
  407.   If (Event.What and evMessage <> 0) then
  408.     begin
  409.     Case Event.Command of
  410.       cmAccounts:    AccountWindow;
  411.       cmPayroll:    PayrollWindow;
  412.       cmBusyWin:    BusyWindow;
  413.       cmHexWin:        HexWindow;
  414.       cmRecDialog:    DoRecDialog;
  415.       cmChime:        Message (Application, evCommand, cmBeep, @Self);
  416.       cmPrint:        PrnCurrentDMX;
  417.       cmPRN_SetOptions:    PrnSetOptions (hcDialogs, hcDialogs, hcDialogs);
  418.       cmPRN_NewPage:    PrintingNewPage;
  419.       cmPRN_EndPage:    PrnPageEnd (Event);
  420.      else
  421.       Exit;
  422.       end;
  423.     If (Event.What = evCommand) then ClearEvent (Event);
  424.     end;
  425. end;
  426.  
  427.  
  428. procedure TMyApp.InitMenuBar;
  429. var  R: TRect;
  430. begin
  431.   GetExtent (R);
  432.   R.B.Y := R.A.Y + 1;
  433.   MenuBar := New (PMenuBar, Init (R, NewMenu (
  434.     NewSubMenu ('~S~amples', hcMenus, NewMenu (
  435.       NewItem ('~A~ccounts', '',    kbNoKey, cmAccounts,hcMenus,
  436.       NewItem ('~P~ayroll',  '',    kbNoKey, cmPayroll, hcMenus,
  437.       NewItem ('~B~usy',     'F4',  kbF4,    cmBusyWin, hcMenus,
  438.       NewItem ('~H~ex',      '',    kbNoKey, cmHexWin,  hcMenus,
  439.       NewLine (
  440.       NewItem ('~D~ialog',   'F2',  kbF2,    cmDialog,  hcMenus,
  441.       NewItem ('P~r~int',    'F9',  kbF9,    cmPrint,    hcMenus,
  442.       NewLine (
  443.       NewItem ('e~X~it',   'Alt-X', kbAltX,  cmQuit,    hcMenus,
  444.       nil)))))))))),
  445.     NewSubMenu ('~W~indow', hcMenus, NewMenu (
  446.       NewItem ('~S~ize/Move', 'Ctrl-F5', kbCtrlF5, cmResize, hcMenus,
  447.       NewItem ('~Z~oom',      'F5',  kbF5,    cmZoom,    hcMenus,
  448.       NewItem ('~T~ile',      '',    kbNoKey, cmTile,    hcMenus,
  449.       NewItem ('C~a~scade',   '',    kbNoKey, cmCascade, hcMenus,
  450.       NewItem ('~N~ext',      'F6',  kbF6,    cmNext,    hcMenus,
  451.       NewItem ('~P~revious',  'Shift-F6', kbShiftF6, cmPrev, hcMenus,
  452.       NewItem ('~C~lose', 'Alt-F3',  kbAltF3, cmClose,   hcMenus,
  453.       NewLine (
  454.       NewItem ('~U~ser screen', 'Alt-F5',  kbAltF5, cmUserScreen, hcMenus,
  455.       nil)))))))))),
  456.     NewSubMenu ('~O~ptions', hcMenus, NewMenu (
  457.       NewSoundItem (hcMenus,
  458.       NewVideoItem (hcMenus,
  459.       NewItem ('~P~rint options...','', kbNoKey, cmPRN_SetOptions, hcMenus,
  460.       nil)))),
  461.     nil)
  462.   )))));
  463. end;
  464.  
  465.  
  466. procedure TMyApp.InitStatusLine;
  467. var  R:    TRect;
  468. begin
  469.   GetExtent (R);
  470.   R.A.Y := R.B.Y - 1;
  471.   StatusLine := New (PMyStatusLine, Init (R,
  472.     NewStatusDef (hcNoContext, hcDeskTop - 1,
  473.       NewStatusKey ('tvDMX',        kbNoKey,cmNoCmd,
  474.       nil),
  475.     NewStatusDef (hcDeskTop, hcDialogs - 1,
  476.       NewStatusKey ('tv~DMX~  ',    kbNoKey,cmNoCmd,
  477.       NewStatusKey ('~F2~ Dialog',    kbF2,    cmDialog,
  478.       NewStatusKey ('~F5~ Zoom',    kbF5,    cmZoom,
  479.       NewStatusKey ('~F6~ Next',    kbF6,    cmNext,
  480.       NewStatusKey ('~F9~ Print',    kbF9,    cmPrint,
  481.       NewStatusKey ('~F10~ Menu',    kbF10,    cmMenu,
  482.       nil)))))),
  483.     NewStatusDef (hcDialogs, hcMenus - 1,
  484.       NewStatusKey ('tvDMX',        kbNoKey,cmNoCmd,
  485.       NewStatusKey ('~Esc~ Cancel',    kbEsc,    cmCancel,
  486.       nil)),
  487.     NewStatusDef (hcMenus, $FFFF,
  488.       NewStatusKey ('tv~DMX~',        kbNoKey,cmNoCmd,
  489.       nil),
  490.     nil))))
  491.   ));
  492. end;
  493.  
  494.  
  495. procedure TMyApp.AccountWindow;
  496. var  R  : TRect;
  497.      W  : PDmxWindow;
  498. begin
  499.   AssignWinRect (R, length (AccountLabel) + 2, 0);
  500.   W := New (PDmxEditTblWin, Init (R,    { window rectangle }
  501.         'Accounts',        { window title }
  502.         wnNextAvail,        { window number }
  503.         AccountInfo,        { template string }
  504.         Accounts,        { data records }
  505.         sizeof (Accounts),    { data size }
  506.         AccountLabel,        { heading label }
  507.         7));            { indicator width }
  508.   W^.HelpCtx := hcAccounts;
  509.   DeskTop^.Insert (ValidView (W));
  510. end;
  511.  
  512.  
  513. procedure TMyApp.PayrollWindow;
  514. var  R     : TRect;
  515.      DMX : PDmxPayroll;
  516.      W     : PWindow;
  517. begin
  518.   AssignWinRect (R, length (PayrollLabelA) + 2, 0);
  519.   New (W, Init (R, 'Payroll', wnNextAvail));
  520.   With W^ do
  521.     begin
  522.     Options := Options or ofTileable;
  523.     HelpCtx := hcPayroll;
  524.     GetExtent (R);
  525.     R.Grow (-1,-3);        { adjust R for border and labels }
  526.     New (DMX, Init (PayrollInfo,    { template string }
  527.         Payroll,        { data records }
  528.         sizeof (Payroll),    { data size }
  529.         R,            { view rectangle }
  530.         New (PDmxLabels, InitInsert (W, @PayrollLabelA)),
  531.         New (PDmxRecInd, InitInsert (W, 7)),
  532.         StandardScrollBar (sbHandleKeyboard or sbHorizontal),
  533.         StandardScrollBar (sbHandleKeyboard or sbVertical))
  534.      );
  535.     Insert (DMX);
  536.     R.Assign (1, Size.Y - 3, pred(Size.X), Size.Y - 1);
  537.     Insert (New (PDmxLabels, Init (@PayrollLabelB, R)));
  538.     end;
  539.   DeskTop^.Insert (ValidView (W));
  540. end;
  541.  
  542.  
  543. procedure TMyApp.BusyWindow;
  544. var  R  : TRect;
  545.      W  : PDmxWindow;
  546.      BusyInfo : string;
  547.  
  548.     function  fldEnumDATE : string;
  549.     begin
  550.       fldEnumDATE :=  ^F + ^P+char(2) +
  551.     InitEnumField (TRUE, 0,0,
  552.         NewSItem ('  0?-',
  553.         NewSItem (' Jan-',
  554.         NewSItem (' Feb-',
  555.         NewSItem (' Mar-',
  556.         NewSItem (' Apr-',
  557.         NewSItem (' May-',
  558.         NewSItem (' Jun-',
  559.         NewSItem (' Jul-',
  560.         NewSItem (' Aug-',
  561.         NewSItem (' Sep-',
  562.         NewSItem (' Oct-',
  563.         NewSItem (' Nov-',
  564.         NewSItem (' Dec-',
  565.         NewSItem (' ERR-',
  566.         nil))))))))))))))
  567.     ) + ^H'B' +  { hide the upper byte of the month's field }
  568.     #0'ZW-'^Z + ^U+char(31) +
  569.     #0'ZZZW '^Z^F + ^P+char(-6) +
  570.     #0 + ^P+char(4);
  571.     end;
  572.  
  573. begin
  574.   BusyInfo    := 'B' + ^H        { hidden byte field }
  575.          + #0' ssssssssssssssssssss`ssssssssss'  { Name field }
  576.          + '| ###-##-#### '    { string of numerics only }
  577.          + '|($rrr,rrr.zz)'    { positive or negative currency }
  578.  
  579.         { DateTime type: }
  580.          + '|' + fldEnumDATE
  581.          + #0  + fldTIME    { constant defined in DMXGIZMA.PAS }
  582.  
  583.                  + '|iii ' + ^Z^R^S    { showzeroes/readonly/skip }
  584.          + '\iii '        { normal integer }
  585.          + '| HHHH:HHHH '    { hex longint value }
  586.          + '|RRR,RRR.RRR '    { positive values only }
  587.          + '| hh ' + ^Z^R;    { showzeroes/readonly field }
  588.  
  589.   AssignWinRect (R, length (BusyLabel) + 2, 0);
  590.   W := New (PDmxEditTblWin, Init (R,    { window rectangle }
  591.         'Busy Window',        { window title }
  592.         wnNextAvail,        { window number }
  593.         BusyInfo,        { template string }
  594.         BusyData,        { data records }
  595.         sizeof (BusyData),    { data size }
  596.         BusyLabel,        { heading label }
  597.         10));            { indicator width }
  598.   W^.HelpCtx := hcBusyWin;
  599.   DeskTop^.Insert (ValidView (W));
  600. end;
  601.  
  602.  
  603. procedure TMyApp.HexWindow;
  604. { uses objects in file tvDMXHEX.PAS }
  605. var  R  : TRect;
  606.      W  : PDmxWindow;
  607. begin
  608.   AssignWinRect (R, length (HexLabels) + 2, 0);
  609.   W := New (PDmxHexWin, Init (R, 'Hex Window', wnNextAvail,
  610.                   BusyData, sizeof (BusyData)));
  611.   W^.HelpCtx := hcHexWin;
  612.   DeskTop^.Insert (ValidView (W));
  613. end;
  614.  
  615.  
  616. procedure TMyApp.AccountDialog (P : PDmxEditTbl);
  617. var  R       : TRect;
  618.      Dialog  : PDialog;
  619.      B       : PButton;
  620.      A       : string;
  621.      Control : word;
  622. begin
  623.   Str (succ (P^.CurrentRecord), A);
  624.   DeskTop^.GetExtent (R);
  625.   Dialog := New (PDialog, Init (R, 'Account Record #' + A));
  626.   If (Dialog <> nil) then
  627.     begin
  628.     With Dialog^ do
  629.       begin
  630.       HelpCtx  := hcDialogs;
  631.       InsertField (Dialog, 5,2, TRUE,  ' ~T~ransaction', ' SSSSSSSSSSSSSSSSSSSSSSSSSS');
  632.       InsertField (Dialog, 2,5, TRUE,  '    ~D~ebit        Credit', ' rrr,rrr.zz  \ rrr,rrr.zz  ');
  633.       InsertField (Dialog, 6,8, FALSE, '~S~tatus: ', '~[Cleared]~'^X);
  634.       R.Assign (0, 10, 10, 12);
  635.       B := New (PButton, Init (R, 'O~K~', cmOK, bfDefault));
  636.       B^.Options := B^.Options or ofCenterX;
  637.       Insert (B);
  638.       SelectNext (FALSE);
  639.       SetData (Accounts [P^.CurrentRecord]);
  640.       end;
  641.     TrimDialog (Dialog);
  642.     Control := DeskTop^.ExecView (Dialog);
  643.     If (Control = cmOK) then
  644.       begin
  645.       { return record to table }
  646.       Dialog^.GetData (Accounts [P^.CurrentRecord]);
  647.       { redraw all windows that use Accounts }
  648.       Message (DeskTop, evBroadcast, cmDMX_DrawData, @Accounts);
  649.       end;
  650.     Dispose (Dialog, Done);
  651.     end;
  652. end;
  653.  
  654.  
  655. procedure TMyApp.PayrollDialog (P : PDmxPayroll);
  656. var  R       : TRect;
  657.      Dialog  : PDialog;
  658.      B       : PButton;
  659.      A       : string;
  660.      Control : word;
  661. begin
  662.   Str (succ (P^.CurrentRecord), A);
  663.   DeskTop^.GetExtent (R);
  664.   Dialog := New (PDialog, Init (R, 'Employee Record #' + A));
  665.   If (Dialog <> nil) then
  666.     begin
  667.     With Dialog^ do
  668.       begin
  669.       HelpCtx  := hcDialogs;
  670.       InsertField (Dialog, 2,2, FALSE, '~N~ame: ', ' ssssssssssssssssssssss');
  671.       InsertField (Dialog, 2,4, FALSE, '~I~D Number: ', ' ZZW ');
  672.       InsertField (Dialog, 2,6, FALSE, '~E~arnings: ', ' $rr,rrr.zz ');
  673.       InsertField (Dialog, 0,0, FALSE, '', 'r'^H#0'r'^H#0'r'^H)^.Hide;
  674.       R.Assign (0, 8, 10, 10);
  675.       B := New (PButton, Init (R, 'O~K~', cmOK, bfDefault));
  676.       B^.Options := B^.Options or ofCenterX;
  677.       Insert (B);
  678.       SelectNext (FALSE);
  679.       SetData (Payroll [P^.CurrentRecord]);
  680.       end;
  681.     TrimDialog (Dialog);
  682.     Control := DeskTop^.ExecView (Dialog);
  683.     If (Control = cmOK) then
  684.       begin
  685.       { return record to table }
  686.       Dialog^.GetData (Payroll [P^.CurrentRecord]);
  687.       P^.RecalcRecord;
  688.       { redraw all windows that use Payroll }
  689.       Message (DeskTop, evBroadcast, cmDMX_DrawData, @Payroll);
  690.       end;
  691.     Dispose (Dialog, Done);
  692.     end;
  693. end;
  694.  
  695.  
  696. procedure TMyApp.BusyDialog (P : PDmxEditTbl);
  697. var  R       : TRect;
  698.      Dialog  : PDialog;
  699.      B       : PButton;
  700.      A       : string;
  701.      Control : word;
  702. begin
  703.   Str (succ (P^.CurrentRecord), A);
  704.   DeskTop^.GetExtent (R);
  705.   Dialog := New (PDialog, Init (R, 'Busy Record #' + A));
  706.   If (Dialog <> nil) then
  707.     begin
  708.     With Dialog^ do
  709.       begin
  710.       HelpCtx  := hcDialogs;
  711.  
  712.       { The Read-Only and Hidden fields are also inserted into this view
  713.     so that the entire BusyInfo record structure is transferable.
  714.     They can be hidden using TView^.Hide() because InsertField() is
  715.     a function that returns a PView pointer --as demonstrated in the
  716.     following instance...
  717.        }
  718.       InsertField (Dialog, 0,  0, FALSE, '',  'B')^.Hide;
  719.       InsertField (Dialog, 2,  2, FALSE, '~N~ame:    ',  ' ssssssssssssssssssssssssssssss');
  720.       InsertField (Dialog, 2,  4, FALSE, '~S~SN:     ',  ' ###-##-#### ');
  721.       InsertField (Dialog, 2,  6, FALSE, '~B~alance: ',  '($rrr,rrr.zz)');
  722.       InsertField (Dialog,11,  8, TRUE,  '  ~D~ate         Time', fldDATETIME);
  723.       InsertField (Dialog, 0,  0, FALSE, '',  'i')^.Hide;
  724.       InsertField (Dialog, 2, 11, FALSE, '~I~nteger: ',  'iii');
  725.       InsertField (Dialog, 2, 13, FALSE, '~P~ointer: ',  ' HHHH:HHHH ');
  726.       InsertField (Dialog, 2, 14, FALSE, '~V~alue:   ',  'RRR,RRR.ZZRR ~pts~ ');
  727.       InsertField (Dialog, 0,  0, FALSE, '',  'B')^.Hide;
  728.  
  729.       R.Assign (0, 16, 10, 18);
  730.       B := New (PButton, Init (R, 'O~K~', cmOK, bfDefault));
  731.       B^.Options := B^.Options or ofCenterX;
  732.       Insert (B);
  733.       SelectNext (FALSE);
  734.       SetData (BusyData [P^.CurrentRecord]);
  735.       end;
  736.  
  737.     TrimDialog (Dialog);
  738.     Control := DeskTop^.ExecView (Dialog);
  739.     If (Control = cmOK) then
  740.       begin
  741.       { return record to table }
  742.       Dialog^.GetData (BusyData [P^.CurrentRecord]);
  743.       { redraw all windows that use BusyData }
  744.       Message (DeskTop, evBroadcast, cmDMX_DrawData, @BusyData);
  745.       end;
  746.     Dispose (Dialog, Done);
  747.     end;
  748. end;
  749.  
  750.  
  751.   { ══════════════════════════════════════════════════════════════════════ }
  752.  
  753.  
  754. procedure InitializeData;
  755. { creates test data }
  756. var  i,j  : integer;
  757.  
  758.     procedure InitAccount (ARecNum : integer;  AName : string);
  759.     begin
  760.       With Accounts [ARecNum] do
  761.     begin
  762.     Account    := AName;
  763.     Debit    := Random (50000) * 0.9;
  764.     Credit    := Random (50000) * 0.9;
  765.     Status    := (Credit > Debit);
  766.     end;
  767.     end;
  768.  
  769.     procedure InitBusyRec (ARecNum : integer;  AName : string);
  770.     var  i : integer;
  771.     begin
  772.       With BusyData [ARecNum] do
  773.     begin
  774.     Name    := AName;
  775.     intfield0  := ARecNum;
  776.     hextwo     := lo (ARecNum);
  777.     If ARecNum < 26 then
  778.       begin
  779.       intfield1    := random (255);
  780.       ptrfield    := pointer (random (MaxInt));
  781.       realfield1    := random (200) * random (200) / succ (random (199));
  782.       realfield2    := random (200) * random (200) / succ (random (199));
  783.       DT.Year    := 1988 + random (4);
  784.       DT.Month    := succ (random (12));
  785.       DT.Day    := succ (random (28));
  786.       DT.Hour    := random (24);
  787.       DT.Min    := random (60);
  788.       DT.Sec    := random (60);
  789.       SSN [0]    := #9;
  790.       For i := 1 to 9 do SSN [i] := chr (random (10) + 48);
  791.       end;
  792.     end;
  793.     end;
  794.  
  795.     procedure InitPayroll (ARecNum : integer;  AName : string);
  796.     begin
  797.       With Payroll [ARecNum] do
  798.     begin
  799.     Employee :=  AName;
  800.     If (ARecNum = 0) then ID := 44 else ID := Random (400);
  801.     Earnings :=  Random (3000) + 4000.0;
  802.     FICA     :=  Earnings * 0.075;
  803.     FITW     :=  Earnings * 0.28;
  804.     SITW     :=  Earnings * 0.05;
  805.     end;
  806.     end;
  807.  
  808. begin
  809.   RandSeed := 31;
  810.   fillchar (Accounts,  sizeof (Accounts),  0);
  811.   fillchar (Payroll,   sizeof (Payroll),   0);
  812.   fillchar (BusyData,  sizeof (BusyData),  0);
  813.  
  814.   InitAccount ( 0, 'ACME TOOL CO.');
  815.   InitAccount ( 1, 'READING R. R.');
  816.   InitAccount ( 2, 'EXXON CORP.');
  817.   InitAccount ( 3, 'ELECTRIC CO.');
  818.   InitAccount ( 4, 'B&O R. R.');
  819.   InitAccount ( 5, 'NYNEX');
  820.  
  821.   InitBusyRec ( 0, 'Abigail Adams');
  822.   InitBusyRec ( 1, 'Betty Boop');
  823.   InitBusyRec ( 2, 'Cindy Crawford');
  824.   InitBusyRec ( 3, 'Dana Delaney');
  825.   InitBusyRec ( 4, 'Eve Easton');
  826.   InitBusyRec ( 5, 'Farrah Fawcett');
  827.   InitBusyRec ( 6, 'Ginger Grant');
  828.   InitBusyRec ( 7, 'Holly Hunter');
  829.   InitBusyRec ( 8, 'Ida Inman');
  830.   InitBusyRec ( 9, 'Janet Jackson');
  831.   InitBusyRec (10, 'Katie Kingfield');
  832.   InitBusyRec (11, 'Lois Lane');
  833.   InitBusyRec (12, 'Marilyn Monroe');
  834.   InitBusyRec (13, 'Nichelle Nichols');
  835.   InitBusyRec (14, 'Olive Oyl');
  836.   InitBusyRec (15, 'Paula Prentiss');
  837.   InitBusyRec (16, 'Quia Quinn');
  838.   InitBusyRec (17, 'Rita Rudner');
  839.   InitBusyRec (18, 'Samantha Stevens');
  840.   InitBusyRec (19, 'Tina Turner');
  841.   InitBusyRec (20, 'Ute Ueberroth');
  842.   InitBusyRec (21, 'Vicky Vail');
  843.   InitBusyRec (22, 'Wendy Wilson');
  844.   InitBusyRec (23, 'Xuxa');
  845.   InitBusyRec (24, 'Yara Yokomuro');
  846.   InitBusyRec (25, 'Zelda Zimmerman');
  847.  
  848.   For i := 26 to MaxRecordNum do InitBusyRec (i, '');
  849.   BusyData [0].SSN  := '';
  850.  
  851.   InitPayroll ( 0, 'Alex Trebek');
  852.   InitPayroll ( 1, 'Pat Sajak');
  853.   InitPayroll ( 2, 'Vanna White');
  854.   InitPayroll ( 3, 'Merv Griffin');
  855. end;
  856.  
  857.  
  858.   { ══════════════════════════════════════════════════════════════════════ }
  859.  
  860. var  MyApp  : TMyApp;
  861.  
  862. Begin
  863.   PrnOpt.Len  := 55;  { change from default value set in tvDMXREP.PAS }
  864.   MyApp.Init;
  865.   MyApp.Run;
  866.   MyApp.Done;
  867. End.
  868.