home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / dtx9203 / tvision / dlgbuild.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1992-03-24  |  147.0 KB  |  3,750 lines

  1. (* **************************************************************** *)
  2. (*                          DIALOGBOX-BUILDER                       *)
  3. (*                                                                  *)
  4. (* DlgBuild ist der "Slot", der sich um die Erstellung von Dialog-  *)
  5. (* boxen kümmert. Ein neuer Dialog kann in die Arbeitsfläche einge- *)
  6. (* fügt werden, indem mit der rechten Maustaste der leere Desktop   *)
  7. (* angeklickt wird oder über das Menü (siehe TOOL). Ein neues Ele-  *)
  8. (* ment kann in den Dialog eingefügt werden, indem mit der rechten  *)
  9. (* Maustaste die leere Dialogfläche angeklickt wird. Überarbeitet   *)
  10. (* werden können Elemente und Dialog mit nochmaligem Klick der      *)
  11. (* rechten Maustaste; das selektierte Element kann über Alt-B eben- *)
  12. (* falls bearbeitet werden; der selektierte Dialog über Alt-D.      *)
  13. (*                                                                  *)
  14. (* tWorkDialog ist das wichtigste Objekt dieser Unit. Es kümmert    *)
  15. (* sich um das Speichern des Dialoges als Quellcode oder als Res-   *)
  16. (* source und um das Einfügen von sogenannten "Templates", Gruppen, *)
  17. (* die entweder nur eine View (z.B. ein tStaticText) oder auch      *)
  18. (* eine zusammengehörende Gruppe (z.B. ein tInputLine plus tHistory *)
  19. (* plus tLabel) enthalten. Damit ein modulares "Zusammenstecken"    *)
  20. (* verschiedener Templates möglich ist, ohne dass tWorkDialog alle  *)
  21. (* verschiedenen Elementarten (tStaticText, tInputLine etc) kennen  *)
  22. (* muss, sind drei prozedurale Arrays nötig, die für jedes Element  *)
  23. (* die zugehörigen drei Prozeduren aufnehmen müssen. Diese Pro-     *)
  24. (* zeduren kümmern sich um das Speichern eines Elements, um den     *)
  25. (* Dialog, in dem die Elementdaten eingegeben werden können, und um *)
  26. (* das Erstellen einer Kopie eines Elements.                        *)
  27. (*                                                                  *)
  28. (* Die folgende Darstellung soll die interne Struktur dieser Units  *)
  29. (* und die Abhängigkeiten der Objekte und Prozeduren untereinander  *)
  30. (* zeigen, wobei Objekte mit einem doppelten Rahmen versehen sind   *)
  31. (* und Prozeduren (bzw prozedurale Arrays) mit einem einfachen:     *)
  32. (*                                                                  *)
  33. (*┌────────────────────────────────────────────────────────────────┐*)
  34. (*│                H A U P T P R O G R A M M                       │*)
  35. (*└────────────────────────────────────────────────────────────────┘*)
  36. (*                              ⌡                       │           *)
  37. (*                          ┌─────────────┐             │           *)
  38. (*                          │  Itemsmenu  │             │           *)
  39. (*                        ┌ └─────────────┘             │           *)
  40. (*                   (2.) ⌡ ⌠ (1.)                      ⌡           *)
  41. (*┌──────────────────┐    │╔═══════════════╗     ┌─────────────────┐*)
  42. (*│ ItemsDialogArray │ «──┘║  tWorkDialog  ║ ──» │ NewOrEditDialog │*)
  43. (*└──────────────────┘     ╚═══════════════╝     └─────────────────┘*)
  44. (*        ⌠  ║                 │  ^                     ║           *)
  45. (*        │  ║                 │  ╚═════════════════════╣           *)
  46. (*        │  ╚════════════» ╔═════════════╗             ║           *)
  47. (*        └──────────────── ║  tTemplate  ║  «══════════╝           *)
  48. (*                          ╚═════════════╝                         *)
  49. (*                                                                  *)
  50. (* ⌠⌡»«^ mussten als Pfeilspitzen herhalten. Doppelt gezeichnete    *)
  51. (* Pfeil bedeuten, dass das Ziel manipuliert oder erstellt wird;    *)
  52. (* einfache Pfeile bedeuten, dass die Prozedur aufgerufen wird;     *)
  53. (* die einfach gezeichnete Verbindung zwischen tWorkDialog und      *)
  54. (* tTemplate bedeutet, dass tWorkDialog diesen Objekttyp (und ihre  *)
  55. (* Nachkommen sowie andere Objekte) enthält). Klar ersichtlich      *)
  56. (* wird, dass tWorkDialog eine zentrale Rolle spielt, was sich in   *)
  57. (* seiner HandleEvent-Methode niederschlägt: Sie muss unzählige     *)
  58. (* Messages bearbeiten. Die Skizze vereinfacht die Struktur dieser  *)
  59. (* Unit, zeigt aber doch die wichtigsten Grundrisse. So kann        *)
  60. (* tWorkDialog ItemsMenu aufrufen (1.) oder ItemsMenu kann vom      *)
  61. (* Systemmenü aus ausgeführt worden sein. Beide Male ist es tWork-  *)
  62. (* Dialog, der sich um das Ausführen von ItemsDialogArray (2.)      *)
  63. (* und um das Einfügen des erstellten Elementes kümmern muss.       *)
  64. (* Auch wird ersichtlich, dass die Bindung zwischen Hauptprogramm   *)
  65. (* und DLGBUILD bewusst locker gehalten wurde: Es wird fast nur     *)
  66. (* über die zwei Prozeduren NewOrEditDialog und ItemsMenu ge-       *)
  67. (* arbeitet und natürlich über Befehle.                             *)
  68. (*                                                                  *)
  69. (*               (c) 1992 by R.Reichert & DMV-Verlag                *)
  70. (* **************************************************************** *)
  71. UNIT DlgBuild;
  72.  
  73. {$F+}
  74.  
  75. INTERFACE
  76.  
  77. USES Objects, Drivers, Memory, HistList, Views,
  78.      Dialogs, Menus, Fields, Editors, App, MsgBox, ToolCmds;
  79.  
  80. TYPE
  81.   pPoint    = ^tPoint;
  82.   pTextFile = ^Text;
  83.  
  84.   pStringColl = ^tStringColl;
  85.   tStringColl = OBJECT (tStringCollection)
  86.     FUNCTION Compare (Key1, Key2: POINTER): INTEGER;          VIRTUAL;
  87.   END;
  88.  
  89.   pSortedViewCollection = ^tSortedViewCollection;
  90.   tSortedViewCollection = OBJECT (tSortedCollection)
  91.     FUNCTION Compare (Key1, Key2: POINTER): INTEGER;          VIRTUAL;
  92.   END;
  93.  
  94.   pTemplate = ^tTemplate;
  95.   tTemplate = OBJECT (tGroup)
  96.     Client:  pView;        { die eigentliche View                    }
  97.     MinSize,               { minimale                                }
  98.     MaxSize: tPoint;       { und maximale Grösse                     }
  99.     Name:    pString;      { der "Name" der Template                 }
  100.     ID:      INTEGER;      { Erkennungsnummer (siehe Konstanten)     }
  101.     DelSelf: BOOLEAN;      { wird nur bei Empfang von cmDeleteTempl
  102.                              auf TRUE gesetzt, damit der Destruktor
  103.                              entsprechend reagieren kann (siehe
  104.                              tExtendedTemplate.Done)                 }
  105.  
  106.     CONSTRUCTOR Init (aClient:  pView;
  107.                       aMinSize,
  108.                       aMaxSize: tPoint;
  109.                       aName:    STRING;
  110.                       aID:      INTEGER);
  111.     CONSTRUCTOR Load (VAR S: tStream);
  112.     PROCEDURE Store (VAR S: tStream);
  113.     PROCEDURE HandleEvent (VAR Event: tEvent);                VIRTUAL;
  114.     PROCEDURE SetState (AState: Word; Enable: Boolean);       virtual;
  115.     PROCEDURE ChangeBounds (VAR Bounds: tRect);               VIRTUAL;
  116.     FUNCTION GetPalette: pPalette;                            VIRTUAL;
  117.     FUNCTION Valid (Command: WORD): BOOLEAN;                  VIRTUAL;
  118.     PROCEDURE Draw;                                           VIRTUAL;
  119.     DESTRUCTOR Done;                                          VIRTUAL;
  120.   END;
  121.  
  122.   pExtendedTemplate = ^tExtendedTemplate;
  123.   tExtendedTemplate = OBJECT (tTemplate)
  124.     ScrollBar: pScrollBar; { nur Referenzzeiger, werden bei der Ver- }
  125.     History:   pHistory;   { schiebung benötigt                      }
  126.     Lab:       pLabel;    { das Label wird in die Template eingefügt }
  127.  
  128.     CONSTRUCTOR Init (aClient:    pView;
  129.                       aLabel:     pLabel;
  130.                       aScrollBar: pScrollBar;
  131.                       aHistory:   pHistory;
  132.                       aMinSize,
  133.                       aMaxSize:   tPoint;
  134.                       aName:      STRING;
  135.                       aID:        INTEGER);
  136.     CONSTRUCTOR Load (VAR S: tStream);
  137.     PROCEDURE Store (VAR S: tStream);
  138.     PROCEDURE Draw;                                           VIRTUAL;
  139.     PROCEDURE NewChangeBounds (R1, R2: tRect);                VIRTUAL;
  140.     PROCEDURE ChangeBounds (VAR Bounds: tRect);               VIRTUAL;
  141.     DESTRUCTOR Done;                                          VIRTUAL;
  142.   END;
  143.  
  144.   pWorkDialog = ^tWorkDialog;
  145.   tWorkDialog = OBJECT (tDialog)
  146.     Saved: BOOLEAN;  { Dialog auf Stream/als Quelltext gespeichert ? }
  147.  
  148.     CONSTRUCTOR Init (VAR Bounds: tRect; aTitle: tTitleStr);
  149.     CONSTRUCTOR Load (VAR S: tStream);
  150.     PROCEDURE SetTitle (aTitle: STRING);
  151.     PROCEDURE SaveAsResource (Where: POINTER; What: BYTE);
  152.     PROCEDURE SaveAsSource (Where: POINTER;
  153.                             AsProcedure: BOOLEAN;
  154.                             What: BYTE);
  155.     PROCEDURE HandleEvent (VAR Event: tEvent);                VIRTUAL;
  156.   END;
  157.  
  158.   pWorkDialog_Dialog = ^tWorkDialog_Dialog;
  159.   tWorkDialog_Dialog = OBJECT (tDialog)
  160.     CONSTRUCTOR Init (Dlg: pDialog);
  161.     PROCEDURE HandleEvent (VAR Event: tEvent);                VIRTUAL;
  162.     FUNCTION Valid (Command: WORD): BOOLEAN;                  VIRTUAL;
  163.   END;
  164.  
  165.   pTemplDialog = ^tTemplDialog;
  166.   tTemplDialog = OBJECT (tDialog)
  167.     PROCEDURE HandleEvent (VAR Event: tEvent);                VIRTUAL;
  168.     FUNCTION Valid (Command: WORD): BOOLEAN;                  VIRTUAL;
  169.   END;
  170.  
  171.   pClusterDialog = ^tClusterDialog;
  172.   tClusterDialog = OBJECT (tTemplDialog)
  173.     List:    pStringCollection;
  174.     ListBox: pListBox;
  175.  
  176.     CONSTRUCTOR Init (aTitle: tTitleStr;
  177.                       aList:  pStringCollection;
  178.                       DelButton: BOOLEAN);
  179.     PROCEDURE HandleEvent (VAR Event: tEvent);                VIRTUAL;
  180.   END;
  181.  
  182.   ItemDialogProcedure = FUNCTION  (Where:     pPoint;
  183.                                    VAR Templ: pTemplate;
  184.                                    Dlg:       pWorkDialog): STRING;
  185.   InsertItemProcedure = PROCEDURE (Templ:  pTemplate;
  186.                                    Dialog: pDialog);
  187.   SaveItemSourceProc  = PROCEDURE (What:  BYTE;
  188.                                    Templ: pTemplate;
  189.                                    Lines: pStringColl);
  190.  
  191. PROCEDURE NewOrEditDialog (Dlg: pDialog);
  192.  
  193. FUNCTION GetItemsMenu: pMenu;
  194.  
  195. FUNCTION ItemsMenu (Where: tPoint): INTEGER;
  196.  
  197. PROCEDURE OtherFieldsDialog (Dlg: pDialog);
  198.  
  199.  
  200. FUNCTION StaticTextDialog   (Where:     pPoint;
  201.                              VAR Templ: pTemplate;
  202.                              Dlg:       pWorkDialog): STRING;
  203. FUNCTION ButtonDialog       (Where:     pPoint;
  204.                              VAR Templ: pTemplate;
  205.                              Dlg:       pWorkDialog): STRING;
  206. FUNCTION OkButtonDialog     (Where:     pPoint;
  207.                              VAR Templ: pTemplate;
  208.                              Dlg:       pWorkDialog): STRING;
  209. FUNCTION CancelButtonDialog (Where:     pPoint;
  210.                              VAR Templ: pTemplate;
  211.                              Dlg:       pWorkDialog): STRING;
  212. FUNCTION YesButtonDialog    (Where:     pPoint;
  213.                              VAR Templ: pTemplate;
  214.                              Dlg:       pWorkDialog): STRING;
  215. FUNCTION NoButtonDialog     (Where:     pPoint;
  216.                              VAR Templ: pTemplate;
  217.                              Dlg:       pWorkDialog): STRING;
  218. FUNCTION HelpButtonDialog   (Where:     pPoint;
  219.                              VAR Templ: pTemplate;
  220.                              Dlg:       pWorkDialog): STRING;
  221. FUNCTION InputLineDialog    (Where:     pPoint;
  222.                              VAR Templ: pTemplate;
  223.                              Dlg:       pWorkDialog): STRING;
  224. FUNCTION ListBoxDialog      (Where:     pPoint;
  225.                              VAR Templ: pTemplate;
  226.                              Dlg:       pWorkDialog): STRING;
  227. FUNCTION MemoDialog         (Where:     pPoint;
  228.                              VAR Templ: pTemplate;
  229.                              Dlg:       pWorkDialog): STRING;
  230. FUNCTION ClusterDialog      (Where:     pPoint;
  231.                              VAR Templ: pTemplate;
  232.                              Dlg:       pWorkDialog;
  233.                              RadioButtons: BOOLEAN): STRING;
  234. FUNCTION CheckBoxesDialog   (Where:     pPoint;
  235.                              VAR Templ: pTemplate;
  236.                              Dlg:       pWorkDialog): STRING;
  237. FUNCTION RadioButtonsDialog (Where:     pPoint;
  238.                              VAR Templ: pTemplate;
  239.                              Dlg:       pWorkDialog): STRING;
  240.  
  241.  
  242. PROCEDURE InsertStaticText   (Templ:  pTemplate;
  243.                               Dialog: pDialog);
  244. PROCEDURE InsertButton       (Templ:  pTemplate;
  245.                               Dialog: pDialog);
  246. PROCEDURE InsertInputLine    (Templ:  pTemplate;
  247.                               Dialog: pDialog);
  248. PROCEDURE InsertListBox      (Templ:  pTemplate;
  249.                               Dialog: pDialog);
  250. PROCEDURE InsertMemo         (Templ:  pTemplate;
  251.                               Dialog: pDialog);
  252. PROCEDURE InsertCluster      (Templ:  pTemplate;
  253.                               Dialog: pDialog;
  254.                               RadioButtons: BOOLEAN);
  255. PROCEDURE InsertRadioButtons (Templ:  pTemplate;
  256.                               Dialog: pDialog);
  257. PROCEDURE InsertCheckBoxes   (Templ:  pTemplate;
  258.                               Dialog: pDialog);
  259.  
  260.  
  261. PROCEDURE StaticTextSource   (What:  BYTE;
  262.                               Templ: pTemplate;
  263.                               Lines: pStringColl);
  264. PROCEDURE ButtonSource       (What:  BYTE;
  265.                               Templ: pTemplate;
  266.                               Lines: pStringColl);
  267. PROCEDURE InputLineSource    (What:  BYTE;
  268.                               Templ: pTemplate;
  269.                               Lines: pStringColl);
  270. PROCEDURE ListBoxSource      (What:  BYTE;
  271.                               Templ: pTemplate;
  272.                               Lines: pStringColl);
  273. PROCEDURE MemoSource         (What:  BYTE;
  274.                               Templ: pTemplate;
  275.                               Lines: pStringColl);
  276. PROCEDURE ClusterSource      (What:  BYTE;
  277.                               Templ: pTemplate;
  278.                               Lines: pStringColl;
  279.                               TypeOfCluster: STRING);
  280. PROCEDURE RadioButtonsSource (What:  BYTE;
  281.                               Templ: pTemplate;
  282.                               Lines: pStringColl);
  283. PROCEDURE CheckBoxesSource   (What:  BYTE;
  284.                               Templ: pTemplate;
  285.                               Lines: pStringColl);
  286.  
  287.  
  288. PROCEDURE RegisterDlgBuild;
  289.  
  290.  
  291. CONST
  292.   MinItemSize:   tPoint = (X: 2;  Y: 1); { min.Grösse für alle Items }
  293.   MinButtonSize: tPoint = (X: 3;  Y: 2); { für Buttons               }
  294.   MinLabelSize:  tPoint = (X: 2;  Y: 2); { für Items mit Labels      }
  295.   MaxItemSize:   tPoint = (X: 80; Y: 25);{ max.Grösse für alle Items }
  296.  
  297.                          { Item-Identifizierungsnummern:             }
  298.   idNoItem      = -1;    { kein Item; Menü abgebrochen               }
  299.   idStaticText  =  0;    { StaticText einfügen                       }
  300.   idButton      =  1;    { Button einfügen                           }
  301.   idOkButton    =  2;    { OK-Button einfügen                        }
  302.   idCancelButton=  3;    { Cancel-Button                             }
  303.   idYesButton   =  4;    { Yes-BUtton                                }
  304.   idNoButton    =  5;    { No-Button                                 }
  305.   idHelpButton  =  6;    { Help-Button                               }
  306.   idInputLine   =  7;    { Eingabezeile plus Label einfügen          }
  307.   idListBox     =  8;    { Eine Listbox optional mit Scrollbalken    }
  308.   idMemo        =  9;    { Ein Memofeld optional mit Scrollbalken    }
  309.   idRadioButtons= 10;    { RadioButtons plus Label                   }
  310.   idCheckBoxes  = 11;    { CheckBoxes plus Label                     }
  311.  
  312.   cmStatictext  = 5000;  { Item-Menünummern: -> -5000 = Item-ID      }
  313.   cmButton      = 5001;
  314.   cmOkButton    = 5002;
  315.   cmCancelButton= 5003;
  316.   cmYesButton   = 5004;
  317.   cmNoButton    = 5005;
  318.   cmHelpButton  = 5006;
  319.   cmInputLine   = 5007;
  320.   cmListBox     = 5008;
  321.   cmMemo        = 5009;
  322.   cmRadioButtons= 5010;
  323.   cmCheckBoxes  = 5011;
  324.  
  325.                          { Befehle an tWorkDialog:                   }
  326.   cmSaveDlgAsR = 7000;   { cmSaveDialogAsResource                    }
  327.     cmSaveInc  =    1;   { cmSaveIncFile, das das REZ-File benutzt   }
  328.     cmSaveRez  =    2;   { cmSaveRezFile, die eigentlichen Daten     }
  329.   cmSaveDlgAsP = 7003;   { cmSaveDialogAsProcedure -> Source         }
  330.   cmSaveDlgAsO = 7004;   { cmSaveDialogAsObject -> Source; Teile:    }
  331.     cmSaveDef  =    1;   { cmSave(Type)Definition                    }
  332.     cmSaveCon  =    2;   { cmSaveConstructor                         }
  333.     cmSavePrc  =    3;   { cmSaveProcedure, die das Objekt benutzt   }
  334.     cmSaveAll  =    4;   { cmSaveAll(these parts)                    }
  335.   cmWhoIsDlg   = 8000;   { cmWhoIsDlgDialog with Name ...            }
  336.   cmDeleteDlg  = 8001;   { cmDeleteDialog                            }
  337.   cmNewTempl   = 8004;   { cmNewTemplate in den Dialog einfügen      }
  338.   cmDeleteTempl= 8005;   { cmDeleteTemplate bzw wieder entfernen     }
  339.  
  340.   cmOtherF     = 8010;   { cmOtherFields (für tWorkDialog_Dialog)    }
  341.  
  342.                          { Befehle an tTemplate:                     }
  343.   cmWhoIsTempl = 8002;   { cmWhoIsTemplate with Name ...             }
  344.   cmEditTempl  = 8006;   { cmEditTemplate                            }
  345.  
  346.                          { für tClusterDialog-Buttons:               }
  347.   cmNewItem    = 9000;   { neues Listenelement anfügen               }
  348.   cmEditItem   = 9001;   { Element bearbeiten                        }
  349.   cmDeleteItem = 9002;   { Element löschen                           }
  350.  
  351.                          { für die SaveSourceArray-Prozeduren:       }
  352.   SaveTypeDef  =    0;   { Type-Definition speichern                 }
  353.   SaveInsertDef=    1;   { oder die Einfüge-Befehle                  }
  354.  
  355.                          { Die prozeduralen Arrays für die Elemente: }
  356.   ItemDialogArray : ARRAY [0..11] OF ItemDialogProcedure =
  357.                       (StaticTextDialog,
  358.                        ButtonDialog,
  359.                        OkButtonDialog,
  360.                        CancelButtonDialog,
  361.                        YesButtonDialog,
  362.                        NoButtonDialog,
  363.                        HelpButtonDialog,
  364.                        InputLineDialog,
  365.                        ListBoxDialog,
  366.                        MemoDialog,
  367.                        RadioButtonsDialog,
  368.                        CheckBoxesDialog);
  369.   InsertItemArray  : ARRAY [0..11] OF InsertItemProcedure =
  370.                       (InsertStaticText,
  371.                        InsertButton,
  372.                        InsertButton,
  373.                        InsertButton,
  374.                        InsertButton,
  375.                        InsertButton,
  376.                        InsertButton,
  377.                        InsertInputLine,
  378.                        InsertListBox,
  379.                        InsertMemo,
  380.                        InsertRadioButtons,
  381.                        InsertCheckBoxes);
  382.   SaveSourceArray : ARRAY [0..11] OF SaveItemSourceProc =
  383.                       (StaticTextSource,
  384.                        ButtonSource,
  385.                        ButtonSource,
  386.                        ButtonSource,
  387.                        ButtonSource,
  388.                        ButtonSource,
  389.                        ButtonSource,
  390.                        InputLineSource,
  391.                        ListBoxSource,
  392.                        MemoSource,
  393.                        RadioButtonsSource,
  394.                        CheckBoxesSource);
  395.  
  396.   rTemplate: tStreamRec = (
  397.     ObjType: 5000;
  398.     VmtLink: Ofs (TypeOf (tTemplate)^);
  399.     Load:    @tTemplate.Load;
  400.     Store:   @tTemplate.Store);
  401.   rExtendedTemplate: tStreamRec = (
  402.     ObjType: 5001;
  403.     VmtLink: Ofs (TypeOf (tExtendedTemplate)^);
  404.     Load:    @tExtendedTemplate.Load;
  405.     Store:   @tExtendedTemplate.Store);
  406.   rWorkDialog: tStreamRec = (
  407.     ObjType: 5002;
  408.     VmtLink: Ofs (TypeOf (tWorkDialog)^);
  409.     Load:    @tWorkDialog.Load;
  410.     Store:   @tDialog.Store);
  411.  
  412. IMPLEMENTATION
  413.  
  414. CONST
  415.   Lines      : pStringColl = NIL;  { Zur Speicherung des Quelltextes }
  416.   InsertStr  : STRING  = '';       { entweder leer oder "Dialog^.",
  417.                                      wird für tWorkDialog.SaveAs-
  418.                                      Source benötigt                 }
  419.   InputLineNo: INTEGER = 0; { für Nummerierung der TYPE-Felder bei   }
  420.   ListBoxNo  : INTEGER = 0; { der Quelltexterzeugung durch tWork-    }
  421.   MemoNo     : INTEGER = 0; { Dialog.SaveAsSource, damit keine iden- }
  422.   ClusterNo  : INTEGER = 0; { tischen Feldernamen entstehen          }
  423.  
  424. (* ---------------------------------------------------------------- *)
  425. (* Zahl in String umwandeln. Wird bei Quelltexterzeugung benötigt.  *)
  426. (* ---------------------------------------------------------------- *)
  427. FUNCTION Int2Str (n: INTEGER): STRING;
  428.   VAR S: string[5];
  429. BEGIN
  430.   Str (n, s);
  431.   Int2Str := s;
  432. END;
  433.  
  434. (* ---------------------------------------------------------------- *)
  435. (* KillInvalidChars entfernt alle nicht-Buchstaben und alle Zahlen, *)
  436. (* die vor dem ersten Buchstaben auftreten, aus s. Wird bei         *)
  437. (* Quelltexterzeugung gebraucht, damit Prozedurnamen nicht          *)
  438. (* ungültige Zeichen enthalten.                                     *)
  439. (* ---------------------------------------------------------------- *)
  440. FUNCTION KillInvalidChars (s: STRING): STRING;
  441.   VAR i: BYTE;
  442. BEGIN
  443.   i := 0;
  444.   WHILE i < Length (s) DO BEGIN
  445.     Inc (i);
  446.     IF s[i] = 'ü' THEN s[i] := 'u';  IF s[i] = 'Ü' THEN s[i] := 'U';
  447.     IF s[i] = 'ö' THEN s[i] := 'o';  IF s[i] = 'Ö' THEN s[i] := 'O';
  448.     IF s[i] = 'ä' THEN s[i] := 'a';  IF s[i] = 'Ä' THEN s[i] := 'A';
  449.     IF NOT (((s[i] >= 'A') AND (s[i] <= 'Z')) OR
  450.             ((s[i] >= 'a') AND (s[i] <= 'z')) OR
  451.             ((s[i] >= '0') AND (s[i] <= '9') AND (i>1))) THEN BEGIN
  452.       Delete (s, i, 1);
  453.       Dec (i);
  454.     END;
  455.   END;
  456.   KillInvalidChars := S;
  457. END;
  458.  
  459. (* ---------------------------------------------------------------- *)
  460. (* TypeDefinition wird sowohl von tWorkDialog.SaveAsSource als auch *)
  461. (* von tWorkDialog.SaveAsResource benötigt. Es speichert die Typen- *)
  462. (* definition, die in den vom Programm erzeugten Quelltext eingefügt*)
  463. (* werden soll. Title gibt den Namen des Dialoges an, ViewColl die  *)
  464. (* Kollektion, die die Views des Dialoges enthält; in Data wird zu- *)
  465. (* rückgegeben, ob der Dialog überhaupt eine Typendefinition        *)
  466. (* benötigt, und in DataName wird der Name des Datenrecords ge-     *)
  467. (* liefert. Geschrieben wird in Lines, der unitprivaten String-     *)
  468. (* kollektion, die vom Aufrufer initialisiert worden sein muss.     *)
  469. (* ---------------------------------------------------------------- *)
  470. PROCEDURE TypeDefinition (Title: STRING;
  471.                           ViewColl: pSortedViewCollection;
  472.                           VAR Data: BOOLEAN;
  473.                           VAR DataName: STRING);
  474.  
  475.   PROCEDURE InsertTypeDef (P: pTemplate); FAR;
  476.   BEGIN
  477.     SaveSourceArray [P^.ID] (SaveTypeDef, P, Lines);
  478.   END;
  479.  
  480.   VAR Delta: INTEGER;
  481.  
  482.  BEGIN
  483.   DataName := KillInvalidChars (Title)+'Data';
  484.   Lines^.Insert (NewStr ('  TYPE'));
  485.   Lines^.Insert (NewStr ('    '+DataName+' = RECORD'));
  486.   Delta := Lines^.Count;
  487.   ViewColl^.ForEach (@InsertTypeDef);
  488.   IF Lines^.Count = Delta THEN BEGIN
  489.     Lines^.AtFree (Delta-1);
  490.     Lines^.AtFree (Delta-2);
  491.     Data := FALSE;
  492.   END ELSE BEGIN
  493.     Lines^.Insert (NewStr ('    END;'));
  494.     Lines^.Insert (NewStr ('  '));
  495.     Data := TRUE;
  496.   END;
  497. END;
  498.  
  499. (* ---------------------------------------------------------------- *)
  500. (* Auch ExecuteDialog wird von den oben genannten Methoden benötigt.*)
  501. (* Es schreibt den Code zum Ausführen eines Dialoges, wobei Data    *)
  502. (* wieder angibt, ob dieser Dialog Datenaustausch erledigt, und     *)
  503. (* DataName für diesen Fall den Namen des Records enthält.          *)
  504. (* ---------------------------------------------------------------- *)
  505. PROCEDURE ExecuteDialog (Data: BOOLEAN; DataName: STRING);
  506. BEGIN
  507.   IF Data THEN BEGIN
  508.     Lines^.Insert (NewStr ('    { Datenrecord initialisieren ! }'));
  509.     Lines^.Insert (NewStr ('  FillChar (Data, SizeOf ('+DataName+'), 0);'));
  510.     Lines^.Insert (NewStr ('  Dialog^.SetData (Data); '));
  511.   END;
  512.   Lines^.Insert (NewStr ('  Code := Desktop^.ExecView (Application^.ValidView (Dialog));'));
  513.   Lines^.Insert (NewStr ('  IF Code <> cmCancel THEN BEGIN'));
  514.   Lines^.Insert (NewStr ('    { cmCancel muss ev ersetzt werden }'));
  515.   Lines^.Insert (NewStr ('    { Code auswerten }'));
  516.   IF Data THEN BEGIN
  517.     Lines^.Insert (NewStr ('    Dialog^.GetData (Data);'));
  518.     Lines^.Insert (NewStr ('    { Data muss ausgewertet werden ! }'));
  519.   END;
  520.   Lines^.Insert (NewStr ('  END;'));
  521.   Lines^.Insert (NewStr ('  IF Dialog <> NIL THEN '));
  522.   Lines^.Insert (NewStr ('    Dispose (Dialog, Done);'));
  523. END;
  524.  
  525. (* ---------------------------------------------------------------- *)
  526. (* GetItems erzeugt eine pSItem-Liste mit den Elementen aus der     *)
  527. (* Stringkollektion Collection und wird bei der Erzeugung von       *)
  528. (* tCluster-Nachkommen gebraucht, da im ClusterDialog die Elemente  *)
  529. (* für den Cluster in eine Kollektion eingefügt werden. GetItems    *)
  530. (* muss daher dieses "Type-Casting" vornehmen.                      *)
  531. (* ---------------------------------------------------------------- *)
  532. FUNCTION GetItems (Collection: pStringCollection): pSItem;
  533.   VAR
  534.     S, Root: pSItem;
  535.     i: INTEGER;
  536. BEGIN
  537.   IF Collection^.Count > 0 THEN BEGIN
  538.     S := NewSItem (String (Collection^.Items^[0]^), NIL);
  539.     Root := S;
  540.     FOR i := 1 TO Collection^.Count-1 DO BEGIN
  541.       S^.Next := NewSItem (String (Collection^.Items^[i]^), NIL);
  542.       S := S^.Next;
  543.     END;
  544.     GetItems := Root;
  545.   END ELSE
  546.     GetItems := NIL;
  547. END;
  548.  
  549. (* ---------------------------------------------------------------- *)
  550. (* GetClientBounds errechnet die Begrenzungen des Client der        *)
  551. (* Template Templ und gibt diese in Bounds zurück. Wird von einigen *)
  552. (* InsertItemArray-Prozeduren benötigt.                             *)
  553. (* ---------------------------------------------------------------- *)
  554. PROCEDURE GetClientBounds (Templ: pTemplate;
  555.                            VAR Bounds: tRect);
  556.   VAR Client: pView;
  557. BEGIN
  558.   Client := Templ^.Client;
  559.   Bounds.A.X := Templ^.Origin.X + Client^.Origin.X;
  560.   Bounds.B.X := Bounds.A.X      + Client^.Size.X;
  561.   Bounds.A.Y := Templ^.Origin.Y + Client^.Origin.Y;
  562.   Bounds.B.Y := Bounds.A.Y      + Client^.Size.Y;
  563. END;
  564.  
  565. (* ---------------------------------------------------------------- *)
  566. (* GetLabelBounds errechnet die Begrenzungen des Labels der         *)
  567. (* Template Templ und gibt diese in Bounds zurück. Wird von einigen *)
  568. (* InsertItemArray-Prozeduren benötigt.                             *)
  569. (* ---------------------------------------------------------------- *)
  570. PROCEDURE GetLabelBounds (Templ: pTemplate;
  571.                           VAR Bounds: tRect);
  572.   VAR Lab: pLabel;
  573. BEGIN
  574.   Lab        := pExtendedTemplate (Templ)^.Lab;
  575.   Bounds.A.X := Templ^.Origin.X + Lab^.Origin.X;
  576.   Bounds.B.X := Bounds.A.X      + Lab^.Size.X;
  577.   Bounds.A.Y := Templ^.Origin.Y + Lab^.Origin.Y;
  578.   Bounds.B.Y := Succ (Bounds.A.Y);
  579. END;
  580.  
  581. (* ---------------------------------------------------------------- *)
  582. (* GetAssignString liefert die "R.Assign (  );"-Anweisung für die   *)
  583. (* Begrenzungen, die in Bounds angegeben sind. Wird von den         *)
  584. (* SaveSourceArray-Prozeduren benötigt.                             *)
  585. (* ---------------------------------------------------------------- *)
  586. FUNCTION GetAssignString (Bounds: tRect): STRING;
  587. BEGIN
  588.   GetAssignString := '  R.Assign ('+Int2Str (Bounds.A.X)+', '+
  589.                                     Int2Str (Bounds.A.Y)+', '+
  590.                                     Int2Str (Bounds.B.X)+', '+
  591.                                     Int2Str (Bounds.B.Y)+');';
  592. END;
  593.  
  594. (* ================================================================ *)
  595. (*                            tStringColl                           *)
  596. (* ================================================================ *)
  597. (* Im Gegensatz zum Vorfahren, tStringCollection, fügt tStringColl  *)
  598. (* die Strings unsortiert, dh in der Reihenfolge des Eintreffens,   *)
  599. (* in die Kollektion ein.                                           *)
  600. (* ---------------------------------------------------------------- *)
  601. FUNCTION tStringColl.Compare (Key1, Key2: POINTER): INTEGER;
  602. BEGIN
  603.   Compare := -1;
  604. END;
  605.  
  606. (* ================================================================ *)
  607. (*                       tSortedViewCollection                      *)
  608. (* ================================================================ *)
  609. (* tSortedViewCollection wird dazu benutzt, die Views eines Dialoges*)
  610. (* in die Reihenfolge zu bringen, in der sie (im Quellcode) in den  *)
  611. (* Dialog eingefügt werden müssen, damit die Reihenfolge für die    *)
  612. (* Selektierung per "TAB" stimmt. Anders ausgedrückt: Da die Dialog-*)
  613. (* elemente von tWorkDialog frei verschiebar sind, stimmt die       *)
  614. (* Reihenfolge des Einfügens nicht mit der "sichtbaren" überein, dh *)
  615. (* nicht mit "von rechts nach links und von oben nach unten". Das   *)
  616. (* muss aber gewährleistet sein, soll ein Dialog als Quellcode oder *)
  617. (* als Ressource gespeichert werden und per "TAB" eine Selektierung *)
  618. (* der Elemente möglich sein.                                       *)
  619. (* ---------------------------------------------------------------- *)
  620. FUNCTION tSortedViewCollection.Compare (Key1, Key2: POINTER): INTEGER;
  621.   VAR View1, View2: pView;
  622. BEGIN
  623.   View1 := Key1;  View2 := Key2;
  624.   IF (View1^.Origin.Y < View2^.Origin.Y) THEN      Compare := -1
  625.   ELSE IF (View1^.Origin.Y > View2^.Origin.Y) THEN Compare :=  1
  626.   ELSE IF (View1^.Origin.X < View2^.Origin.X) THEN Compare := -1
  627.   ELSE IF (View1^.Origin.X > View2^.Origin.X) THEN Compare :=  1
  628.                                               ELSE Compare :=  0;
  629. END;
  630.  
  631. (* ================================================================ *)
  632. (*                            tTemplate                             *)
  633. (* ================================================================ *)
  634. (* tTemplate ist eine Gruppe, die einen "Namen" und eine "Kenn-     *)
  635. (* nummer" hat. Die Kennummer ist eine der "IDXXX"-Konstanten.      *)
  636. (* aClient ist die View, die auf den Namen aName                    *)
  637. (* hören soll und die typmässig zu aID passen muss, damit die       *)
  638. (* richtigen Prozeduren der Prozeduren-Arrays aufgerufen werden.    *)
  639. (* Dass nicht direkt z.B. ein Button in den tWorkDialog eingefügt   *)
  640. (* wird, sondern eine Template, die diesen Button enthält, liegt    *)
  641. (* daran, dass die Template samt Client verschoben und vergrössert  *)
  642. (* werden kann (über Ziehen mit beiden Maustasten gedrückt). Das    *)
  643. (* laubt eine beliebige Positionierung und Grösseneinstellung.      *)
  644. (* ---------------------------------------------------------------- *)
  645. CONSTRUCTOR tTemplate.Init (aClient:  pView;
  646.                             aMinSize,
  647.                             aMaxSize: tPoint;
  648.                             aName:    STRING;
  649.                             aID:      INTEGER);
  650.   VAR R: tRect;
  651. BEGIN
  652.   aClient^.GetBounds (R);
  653.   tGroup.Init (R);
  654.   Client  := aClient;
  655.   ID      := aID;
  656.   MaxSize := aMaxSize;
  657.   MinSize := aMinSize;
  658.   Options := Client^.Options OR (ofTopSelect + ofFirstClick);
  659.   (* --------------------------------------------------------------
  660.      sie muss sich in den Vordergrund setzen, sobald sie selektiert
  661.      wird. Dh, die Elemente werden mit TAB in der Reihenfolge se-
  662.      lektiert, in der sie mit der Maus angeklickt wurden. So ist
  663.      es schon vor dem Speichern möglich, die Selektierungs-Reihen-
  664.      folge richtig einzustellen (was für das Speichern NICHT nötig
  665.      ist, da es automatisch getan wird).
  666.      -------------------------------------------------------------- *)
  667.   State   := Client^.State;        { wird übernommen                 }
  668.   DragMode:= dmDragGrow;           { eine Template ist vergrösserbar }
  669.   Client^.Origin.X := 0;
  670.   Client^.Origin.Y := 0;
  671.   Client^.Size     := Size;
  672.   Insert (Client);
  673.   Name := NewStr (aName);
  674.   DelSelf := FALSE;
  675. END;
  676.  
  677. CONSTRUCTOR tTemplate.Load (VAR S: tStream);
  678. BEGIN
  679.   tGroup.Load (S);
  680.   GetSubViewPtr (S, Client);
  681.   S.Read (MaxSize, SizeOf (MaxSize));
  682.   S.Read (MinSize, SizeOf (MinSize));
  683.   Name := S.ReadStr;
  684.   S.Read (ID, SizeOf (ID));
  685.   DelSelf := FALSE;
  686.   SetState (sfSelected, FALSE);
  687.     { die Objekte halten sich alle für selektiert, wenn sie geladen
  688.       werden. Dem wird hier abgeholfen.                              }
  689. END;
  690.  
  691. PROCEDURE tTemplate.Store (VAR S: tStream);
  692. BEGIN
  693.   tGroup.Store (S);
  694.   PutSubViewPtr (S, Client);
  695.   S.Write (MaxSize, SizeOf (MaxSize));
  696.   S.Write (MinSize, SizeOf (MinSize));
  697.   S.WriteStr (Name);
  698.   S.Write (ID, SizeOf (ID));
  699. END;
  700.  
  701. PROCEDURE tTemplate.Draw;
  702. BEGIN
  703.   tView.Draw;               { damit der Hintergergrund gelöscht wird }
  704.   tGroup.Draw;
  705. END;
  706.  
  707. FUNCTION tTemplate.GetPalette: pPalette;
  708. BEGIN
  709.   GetPalette := NIL;              { Aufruf an den Owner weiterleiten }
  710. END;
  711.  
  712. FUNCTION tTemplate.Valid (Command: WORD): BOOLEAN;
  713. BEGIN
  714.   Valid := True;
  715. END;
  716.  
  717. (* ---------------------------------------------------------------- *)
  718. (* HandleEvent reagiert auf den Broadcast cmWhoIsTempl mit dem Auf- *)
  719. (* ruf von ClearEvent, sofern Event.InfoPtr^ mit Name^ überein-     *)
  720. (* stimmt und auf cmEditTempl bzw das Anklicken mit der rechten     *)
  721. (* Maustaste oder auf das Drücken von Alt-B mit dem Aufruf der      *)
  722. (* ItemDialogArray-Prozedur. Wird das Objekt mit beiden Maustasten  *)
  723. (* angeklickt, so kann es verschoben oder vergrössert werden.       *)
  724. (* ---------------------------------------------------------------- *)
  725. PROCEDURE tTemplate.HandleEvent (VAR Event: tEvent);
  726.   CONST
  727.     Templ: pTemplate = NIL;
  728.   VAR
  729.     MouseInTemplate,
  730.     PointInDeskTop: tPoint;  
  731.     R, Limits:      tRect;
  732.     ResizeMode:     BOOLEAN;
  733.     S:              STRING;
  734. BEGIN
  735.   IF (Event.What = evBroadCast) THEN
  736.     IF (Event.Command = cmWhoIsTempl) AND
  737.        (String (Event.InfoPtr^) = Name^) THEN
  738.       ClearEvent (Event);
  739.  
  740.   IF ((Event.What = evMouseDown) AND
  741.       (Event.Buttons = mbRightButton)) OR
  742.      ((Event.What = evBroadCast) AND
  743.       (Event.Command = cmEditTempl) AND
  744.       (String (Event.InfoPtr^) = Name^)) OR
  745.      ((Event.What = evKeyDown) AND
  746.       (Event.KeyCode = kbAltB))  THEN BEGIN
  747.     Select;
  748.     Templ := @Self;
  749.  
  750.     S := ItemDialogArray [ID] (NIL, Templ, pWorkDialog (Owner));
  751.  
  752.     ClearEvent (Event);
  753.     IF (S <> '') AND (S <> Name^) THEN BEGIN
  754.       DisposeStr (Name);  
  755.       Name := NewStr (S);               { den neuen Namen übernehmen }
  756.     END;
  757.     IF S = '' THEN BEGIN
  758.       DelSelf := TRUE;
  759.         { der Dekonstruktor von tExtendedTemplate muss wissen, ob der
  760.           Dialog aufgelöst wird und somit z.B. ein History-Objekt
  761.           von dem Dekonstruktor des Dialoges entfernt wird, oder
  762.           aber, ob nur die Template gelöscht wird. Dann muss das
  763.           History-Objekt selbst entfernt werden.                     }
  764.       Message (Owner, evCommand, cmDeleteTempl, @Self);
  765.       Exit;
  766.     END;
  767.   END;
  768.  
  769.   GetBounds (R);
  770.   Owner^.MakeLocal (Event.Where, PointInDeskTop);
  771.   IF (Event.What = evMouseDown) AND
  772.      (Event.Buttons = mbLeftButton+mbRightButton) AND
  773.      (R.Contains (PointInDeskTop)) THEN BEGIN
  774.     Select;
  775.     MakeLocal (Event.Where, MouseInTemplate);
  776.     ResizeMode := (MouseInTemplate.X+1 = Size.X) AND
  777.                   (MouseInTemplate.Y+1 = Size.Y);
  778.     Owner^.GetExtent (Limits);
  779.     Limits.Grow (-1, -1);
  780.     IF ResizeMode THEN
  781.       DragView (Event, dmDragGrow, Limits, MinSize, MaxSize)
  782.     ELSE
  783.       DragView (Event, dmDragMove, Limits, MinSize, MaxSize);
  784.     DrawView;
  785.     ClearEvent (Event);
  786.   END;
  787.  
  788.   tGroup.HandleEvent (Event);
  789. END;
  790.  
  791. (* ---------------------------------------------------------------- *)
  792. (* Nicht ganz einsichtig, aber Tatsache: Nach einem Aufruf von      *)
  793. (* "tTemplate.SetState (sfFocused, FALSE);" wird der nächste,       *)
  794. (* "tTemplate.SetState (sfSelected, FALSE);" nicht mehr an den      *)
  795. (* Client weitergeleitet, weshalb das hier von Hand erledigt wird.  *)
  796. (* Diese beiden Aufrufe erfolgen automatisch, sobald ein Objekt den *)
  797. (* Fokus abgegeben soll. Damit nun der Client nicht selektiert und  *)
  798. (* somit hervorgehoben bleibt, wird sein SetState explizit auf-     *)
  799. (* gerufen.                                                         *)
  800. (* ---------------------------------------------------------------- *)
  801. PROCEDURE tTemplate.SetState (aState: WORD; Enable: BOOLEAN);
  802. BEGIN
  803.   Client^.SetState (aState, Enable);
  804.   tGroup.SetState (aState, Enable);
  805. END;
  806.  
  807. (* ---------------------------------------------------------------- *)
  808. (* Der Client ist nur von einer Grössenänderung betroffen, weshalb  *)
  809. (* seine Grösse mit der der Template gleichgesetzt wird. Der Client *)
  810. (* von tTemplate füllt also immer die ganze Template aus! (Im Gegen-*)
  811. (* satz zu dem Client einer tExtendedTemplate.)                     *)
  812. (* ---------------------------------------------------------------- *)
  813. PROCEDURE tTemplate.ChangeBounds (VAR Bounds: tRect);
  814. BEGIN
  815.   tGroup.ChangeBounds (Bounds);
  816.   Client^.Size := Size;
  817. END;
  818.  
  819. DESTRUCTOR tTemplate.Done;
  820. BEGIN
  821.   DisposeStr (Name);
  822.   tGroup.Done;
  823. END;
  824.  
  825. (* ================================================================ *)
  826. (*                          tExtendedTemplate                       *)
  827. (* ================================================================ *)
  828. (* tExtendedTemplate ist eine Template, die zusätzlich zum Client   *)
  829. (* noch ein tLabel-Objekt aufnehmen und mit einem tHistory- sowie   *)
  830. (* tScrollBar-Objekt kommunizieren kann. tExtendedTemplate wird     *)
  831. (* für zusammengesetzte Dialogelemente wie Eingabezeilen, Listen    *)
  832. (* etc verwendet. Damit das Label beim Client bleibt, muss "New-    *)
  833. (* ChangeBounds" die Begrenzungen etwas aufwendig errechnen und     *)
  834. (* ausserdem den Scrollbalken und das History-Objekt von einer Ver- *)
  835. (* schiebung oder Grössenänderung informieren.                      *)
  836. (* Init wurde vollständig überschrieben, dh es wird nicht der       *)
  837. (* Konstruktor des Vorgängers aufgerufen, sondern tGroup.Init, da   *)
  838. (* tTemplate.Init die Client-Werte falsch setzen würde.             *)
  839. (* ---------------------------------------------------------------- *)
  840. CONSTRUCTOR tExtendedTemplate.Init (aClient:    pView;
  841.                                     aLabel:     pLabel;
  842.                                     aScrollBar: pScrollBar;
  843.                                     aHistory:   pHistory;
  844.                                     aMinSize,
  845.                                     aMaxSize:   tPoint;
  846.                                     aName:      STRING;
  847.                                     aID:        INTEGER);
  848.   VAR R1, R2: tRect;
  849. BEGIN
  850.   R1.Assign (0, 0, 10, 1);
  851.   tGroup.Init (R1);               { diese Misseinstellung wird durch }
  852.   Client   := aClient;            { den Aufruf von NewChangeBounds   }
  853.   Lab      := aLabel;             { (unten) korrigiert               }
  854.   ScrollBar:= aScrollBar;
  855.   History  := aHistory;
  856.   MaxSize  := aMaxSize;
  857.   MinSize  := aMinSize;
  858.   ID       := aID;
  859.   Options  := aClient^.Options OR (ofTopSelect + ofFirstClick);
  860.   State    := aClient^.State;
  861.   DragMode := dmDragGrow;
  862.   aClient^.GetBounds (R1);
  863.   aLabel^.GetBounds (R2);
  864.   Insert (Lab);
  865.   Insert (Client);
  866.   NewChangeBounds (R1, R2);
  867.   NewChangeBounds (R1, R2);
  868.   Name := NewStr (aName);
  869. END;
  870.  
  871. CONSTRUCTOR tExtendedTemplate.Load (VAR S: tStream);
  872. BEGIN
  873.   tTemplate.Load (S);
  874.   GetPeerViewPtr (S, ScrollBar);
  875.   GetPeerViewPtr (S, History);
  876.   GetSubViewPtr (S, Lab);
  877. END;
  878.  
  879. PROCEDURE tExtendedTemplate.Store (VAR S: tStream);
  880. BEGIN
  881.   tTemplate.Store (S);
  882.   PutPeerViewPtr (S, ScrollBar);
  883.   PutPeerViewPtr (S, History);
  884.   PutSubViewPtr (S, Lab);
  885. END;
  886.  
  887. PROCEDURE tExtendedTemplate.Draw;
  888. BEGIN
  889.   tTemplate.Draw;
  890.   IF History <> NIL THEN BEGIN
  891.     IF History^.Link = NIL THEN
  892.       History^.Link := pInputLine (Client);
  893.     History^.DrawView;
  894.   END;
  895.   IF ScrollBar <> NIL THEN
  896.     ScrollBar^.DrawView;
  897. END;
  898.  
  899. (* ---------------------------------------------------------------- *)
  900. (* NewChangeBounds "weiss" nicht, ob das Label oder der Client      *)
  901. (* weiter links oder oben stehen, weshalb die Gesamtausdehnung der  *)
  902. (* beiden Objekte zusammen ermittelt werden muss. Anschliessend     *)
  903. (* werden für den Client und das Label und die neuen Werte gesetzt, *)
  904. (* die relativ zum Origin von tExtendedTemplate angegeben werden    *)
  905. (* müssen. Die zugehörige ItemsDialogArray-Prozedur muss das bei    *)
  906. (* der Ausgabe der Werte berücksichtigen ! (Beispiel InputLine)     *)
  907. (* ---------------------------------------------------------------- *)
  908. PROCEDURE tExtendedTemplate.NewChangeBounds (R1, R2: tRect);
  909.   VAR R: tRect;
  910. BEGIN
  911.   IF R1.A.Y < R2.A.Y THEN R.A.Y := R1.A.Y
  912.                      ELSE R.A.Y := R2.A.Y;
  913.   IF R1.A.X < R2.A.X THEN R.A.X := R1.A.X
  914.                      ELSE R.A.X := R2.A.X;
  915.   IF R1.B.Y > R2.B.Y THEN R.B.Y := R1.B.Y
  916.                      ELSE R.B.Y := R2.B.Y;
  917.   IF R1.B.X > R2.B.X THEN R.B.X := R1.B.X
  918.                      ELSE R.B.X := R2.B.X;
  919.   Dec (R1.A.X, R.A.X);  Dec (R1.A.Y, R.A.Y);
  920.   Dec (R1.B.X, R.A.X);  Dec (R1.B.Y, R.A.Y);
  921.   Dec (R2.A.X, R.A.X);  Dec (R2.A.Y, R.A.Y);
  922.   Dec (R2.B.X, R.A.X);  Dec (R2.B.Y, R.A.Y);
  923.   Client^.ChangeBounds (R1);
  924.   Lab^.ChangeBounds (R2);
  925.   ChangeBounds (R);
  926. END;
  927.  
  928. (* ---------------------------------------------------------------- *)
  929. (* ChangeBounds muss nun auch das History-Objekt und den Scroll-    *)
  930. (* balken berücksichtigen und entsprechend ihre Position und Aus-   *)
  931. (* dehnung verändern. Dabei wird angenommen, dass Label-Objekte     *)
  932. (* sowie Scrollbalken immer rechts vom Client stehen, weshalb nicht *)
  933. (* beide gleichzeitig verwendet werden können ! Bei einer Ver-      *)
  934. (* grösserung wird nur der Client vergrössert, nicht aber das Label,*)
  935. (* da z.B. ja nur das Memofeld vergrössert werden soll.             *)
  936. (* ---------------------------------------------------------------- *)
  937. PROCEDURE tExtendedTemplate.ChangeBounds (VAR Bounds: tRect);
  938.   VAR R: tRect;
  939.       p: tPoint;
  940.       dx, dy: INTEGER;
  941. BEGIN
  942.   IF (Origin.X = Bounds.A.X) AND (Origin.Y = Bounds.A.Y) THEN BEGIN
  943.     dx := Origin.X + Client^.Origin.X + Client^.Size.X - Bounds.B.X;
  944.     dy := Origin.Y + Client^.Origin.Y + Client^.Size.Y - Bounds.B.Y;
  945.     Client^.GetBounds (R);
  946.     Dec (R.B.X, dx);
  947.     Dec (R.B.Y, dy);
  948.     Client^.ChangeBounds (R);
  949.   END;
  950.  
  951.   tGroup.ChangeBounds (Bounds);
  952.  
  953.   IF History <> NIL THEN BEGIN
  954.     p.X := Origin.X + Client^.Origin.X + Client^.Size.X;
  955.     p.Y := Origin.Y + Client^.Origin.Y;
  956.     R.Assign (P.X, P.Y,
  957.               P.X+3, P.Y+1);
  958.     History^.Hide;
  959.     History^.ChangeBounds (R);
  960.     History^.Show;
  961.   END;
  962.   IF ScrollBar <> NIL THEN BEGIN
  963.     R.A.X := Origin.X + Client^.Origin.X + Client^.Size.X;
  964.     R.B.X := Succ (R.A.X);
  965.     R.A.Y := Origin.Y + Client^.Origin.Y;
  966.     R.B.Y := R.A.Y + Client^.Size.Y;
  967.     ScrollBar^.Hide;
  968.     ScrollBar^.ChangeBounds (R);
  969.     ScrollBar^.Show;
  970.   END;
  971. END;
  972.  
  973. (* ---------------------------------------------------------------- *)
  974. (* DelSelf ist TRUE, wenn die Template den Befehl cmDeleteTempl er- *)
  975. (* halten hat. In diesem Fall wird nicht der Dialog aufgelöst,      *)
  976. (* sondern es soll nur die Template entfernt werden. Mit ihr müssen *)
  977. (* aber auch History und ScrollBar aus dem Dialog entfernt werden!  *)
  978. (* ---------------------------------------------------------------- *)
  979. DESTRUCTOR tExtendedTemplate.Done;
  980. BEGIN
  981.   IF DelSelf THEN BEGIN
  982.     IF History <> NIL THEN BEGIN
  983.       Owner^.Delete (History);
  984.       Dispose (History, Done);
  985.     END;
  986.     IF ScrollBar <> NIL THEN BEGIN
  987.       Owner^.Delete (ScrollBar);
  988.       Dispose (ScrollBar, Done);
  989.     END;
  990.   END;
  991.   tTemplate.Done;
  992. END;
  993.  
  994. (* ================================================================ *)
  995. (*                             tWorkDialog                          *)
  996. (* ================================================================ *)
  997. (* tWorkDialog ist ein Dialog, der vergrössert werden kann und der  *)
  998. (* sich und seine Templates als Quellcode oder auf Ressource        *)
  999. (* speichern kann. Sein Titel, seine Position und Ausdehnung sowie  *)
  1000. (* weitere Felder können in dem "tWorkDialog_Dialog" eingestellt    *)
  1001. (* werden. Wie aus der Strukturabbildung am Anfang des Quelltextes  *)
  1002. (* hervorgeht, ist tWorkDialog die Drehscheibe dieser Unit, die     *)
  1003. (* fast alles andere direkt oder indirekt steuert. Der Hauptteil    *)
  1004. (* der Arbeit fällt HandleEvent zu; SaveAsSource und SaveAsRessource*)
  1005. (* sind für das Speichern zuständig.                                *)
  1006. (* ---------------------------------------------------------------- *)
  1007. CONSTRUCTOR tWorkDialog.Init (VAR Bounds: tRect; aTitle: tTitleStr);
  1008. BEGIN
  1009.   tDialog.Init (Bounds, aTitle);
  1010.   Flags := Flags OR wfGrow;
  1011.   Saved := FALSE;
  1012. END;
  1013.  
  1014. CONSTRUCTOR tWorkDialog.Load (VAR S: tStream);
  1015. BEGIN
  1016.   tDialog.Load (S);
  1017.   Saved := FALSE;
  1018. END;
  1019.  
  1020. (* ---------------------------------------------------------------- *)
  1021. (* Ist What gleich cmSaveRez, so wird Where als Zeiger auf ein      *)
  1022. (* tResourceFile-Objekt interpretiert, und das Objekt wird unter    *)
  1023. (* dem Namen Title^ als normaler Dialog gespeichert. Falls What     *)
  1024. (* cmSaveInc ist, so wird Where als Zeiger auf eine Text-Datei ver- *)
  1025. (* standen, und es werden die Befehle gespeichert, die nötig sind,  *)
  1026. (* um den Dialog aus der Ressourcendatei zu laden und ihn auszu-    *)
  1027. (* führen. Diese beiden getrennt gespeicherten "Teile" gehören fest *)
  1028. (* zusammen!                                                        *)
  1029. (* ---------------------------------------------------------------- *)
  1030. PROCEDURE tWorkDialog.SaveAsResource (Where: POINTER;
  1031.                                       What: BYTE);
  1032.   CONST
  1033.     t : pTextFile = NIL;
  1034.   VAR
  1035.     RezFile:  pResourceFile;
  1036.     ViewColl: pSortedViewCollection;
  1037.     Dialog:   pDialog;
  1038.     R:        tRect;
  1039.  
  1040.   PROCEDURE WriteLineToFile (Line: pString); FAR;
  1041.   BEGIN
  1042.     Writeln (t^, Line^);
  1043.   END;
  1044.  
  1045.   (* -------------------------------------------------------------- *)
  1046.   (* SaveIncFile schreibt in t^ (Where^) die Befehle zum Laden und  *)
  1047.   (* Ausführen des in die Ressourcendatei gespeicherten Dialoges.   *)
  1048.   (* Die Prozedur erhält den Namen "(Title^)+Dialog", wobei un-     *)
  1049.   (* gültige Zeichen von KillInvalidChars entfernt werden.          *)
  1050.   (* Es wird angenommen, dass in dem Programm, in das die Dialog-   *)
  1051.   (* prozedur eingebunden wird, ein Objekt namens RezFile vom Typ   *)
  1052.   (* tResourceFile existiert. Aus dieser Ressourcendatei wird das   *)
  1053.   (* Dialogobjekt geladen.                                          *)
  1054.   (* -------------------------------------------------------------- *)
  1055.   PROCEDURE SaveIncFile;
  1056.     VAR
  1057.       Data:     BOOLEAN;
  1058.       DataName: STRING;
  1059.   BEGIN
  1060.     InputLineNo := 0;
  1061.     ListBoxNo   := 0;
  1062.     MemoNo      := 0;
  1063.     ClusterNo   := 0;
  1064.  
  1065.     Lines := New (pStringColl, Init (200, 10));
  1066.     Lines^.Duplicates := TRUE;
  1067.  
  1068.     Lines^.Insert (NewStr ('PROCEDURE '+KillInvalidChars (Title^)+'Dialog;  '));
  1069.     TypeDefinition (Title^, ViewColl, Data, DataName);
  1070.     Lines^.Insert (NewStr ('  VAR  '));
  1071.     Lines^.Insert (NewStr ('    Dialog: pDialog;  '));
  1072.     IF Data THEN
  1073.       Lines^.Insert (NewStr ('    Data:   '+DataName+';'));
  1074.     Lines^.Insert (NewStr ('    Code:   INTEGER;'));
  1075.     Lines^.Insert (NewStr ('    R:      tRect;  '));
  1076.     Lines^.Insert (NewStr ('BEGIN  '));
  1077.     Lines^.Insert (NewStr ('  Dialog := pDialog (RezFile.Get ('''+Title^+'''));  '));
  1078.     Lines^.Insert (NewStr (' '));
  1079.     ExecuteDialog (Data, DataName);
  1080.     Lines^.Insert (NewStr ('END;  '));
  1081.  
  1082.     Lines^.ForEach (@WriteLineToFile);
  1083.     Dispose (Lines, Done);
  1084.   END;
  1085.  
  1086.   (* -------------------------------------------------------------- *)
  1087.   (* Fügt der ViewColl (tSortedViewCollection) die Template P hinzu,*)
  1088.   (* sofern P eine Template ist.                                    *)
  1089.   (* -------------------------------------------------------------- *)
  1090.   PROCEDURE AddViewToColl (P: pTemplate); FAR;
  1091.   BEGIN
  1092.     IF (TypeOf (p^) = TypeOf (tTemplate)) OR
  1093.        (TypeOf (p^) = TypeOf (tExtendedTemplate)) THEN
  1094.       ViewColl^.Insert (P);
  1095.   END;
  1096.  
  1097.   (* -------------------------------------------------------------- *)
  1098.   (* AddToDialog fügt die Template P (P muss jetzt eine Template    *)
  1099.   (* sein, was durch AddViewToColl sichergestellt wird) in den neu  *)
  1100.   (* erstellten Dialog "Dialog" ein. Das übernehmem die Prozeduren  *)
  1101.   (* des InsertItemArrays, die den Client der Template P in den     *)
  1102.   (* Dialog "Dialog" einfügen. Dass nicht einfach der Client der    *)
  1103.   (* Template eingefügt werden kann, liegt daran, dass seine Pos.   *)
  1104.   (* nur relativ zum Origin der Template, nicht aber zum Origin des *)
  1105.   (* Dialoges ist. Ausserdem muss für pExtendedTemplate-Objekt das  *)
  1106.   (* History- oder ScrollBar-Objekt "von Hand" mit in dem Dialog    *)
  1107.   (* eingefügt werden.                                              *)
  1108.   (* -------------------------------------------------------------- *)
  1109.   PROCEDURE AddToDialog (P: pTemplate); FAR;
  1110.   BEGIN
  1111.     InsertItemArray [P^.ID] (P, Dialog);
  1112.   END;
  1113.  
  1114. BEGIN
  1115.   ViewColl := New (pSortedViewCollection, Init (20, 10));
  1116.   ForEach (@AddViewToColl);
  1117.  
  1118.   GetBounds (R);
  1119.   Dialog := New (pDialog, Init (R, Title^));
  1120.   Dialog^.State := State+sfModal;  { Jeder erzeugte Dialog ist modal }
  1121.   Dialog^.Flags := Flags-wfGrow;   { und darf nicht "wachsen"        }
  1122.   Dialog^.Options := Options;      { Options kann übernommen werden  }
  1123.   ViewColl^.ForEach (@AddToDialog);
  1124.  
  1125.   IF What = cmSaveRez THEN BEGIN
  1126.     Dialog^.SelectNext (FALSE);
  1127.     RezFile := pResourceFile (Where);
  1128.     RezFile^.Put (Dialog, Title^);
  1129.     IF (RezFile^.Stream^.Status <> 0) THEN BEGIN
  1130.       MessageBox (^C'Fehler beim Speichern des Objekts !',
  1131.                   NIL, mfError+mfOkButton);
  1132.     END;
  1133.   END ELSE IF What = cmSaveInc THEN BEGIN
  1134.     t := pTextFile (Where);
  1135.     SaveIncFile;
  1136.   END;
  1137.  
  1138.   Dispose (Dialog, Done);
  1139.   FreeMem (ViewColl^.Items, ViewColl^.Limit * SizeOf (Pointer));
  1140.   Dispose (ViewColl);    { Done wird NICHT aufgerufen, da sonst die
  1141.                            Templates freigegeben würden ! Daher muss
  1142.                            der Zeigerarray Items "von Hand" freigege-
  1143.                            ben werden.                               }
  1144.   ShowCursor;
  1145.     { der Cursor verschwindet (warum auch immer) beim Speichern      }
  1146. END;
  1147.  
  1148. (* ---------------------------------------------------------------- *)
  1149. (* SaveAsSource speichert den Dialog als Quellcode. Ist AsProcedure *)
  1150. (* TRUE, so wird in Where, das als Zeiger auf eine Textdatei inter- *)
  1151. (* pretiert wird, der Code für eine Prozedur geschrieben, die einen *)
  1152. (* Dialog anlegt, alle Elemente einfügt und den Dialog ausführt.    *)
  1153. (* Ist AsProcedure hingegen FALSE, so wird in Abhängigkeit von What *)
  1154. (* - die Objekt- und Datenrecord-Definition,                        *)
  1155. (* - der Konstruktor des Dialogobjekts oder                         *)
  1156. (* - die Prozedur, die dieses Objekt benutzt, geschrieben.          *)
  1157. (* Dass diese Teile getrennt geschrieben werden können, liegt daran,*)
  1158. (* dass bei der Erzeugung eines vollständigen Programms diese Teile *)
  1159. (* an verschiedenen Stellen geschrieben werden müssen. Soll nur ein *)
  1160. (* Dialog gespeichert werden, so können auch alle drei Teile anein- *)
  1161. (* ander gespeichert werden, und die so erzeugte Datei könnte über  *)
  1162. (* {$I NAME.PAS} ins Programm eingebunden werden.                   *)
  1163. (* Da sich die Speicherung von als Objekt oder als Prozedur zum Teil*)
  1164. (* überschneidet, wurden kleine "Blocks" (Prozeduren) gebildet, die *)
  1165. (* einen Teil des Quellcodes schreiben. So braucht SaveAsSource nur *)
  1166. (* noch, in Abhängigkeit von AsProcedure, diese Blocks in der       *)
  1167. (* jeweiligen Reihenfolge schreiben zu lassen.                      *)
  1168. (* ---------------------------------------------------------------- *)
  1169. PROCEDURE tWorkDialog.SaveAsSource (Where: POINTER;
  1170.                                     AsProcedure: BOOLEAN;
  1171.                                     What: BYTE);
  1172.   CONST
  1173.     VarConstructor = 0;
  1174.     VarProcedure   = 1;
  1175.     VarMixed       = 2;
  1176.  
  1177.   VAR
  1178.     DialogName: STRING;                { Name des Dialogs            }
  1179.     DataName:   STRING;                { Name des Datenrecords       }
  1180.     ViewColl:   pSortedViewCollection; { die sortierten Templates    }
  1181.     Data:       BOOLEAN;               { ob überhaupt ein Datenrecord
  1182.                                          gebraucht wird              }
  1183.     t:          pTextFile;             { die Datei, in die
  1184.                                          geschrieben wird            }
  1185.  
  1186.   PROCEDURE AddViewToColl (P: pTemplate); FAR;
  1187.   BEGIN
  1188.     IF (TypeOf (p^) = TypeOf (tTemplate)) OR
  1189.        (TypeOf (p^) = TypeOf (tExtendedTemplate)) THEN
  1190.       ViewColl^.Insert (P);
  1191.   END;
  1192.  
  1193.   PROCEDURE ProcedureDefinition;
  1194.   BEGIN
  1195.     Lines^.Insert (NewStr ('PROCEDURE '+KillInvalidChars (Title^)+'Dialog;'));
  1196.   END;
  1197.  
  1198.  
  1199.   PROCEDURE VarDefinition (Kind: INTEGER);
  1200.   BEGIN
  1201.     Lines^.Insert (NewStr ('  VAR'));
  1202.     Lines^.Insert (NewStr ('    R: tRect;'));
  1203.     IF Kind <> VarMixed THEN
  1204.       Lines^.Insert (NewStr ('    View: pView;'));
  1205.     IF Kind <> VarConstructor THEN BEGIN
  1206.       IF Data THEN
  1207.         Lines^.Insert (NewStr ('    Data: '+DataName+';'));
  1208.       Lines^.Insert (NewStr ('    Code: INTEGER;'));
  1209.       Lines^.Insert (NewStr ('    Dialog: pDialog;'));
  1210.     END;
  1211.   END;
  1212.  
  1213.   PROCEDURE WriteBegin;
  1214.   BEGIN
  1215.     Lines^.Insert (NewStr ('BEGIN'));
  1216.   END;
  1217.  
  1218.   PROCEDURE DialogDefinition (DialogType: STRING);
  1219.   BEGIN
  1220.     Lines^.Insert (NewStr ('  R.Assign ('+Int2Str (Origin.X)+', '+
  1221.                                         Int2Str (Origin.Y)+', '+
  1222.                                         Int2Str (Origin.X+Size.X)+', '+
  1223.                                         Int2Str (Origin.Y+Size.Y)+');'));
  1224.     Lines^.Insert (NewStr ('  Dialog := New ('+DialogType+', '+
  1225.                                              'Init (R, '''+Title^+'''));'));
  1226.   END;
  1227.  
  1228.   PROCEDURE FieldManipulations (InConstructor: BOOLEAN);
  1229.     VAR s: STRING;
  1230.   BEGIN
  1231.     IF InConstructor THEN s := '  '
  1232.                      ELSE s := '  Dialog^.';
  1233.     { Falls die Felder von den Standardwerten eines Dialoges
  1234.       abweichen, werden sie direkt gesetzt.  }
  1235.     IF Flags <> 7 THEN
  1236.       Lines^.Insert (NewStr (s+'Flags := '+Int2Str (Flags)+';'));
  1237.     IF Options <> 67 THEN
  1238.       Lines^.Insert (NewStr (s+'Options := '+Int2Str (Options)+';'));
  1239.     IF State <> $879 THEN  { sfmodal nicht dabei }
  1240.       Lines^.Insert (NewStr (s+'State := '+Int2Str (State)+';'));
  1241.   END;
  1242.  
  1243.   PROCEDURE InsertItemDef (P: pTemplate); FAR;
  1244.   BEGIN
  1245.     SaveSourceArray [P^.ID] (SaveInsertDef, P, Lines);
  1246.     Lines^.Insert (NewStr (' '));
  1247.   END;
  1248.  
  1249.   PROCEDURE InsertItems (InConstructor: BOOLEAN);
  1250.   BEGIN
  1251.     IF NOT InConstructor THEN
  1252.       InsertStr := 'Dialog^.'
  1253.     ELSE
  1254.       InsertStr := '';
  1255.     ViewColl^.ForEach (@InsertItemDef);
  1256.     Lines^.Insert (NewStr ('  '+InsertStr+'SelectNext (FALSE);'));
  1257.   END;
  1258.  
  1259.   PROCEDURE WriteEnd;
  1260.   BEGIN
  1261.     Lines^.Insert (NewStr ('END;'));
  1262.   END;
  1263.  
  1264.   PROCEDURE EmptyLine;
  1265.   BEGIN
  1266.     Lines^.Insert (NewStr (' '));
  1267.   END;
  1268.  
  1269.   PROCEDURE ObjectDefinition;
  1270.   BEGIN
  1271.     DialogName := KillInvalidChars (Title^)+'Dialog';
  1272.     IF NOT Data THEN
  1273.       Lines^.Insert (NewStr ('TYPE'));
  1274.     Lines^.Insert (NewStr ('  p'+DialogName+' = ^t'+DialogName+';'));
  1275.     Lines^.Insert (NewStr ('  t'+DialogName+' = OBJECT (tDialog)'));
  1276.     Lines^.Insert (NewStr ('    CONSTRUCTOR Init (VAR Bounds: tRect; aTitle: tTitleStr);'));
  1277.     Lines^.Insert (NewStr ('  END;'));
  1278.   END;
  1279.  
  1280.   PROCEDURE ConstructorDefinition;
  1281.   BEGIN
  1282.     Lines^.Insert (NewStr ('CONSTRUCTOR t'+DialogName+'.Init (VAR Bounds: tRect; aTitle: tTitleStr);'));
  1283.   END;
  1284.  
  1285.   PROCEDURE ParentInit;
  1286.   BEGIN
  1287.     Lines^.Insert (NewStr ('  tDialog.Init (Bounds, aTitle);'));
  1288.   END;
  1289.  
  1290.   PROCEDURE WriteLineToFile (Line: pString); FAR;
  1291.   BEGIN
  1292.     Writeln (t^, Line^);
  1293.   END;
  1294.  
  1295. BEGIN
  1296.   t := pTextFile (Where);
  1297.   InputLineNo := 0;
  1298.   ListBoxNo   := 0;
  1299.   MemoNo      := 0;
  1300.   ClusterNo   := 0;
  1301.  
  1302.   Lines := New (pStringColl, Init (200, 10));
  1303.   Lines^.Duplicates := TRUE;
  1304.  
  1305.   ViewColl := New (pSortedViewCollection, Init (20, 10));
  1306.   ViewColl^.Duplicates := TRUE;
  1307.   ForEach (@AddViewToColl);
  1308.  
  1309.   IF AsProcedure THEN BEGIN
  1310.     ProcedureDefinition;
  1311.       TypeDefinition (Title^, ViewColl, Data, DataName);
  1312.       VarDefinition (VarProcedure);
  1313.     WriteBegin;
  1314.       DialogDefinition ('pDialog');
  1315.       FieldManipulations (FALSE);
  1316.       EmptyLine;
  1317.       InsertItems (FALSE);
  1318.       EmptyLine;
  1319.       ExecuteDialog (Data, DataName);
  1320.     WriteEnd;
  1321.   END ELSE BEGIN
  1322.     IF (What = cmSaveDef) OR (What = cmSaveAll) THEN BEGIN
  1323.       TypeDefinition (Title^, ViewColl, Data, DataName);
  1324.       ObjectDefinition;
  1325.       EmptyLine;
  1326.     END;
  1327.  
  1328.     IF (What = cmSaveCon) OR (What = cmSaveAll) THEN BEGIN
  1329.       ConstructorDefinition;
  1330.         VarDefinition (VarConstructor);
  1331.       WriteBegin;
  1332.         ParentInit;
  1333.         FieldManipulations (TRUE);
  1334.         InsertItems (TRUE);
  1335.       WriteEnd;
  1336.       EmptyLine;
  1337.     END;
  1338.  
  1339.     IF (What = cmSavePrc) OR (What = cmSaveAll) THEN BEGIN
  1340.       ProcedureDefinition;
  1341.         VarDefinition (VarMixed);
  1342.       WriteBegin;
  1343.         DialogDefinition ('p'+DialogName);
  1344.         EmptyLine;
  1345.         ExecuteDialog (Data, DataName);
  1346.       WriteEnd;
  1347.     END;
  1348.   END;
  1349.  
  1350.   Lines^.ForEach (@WriteLineToFile);
  1351.   Dispose (Lines, Done);
  1352.   FreeMem (ViewColl^.Items, ViewColl^.Limit * SizeOf (Pointer));
  1353.   Dispose (ViewColl);
  1354. END;
  1355.  
  1356. PROCEDURE tWorkDialog.SetTitle (aTitle: STRING);
  1357. BEGIN
  1358.   IF Title <> NIL THEN
  1359.     DisposeStr (Title);
  1360.   Title := NewStr (aTitle);
  1361. END;
  1362.  
  1363. (* ---------------------------------------------------------------- *)
  1364. (* HandleEvent ist ziemlich komplex und muss auf einige Ereignisse  *)
  1365. (* reagieren:                                                       *)
  1366. (* ■ Befehle:                                                       *)
  1367. (*   - cmEditGroup                                                  *)
  1368. (*   - cmGetItemsMenu                                               *)
  1369. (*   - cmNewTempl                                                   *)
  1370. (*   - cmStaticText, cmButton, cmInputLine etc                      *)
  1371. (*   - cmDeleteTempl                                                *)
  1372. (*   - cmClose                                                      *)
  1373. (*   - cmSaveDlgAsXXX                                               *)
  1374. (* ■ Broadcast:                                                     *)
  1375. (*   - cmWhoIsDlg                                                   *)
  1376. (* ■ Rechte Maustaste                                               *)
  1377. (*   - auf oberen Rahmenrand                                        *)
  1378. (*   - auf leere Dialogfläche                                       *)
  1379. (* ---------------------------------------------------------------- *)
  1380. PROCEDURE tWorkDialog.HandleEvent (VAR Event: tEvent);
  1381.   CONST
  1382.     Where: tPoint = (X: 0; Y: 0);
  1383.   VAR
  1384.     MousePos: tPoint;
  1385.     ID:       INTEGER;
  1386.     Item:     pView;
  1387.     Templ:    pTemplate;
  1388.     Min, Max: tPoint;
  1389.     Name:     STRING;
  1390.     Code:     INTEGER;
  1391. BEGIN
  1392.   (* --------------------------------------------------------------
  1393.      Zusätzlich zu dem Shotcut Alt-G aus dem Systemmenü soll ein
  1394.      Dialog (und nur ein Dialog; nicht irgendeine andere Gruppe)
  1395.      auch über Alt-D bearbeitet werden können.
  1396.      -------------------------------------------------------------- *)
  1397.   IF (Event.What = evKeyDown) AND
  1398.      (Event.KeyCode = kbAltD) THEN BEGIN
  1399.     Message (@Self, evCommand, cmEditGroup, NIL);
  1400.     ClearEvent (Event);
  1401.   END;
  1402.   (* --------------------------------------------------------------
  1403.      Falls mit der rechten Maustaste der oberen Rahmenrand ange-
  1404.      klickt wurde oder der Befehl cmEditGroup eintrifft, wird
  1405.      NewOrEditDialog zum Editieren der Dialogdaten aufgerufen.
  1406.      -------------------------------------------------------------- *)
  1407.   MakeLocal (Event.Where, MousePos);
  1408.   IF ((Event.What = evMouseDown) AND
  1409.       (Event.Buttons = mbRightButton) AND
  1410.       (MousePos.Y = 0)) OR
  1411.      ((Event.What = evCommand) AND
  1412.       (Event.Command = cmEditGroup)) THEN BEGIN
  1413.     Select;
  1414.     NewOrEditDialog (@Self);
  1415.     ClearEvent (Event);
  1416.   END;
  1417.  
  1418.   IF (Event.What = evCommand) THEN
  1419.     CASE Event.Command OF
  1420.       (* ----------------------------------------------------------
  1421.          Auf cmGetItemsMenu hin wird über GetItemsMenu ein Menü mit
  1422.          den einzufügenden Elementen erzeugt, das vom Hauptprogramm
  1423.          in das Systemmenü eingefügt wird. Siehe auch
  1424.          TOOL.tCaseToolApp.GetItemsMenu.
  1425.          ---------------------------------------------------------- *)
  1426.       cmGetItemsMenu:
  1427.         BEGIN
  1428.           pMenu (Event.InfoPtr^) := GetItemsMenu;
  1429.           ClearEvent (Event);
  1430.         END;
  1431.       (* ----------------------------------------------------------
  1432.          cmNewTempl wird von tWorkDialog_Dialog abgesetzt. Handle-
  1433.          Event führt das ItemsMenu im linken oberen Ecken des
  1434.          Dialoges aus und schickt dann den Befehl ID (also cm-
  1435.          StaticText, cmButton etc) an sich selbst, damit der zuge-
  1436.          hörige Dialog ausgeführt wird (siehe unten).
  1437.          ---------------------------------------------------------- *)
  1438.       cmNewTempl:
  1439.         BEGIN
  1440.           Where.X := Origin.X+1; Where.Y := Origin.Y+2;
  1441.           Item := NIL;
  1442.           ID := ItemsMenu (Where);
  1443.           IF ID <> idNoItem THEN
  1444.             Message (@Self, evCommand, ID, NIL);
  1445.               { "ID" ist eigentlich falsch, denn ItemsMenu liefert
  1446.                 nur den zugehörigen cmXXX-Wert. Erst der folgende
  1447.                 Teil der HandleEvent-Methode wandelt diesen Wert
  1448.                 in den IDXXX-Wert um.                                }
  1449.           ClearEvent (Event);
  1450.         END;
  1451.       (* ----------------------------------------------------------
  1452.          cmStaticText, cmButton etc werden entweder direkt vom
  1453.          Systemmenü oder aber durch das Drücken der rechten Maus-
  1454.          taste im leeren Dialogbereich (siehe weiter unten) aus-
  1455.          gelöst. Ist letzteres der Fall, so muss Event.InfoPtr auf
  1456.          die Konstante Where zeigen, sonst wird angenommen, dass
  1457.          der Befehl aus dem Menü stammt, und Where wird mit
  1458.          Standardwerten belegt, Event.InfoPtr mit @Where. Die Pro-
  1459.          zeduren von *ItemDialogArray* erwarten einen Positionsvor-
  1460.          schlag, weshalb ein Zeiger auf Event.InfoPtr übergeben
  1461.          wird. Wurde von der ID entsprechenden Prozedur eine
  1462.          Template erstellt, so wird sie in den Dialog eingefügt.
  1463.          ---------------------------------------------------------- *)
  1464.       cmStaticText,
  1465.       cmButton,
  1466.       cmOkButton,
  1467.       cmCancelButton,
  1468.       cmYesButton,
  1469.       cmNoButton,
  1470.       cmHelpButton,
  1471.       cmInputLine,
  1472.       cmListBox,
  1473.       cmMemo,
  1474.       cmRadioButtons,
  1475.       cmCheckBoxes:
  1476.         BEGIN
  1477.           Item := NIL;
  1478.           Templ:= NIL;
  1479.           ID   := Event.Command - cmStaticText;
  1480.                    { Menübefehl - 5000 = ID des Objekts }
  1481.           IF Event.InfoPtr <> @Where THEN BEGIN
  1482.             Where.X := 1;  Where.Y := 1;
  1483.           END;
  1484.           Name := ItemDialogArray [ID] (@Where, Templ, @Self);
  1485.           IF Templ <> NIL THEN BEGIN
  1486.             Insert (Templ);
  1487.             (* ----------------------------------------------------
  1488.                es wird davon ausgegangen, dass das Objekt Templ
  1489.                einer Sicherheitsprüfung durch ValidView schon
  1490.                unterzogen wurde. Es wird hier nicht erledigt, da
  1491.                nur die ItemDialogArray-Prozeduren wissen, ob noch
  1492.                weitere Objekte wie Historys zur Template gehören
  1493.                ---------------------------------------------------- *)
  1494.             Templ^.SetState (sfActive, TRUE);
  1495.             (* ----------------------------------------------------
  1496.                Ein weiteres Kuriosum (siehe auch tTemplate.SetState):
  1497.                NUR tButtons-Template halten sich auch nach dem
  1498.                Einfügen in den Dialog für nicht der aktiven Gruppe
  1499.                zugehörig, dh ihr sfActive-Bit ist nicht gesetzt.
  1500.                Daher reagieren die Buttons nicht mit der Veränderung
  1501.                der Farbe auf eine Selektierung. Damit das ermöglicht
  1502.                wird, muss sfActive einmal mehr "von Hand" gesetzt
  1503.                werden.
  1504.                ---------------------------------------------------- *)
  1505.             Saved := FALSE;
  1506.           END;
  1507.           ClearEvent (Event);
  1508.         END;
  1509.       (* ----------------------------------------------------------
  1510.          Die Template, auf die Event.InfoPtr zeigt, wird freige-
  1511.          geben und somit aus der Gruppe entfernt.
  1512.          ---------------------------------------------------------- *)
  1513.       cmDeleteTempl :
  1514.         BEGIN
  1515.           Dispose (pTemplate (Event.InfoPtr), Done);
  1516.           ClearEvent (Event);
  1517.         END;
  1518.       (* ----------------------------------------------------------
  1519.          Bei cmClose wird rückgefragt, ob das Schliessen wirklich
  1520.          gewünscht wird, falls der Dialog noch nicht gespeichert
  1521.          wurde, sei es auf Stream (in TOOL.DSK) oder als Quellcode/
  1522.          Ressource.
  1523.          ---------------------------------------------------------- *)
  1524.       cmClose :
  1525.         IF NOT Saved THEN BEGIN
  1526.           ClearEvent (Event);  { sonst wird cmClose zum zweiten Mal
  1527.                                  in der MessageBox verwendet, und der
  1528.                                  Benutzer sieht nur ein Aufflackern
  1529.                                  einer Dialogbox                     }
  1530.           Code := MessageBox (^C'Dialog "'+Title^+
  1531.                          '" noch nicht gespeichert -'+
  1532.                          #13^C' trotzdem schliessen ? ', NIL,
  1533.                          mfConfirmation + mfYesNoCancel);
  1534.           IF Code = cmYes THEN BEGIN
  1535.             Event.What := evCommand;  { der hier eingesetzte Befehl  }
  1536.             Event.Command := cmClose; { wird weiter unten an tDialog.}
  1537.             Event.InfoPtr := @Self;   { HandleEvent weitergeleitet   }
  1538.           END;
  1539.         END;
  1540.       (* ----------------------------------------------------------
  1541.          cmSaveDlgAsR+cmSaveInc/cmSaveRez bewirkt den Aufruf von
  1542.          SaveAsResource, wobei Event.InfoPtr angeben muss, "wohin"
  1543.          der Dialog gespeichert werden muss. Es liegt in der Ver-
  1544.          antwortung des Absenders des Befehls, sicherzustellen,
  1545.          dass Event.InfoPtr auf eine Textdatei (+cmSaveInc) oder
  1546.          auf eine Ressourcendatei (+cmSaveRez) zeigt !
  1547.          ---------------------------------------------------------- *)
  1548.       cmSaveDlgAsR+cmSaveInc,
  1549.       cmSaveDlgAsR+cmSaveRez:
  1550.         BEGIN
  1551.           SaveAsResource (Event.InfoPtr,
  1552.                           Event.Command-cmSaveDlgAsR);
  1553.           ClearEvent (Event);
  1554.         END;
  1555.       (* ----------------------------------------------------------
  1556.          Damit der Dialog als Prozedur gespeichert werden kann,
  1557.          muss Event.InfoPtr auf eine Textdatei zeigen.
  1558.          ---------------------------------------------------------- *)
  1559.       cmSaveDlgAsP:
  1560.         BEGIN
  1561.           SaveAsSource (Event.InfoPtr, TRUE, 0);
  1562.           ClearEvent (Event);
  1563.         END;
  1564.       (* ----------------------------------------------------------
  1565.          cmSaveDlgAsO(bject)+cmSaveXXX wird an SaveAsSource weiter-
  1566.          gegeben, das dann genauer unterscheidet, welche Teile
  1567.          gespeichert werden sollen.
  1568.          ---------------------------------------------------------- *)
  1569.       cmSaveDlgAsO+cmSaveAll,
  1570.       cmSaveDlgAsO+cmSaveDef,
  1571.       cmSaveDlgAsO+cmSaveCon,
  1572.       cmSaveDlgAsO+cmSavePrc:
  1573.         BEGIN
  1574.           SaveAsSource (Event.InfoPtr, FALSE,
  1575.                         Event.Command-cmSaveDlgAsO);
  1576.           ClearEvent (Event);
  1577.         END;
  1578.     END;
  1579.  
  1580.   IF (Event.What = evBroadCast) THEN
  1581.     CASE Event.Command OF
  1582.       (* ----------------------------------------------------------
  1583.          Falls der In Event.InfoPtr^ übergebene String mit Title^
  1584.          identisch ist, gibt sich das Objekt über ClearEvent
  1585.          zu erkennen.
  1586.          ---------------------------------------------------------- *)
  1587.       cmWhoIsDlg : IF pString (Event.InfoPtr)^ = Title^ THEN
  1588.                   ClearEvent (Event);
  1589.     END;
  1590.  
  1591.   tDialog.HandleEvent (Event);
  1592.  
  1593.   (* --------------------------------------------------------------
  1594.      Falls mit der rechten Maustaste in das Dialogfenster geklickt
  1595.      wurde, ohne dass eine Template darauf reagiert hat, wird
  1596.      das Menu ItemsMenu ausgeführt, das die ID des einzufügenden
  1597.      Elements liefert. Dann wird es dem obigen Teil der Methode über-
  1598.      lassen, sich um den Dialog aus ItemsDialogArray, zu kümmern. 
  1599.      -------------------------------------------------------------- *)
  1600.   IF (Event.What = evMouseDown) AND
  1601.      (Event.Buttons = mbRightButton) THEN BEGIN
  1602.     MakeLocal (Event.Where, MousePos);
  1603.     IF (MousePos.X >= 1) AND (MousePos.X < Size.X-1) AND
  1604.        (MousePos.Y < Size.Y-1) THEN BEGIN
  1605.       Item := NIL;
  1606.       Where:= Event.Where;
  1607.       ID   := ItemsMenu (Where);
  1608.       IF ID <> idNoItem THEN BEGIN
  1609.         MakeLocal (Event.Where, Where);
  1610.         Message (@Self, evCommand, ID, @Where);
  1611.       END;
  1612.     END;
  1613.     ClearEvent (Event);
  1614.   END;
  1615. END;
  1616.  
  1617. (* ================================================================ *)
  1618. (*                         tWorkDialog_Dialog                       *)
  1619. (* ================================================================ *)
  1620. (* tWorkDialog_Dialog lässt sämtliche Einstellungen eines tWork-    *)
  1621. (* Dialog editieren. Auch ist es möglich, Elemente einzufügen, zu   *)
  1622. (* löschen oder zu bearbeiten; ebenso können "Weitere Felder" wie   *)
  1623. (* Options, State und Flags direkt manipuliert werden (über den     *)
  1624. (* Dialog OtherFieldsDialog). tWorkDialog_Dialog.HandleEvent        *)
  1625. (* beendet bei folgenden Befehlen die Modalität:                    *)
  1626. (* - cmDeleteDlg, cmDeleteTempl, cmNewTempl, cmEditTempl, cmOtherF  *)
  1627. (* Bei cmDeleteDlg und cmDeleteTempl wird noch gefragt, ob wirklich *)
  1628. (* gelöscht werden soll.                                            *)
  1629. (* Init fügt unter Berücksichtigung von Dlg die Dialogelemente ein. *)
  1630. (* Ist Dlg NIL, so werden die Liste und die zugehörigen Buttons     *)
  1631. (* nicht eingefügt.                                                 *)
  1632. (* ---------------------------------------------------------------- *)
  1633. CONSTRUCTOR tWorkDialog_Dialog.Init (Dlg: pDialog);
  1634.   VAR
  1635.     ScrollBar: pScrollBar;
  1636.     ListBox:   pListBox;
  1637.     View:      pView;
  1638.     Box:       pDialog;
  1639.     R:         tRect;
  1640. BEGIN
  1641.   IF Dlg = NIL THEN BEGIN
  1642.     R.Assign (10, 5, 70, 16);
  1643.     tDialog.Init (R, ' Neue Dialogbox erstellen ');
  1644.   END ELSE BEGIN
  1645.     R.Assign (10, 2, 70, 23);
  1646.     tDialog.Init (R, ' Dialog bearbeiten ');
  1647.   END;
  1648.  
  1649.   R.Assign (10, 1, 40, 2);
  1650.   View := New (pKeyInputLine, Init (R, 80));
  1651.   Insert (View);
  1652.   R.Assign (2, 1, 10, 2);
  1653.   Insert (New (pLabel, Init (R, 'Titel: ', View)));
  1654.  
  1655.   R.Assign (14, 3, 19, 4);
  1656.   View := New (pNumInputLine, Init (R, 5, 0, ScreenWidth));
  1657.   Insert (View);
  1658.   R.Assign (2, 3, 14, 4);
  1659.   Insert (New (pLabel, Init (R, 'Ursprung X: ', View)));
  1660.   R.Assign (14, 4, 19, 5);
  1661.   View := New (pNumInputLine, Init (R, 5, 0, ScreenHeight));
  1662.   Insert (View);
  1663.   R.Assign (2, 4, 14, 5);
  1664.   Insert (New (pLabel, Init (R, 'Ursprung Y: ', View)));
  1665.  
  1666.   R.Assign (41, 3, 46, 4);
  1667.   View := New (pNumInputLine, Init (R, 5, 0, ScreenWidth));
  1668.   Insert (View);
  1669.   R.Assign (29, 3, 40, 4);
  1670.   Insert (New (pLabel, Init (R, 'Grösse X: ', View)));
  1671.   R.Assign (41, 4, 46, 5);
  1672.   View := New (pNumInputLine, Init (R, 5, 0, ScreenHeight));
  1673.   Insert (View);
  1674.   R.Assign (29, 4, 40, 5);
  1675.   Insert (New (pLabel, Init (R, 'Grösse Y: ', View)));
  1676.  
  1677.   IF Dlg <> NIL THEN BEGIN
  1678.     R.Assign (30, 7, 31, 15);
  1679.     ScrollBar := New (pScrollBar, Init (R));
  1680.     Insert (ScrollBar);
  1681.     R.Assign (3, 7, 30, 15);
  1682.     ListBox := New (pListBox, Init (R, 1, ScrollBar));
  1683.     Insert (ListBox);
  1684.     R.Assign (2, 6, 20, 7);
  1685.     Insert (New (pLabel, Init (R, 'Dialogelemente:', ListBox)));
  1686.  
  1687.     R.Assign (38, 8, 52, 10);
  1688.     Insert (New (pButton, Init (R, 'Element ~n~eu', cmNewTempl, bfNormal)));
  1689.     R.Assign (38, 10, 52, 12);
  1690.     Insert (New (pButton, Init (R, '~L~öschen', cmDeleteTempl, bfNormal)));
  1691.     R.Assign (38, 12, 52, 14);
  1692.     Insert (New (pButton, Init (R, '~B~earbeiten', cmEditTempl, bfNormal)));
  1693.   END;
  1694.  
  1695.   R.Assign (35, Size.Y-5, 55, Size.Y-3);
  1696.   Insert (New (pButton, Init (R, '~W~eitere Felder', cmOtherF, bfNormal)));
  1697.  
  1698.   R.Assign (5, Size.Y-3, 15, Size.Y-1);
  1699.   Insert (New (pButton, Init (R, '~O~K', cmOk, bfDefault)));
  1700.   IF Dlg <> NIL THEN BEGIN
  1701.     R.Assign (20, Size.Y-3, 40, Size.Y-1);
  1702.     Insert (New (pButton, Init (R, '~D~ialog löschen', cmDeleteDlg, bfNormal)));
  1703.   END;
  1704.   R.Assign (45, Size.Y-3, 55, Size.Y-1);
  1705.   Insert (New (pButton, Init (R, '~C~ancel', cmCancel, bfNormal)));
  1706.  
  1707.   SelectNext (FALSE);
  1708. END;
  1709.  
  1710. PROCEDURE tWorkDialog_Dialog.HandleEvent (VAR Event: tEvent);
  1711. BEGIN
  1712.   IF (Event.What = evCommand) AND
  1713.      ((Event.Command = cmDeleteDlg) OR
  1714.       (Event.Command = cmDeletetempl) OR
  1715.       (Event.Command = cmNewTempl) OR
  1716.       (Event.Command = cmEditTempl) OR
  1717.       (Event.Command = cmOtherF)) THEN BEGIN
  1718.     EndModal (Event.Command);
  1719.     ClearEvent (Event);
  1720.   END;
  1721.  
  1722.   tDialog.HandleEvent (Event);
  1723. END;
  1724.  
  1725. (* ---------------------------------------------------------------- *)
  1726. (* Valid fragt den Benutzer, ob er das Objekt, also entweder den    *)
  1727. (* Dialog oder nur ein Element, wirklich löschen wolle.             *)
  1728. (* ---------------------------------------------------------------- *)
  1729. FUNCTION tWorkDialog_Dialog.Valid (Command: WORD): BOOLEAN;
  1730. BEGIN
  1731.   Valid := tDialog.Valid (Command);
  1732.   IF (Command = cmDeleteDlg) OR
  1733.      (Command = cmDeleteTempl) THEN
  1734.     IF MessageBox ('Das Objekt wirklich löschen ?',
  1735.                    NIL,
  1736.                    mfConfirmation + mfYesNoCancel) = cmYes THEN
  1737.       Valid := TRUE
  1738.     ELSE
  1739.       Valid := FALSE;
  1740. END;
  1741.  
  1742. (* ================================================================ *)
  1743. (*                             tTemplDialog                         *)
  1744. (* ================================================================ *)
  1745. (* tTemplDialog wird von den ItemsDialogArray-Prozeduren benutzt.   *)
  1746. (* Bei cmDeleteTempl wird rückgefragt, ob das Element wirklich ge-  *)
  1747. (* löscht werden soll. HandleEvent beendet (oder versucht zu        *)
  1748. (* beenden) die Modalität bei Eintreffen von cmDeleteTempl.         *)
  1749. (* ---------------------------------------------------------------- *)
  1750. PROCEDURE tTemplDialog.HandleEvent (VAR Event: tEvent);
  1751. BEGIN
  1752.   IF (Event.What = evCommand) AND
  1753.      (Event.Command = cmDeleteTempl) THEN BEGIN
  1754.     EndModal (cmDeleteTempl);
  1755.     ClearEvent (Event);
  1756.   END;
  1757.   tDialog.HandleEvent (Event);
  1758. END;
  1759.  
  1760. (* ---------------------------------------------------------------- *)
  1761. (* Dass auch tTemplDialog.Valid nachfragt, ob das Objekt gelöscht   *)
  1762. (* werden soll, liegt daran, dass tWorkDialog_Dialog die Modalität  *)
  1763. (* bei einer Bestätigung obiger Rückfrage beenden soll. Ein Template*)
  1764. (* dialog aber soll seine Modalität auch nur nach einer Bestätigung *)
  1765. (* beenden, weshalb die Rückfrage doppelt vorkommt.                 *)
  1766. (* ---------------------------------------------------------------- *)
  1767. FUNCTION tTemplDialog.Valid (Command: WORD): BOOLEAN;
  1768.   VAR OK: BOOLEAN;
  1769. BEGIN
  1770.   OK := FALSE;
  1771.   IF Command = cmDeleteTempl THEN
  1772.     IF MessageBox ('Das Objekt wirklich löschen ?',
  1773.                    NIL, mfConfirmation + mfYesNoCancel) = cmYes THEN
  1774.       OK := TRUE;
  1775.   IF NOT OK THEN
  1776.     OK := tDialog.Valid (Command);
  1777.   Valid := OK;
  1778. END;
  1779.  
  1780. (* ================================================================ *)
  1781. (*                            tClusterDialog                        *)
  1782. (* ================================================================ *)
  1783. (* tClusterDialog ist der Dialog für Radiobuttons und CheckBoxes.   *)
  1784. (* aTitle gibt seine Überschrift an, aList zeigt auf die Kollektion,*)
  1785. (* die verwendet werden soll, DelButton muss TRUE sein, wenn ein    *)
  1786. (* "Löschen"-Button eingefügt werden soll, also das Dialogelement   *)
  1787. (* schon existiert.                                                 *)
  1788. (* ---------------------------------------------------------------- *)
  1789. CONSTRUCTOR tClusterDialog.Init (aTitle:    tTitleStr;
  1790.                                  aList:     pStringCollection;
  1791.                                  DelButton: BOOLEAN);
  1792.   VAR
  1793.     View: pView;
  1794.     R: tRect;
  1795. BEGIN
  1796.   R.Assign (10, 1, 67, 21);
  1797.   tDialog.Init (R, aTitle);
  1798.  
  1799.   R.Assign (5, 1, 18, 2);
  1800.   Insert (New (pStaticText, Init (R, 'Beschriftung:')));
  1801.  
  1802.   R.Assign (14, 2, 44, 3);
  1803.   View := New (pKeyInputLine, Init (R, 80));
  1804.   Insert (View);
  1805.   R.Assign (7, 2, 14, 3);
  1806.   Insert (New (pLabel, Init (R, 'Text: ', View)));
  1807.  
  1808.   R.Assign (11, 4, 17, 5);
  1809.   View := New (pNumInputLine, Init (R, 5, 0, 80));
  1810.   Insert (View);
  1811.   R.Assign (7, 4, 10, 5);
  1812.   Insert (New (pLabel, Init (R, 'X:', View)));
  1813.  
  1814.   R.Assign (26, 4, 32, 5);
  1815.   View := New (pNumInputLine, Init (R, 5, 0, 80));
  1816.   Insert (View);
  1817.   R.Assign (22, 4, 26, 5);
  1818.   Insert (New (pLabel, Init (R, 'Y: ', View)));
  1819.  
  1820.   R.Assign (5, 6, 24, 7);
  1821.   Insert (New (pStaticText, Init (R, 'tCheckBoxes-Daten: ')));
  1822.  
  1823.   R.Assign (30, 8, 31, 16);
  1824.   View := New (pScrollBar, Init  (R));
  1825.   Insert (View);
  1826.   R.Assign (8, 8, 30, 16);
  1827.   ListBox := New (pListBox, Init (R, 1, pScrollBar (View)));
  1828.   Insert (ListBox);
  1829.   R.Assign (8, 7, 23, 8);
  1830.   Insert (New (pLabel, Init (R, 'Elementliste: ', ListBox)));
  1831.   List := aList;
  1832.  
  1833.   R.Assign (39, 8, 53, 10);
  1834.   Insert (New (pButton, Init (R, '~N~eu', cmNewItem, 0)));
  1835.  
  1836.   R.Assign (39, 11, 53, 13);
  1837.   Insert (New (pButton, Init (R, '~L~öschen', cmDeleteItem, 0)));
  1838.  
  1839.   R.Assign (39, 14, 53, 16);
  1840.   Insert (New (pButton, Init (R, '~B~earbeiten', cmEditItem, 0)));
  1841.  
  1842.   R.Assign (3, 17, 11, 19);
  1843.   Insert (New (pButton, Init (R, ' ~O~K ', cmOk, 1)));
  1844.  
  1845.   IF DelButton THEN BEGIN
  1846.     R.Assign (18, 17, 31, 19);
  1847.     Insert (New (pButton, Init (R, '~L~öschen', cmDeleteTempl, 0)));
  1848.   END;
  1849.  
  1850.   R.Assign (39, 17, 52, 19);
  1851.   Insert (New (pButton, Init (R, '~A~bbruch', cmCancel, 0)));
  1852.  
  1853.   SelectNext (FALSE);
  1854. END;
  1855.  
  1856. (* ---------------------------------------------------------------- *)
  1857. (* tClusterDialog.HandleEvent muss auf die Befehle cmNewItem,       *)
  1858. (* cmEdit- und cmDeleteItem reagieren, die von den in Init einge-   *)
  1859. (* fügten Buttons ausgeschickt werden.                              *)
  1860. (* ---------------------------------------------------------------- *)
  1861. PROCEDURE tClusterDialog.HandleEvent (VAR Event: tEvent);
  1862.   VAR
  1863.     s: STRING;
  1864.     i: INTEGER;
  1865.     p: pString;
  1866. BEGIN
  1867.   IF (Event.What = evCommand) THEN
  1868.     CASE Event.Command OF
  1869.       (* ----------------------------------------------------------
  1870.          Bei cmNewItem kann der Anwender in einer InputBox ein
  1871.          neues Listenelement eingeben. Gibt er einen nicht-leeren
  1872.          String ein, wird dieser in die Liste "List" eingefügt
  1873.          und anschliessend die Listbox aktualisiert. Das geschieht
  1874.          "von Hand", da tListBox keine Methode zum Einfügen eines
  1875.          neuen Strings nach dem Erzeugen des Objekts kennt.
  1876.          ---------------------------------------------------------- *)
  1877.       cmNewItem:
  1878.         BEGIN
  1879.           s := '';
  1880.           IF (InputBox ('Neues Listenelement', 'Beschriftung: ',
  1881.                         S, 80) = cmOk) AND (S <> '') THEN BEGIN
  1882.             IF ListBox^.Range = 0 THEN
  1883.               i := 0
  1884.             ELSE
  1885.               i := ListBox^.Focused+1;
  1886.             List^.AtInsert (i, NewStr (s));
  1887.             ListBox^.SetRange (Succ (ListBox^.Range));
  1888.             ListBox^.FocusItem (i);
  1889.             ListBox^.DrawView;
  1890.           END;
  1891.           ClearEvent (Event);
  1892.         END;
  1893.       (* ----------------------------------------------------------
  1894.          Falls in der Listbox schon ein Element eingefügt ist,
  1895.          kann es der Benutzer in einer InputBox bearbeiten. Gibt er
  1896.          einen nicht-leeren String ein, so wird der alte wiederum
  1897.          "von Hand" ersetzt; gibt er einen leeren String ein, so
  1898.          wird der Befehl cmDeleteItem an Self abgeschickt.
  1899.          ---------------------------------------------------------- *)
  1900.       cmEditItem:
  1901.         BEGIN
  1902.           IF ListBox^.Range <> 0 THEN BEGIN
  1903.             i := ListBox^.Focused;
  1904.             s := String (List^.At (i)^);
  1905.             IF (InputBox ('Listenelement bearbeiten', 'Beschriftung: ',
  1906.                           S, 80) = cmOk) AND (S <> '') THEN BEGIN
  1907.               p := List^.At (i);
  1908.               List^.AtFree (i);
  1909.               List^.AtInsert (i, NewStr (s));
  1910.               ListBox^.DrawView;
  1911.             END ELSE
  1912.               IF S = '' THEN
  1913.                 Message (@Self, evCommand, cmDeleteItem, NIL);
  1914.           END;
  1915.           ClearEvent (Event);
  1916.         END;
  1917.       (* ----------------------------------------------------------
  1918.          Das selektierte Element wird gelöscht, sofern die Liste
  1919.          überhaupt Elemente enthält.
  1920.          ---------------------------------------------------------- *)
  1921.       cmDeleteItem:
  1922.         BEGIN
  1923.           IF ListBox^.Range <> 0 THEN BEGIN
  1924.             List^.AtFree (ListBox^.Focused);
  1925.             ListBox^.SetRange (Pred (ListBox^.Range));
  1926.             ListBox^.DrawView;
  1927.           END;
  1928.           ClearEvent (Event);
  1929.         END;
  1930.     END;
  1931.  
  1932.   tTemplDialog.HandleEvent (Event);
  1933. END;
  1934.  
  1935. (* ================================================================ *)
  1936. (*                          OtherFieldsDialog                       *)
  1937. (* ================================================================ *)
  1938. (* OtherFieldsDialog lässt die Felder Flags, Options und State des  *)
  1939. (* Dialoges Dlg  manipulieren. Aber ACHTUNG: Was eingegeben wird,   *)
  1940. (* wird auch gesetzt! sfVisible zu löschen hat zur Folge, dass der  *)
  1941. (* Dialog nicht mehr auf den Bildschirm geholt werden kann!         *)
  1942. (* ---------------------------------------------------------------- *)
  1943. PROCEDURE OtherFieldsDialog (Dlg: pDialog);
  1944.   TYPE
  1945.     Data = RECORD
  1946.              Flags: WORD;
  1947.              Options: WORD;
  1948.              State: WORD;
  1949.            END;
  1950.   VAR
  1951.     Code: INTEGER;
  1952.     DD:   Data;
  1953.     Box:  pDialog;
  1954.     R:    tRect;
  1955.     View: pView;
  1956. BEGIN
  1957.   R.Assign (10, 0, 70, 23);
  1958.   Box := New (pDialog, Init (R, 'Weitere Felder ...'));
  1959.  
  1960.   R.Assign (2, 2, 20, 6);
  1961.   View := New (pCheckBoxes, Init (R, NewSItem ('wfMove',
  1962.                                      NewSItem ('wfGrow',
  1963.                                      NewSItem ('wfClose',
  1964.                                      NewSItem ('wfZoom',
  1965.                                      NIL))))));
  1966.   Box^.Insert (View);
  1967.   R.Assign (2, 1, 21, 2);
  1968.   Box^.Insert (New (pLabel, Init (R, 'Flags: ', View)));
  1969.  
  1970.   R.Assign (2, 8, 21, 19);
  1971.   View := New (pCheckBoxes, Init (R, NewSItem ('ofSelectable',
  1972.                                      NewSItem ('ofTopSelect',
  1973.                                      NewSItem ('ofFirstClick',
  1974.                                      NewSItem ('ofFramed',
  1975.                                      NewSItem ('ofPreProcess',
  1976.                                      NewSItem ('ofPostProcess',
  1977.                                      NewSItem ('ofBuffered',
  1978.                                      NewSItem ('ofTileable',
  1979.                                      NewSItem ('ofCenterX',
  1980.                                      NewSItem ('ofCenterY',
  1981.                                      NewSItem ('ofCentered',
  1982.                                      NIL)))))))))))));
  1983.   Box^.Insert (View);
  1984.   R.Assign (2, 7, 21, 8);
  1985.   Box^.Insert (New (pLabel, Init (R, 'Options: ', View)));
  1986.  
  1987.   R.Assign (25, 8, 44, 19);
  1988.   View := New (pCheckBoxes, Init (R, NewSItem ('sfVisible',
  1989.                                      NewSItem ('sfCursorVis',
  1990.                                      NewSItem ('sfCursorIns',
  1991.                                      NewSItem ('sfShadow',
  1992.                                      NewSItem ('sfActive',
  1993.                                      NewSItem ('sfSelected',
  1994.                                      NewSItem ('sfFocused',
  1995.                                      NewSItem ('sfDragging',
  1996.                                      NewSItem ('sfDisabled',
  1997.                                      NewSItem ('sfModal',
  1998.                                      NewSItem ('sfExposed',
  1999.                                      NIL)))))))))))));
  2000.   Box^.Insert (View);
  2001.   R.Assign (25, 7, 44, 8);
  2002.   Box^.Insert (New (pLabel, Init (R, 'State:', View)));
  2003.  
  2004.   R.Assign (10, Box^.Size.Y-3, 20, Box^.Size.Y-1);
  2005.   Box^.Insert (New (pButton, Init (R, '~O~K', cmOK, bfDefault)));
  2006.   R.Assign (30, Box^.Size.Y-3, 40, Box^.Size.Y-1);
  2007.   Box^.Insert (New (pButton, Init (R, '~C~ancel', cmCancel, bfNormal)));
  2008.  
  2009.   DD.Flags  := Dlg^.Flags;
  2010.   DD.Options:= Dlg^.Options;
  2011.   DD.State  := Dlg^.State;
  2012.   Box^.SetData (DD);
  2013.   Box^.SelectNext (FALSE);
  2014.  
  2015.   Code := Desktop^.ExecView (Application^.ValidView (Box));
  2016.  
  2017.   IF Code <> cmCancel THEN BEGIN
  2018.     Box^.GetData (DD);
  2019.     Dlg^.Flags  := DD.Flags;
  2020.     Dlg^.Options:= DD.Options;
  2021.     Dlg^.State  := DD.State;
  2022.   END;
  2023.   IF Box <> NIL THEN
  2024.     Dispose (Box);
  2025. END;
  2026.  
  2027. (* ================================================================ *)
  2028. (*                            NewOrEditDialog                       *)
  2029. (* ================================================================ *)
  2030. (* Der zentrale Dialog für tWorkDialog-Objekte; benutzt tWorkDialog_*)
  2031. (* Dialog und muss auf diverse Befehle reagieren, mit denen der     *)
  2032. (* Dialog beendet werden kann.                                      *)
  2033. (* ---------------------------------------------------------------- *)
  2034. PROCEDURE NewOrEditDialog (Dlg: pDialog);
  2035.  
  2036.   CONST
  2037.     Name : STRING = '';
  2038.  
  2039.   TYPE
  2040.     DialogData = RECORD
  2041.        Title: STRING [80];
  2042.        x1, y1, x2, y2 : LONGINT;
  2043.        ListPtr: pCollection;
  2044.        Focused: INTEGER;
  2045.     END;
  2046.  
  2047.   VAR
  2048.     Box: pDialog;
  2049.     R: tRect;
  2050.     DD: DialogData;
  2051.     StrList: pStringCollection;
  2052.     Code: INTEGER;
  2053.     Quit: BOOLEAN;
  2054.  
  2055.   PROCEDURE AddToList (Templ: pView); FAR;
  2056.     VAR Name: STRING;
  2057.   BEGIN
  2058.     IF (TypeOf (Templ^) = TypeOf (tTemplate)) OR
  2059.        (TypeOf (Templ^) = TypeOf (tExtendedTemplate)) THEN BEGIN
  2060.       Name := pTemplate (Templ)^.Name^;
  2061.       StrList^.Insert (NewStr (Name));
  2062.     END;
  2063.   END;
  2064.  
  2065.   PROCEDURE SetNewDlgData;
  2066.   BEGIN
  2067.     IF Dlg <> NIL THEN BEGIN
  2068.       pWorkDialog (Dlg)^.SetTitle (DD.Title);
  2069.       R.Assign (DD.X1, DD.Y1, DD.X1+DD.X2, DD.Y1+DD.Y2);
  2070.       Dlg^.ChangeBounds (R);
  2071.       Desktop^.ReDraw;
  2072.     END;
  2073.   END;
  2074.  
  2075.   PROCEDURE MakeDialog;
  2076.   BEGIN
  2077.     R.Assign (DD.X1, DD.Y1, DD.X1+DD.X2, DD.Y1+DD.Y2);
  2078.     Dlg := New (pWorkDialog, Init (R, DD.Title));
  2079.     Desktop^.Insert (Application^.ValidView (Dlg));
  2080.     IF Dlg = NIL THEN Quit := TRUE;
  2081.   END;
  2082.  
  2083. BEGIN
  2084.   Box := New (pWorkDialog_Dialog, Init (Dlg));
  2085.  
  2086.   StrList := NIL;
  2087.   IF Dlg <> NIL THEN BEGIN
  2088.     StrList := New (pStringCollection, Init (20, 10));
  2089.     StrList^.Duplicates := TRUE;
  2090.     Dlg^.ForEach (@AddToList);
  2091.     DD.ListPtr := StrList;
  2092.     DD.Focused := 0;
  2093.   END;
  2094.  
  2095.   DD.Title := '';
  2096.   IF Dlg=NIL THEN BEGIN
  2097.     DD.X1 := 20;  DD.Y1 := 5;
  2098.     DD.X2 := 40;  DD.Y2 := 10;
  2099.   END ELSE BEGIN
  2100.     IF Dlg^.Title <> NIL THEN DD.Title := Dlg^.Title^;
  2101.     DD.X1 := Dlg^.Origin.X; DD.Y1 := Dlg^.Origin.Y;
  2102.     DD.X2 := Dlg^.Size.X;   DD.Y2 := Dlg^.Size.Y;
  2103.   END;
  2104.  
  2105.   Box^.SetData (DD);
  2106.  
  2107.   REPEAT
  2108.     Quit := TRUE;
  2109.     Code := Desktop^.ExecView (Application^.ValidView (Box));
  2110.     Box^.GetData (DD);
  2111.     CASE Code OF
  2112.       cmOtherF:
  2113.         BEGIN
  2114.           IF Dlg = NIL THEN
  2115.             MakeDialog;
  2116.           IF Dlg <> NIL THEN BEGIN
  2117.             OtherFieldsDialog (Dlg);
  2118.             Quit := FALSE;
  2119.           END;
  2120.         END;
  2121.       cmOk:
  2122.           IF Dlg = NIL THEN MakeDialog
  2123.                        ELSE SetNewDlgData;
  2124.       cmDeleteDlg:
  2125.         Dispose (Dlg, Done);
  2126.       cmNewTempl:
  2127.         BEGIN
  2128.           Message (Dlg, evCommand, cmNewTempl, NIL);
  2129.           SetNewDlgData;
  2130.         END;
  2131.       cmEditTempl:
  2132.         IF DD.ListPtr^.Count > 0 THEN BEGIN
  2133.           Name := String (DD.ListPtr^.At (DD.Focused)^);
  2134.           SetNewDlgData;
  2135.           Message (Dlg, evBroadCast, cmEditTempl, @Name);
  2136.         END ELSE
  2137.           Quit := FALSE;
  2138.       cmDeleteTempl:
  2139.         IF DD.ListPtr^.Count > 0 THEN BEGIN
  2140.           Message (Dlg,
  2141.                    evCommand, cmDeleteTempl,
  2142.                    Message (Dlg, evBroadCast,
  2143.                             cmWhoIsTempl,
  2144.                             DD.ListPtr^.At (DD.Focused)));
  2145.           SetNewDlgData;
  2146.         END ELSE
  2147.           Quit := FALSE;
  2148.       END;
  2149.   UNTIL (Quit) OR (Code = cmCancel);
  2150.   IF Dlg <> NIL THEN
  2151.     Dlg^.Redraw;
  2152.   IF Box <> NIL THEN
  2153.     Dispose (Box, Done);
  2154.   IF StrList <> NIL THEN
  2155.     Dispose (StrList, Done);
  2156. END;
  2157.  
  2158. (* ================================================================ *)
  2159. (*                             ItemsMenu                            *)
  2160. (* ================================================================ *)
  2161. FUNCTION GetItemsMenu: pMenu;
  2162. BEGIN
  2163.   GetItemsMenu := NewMenu (
  2164.     NewItem ('t~S~taticText', '', 0, cmStaticText, hcNoContext,
  2165.     NewItem ('t~B~utton', '', 0, cmButton, hcNoContext,
  2166.     NewItem ('t~I~nputLine', '', 0, cmInputLine, hcNoContext,
  2167.     NewItem ('t~L~istBox', '', 0, cmListBox, hcNoContext,
  2168.     NewItem ('t~M~emo', '', 0, cmMemo, hcNoContext,
  2169.     NewItem ('t~R~adioButtons', '', 0, cmRadioButtons, hcNoContext,
  2170.     NewItem ('t~C~heckBoxes', '', 0, cmCheckBoxes, hcNoContext,
  2171.     NewLine (
  2172.     NewSubMenu ('S~t~andardbuttons', hcNoContext, NewMenu (
  2173.       NewItem ('~O~K-Button', '', 0, cmOkButton, hcNoContext,
  2174.       NewItem ('~A~bbruch-Button', '', 0, cmCancelButton, hcNoContext,
  2175.       NewItem ('~J~a-Button', '', 0, cmYesButton, hcNoContext,
  2176.       NewItem ('~N~ein-Button', '', 0, cmNoButton, hcNoContext,
  2177.       NewItem ('~H~ilfe-Button', '', 0, cmHelpButton, hcNoContext,
  2178.       NIL)))))),
  2179.     NIL))))))))));
  2180. END;
  2181.  
  2182. (* ================================================================ *)
  2183. (*                             ItemsMenu                            *)
  2184. (* ================================================================ *)
  2185. FUNCTION ItemsMenu (Where: tPoint): INTEGER;
  2186.   CONST
  2187.     ItemsMenuOpen : BOOLEAN = FALSE;
  2188.   VAR
  2189.     Menu: pMenu;
  2190.     Code : WORD;
  2191.     Box: pMenuBox;
  2192.     R: tRect;
  2193. BEGIN
  2194.   IF NOT ItemsMenuOpen THEN BEGIN
  2195.     ItemsMenuOpen := TRUE;
  2196.     IF (Where.X > 53) THEN Where.X := 53;
  2197.     IF (Where.Y > ScreenHeight-12) THEN
  2198.       Where.Y := ScreenHeight-12;
  2199.  
  2200.     R.Assign (Where.X, Where.Y,
  2201.               Where.X+25, Where.Y+11);
  2202.     Menu := GetItemsMenu;
  2203.     Box  := New (pMenuBox, Init (R, Menu, NIL));
  2204.     Code := Application^.ExecView (Box);
  2205.     Dispose (Box, Done);
  2206.     DisposeMenu (Menu);
  2207.  
  2208.     IF Code <> 0 THEN ItemsMenu := Code
  2209.                  ELSE ItemsMenu := idNoItem;
  2210.     ItemsMenuOpen := FALSE;
  2211.   END;
  2212. END;
  2213.  
  2214. (* ================================================================ *)
  2215. (*    I T E M S  D I A L O G  A R R A Y  -  P R O Z E D U R E N     *)
  2216. (* ================================================================ *)
  2217. (* Die ItemsDialogArray-Prozeduren führen die Dialoge für die       *)
  2218. (* einzelnen Dialogelement-Arten aus. Sie werden aufgerufen, wenn   *)
  2219. (* der Benutzer ein Element einfügen oder überarbeiten will, und    *)
  2220. (* daher auch für beide Fälle gerüstet sein, was die Prozeduren ein *)
  2221. (* wenig aufbläst. Optimieren wäre hier möglich; es wurde jedoch    *)
  2222. (* bewusst darauf verzichtet, damit eigene Ideen leichter einge-    *)
  2223. (* bracht werden können. - Diese Prozeduren nehmen über über 1000   *)
  2224. (* Zeilen dieser Unit ein!                                          *)
  2225. (* ---------------------------------------------------------------- *)
  2226. (*                         StaticTextDialog                         *)
  2227. (* ---------------------------------------------------------------- *)
  2228. (* StaticTextDialog ist der einfachste Dialog aus dem ItemsDialog-  *)
  2229. (* Array, da für einen StaticText nur Position und Text benötigt    *)
  2230. (* werden. Doch alle Prozeduren folgen dem Schema, das StaticText-  *)
  2231. (* Dialog verwendet und das durch die Trennstriche ersichtlich wird.*)
  2232. (* ---------------------------------------------------------------- *)
  2233. FUNCTION StaticTextDialog (Where:     pPoint;
  2234.                            VAR Templ: pTemplate;
  2235.                            Dlg:       pWorkDialog): STRING;
  2236.  
  2237.   TYPE
  2238.     DialogData = RECORD
  2239.        Title: STRING [80];
  2240.        x, y : LONGINT;
  2241.     END;
  2242.  
  2243.   VAR
  2244.     StaticText: pStaticText;
  2245.     View:       pView;
  2246.     Box:        pDialog;
  2247.     DD:         DialogData;
  2248.     Code:       INTEGER;
  2249.     R:          tRect;
  2250.  
  2251. BEGIN
  2252.   (* -------------------------------------------------------------- *)
  2253.   IF Templ <> NIL THEN
  2254.     StaticText := pStaticText (Templ^.Client)
  2255.   ELSE
  2256.     StaticText := NIL;
  2257.   (* -------------------------------------------------------------- *)
  2258.   R.Assign (10, 5, 70, 15);
  2259.   Box := New (pTemplDialog, Init (R, ' tStaticText-Dialog '));
  2260.   WITH Box^ DO BEGIN
  2261.     R.Assign (21, 1, 50, 2);
  2262.     View := New (pKeyInputLine, Init (R, 80));
  2263.     Insert (View);
  2264.     R.Assign (2, 1, 21, 2);
  2265.     Insert (New (pLabel, Init (R, 'Text: ', View)));
  2266.  
  2267.     R.Assign (16, 3, 21, 4);
  2268.     View := New (pNumInputLine, Init (R, 5, 0, 80));
  2269.     Insert (View);
  2270.     R.Assign (2, 3, 15, 4);
  2271.     Insert (New (pLabel, Init (R, 'Ursprung X: ', View)));
  2272.     R.Assign (16, 5, 21, 6);
  2273.     View := New (pNumInputLine, Init (R, 5, 0, 25));
  2274.     Insert (View);
  2275.     R.Assign (2, 5, 15, 6);
  2276.     Insert (New (pLabel, Init (R, 'Ursprung Y: ', View)));
  2277.  
  2278.     R.Assign (5, Size.Y-3, 15, Size.Y-1);
  2279.     Insert (New (pButton, Init (R, '~O~K', cmOk, bfDefault)));
  2280.     IF StaticText <> NIL THEN BEGIN
  2281.       R.Assign (20, Size.Y-3, 40, Size.Y-1);
  2282.       Insert (New (pButton, Init (R, 'Objekt ~l~öschen ',
  2283.                                   cmDeleteTempl, bfNormal)));
  2284.     END;
  2285.     R.Assign (45, Size.Y-3, 55, Size.Y-1);
  2286.     Insert (New (pButton, Init (R, '~C~ancel', cmCancel, bfNormal)));
  2287.     SelectNext (FALSE);
  2288.   END;
  2289.   (* -------------------------------------------------------------- *)
  2290.   DD.Title := '';
  2291.   IF StaticText=NIL THEN BEGIN
  2292.     DD.X := Where^.X;
  2293.     DD.Y := Where^.Y;
  2294.   END ELSE BEGIN
  2295.     IF StaticText^.Text <> NIL THEN
  2296.       DD.Title := StaticText^.Text^;
  2297.     DD.X := Templ^.Origin.X;
  2298.     DD.Y := Templ^.Origin.Y;
  2299.   END;
  2300.   (* -------------------------------------------------------------- *)
  2301.   Box^.SetData (DD);
  2302.   Code := Desktop^.ExecView (Application^.ValidView (Box));
  2303.   StaticTextDialog := DD.Title;
  2304.   (* -------------------------------------------------------------- *)
  2305.   IF Code = cmOk THEN BEGIN
  2306.     Box^.GetData (DD);
  2307.     R.Assign (DD.X, DD.Y, DD.X+Length (DD.Title), Succ (DD.Y));
  2308.     IF Templ = NIL THEN BEGIN
  2309.       StaticText := New (pStaticText, Init (R, DD.Title));
  2310.       Templ := New (pTemplate,
  2311.                     Init (StaticText, MinItemSize, MaxItemSize,
  2312.                           DD.Title, idStaticText));
  2313.       Templ := pTemplate (Application^.ValidView (Templ));
  2314.     END ELSE BEGIN
  2315.       IF StaticText^.Text <> NIL THEN
  2316.         DisposeStr (StaticText^.Text);
  2317.       StaticText^.Text := NewStr (DD.Title);
  2318.       Templ^.ChangeBounds (R);
  2319.       Dlg^.ReDraw;
  2320.     END;
  2321.   END ELSE IF (Code = cmDeleteTempl) THEN
  2322.     StaticTextDialog := '';
  2323.  
  2324.   IF Box <>  NIL THEN
  2325.     Dispose (Box, Done);
  2326. END;
  2327.  
  2328. (* ---------------------------------------------------------------- *)
  2329. (*                            ButtonDialog                          *)
  2330. (* ---------------------------------------------------------------- *)
  2331. FUNCTION ButtonDialog (Where:     pPoint;
  2332.                        VAR Templ: pTemplate;
  2333.                        Dlg:       pWorkDialog): STRING;
  2334.   TYPE
  2335.     DialogData = RECORD
  2336.        Title: STRING [80];
  2337.        x, y : LONGINT;
  2338.        Command: LONGINT;
  2339.        Default: WORD;
  2340.        LeftJust: WORD;
  2341.     END;
  2342.  
  2343.   VAR
  2344.     Button: pButton;
  2345.     View:   pView;
  2346.     KeyInputLine: pKeyInputLine;
  2347.     Box:    pDialog;
  2348.     DD:     DialogData;
  2349.     Code:   INTEGER;
  2350.     R:      tRect;
  2351.  
  2352. BEGIN
  2353.   (* -------------------------------------------------------------- *)
  2354.   IF Templ <> NIL THEN
  2355.     Button := pButton (Templ^.Client)
  2356.   ELSE
  2357.     Button := NIL;
  2358.   (* -------------------------------------------------------------- *)
  2359.   R.Assign (10, 3, 70, 18);
  2360.   Box := New (pTemplDialog, Init (R, ' tButton-Dialog '));
  2361.   WITH Box^ DO BEGIN
  2362.     R.Assign (23, 1, 50, 2);
  2363.     KeyInputLine := New (pKeyInputLine, Init (R, 80));
  2364.     Insert (KeyInputLine);
  2365.     R.Assign (2, 1, 21, 2);
  2366.     Insert (New (pLabel, Init (R, 'Beschriftung: ', KeyInputLine)));
  2367.  
  2368.     R.Assign (11, 2, 16, 3);
  2369.     View := New (pNumInputLine, Init (R, 5, 0, 80));
  2370.     Insert (View);
  2371.     R.Assign (6, 2, 9, 3);
  2372.     Insert (New (pLabel, Init (R, 'X: ', View)));
  2373.  
  2374.     R.Assign (25, 2, 30, 3);
  2375.     View := New (pNumInputLine, Init (R, 5, 0, 25));
  2376.     Insert (View);
  2377.     R.Assign (20, 2, 23, 3);
  2378.     Insert (New (pLabel, Init (R, 'Y: ', View)));
  2379.  
  2380.     R.Assign (24, 4, 30, 5);
  2381.     View := New (pNumInputLine, Init (R, 5, 0, 80));
  2382.     Insert (View);
  2383.     R.Assign (2, 4, 24, 5);
  2384.     Insert (New (pLabel, Init (R, 'Abzusetzender Befehl: ', View)));
  2385.  
  2386.     R.Assign (2, 7, 30, 9);
  2387.     View := New (pRadioButtons, Init (R, NewSItem ('bfNormal',
  2388.                                          NewSItem ('bfDefault',
  2389.                                          NIL))));
  2390.     Insert (View);
  2391.     R.Assign (2, 6, 30, 7);
  2392.     Insert (New (pLabel, Init (R, 'Erscheinungsbild: ', View)));
  2393.  
  2394.     R.Assign (2, 9, 30, 10);
  2395.     View := New (pCheckBoxes, Init (R, NewSItem ('bfLeftJust',
  2396.                                        NIL)));
  2397.     Insert (View);
  2398.  
  2399.     R.Assign (5, Size.Y-3, 15, Size.Y-1);
  2400.     Insert (New (pButton, Init (R, '~O~K', cmOk, bfDefault)));
  2401.     IF Button <> NIL THEN BEGIN
  2402.       R.Assign (20, Size.Y-3, 40, Size.Y-1);
  2403.       Insert (New (pButton, Init (R, 'Objekt ~l~öschen ',
  2404.                                   cmDeleteTempl, bfNormal)));
  2405.     END;
  2406.     R.Assign (45, Size.Y-3, 55, Size.Y-1);
  2407.     Insert (New (pButton, Init (R, '~C~ancel', cmCancel, bfNormal)));
  2408.     SelectNext (FALSE);
  2409.   END;
  2410.   (* -------------------------------------------------------------- *)
  2411.   DD.Title := '';
  2412.   IF Button=NIL THEN BEGIN
  2413.     DD.X := Where^.X;
  2414.     DD.Y := Where^.Y;
  2415.     DD.Command := 0;
  2416.     DD.Default := 0;
  2417.     DD.LeftJust := 0;
  2418.   END ELSE BEGIN
  2419.     IF Button^.Title <> NIL THEN
  2420.       DD.Title := Button^.Title^;
  2421.     DD.X := Button^.Owner^.Origin.X;
  2422.     DD.Y := Button^.Owner^.Origin.Y;
  2423.     DD.Command := Button^.Command;
  2424.     DD.Default := (Button^.Flags AND bfDefault);
  2425.     DD.LeftJust:= WORD ((Button^.Flags AND bfLeftJust) > 0);
  2426.   END;
  2427.   (* -------------------------------------------------------------- *)
  2428.   Box^.SetData (DD);
  2429.   Code := Desktop^.ExecView (Application^.ValidView (Box));
  2430.   ButtonDialog := DD.Title;
  2431.   (* -------------------------------------------------------------- *)
  2432.   IF Code = cmOk THEN BEGIN
  2433.     Box^.GetData (DD);
  2434.     R.Assign (DD.X, DD.Y, DD.X+Length (DD.Title)+4, DD.Y+2);
  2435.     IF (DD.LeftJust AND $01) > 0 THEN
  2436.       DD.LeftJust := bfLeftJust;
  2437.     IF Templ = NIL THEN BEGIN
  2438.       Button := New (pButton, Init (R, DD.Title,
  2439.                                        DD.Command,
  2440.                                        DD.Default+DD.LeftJust));
  2441.       Button^.Options := Button^.Options AND NOT ofPreProcess;
  2442.       Templ := New (pTemplate,
  2443.                     Init (Button, MinButtonSize, MaxItemSize,
  2444.                           DD.Title, idButton));
  2445.       Templ := pTemplate (Application^.ValidView (Templ));
  2446.     END ELSE BEGIN
  2447.       IF Button^.Title <> NIL THEN
  2448.         DisposeStr (Button^.Title);
  2449.       Button^.Title   := NewStr (DD.Title);
  2450.       Button^.Flags   := (DD.Default+DD.LeftJust);
  2451.       Button^.Command := DD.Command;
  2452.       Templ^.ChangeBounds (R);
  2453.       Dlg^.ReDraw;
  2454.     END
  2455.   END ELSE IF (Code = cmDeleteTempl) THEN 
  2456.     ButtonDialog := '';
  2457.  
  2458.   IF Box <>  NIL THEN
  2459.     Dispose (Box, Done);
  2460. END;
  2461.  
  2462. (* ---------------------------------------------------------------- *)
  2463. (*                          InputLineDialog                         *)
  2464. (* ---------------------------------------------------------------- *)
  2465. FUNCTION InputLineDialog (Where:     pPoint;
  2466.                           VAR Templ: pTemplate;
  2467.                           Dlg:       pWorkDialog): STRING;
  2468.  
  2469.   TYPE
  2470.     DialogData = RECORD
  2471.        Title:   STRING [80];
  2472.        TX,TY:   LONGINT;
  2473.        X, Y:    LONGINT;
  2474.        Length:  LONGINT;
  2475.        MaxLen:  LONGINT;
  2476.        History: WORD;
  2477.        ID     : LONGINT;
  2478.     END;
  2479.  
  2480.   VAR
  2481.     InputLine: pInputLine;
  2482.     History:   pHistory;
  2483.     Lab:       pLabel;
  2484.     View:      pView;
  2485.     Box:       pDialog;
  2486.     Code:      INTEGER;
  2487.     DD:        DialogData;
  2488.     R, RL, RH: tRect;
  2489. BEGIN
  2490.   (* -------------------------------------------------------------- *)
  2491.   IF Templ <> NIL THEN BEGIN
  2492.     InputLine:= pInputLine (Templ^.Client);
  2493.     Lab      := pExtendedTemplate (Templ)^.Lab;
  2494.     History  := pExtendedTemplate (Templ)^.History;
  2495.   END ELSE BEGIN
  2496.     InputLine:= NIL;
  2497.     Lab      := NIL;
  2498.     History  := NIL;
  2499.   END;
  2500.   (* -------------------------------------------------------------- *)
  2501.   R.Assign (10, 3, 70, 18);
  2502.   Box := New (pTemplDialog, Init (R, ' tInputLine-Dialog '));
  2503.   WITH Box^ DO BEGIN
  2504.     R.Assign (5, 2, 18, 3);
  2505.     Insert (New (pStaticText, Init (R, 'Beschriftung: ')));
  2506.  
  2507.     R.Assign (15, 3, 50, 4);
  2508.     View := New (pKeyInputLine, Init (R, 80));
  2509.     Insert (View);
  2510.     R.Assign (8, 3, 14, 4);
  2511.     Insert (New (pLabel, Init (R, 'Text: ', View)));
  2512.  
  2513.     R.Assign (12, 4, 17, 5);
  2514.     View := New (pNumInputLine, Init (R, 5, 0, 80));
  2515.     Insert (View);
  2516.     R.Assign (8, 4, 11, 5);
  2517.     Insert (New (pLabel, Init (R, 'X: ', View)));
  2518.  
  2519.     R.Assign (23, 4, 28, 5);
  2520.     View := New (pNumInputLine, Init (R, 5, 0, 25));
  2521.     Insert (View);
  2522.     R.Assign (19, 4, 22, 5);
  2523.     Insert (New (pLabel, Init (R, 'Y: ', View)));
  2524.  
  2525.     R.Assign (4, 6, 17, 7);
  2526.     Insert (New (pStaticText, Init (R, 'Eingabezeile:')));
  2527.  
  2528.     R.Assign (12, 7, 17, 8);
  2529.     View := New (pNumInputLine, Init (R, 5, 0, 80));
  2530.     Insert (View);
  2531.     R.Assign (8, 7, 11, 8);
  2532.     Insert (New (pLabel, Init (R, 'X: ', View)));
  2533.  
  2534.     R.Assign (23, 7, 28, 8);
  2535.     View := New (pNumInputLine, Init (R, 5, 0, 25));
  2536.     Insert (View);
  2537.     R.Assign (19, 7, 22, 8);
  2538.     Insert (New (pLabel, Init (R, 'Y: ', View)));
  2539.  
  2540.     R.Assign (39, 7, 45, 8);
  2541.     View := New (pNumInputLine, Init (R, 5, 0, 80));
  2542.     Insert (View);
  2543.     R.Assign (31, 7, 38, 8);
  2544.     Insert (New (pStaticText, Init (R, 'Länge: ')));
  2545.  
  2546.     R.Assign (28, 8, 35, 9);
  2547.     View := New (pNumInputLine, Init (R, 5, 0, 255));
  2548.     Insert (View);
  2549.     R.Assign (8, 8, 27, 9);
  2550.     Insert (New (pStaticText, Init (R, 'max. Eingabenlänge: ')));
  2551.  
  2552.     R.Assign (4, 10, 19, 11);
  2553.     Insert (New (pCheckBoxes, Init (R, NewSItem ('tHistory', NIL))));
  2554.     R.Assign (35, 10, 42, 11);
  2555.     View := New (pNumInputLine, Init (R, 6, 0, 32000));
  2556.     Insert (View);
  2557.     R.Assign (22, 10, 35, 11);
  2558.     Insert (New (pLabel, Init (R, 'History-ID:', View)));
  2559.  
  2560.     R.Assign (5, Size.Y-3, 15, Size.Y-1);
  2561.     Insert (New (pButton, Init (R, '~O~K', cmOk, bfDefault)));
  2562.     IF InputLine <> NIL THEN BEGIN
  2563.       R.Assign (20, Size.Y-3, 40, Size.Y-1);
  2564.       Insert (New (pButton, Init (R, 'Objekt ~l~öschen ',
  2565.                                   cmDeleteTempl, bfNormal)));
  2566.     END;
  2567.     R.Assign (45, Size.Y-3, 55, Size.Y-1);
  2568.     Insert (New (pButton, Init (R, '~C~ancel', cmCancel, bfNormal)));
  2569.     SelectNext (FALSE);
  2570.   END;
  2571.   (* -------------------------------------------------------------- *)
  2572.   IF Templ=NIL THEN BEGIN
  2573.     DD.Title := ''; 
  2574.     DD.TX := Where^.X;  DD.TY := Where^.Y;
  2575.     DD.X  := DD.TX;     DD.Y  := DD.TY + 1;
  2576.     DD.Length := 10;
  2577.     DD.MaxLen := 80;
  2578.     DD.History:= 1;
  2579.     DD.ID     := 0;
  2580.   END ELSE BEGIN
  2581.     IF Lab^.Text <> NIL THEN
  2582.       DD.Title := Lab^.Text^;
  2583.     DD.TX := Templ^.Origin.X + Lab^.Origin.X;
  2584.     DD.TY := Templ^.Origin.Y + Lab^.Origin.Y;
  2585.     DD.X  := Templ^.Origin.X + InputLine^.Origin.X;
  2586.     DD.Y  := Templ^.Origin.Y + InputLine^.Origin.Y;
  2587.     DD.Length := InputLine^.Size.X;
  2588.     DD.MaxLen := InputLine^.MaxLen;
  2589.     DD.History:= WORD (History <> NIL);
  2590.     IF History <> NIL THEN
  2591.       DD.ID := History^.HistoryID
  2592.     ELSE
  2593.       DD.ID := 0;
  2594.   END;
  2595.   (* -------------------------------------------------------------- *)
  2596.   Box^.SetData (DD);
  2597.   Code := Desktop^.ExecView (Application^.ValidView (Box));
  2598.   InputLineDialog := DD.Title;
  2599.   (* -------------------------------------------------------------- *)
  2600.   IF Code = cmOk THEN BEGIN
  2601.     Box^.GetData (DD);
  2602.     RL.Assign (DD.TX, DD.TY,
  2603.                Succ (DD.TX + Length (DD.Title)), Succ (DD.TY));
  2604.     R.Assign (DD.X, DD.Y, DD.X + DD.Length, Succ (DD.Y));
  2605.     RH.Assign (DD.X+DD.Length, DD.Y, DD.X+DD.Length+3, DD.Y+1);
  2606.     IF (Templ = NIL) THEN BEGIN
  2607.       (* ---------------------------------------------------------- *)
  2608.       InputLine := New (pInputLine, Init (R, DD.MaxLen));
  2609.       Lab := New (pLabel, Init (Rl, DD.Title, InputLine));
  2610.       IF DD.History = 1 THEN BEGIN
  2611.         History := New (pHistory, Init (RH, InputLine, DD.ID));
  2612.         Dlg^.Insert (History);
  2613.       END;
  2614.       Templ := New (pExtendedTemplate,
  2615.                     Init (InputLine, Lab, NIL, History,
  2616.                           MinItemSize, MaxItemSize,
  2617.                           DD.Title, idInputLine));
  2618.       IF LowMemory THEN BEGIN
  2619.         Application^.OutOfMemory;
  2620.         Dispose (Templ, Done);
  2621.         Dispose (History, Done);
  2622.       END;
  2623.     END ELSE BEGIN
  2624.       (* ---------------------------------------------------------- *)
  2625.       InputLine^.MaxLen := DD.MaxLen;
  2626.  
  2627.       IF Lab^.Text <> NIL THEN
  2628.         DisposeStr (Lab^.Text);
  2629.       Lab^.Text := NewStr (DD.Title);
  2630.  
  2631.       IF (History <> NIL) AND (DD.History = 1) THEN
  2632.         History^.HistoryID := DD.ID;
  2633.  
  2634.       IF (DD.History = 0) AND (History <> NIL) THEN BEGIN
  2635.         Dlg^.Delete (History);
  2636.         Dispose (History, Done);
  2637.         History := NIL;
  2638.         pExtendedTemplate (Templ)^.History := NIL;
  2639.       END;
  2640.       IF (DD.History = 1) AND (History = NIL) THEN BEGIN
  2641.         History := New (pHistory, Init (RH, InputLine, DD.ID));
  2642.         pExtendedTemplate (Templ)^.History := History;
  2643.         Dlg^.Insert (History);
  2644.       END;
  2645.  
  2646.       pExtendedTemplate (Templ)^.NewChangeBounds (R, RL);
  2647.       Dlg^.ReDraw;
  2648.     END;
  2649.   END ELSE IF (Code = cmDeleteTempl) THEN
  2650.     InputLineDialog := '';
  2651.  
  2652.   IF Box <>  NIL THEN
  2653.     Dispose (Box, Done);
  2654. END;
  2655.  
  2656. (* ---------------------------------------------------------------- *)
  2657. (*                            ListBoxDialog                         *)
  2658. (* ---------------------------------------------------------------- *)
  2659. FUNCTION ListBoxDialog (Where:     pPoint;
  2660.                         VAR Templ: pTemplate;
  2661.                         Dlg:       pWorkDialog): STRING;
  2662.  
  2663.   TYPE
  2664.     DialogData = RECORD
  2665.        Title:    STRING [80];
  2666.        TX,TY:    LONGINT;
  2667.        X, Y:     LONGINT;
  2668.        XL, YL:   LONGINT;
  2669.        ColNum:   LONGINT;
  2670.        ScrollBar:WORD;
  2671.     END;
  2672.  
  2673.   VAR
  2674.     ListBox:   pListBox;
  2675.     Scrollbar: pScrollBar;
  2676.     Lab:       pLabel;
  2677.     View:      pView;
  2678.     Box:       pDialog;
  2679.     Code:      INTEGER;
  2680.     DD:        DialogData;
  2681.     R, RL, RS: tRect;
  2682. BEGIN
  2683.   (* -------------------------------------------------------------- *)
  2684.   IF Templ <> NIL THEN BEGIN
  2685.     ListBox  := pListBox (Templ^.Client);
  2686.     Lab      := pExtendedTemplate (Templ)^.Lab;
  2687.     ScrollBar:= pExtendedTemplate (Templ)^.ScrollBar;
  2688.   END ELSE BEGIN
  2689.     ListBox  := NIL;
  2690.     Lab      := NIL;
  2691.     ScrollBar:= NIL;
  2692.   END;
  2693.   (* -------------------------------------------------------------- *)
  2694.   R.Assign (10, 3, 70, 18);
  2695.   Box := New (pTemplDialog, Init (R, ' tListBox-Dialog '));
  2696.   WITH Box^ DO BEGIN
  2697.     R.Assign (5, 2, 18, 3);
  2698.     Insert (New (pStaticText, Init (R, 'Beschriftung: ')));
  2699.  
  2700.     R.Assign (15, 3, 50, 4);
  2701.     View := New (pKeyInputLine, Init (R, 80));
  2702.     Insert (View);
  2703.     R.Assign (8, 3, 14, 4);
  2704.     Insert (New (pLabel, Init (R, 'Text: ', View)));
  2705.  
  2706.     R.Assign (12, 4, 17, 5);
  2707.     View := New (pNumInputLine, Init (R, 5, 0, 80));
  2708.     Insert (View);
  2709.     R.Assign (8, 4, 11, 5);
  2710.     Insert (New (pLabel, Init (R, 'X: ', View)));
  2711.  
  2712.     R.Assign (23, 4, 28, 5);
  2713.     View := New (pNumInputLine, Init (R, 5, 0, 25));
  2714.     Insert (View);
  2715.     R.Assign (19, 4, 22, 5);
  2716.     Insert (New (pLabel, Init (R, 'Y: ', View)));
  2717.  
  2718.     R.Assign (4, 6, 17, 7);
  2719.     Insert (New (pStaticText, Init (R, 'Listbox:')));
  2720.  
  2721.     R.Assign (12, 7, 17, 8);
  2722.     View := New (pNumInputLine, Init (R, 5, 0, 80));
  2723.     Insert (View);
  2724.     R.Assign (8, 7, 11, 8);
  2725.     Insert (New (pLabel, Init (R, 'X: ', View)));
  2726.  
  2727.     R.Assign (23, 7, 28, 8);
  2728.     View := New (pNumInputLine, Init (R, 5, 0, 25));
  2729.     Insert (View);
  2730.     R.Assign (19, 7, 22, 8);
  2731.     Insert (New (pLabel, Init (R, 'Y: ', View)));
  2732.  
  2733.     R.Assign (18, 8, 25, 9);
  2734.     View := New (pNumInputLine, Init (R, 5, 0, 80));
  2735.     Insert (View);
  2736.     R.Assign (8, 8, 17, 9);
  2737.     Insert (New (plabel, Init (R, 'Länge X: ', View)));
  2738.  
  2739.     R.Assign (38, 8, 45, 9);
  2740.     View := New (pNumInputLine, Init (R, 5, 0, 255));
  2741.     Insert (View);
  2742.     R.Assign (28, 8, 37, 9);
  2743.     Insert (New (pLabel, Init (R, 'Länge Y: ', View)));
  2744.  
  2745.     R.Assign (25, 9, 32, 10);
  2746.     View := New (pNumInputLine, Init (R, 5, 0, 20));
  2747.     Insert (View);
  2748.     R.Assign (8, 9, 25, 10);
  2749.     Insert (New (pLabel, Init (R, 'Anzahl Spalten: ', View)));
  2750.  
  2751.     R.Assign (4, 10, 22, 11);
  2752.     Insert (New (pCheckBoxes, Init (R, NewSItem ('Scrollbalken', NIL))));
  2753.  
  2754.     R.Assign (5, Size.Y-3, 15, Size.Y-1);
  2755.     Insert (New (pButton, Init (R, '~O~K', cmOk, bfDefault)));
  2756.     IF ListBox <> NIL THEN BEGIN
  2757.       R.Assign (20, Size.Y-3, 40, Size.Y-1);
  2758.       Insert (New (pButton, Init (R, 'Objekt ~l~öschen ',
  2759.                                   cmDeleteTempl, bfNormal)));
  2760.     END;
  2761.     R.Assign (45, Size.Y-3, 55, Size.Y-1);
  2762.     Insert (New (pButton, Init (R, '~C~ancel', cmCancel, bfNormal)));
  2763.     SelectNext (FALSE);
  2764.   END;
  2765.   (* -------------------------------------------------------------- *)
  2766.   IF Templ=NIL THEN BEGIN
  2767.     DD.Title := ''; 
  2768.     DD.TX := Where^.X;  DD.TY := Where^.Y;
  2769.     DD.X  := DD.TX;     DD.Y  := DD.TY + 1;
  2770.     DD.XL := 10;        DD.YL := 5;
  2771.     DD.ColNum := 1;
  2772.     DD.ScrollBar := 1;
  2773.   END ELSE BEGIN
  2774.     IF Lab^.Text <> NIL THEN
  2775.       DD.Title := Lab^.Text^;
  2776.     DD.TX := Templ^.Origin.X + Lab^.Origin.X;
  2777.     DD.TY := Templ^.Origin.Y + Lab^.Origin.Y;
  2778.     DD.X  := Templ^.Origin.X + ListBox^.Origin.X;
  2779.     DD.Y  := Templ^.Origin.Y + ListBox^.Origin.Y;
  2780.     DD.XL := ListBox^.Size.X;
  2781.     DD.YL := ListBox^.Size.Y;
  2782.     DD.ColNum := ListBox^.NumCols;
  2783.     DD.ScrollBar := WORD (ScrollBar <> NIL);
  2784.   END;
  2785.   (* -------------------------------------------------------------- *)
  2786.   Box^.SetData (DD);
  2787.   Code := Desktop^.ExecView (Application^.ValidView (Box));
  2788.   ListBoxDialog := DD.Title;
  2789.   (* -------------------------------------------------------------- *)
  2790.   IF Code = cmOk THEN BEGIN
  2791.     Box^.GetData (DD);
  2792.     RL.Assign (DD.TX, DD.TY,
  2793.                Succ (DD.TX + Length (DD.Title)), Succ (DD.TY));
  2794.     R.Assign (DD.X, DD.Y, DD.X + DD.XL, DD.Y + DD.YL);
  2795.     RS.Assign (DD.X+DD.XL, DD.Y, DD.X+DD.XL+1, DD.Y+DD.YL);
  2796.     IF (Templ = NIL) THEN BEGIN
  2797.       (* ---------------------------------------------------------- *)
  2798.       IF DD.ScrollBar = 1 THEN BEGIN
  2799.         ScrollBar := New (pScrollBar, Init (RS));
  2800.         ScrollBar^.SetRange (0, 1);
  2801.         ScrollBar^.GrowMode := 0;
  2802.         Dlg^.Insert (ScrollBar);
  2803.       END;
  2804.       ListBox := New (pListBox, Init (R, DD.ColNum, ScrollBar));
  2805.       Lab := New (pLabel, Init (Rl, DD.Title, ListBox));
  2806.       Templ := New (pExtendedTemplate,
  2807.                     Init (ListBox, Lab, ScrollBar, NIL,
  2808.                           MinItemSize, MaxItemSize,
  2809.                           DD.Title, idListBox));
  2810.       pExtendedTemplate (Templ)^.NewChangeBounds (R, RL);
  2811.       IF LowMemory THEN BEGIN
  2812.         Application^.OutOfMemory;
  2813.         Dispose (Templ, Done);
  2814.         IF ScrollBar <> NIL THEN
  2815.           Dispose (ScrollBar, Done);
  2816.       END;
  2817.     END ELSE BEGIN
  2818.       (* ---------------------------------------------------------- *)
  2819.       ListBox^.NumCols := DD.ColNum;
  2820.  
  2821.       IF Lab^.Text <> NIL THEN
  2822.         DisposeStr (Lab^.Text);
  2823.       Lab^.Text := NewStr (DD.Title);
  2824.  
  2825.       IF (DD.ScrollBar = 0) AND (ScrollBar <> NIL) THEN BEGIN
  2826.         Dlg^.Delete (ScrollBar);
  2827.         Dispose (ScrollBar, Done);
  2828.         ScrollBar := NIL;
  2829.         pExtendedTemplate (Templ)^.ScrollBar := NIL;
  2830.       END;
  2831.       IF (DD.ScrollBar = 1) AND (ScrollBar = NIL) THEN BEGIN
  2832.         ScrollBar := New (pScrollBar, Init (RS));
  2833.         pExtendedTemplate (Templ)^.ScrollBar := ScrollBar;
  2834.         Dlg^.Insert (ScrollBar);
  2835.       END;
  2836.  
  2837.       pExtendedTemplate (Templ)^.NewChangeBounds (R, RL);
  2838.       Dlg^.ReDraw;
  2839.     END;
  2840.   END ELSE IF (Code = cmDeleteTempl) THEN
  2841.     ListBoxDialog := '';
  2842.  
  2843.   IF Box <>  NIL THEN
  2844.     Dispose (Box, Done);
  2845. END;
  2846.  
  2847. (* ---------------------------------------------------------------- *)
  2848. (*                             MemoDialog                           *)
  2849. (* ---------------------------------------------------------------- *)
  2850. FUNCTION MemoDialog (Where:     pPoint;
  2851.                      VAR Templ: pTemplate;
  2852.                      Dlg:       pWorkDialog): STRING;
  2853.  
  2854.   TYPE
  2855.     DialogData = RECORD
  2856.        Title:    STRING [80];
  2857.        TX,TY:    LONGINT;
  2858.        X, Y:     LONGINT;
  2859.        XL, YL:   LONGINT;
  2860.        MaxLen:   LONGINT;
  2861.        ScrollBar:WORD;
  2862.     END;
  2863.  
  2864.   VAR
  2865.     Memo:      pMemo;
  2866.     Scrollbar: pScrollBar;
  2867.     Lab:       pLabel;
  2868.     View:      pView;
  2869.     Box:       pDialog;
  2870.     Code:      INTEGER;
  2871.     DD:        DialogData;
  2872.     R, RL, RS: tRect;
  2873. BEGIN
  2874.   (* -------------------------------------------------------------- *)
  2875.   IF Templ <> NIL THEN BEGIN
  2876.     Memo     := pMemo (Templ^.Client);
  2877.     Lab      := pExtendedTemplate (Templ)^.Lab;
  2878.     ScrollBar:= pExtendedTemplate (Templ)^.ScrollBar;
  2879.   END ELSE BEGIN
  2880.     Memo     := NIL;
  2881.     Lab      := NIL;
  2882.     ScrollBar:= NIL;
  2883.   END;
  2884.   (* -------------------------------------------------------------- *)
  2885.   R.Assign (10, 3, 70, 19);
  2886.   Box := New (pTemplDialog, Init (R, ' tMemo-Dialog '));
  2887.   WITH Box^ DO BEGIN
  2888.     R.Assign (5, 2, 18, 3);
  2889.     Insert (New (pStaticText, Init (R, 'Beschriftung: ')));
  2890.  
  2891.     R.Assign (15, 3, 50, 4);
  2892.     View := New (pKeyInputLine, Init (R, 80));
  2893.     Insert (View);
  2894.     R.Assign (8, 3, 14, 4);
  2895.     Insert (New (pLabel, Init (R, 'Text: ', View)));
  2896.  
  2897.     R.Assign (12, 4, 17, 5);
  2898.     View := New (pNumInputLine, Init (R, 5, 0, 80));
  2899.     Insert (View);
  2900.     R.Assign (8, 4, 11, 5);
  2901.     Insert (New (pLabel, Init (R, 'X: ', View)));
  2902.  
  2903.     R.Assign (23, 4, 28, 5);
  2904.     View := New (pNumInputLine, Init (R, 5, 0, 25));
  2905.     Insert (View);
  2906.     R.Assign (19, 4, 22, 5);
  2907.     Insert (New (pLabel, Init (R, 'Y: ', View)));
  2908.  
  2909.     R.Assign (4, 6, 17, 7);
  2910.     Insert (New (pStaticText, Init (R, 'Listbox:')));
  2911.  
  2912.     R.Assign (12, 7, 17, 8);
  2913.     View := New (pNumInputLine, Init (R, 5, 0, 80));
  2914.     Insert (View);
  2915.     R.Assign (8, 7, 11, 8);
  2916.     Insert (New (pLabel, Init (R, 'X: ', View)));
  2917.  
  2918.     R.Assign (23, 7, 28, 8);
  2919.     View := New (pNumInputLine, Init (R, 5, 0, 25));
  2920.     Insert (View);
  2921.     R.Assign (19, 7, 22, 8);
  2922.     Insert (New (pLabel, Init (R, 'Y: ', View)));
  2923.  
  2924.     R.Assign (18, 8, 26, 9);
  2925.     View := New (pNumInputLine, Init (R, 5, 0, 80));
  2926.     Insert (View);
  2927.     R.Assign (8, 8, 17, 9);
  2928.     Insert (New (plabel, Init (R, 'Länge X: ', View)));
  2929.  
  2930.     R.Assign (38, 8, 45, 9);
  2931.     View := New (pNumInputLine, Init (R, 5, 0, 255));
  2932.     Insert (View);
  2933.     R.Assign (28, 8, 37, 9);
  2934.     Insert (New (pLabel, Init (R, 'Länge Y: ', View)));
  2935.  
  2936.     R.Assign (29, 9, 36, 10);
  2937.     View := New (pNumInputLine, Init (R, 5, 0, MaxLongInt));
  2938.     Insert (View);
  2939.     R.Assign (8, 9, 29, 10);
  2940.     Insert (New (pLabel, Init (R, 'Max. Zeichenanzahl: ', View)));
  2941.  
  2942.     R.Assign (4, 11, 21, 12);
  2943.     Insert (New (pCheckBoxes, Init (R, NewSItem (' ScrollBar ', NIL))));
  2944.  
  2945.     R.Assign (5, Size.Y-3, 15, Size.Y-1);
  2946.     Insert (New (pButton, Init (R, '~O~K', cmOk, bfDefault)));
  2947.     IF Memo <> NIL THEN BEGIN
  2948.       R.Assign (20, Size.Y-3, 40, Size.Y-1);
  2949.       Insert (New (pButton, Init (R, 'Objekt ~l~öschen ',
  2950.                                   cmDeleteTempl, bfNormal)));
  2951.     END;
  2952.     R.Assign (45, Size.Y-3, 55, Size.Y-1);
  2953.     Insert (New (pButton, Init (R, '~C~ancel', cmCancel, bfNormal)));
  2954.     SelectNext (FALSE);
  2955.   END;
  2956.   (* -------------------------------------------------------------- *)
  2957.   IF Templ=NIL THEN BEGIN
  2958.     DD.Title := ''; 
  2959.     DD.TX := Where^.X;  DD.TY := Where^.Y;
  2960.     DD.X  := DD.TX;     DD.Y  := DD.TY + 1;
  2961.     DD.XL := 10;        DD.YL := 5;
  2962.     DD.MaxLen := 512;
  2963.     DD.ScrollBar := 1;
  2964.   END ELSE BEGIN
  2965.     IF Lab^.Text <> NIL THEN
  2966.       DD.Title := Lab^.Text^;
  2967.     DD.TX := Templ^.Origin.X + Lab^.Origin.X;
  2968.     DD.TY := Templ^.Origin.Y + Lab^.Origin.Y;
  2969.     DD.X  := Templ^.Origin.X + Memo^.Origin.X;
  2970.     DD.Y  := Templ^.Origin.Y + Memo^.Origin.Y;
  2971.     DD.XL := Memo^.Size.X;
  2972.     DD.YL := Memo^.Size.Y;
  2973.     DD.MaxLen := Memo^.BufSize;
  2974.     DD.ScrollBar := WORD (ScrollBar <> NIL);
  2975.   END;
  2976.   (* -------------------------------------------------------------- *)
  2977.   Box^.SetData (DD);
  2978.   Code := Desktop^.ExecView (Application^.ValidView (Box));
  2979.   MemoDialog := DD.Title;
  2980.   (* -------------------------------------------------------------- *)
  2981.   IF Code = cmOk THEN BEGIN
  2982.     Box^.GetData (DD);
  2983.     RL.Assign (DD.TX, DD.TY,
  2984.                Succ (DD.TX + Length (DD.Title)), Succ (DD.TY));
  2985.     R.Assign (DD.X, DD.Y, DD.X + DD.XL, DD.Y + DD.YL);
  2986.     RS.Assign (DD.X+DD.XL, DD.Y, DD.X+DD.XL+1, DD.Y+DD.YL);
  2987.     IF (Templ = NIL) THEN BEGIN
  2988.       (* ---------------------------------------------------------- *)
  2989.       IF DD.ScrollBar = 1 THEN BEGIN
  2990.         ScrollBar := New (pScrollBar, Init (RS));
  2991.         ScrollBar^.SetRange (0, 1);
  2992.         ScrollBar^.GrowMode := 0;
  2993.         Dlg^.Insert (ScrollBar);
  2994.       END;
  2995.       Memo := New (pMemo, Init (R, NIL, ScrollBar, NIL, DD.MaxLen));
  2996.       Memo^.GrowMode := 0;
  2997.       Lab  := New (pLabel, Init (RL, DD.Title, Memo));
  2998.       Templ:= New (pExtendedTemplate,
  2999.                     Init (Memo, Lab, ScrollBar, NIL,
  3000.                           MinItemSize, MaxItemSize,
  3001.                           DD.Title, idMemo));
  3002.       pExtendedTemplate (Templ)^.NewChangeBounds (R, RL);
  3003.       IF LowMemory THEN BEGIN
  3004.         Application^.OutOfMemory;
  3005.         Dispose (Templ, Done);
  3006.         IF ScrollBar <> NIL THEN
  3007.           Dispose (ScrollBar, Done);
  3008.       END;
  3009.     END ELSE BEGIN
  3010.       (* ---------------------------------------------------------- *)
  3011.       Memo^.SetBufSize (DD.MaxLen);
  3012.  
  3013.       IF Lab^.Text <> NIL THEN
  3014.         DisposeStr (Lab^.Text);
  3015.       Lab^.Text := NewStr (DD.Title);
  3016.  
  3017.       IF (DD.ScrollBar = 0) AND (ScrollBar <> NIL) THEN BEGIN
  3018.         Dlg^.Delete (ScrollBar);
  3019.         Dispose (ScrollBar, Done);
  3020.         ScrollBar := NIL;
  3021.         pExtendedTemplate (Templ)^.ScrollBar := NIL;
  3022.       END;
  3023.       IF (DD.ScrollBar = 1) AND (ScrollBar = NIL) THEN BEGIN
  3024.         ScrollBar := New (pScrollBar, Init (RS));
  3025.         pExtendedTemplate (Templ)^.ScrollBar := ScrollBar;
  3026.         Dlg^.Insert (ScrollBar);
  3027.       END;
  3028.  
  3029.       pExtendedTemplate (Templ)^.NewChangeBounds (R, RL);
  3030.       Dlg^.ReDraw;
  3031.     END;
  3032.   END ELSE IF (Code = cmDeleteTempl) THEN
  3033.     MemoDialog := '';
  3034.  
  3035.   IF Box <>  NIL THEN
  3036.     Dispose (Box, Done);
  3037. END;
  3038.  
  3039. (* ---------------------------------------------------------------- *)
  3040. (*                          ClusterDialog                           *)
  3041. (* ---------------------------------------------------------------- *)
  3042. (* ClusterDialog dient als Grundlage für RadioButtonsDialog und     *)
  3043. (* CheckBoxesDialog; der zusätzliche Parameter RadioButtons gibt an,*)
  3044. (* welches Dialogelement erzeugt werden soll.                       *)
  3045. (* ---------------------------------------------------------------- *)
  3046. FUNCTION ClusterDialog (Where:     pPoint;
  3047.                         VAR Templ: pTemplate;
  3048.                         Dlg:       pWorkDialog;
  3049.                         RadioButtons: BOOLEAN): STRING;
  3050.  
  3051.   TYPE
  3052.     DialogData = RECORD
  3053.       Title: STRING [80];
  3054.       TX: LONGINT;
  3055.       TY: LONGINT;
  3056.       ItemsList: pStringCollection;
  3057.       Focused: INTEGER;
  3058.     END;
  3059.  
  3060.   VAR
  3061.     Cluster: pCluster;
  3062.     Lab:     pLabel;
  3063.     View:    pView;
  3064.     Box:     pDialog;
  3065.     Code:    INTEGER;
  3066.     DD:      DialogData;
  3067.     R, RL:   tRect;
  3068.     ID:      INTEGER;
  3069.  
  3070.   FUNCTION GetMaxWidth: INTEGER;
  3071.     VAR
  3072.       j, i, Max: INTEGER;
  3073.   BEGIN
  3074.     Max := 0;
  3075.     FOR i := 0 TO DD.ItemsList^.Count-1 DO BEGIN
  3076.       j := Length (String (DD.ItemsList^.Items^[i]^));
  3077.       IF j > Max THEN
  3078.         Max := j;
  3079.     END;
  3080.     GetMaxWidth := Max + 6;
  3081.   END;
  3082.  
  3083.   PROCEDURE Cluster2DD;
  3084.     VAR i: INTEGER;
  3085.   BEGIN
  3086.     DD.ItemsList := New (pStringColl, Init (20, 10));
  3087.     FOR i := 0 TO Cluster^.Strings.Count-1 DO
  3088.       DD.ItemsList^.Insert (NewStr (String (Cluster^.Strings.At (i)^)));
  3089.   END;
  3090.  
  3091.   PROCEDURE DD2Cluster;
  3092.     VAR i: INTEGER;
  3093.   BEGIN
  3094.     Cluster^.Strings.FreeAll;
  3095.     Cluster^.Strings.SetLimit (DD.ItemsList^.Count);
  3096.     FOR i := 0 TO DD.ItemsList^.Count-1 DO
  3097.       Cluster^.Strings.AtInsert (i, NewStr (String (DD.ItemsList^.At (i)^)));
  3098.   END;
  3099.  
  3100. BEGIN
  3101.   (* -------------------------------------------------------------- *)
  3102.   IF Templ <> NIL THEN BEGIN
  3103.     Cluster := pCluster (Templ^.Client);
  3104.     Lab     := pExtendedTemplate (Templ)^.Lab;
  3105.     Cluster2DD;
  3106.   END ELSE BEGIN
  3107.     Cluster := NIL;
  3108.     Lab     := NIL;
  3109.     DD.ItemsList := New (pStringColl, Init (20, 10));
  3110.   END;
  3111.   (* -------------------------------------------------------------- *)
  3112.   IF RadioButtons THEN
  3113.     Box := New (pClusterDialog, Init (' tRadioButtons-Dialog ',
  3114.                                       DD.ItemsList,
  3115.                                       Templ <> NIL))
  3116.   ELSE
  3117.     Box := New (pClusterDialog, Init (' tCheckBoxes-Dialog ',
  3118.                                       DD.ItemsList,
  3119.                                       Templ <> NIL));
  3120.   (* -------------------------------------------------------------- *)
  3121.   IF Templ=NIL THEN BEGIN
  3122.     DD.Title := ''; 
  3123.     DD.TX := Where^.X;  DD.TY := Where^.Y;
  3124.     DD.Focused := 0;
  3125.   END ELSE BEGIN
  3126.     IF Lab^.Text <> NIL THEN
  3127.       DD.Title := Lab^.Text^;
  3128.     DD.TX := Templ^.Origin.X + Lab^.Origin.X;
  3129.     DD.TY := Templ^.Origin.Y + Lab^.Origin.Y;
  3130.     DD.Focused := 0;
  3131.   END;
  3132.   (* -------------------------------------------------------------- *)
  3133.   Box^.SetData (DD);
  3134.   Code := Desktop^.ExecView (Application^.ValidView (Box));
  3135.   ClusterDialog := DD.Title;
  3136.   (* -------------------------------------------------------------- *)
  3137.   IF Code = cmOk THEN BEGIN
  3138.     Box^.GetData (DD);
  3139.     RL.Assign (DD.TX, DD.TY,
  3140.                Succ (DD.TX + Length (DD.Title)), Succ (DD.TY));
  3141.  
  3142.     R.Assign (DD.TX, DD.TY+1,
  3143.               DD.TX + GetMaxWidth, DD.TY + 1 + DD.ItemsList^.Count);
  3144.     IF (Templ = NIL) THEN BEGIN
  3145.       (* ---------------------------------------------------------- *)
  3146.       IF RadioButtons THEN BEGIN
  3147.         Cluster := New (pRadioButtons, Init (R, GetItems (DD.ItemsList)));
  3148.         ID := idRadioButtons;
  3149.       END ELSE BEGIN
  3150.         Cluster := New (pCheckBoxes, Init (R, GetItems (DD.ItemsList)));
  3151.         ID := idCheckBoxes;
  3152.       END;
  3153.  
  3154.       Lab  := New (pLabel, Init (RL, DD.Title, Cluster));
  3155.       Templ:= New (pExtendedTemplate,
  3156.                     Init (Cluster, Lab, NIL, NIL,
  3157.                           MinItemSize, MaxItemSize,
  3158.                           DD.Title, ID));
  3159.       Templ := pExtendedTemplate (Application^.ValidView (Templ));
  3160.     END ELSE BEGIN
  3161.       (* ---------------------------------------------------------- *)
  3162.       DD2Cluster;
  3163.  
  3164.       IF Lab^.Text <> NIL THEN
  3165.         DisposeStr (Lab^.Text);
  3166.       Lab^.Text := NewStr (DD.Title);
  3167.  
  3168.       pExtendedTemplate (Templ)^.NewChangeBounds (R, RL);
  3169.       Dlg^.ReDraw;
  3170.     END;
  3171.   END ELSE IF (Code = cmDeleteTempl) THEN
  3172.     ClusterDialog := '';
  3173.  
  3174.   IF Box <>  NIL THEN
  3175.     Dispose (Box, Done);
  3176.   IF DD.ItemsList <> NIL THEN
  3177.     Dispose (DD.ItemsList, Done);
  3178. END;
  3179.  
  3180. (* ---------------------------------------------------------------- *)
  3181. (*                        RadioButtonsDialog                        *)
  3182. (* ---------------------------------------------------------------- *)
  3183. FUNCTION RadioButtonsDialog (Where: pPoint;
  3184.                              VAR Templ: pTemplate;
  3185.                              Dlg: pWorkDialog): STRING;
  3186. BEGIN
  3187.   RadioButtonsDialog := ClusterDialog (Where, Templ, Dlg, TRUE);
  3188. END;
  3189.  
  3190. (* ---------------------------------------------------------------- *)
  3191. (*                          CheckBoxesDialog                        *)
  3192. (* ---------------------------------------------------------------- *)
  3193. FUNCTION CheckBoxesDialog (Where: pPoint;
  3194.                            VAR Templ: pTemplate;
  3195.                            Dlg: pWorkDialog): STRING;
  3196. BEGIN
  3197.   CheckBoxesDialog := ClusterDialog (Where, Templ, Dlg, FALSE);
  3198. END;
  3199.  
  3200. (* ---------------------------------------------------------------- *)
  3201. (*                     StandardButtons - Dialoge                    *)
  3202. (* ---------------------------------------------------------------- *)
  3203. FUNCTION StandardButton (Where:     pPoint;
  3204.                          VAR Templ: pTemplate;
  3205.                          Dlg:       pWorkDialog;
  3206.                          ID:        WORD;
  3207.                          Title:     STRING;
  3208.                          Command:   WORD;
  3209.                          Flags:     WORD): STRING;
  3210.   VAR
  3211.     Button: pButton;
  3212.     R:      tRect;
  3213. BEGIN
  3214.   IF Templ <> NIL THEN
  3215.     StandardButton := ButtonDialog (Where, Templ, Dlg)
  3216.   ELSE BEGIN
  3217.     R.Assign (Where^.X, Where^.Y,
  3218.               Where^.X+Length (Title)+4, Where^.Y+2);
  3219.     Button := New (pButton,
  3220.                    Init (R, Title, Command, Flags));
  3221.     Button^.Options := Button^.Options AND NOT ofPreProcess;
  3222.     Templ := New (pTemplate,
  3223.                   Init (Button, MinButtonSize, MaxItemSize, Title, ID));
  3224.     IF Application^.ValidView (Templ) <> NIL THEN
  3225.       StandardButton := Title
  3226.     ELSE
  3227.       StandardButton := '';
  3228.   END;
  3229. END;
  3230.  
  3231. FUNCTION OkButtonDialog (Where:     pPoint;
  3232.                          VAR Templ: pTemplate;
  3233.                          Dlg:       pWorkDialog): STRING;
  3234. BEGIN
  3235.   OKButtonDialog := StandardButton (Where, Templ, Dlg, idOkButton,
  3236.                                     '~O~K', cmOk, bfDefault);
  3237. END;
  3238.  
  3239. FUNCTION CancelButtonDialog  (Where:     pPoint;
  3240.                               VAR Templ: pTemplate;
  3241.                               Dlg:       pWorkDialog): STRING;
  3242. BEGIN
  3243.   CancelButtonDialog := StandardButton (Where, Templ, Dlg, idCancelButton,
  3244.                                         '~A~bbruch', cmCancel, bfNormal);
  3245. END;
  3246.  
  3247. FUNCTION YesButtonDialog (Where:     pPoint;
  3248.                           VAR Templ: pTemplate;
  3249.                           Dlg:       pWorkDialog): STRING;
  3250. BEGIN
  3251.   YesButtonDialog := StandardButton (Where, Templ, Dlg, idYesButton,
  3252.                                     '~J~a', cmYes, bfNormal);
  3253. END;
  3254.  
  3255. FUNCTION NoButtonDialog (Where:     pPoint;
  3256.                          VAR Templ: pTemplate;
  3257.                          Dlg:       pWorkDialog): STRING;
  3258. BEGIN
  3259.   NoButtonDialog := StandardButton (Where, Templ, Dlg, idNoButton,
  3260.                                     '~N~ein', cmNo, bfNormal);
  3261. END;
  3262.  
  3263. FUNCTION HelpButtonDialog (Where:     pPoint;
  3264.                            VAR Templ: pTemplate;
  3265.                            Dlg:       pWorkDialog): STRING;
  3266. BEGIN
  3267.   HelpButtonDialog := StandardButton (Where, Templ, Dlg, idHelpButton,
  3268.                                       '~H~ilfe', cmHelp, bfNormal);
  3269. END;
  3270.  
  3271. (* ================================================================ *)
  3272. (*     I N S E R T  I T E M  A R R A Y  -  P R O Z E D U R E N      *)
  3273. (* ================================================================ *)
  3274. (* Die InsertItemArray-Prozeduren müssen die Template Templ als     *)
  3275. (* Dialogelement in den Dialog "Dialog" einfügen und werden aufge-  *)
  3276. (* rufen, wenn ein tWorkDialog auf Ressource gespeichert werden     *)
  3277. (* soll. Es kann nicht einfach der Client der Template eingefügt    *)
  3278. (* werden,da sein Origin relativ zu dem der Template angegeben wird.*)
  3279. (* Ausserdem müssen bei den tExtendedTemplate-Objekten auch noch    *)
  3280. (* die zugehörigen Objekte wie Labels, Historys und Scrollbalken    *)
  3281. (* in den Dialog eingefügt werden (z.B. bei InsertMemo).            *)
  3282. (* ---------------------------------------------------------------- *)
  3283. (*                         InsertStaticText                         *)
  3284. (* ---------------------------------------------------------------- *)
  3285. PROCEDURE InsertStaticText (Templ:  pTemplate;
  3286.                             Dialog: pDialog);
  3287.   VAR R: tRect;
  3288. BEGIN
  3289.   Templ^.GetBounds (R);
  3290.   Dialog^.Insert (New (pStaticText, Init (R, Templ^.Name^)));
  3291. END;
  3292.  
  3293. (* ---------------------------------------------------------------- *)
  3294. (*                            InsertButton                          *)
  3295. (* ---------------------------------------------------------------- *)
  3296. PROCEDURE InsertButton (Templ:  pTemplate;
  3297.                         Dialog: pDialog);
  3298.   VAR
  3299.     R: tRect;
  3300.     Button: pButton;
  3301. BEGIN
  3302.   Button := pButton (Templ^.Client);
  3303.   Templ^.GetBounds (R);
  3304.   Dialog^.Insert (New (pButton, Init (R, Button^.Title^,
  3305.                                          Button^.Command,
  3306.                                          Button^.Flags)));
  3307. END;
  3308.  
  3309. (* ---------------------------------------------------------------- *)
  3310. (*                          InsertInputLine                         *)
  3311. (* ---------------------------------------------------------------- *)
  3312. (* Erstellt ein InputLine-Objekt und fügt es samt dem Label in den  *)
  3313. (* Dialog ein. Verfügt die Eingabezeile über eine Aufzeichnungs-    *)
  3314. (* liste, so wird das History-Objekt auch eingefügt, wobei es sowie *)
  3315. (* das Label mit der Eingabezeile verbunden werden. Es wird ange-   *)
  3316. (* nommen, dass Templ den Typ pExtendedTemplate hat!, was sicherge- *)
  3317. (* stellt ist, da nur InputLineDialog eine Eingabezeile erstellt    *)
  3318. (* und durch die Prozeduren-Arrays immer nur die zugehörigen Pro-   *)
  3319. (* zeduren aufgerufen werden.                                       *)
  3320. (* ---------------------------------------------------------------- *)
  3321. PROCEDURE InsertInputLine (Templ:  pTemplate;
  3322.                            Dialog: pDialog);
  3323.   VAR
  3324.     InputLine: pInputLine;
  3325.     Lab:       pLabel;
  3326.     History:   pHistory;
  3327.     R:         tRect;
  3328. BEGIN
  3329.   InputLine  := pInputLine (Templ^.Client);
  3330.   GetClientBounds (Templ, R);
  3331.   InputLine := New (pInputLine, Init (R, InputLine^.MaxLen));
  3332.   Dialog^.Insert (InputLine);
  3333.  
  3334.   Lab := pExtendedTemplate (Templ)^.Lab;
  3335.   GetLabelBounds (Templ, R);
  3336.   Dialog^.Insert (New (pLabel, Init (R, Lab^.Text^, InputLine)));
  3337.  
  3338.   History := pExtendedTemplate (Templ)^.History;
  3339.   IF History <> NIL THEN BEGIN
  3340.     History^.GetBounds (R);
  3341.     Dialog^.Insert (New (pHistory, Init (R, InputLine, History^.HistoryID)));
  3342.   END;
  3343. END;
  3344.  
  3345. (* ---------------------------------------------------------------- *)
  3346. (*                            InsertListBox                         *)
  3347. (* ---------------------------------------------------------------- *)
  3348. (* InsertListBox fügt zunächst den Scrollbalken ein, sofern die     *)
  3349. (* Template mit einem solchen verknüpft ist. Anschliessend werden   *)
  3350. (* der Client und das Label eingefügt.                              *)
  3351. (* ---------------------------------------------------------------- *)
  3352. PROCEDURE InsertListBox (Templ:  pTemplate;
  3353.                          Dialog: pDialog);
  3354.   VAR
  3355.     ListBox:   pListBox;
  3356.     Lab:       pLabel;
  3357.     ScrollBar: pScrollBar;
  3358.     R:         tRect;
  3359. BEGIN
  3360.   ScrollBar := pExtendedTemplate (Templ)^.ScrollBar;
  3361.   IF ScrollBar <> NIL THEN BEGIN
  3362.     ScrollBar^.GetBounds (R);
  3363.     ScrollBar := New (pScrollBar, Init (R));
  3364.     Dialog^.Insert (ScrollBar);
  3365.   END;
  3366.  
  3367.   ListBox := pListBox (Templ^.Client);
  3368.   GetClientBounds (Templ, R);
  3369.   ListBox := New (pListBox, Init (R, ListBox^.NumCols, ScrollBar));
  3370.   Dialog^.Insert (ListBox);
  3371.  
  3372.   Lab := pExtendedTemplate (Templ)^.Lab;
  3373.   GetLabelBounds (Templ, R);
  3374.   Dialog^.Insert (New (pLabel, Init (R, Lab^.Text^, ListBox)));
  3375. END;
  3376.  
  3377. (* ---------------------------------------------------------------- *)
  3378. (*                             InsertMemo                           *)
  3379. (* ---------------------------------------------------------------- *)
  3380. PROCEDURE InsertMemo (Templ:  pTemplate;
  3381.                       Dialog: pDialog);
  3382.   VAR
  3383.     Memo:      pMemo;
  3384.     Lab:       pLabel;
  3385.     ScrollBar: pScrollBar;
  3386.     R:         tRect;
  3387. BEGIN
  3388.   ScrollBar := pExtendedTemplate (Templ)^.ScrollBar;
  3389.   IF ScrollBar <> NIL THEN BEGIN
  3390.     ScrollBar^.GetBounds (R);
  3391.     ScrollBar := New (pScrollBar, Init (R));
  3392.     Dialog^.Insert (ScrollBar);
  3393.   END;
  3394.  
  3395.   Memo := pMemo (Templ^.Client);
  3396.   GetClientBounds (Templ, R);
  3397.   Memo := New (pMemo, Init (R, NIL, ScrollBar, NIL, Memo^.BufSize));
  3398.   Dialog^.Insert (Memo);
  3399.  
  3400.   Lab := pExtendedTemplate (Templ)^.Lab;
  3401.   GetLabelBounds (Templ, R);
  3402.   Dialog^.Insert (New (pLabel, Init (R, Lab^.Text^, Memo)));
  3403. END;
  3404.  
  3405. (* ---------------------------------------------------------------- *)
  3406. (*                             InsertCluster                        *)
  3407. (* ---------------------------------------------------------------- *)
  3408. (* InsertCluster wird nicht direkt aufgerufen, sondern nur von      *)
  3409. (* InsertRadioButtons und InsertCheckboxes. Ist der zusätzliche     *)
  3410. (* Parameter RadioButtons TRUE, so wird ein RadioButtons-Objekt er- *)
  3411. (* zeugt, sonst ein CheckBoxes.                                     *)
  3412. (* ---------------------------------------------------------------- *)
  3413. PROCEDURE InsertCluster (Templ:  pTemplate;
  3414.                          Dialog: pDialog;
  3415.                          RadioButtons: BOOLEAN);
  3416.   VAR
  3417.     Cluster: pCluster;
  3418.     Lab:     pLabel;
  3419.     R:       tRect;
  3420. BEGIN
  3421.   Cluster := pCluster (Templ^.Client);
  3422.   GetClientBounds (Templ, R);
  3423.   IF RadioButtons THEN
  3424.     Cluster := New (pRadioButtons,
  3425.                     Init (R, GetItems (@Cluster^.Strings)))
  3426.   ELSE
  3427.     Cluster := New (pCheckBoxes,
  3428.                     Init (R, GetItems (@Cluster^.Strings)));
  3429.   Dialog^.Insert (Cluster);
  3430.  
  3431.   Lab := pExtendedTemplate (Templ)^.Lab;
  3432.   GetLabelBounds (Templ, R);
  3433.   Dialog^.Insert (New (pLabel, Init (R, Lab^.Text^, Cluster)));
  3434. END;
  3435.  
  3436. (* ---------------------------------------------------------------- *)
  3437. (*                          InsertRadioButtons                      *)
  3438. (* ---------------------------------------------------------------- *)
  3439. PROCEDURE InsertRadioButtons (Templ:  pTemplate;
  3440.                               Dialog: pDialog);
  3441. BEGIN
  3442.   InsertCluster (Templ, Dialog, TRUE);
  3443. END;
  3444.  
  3445. (* ---------------------------------------------------------------- *)
  3446. (*                          InsertCheckBoxes                        *)
  3447. (* ---------------------------------------------------------------- *)
  3448. PROCEDURE InsertCheckBoxes (Templ:  pTemplate;
  3449.                             Dialog: pDialog);
  3450. BEGIN
  3451.   InsertCluster (Templ, Dialog, FALSE);
  3452. END;
  3453.  
  3454. (* ================================================================ *)
  3455. (*      S A V E  S O U R C E  A R R A Y  -  P R O Z E D U R E N     *)
  3456. (* ================================================================ *)
  3457. (* Die SaveSourceArray-Prozeduren speichern in die übergebene       *)
  3458. (* Stringkollektion Lines den Quelltext, den es zur Erzeugung der   *)
  3459. (* Template Templ bzw ihres Clients benötigt. Ist What gleich       *)
  3460. (* SaveInsertDef, so werden die zum Einfügen in einen Dialog        *)
  3461. (* benötigten Befehle wie R.Assign etc gespeichert; ist What gleich *)
  3462. (* SaveTypeDef, so wird gespeichert, welchen Typ der Client für     *)
  3463. (* den Datenaustausch mit dem künftigen Dialog braucht (z.B.        *)
  3464. (* "String0: STRING [80];"; siehe auch InputLineSource).            *)
  3465. (* ---------------------------------------------------------------- *)
  3466. (*                         StaticTextSource                         *)
  3467. (* ---------------------------------------------------------------- *)
  3468. (* Ein tStaticText-Objekt braucht kein Feld für den Datenaustausch, *)
  3469. (* weshalb nur bei What=SaveInsertDef die Befehle zum Einfügen ge-  *)
  3470. (* schrieben werden.                                                *)
  3471. (* ---------------------------------------------------------------- *)
  3472. PROCEDURE StaticTextSource (What:  BYTE;
  3473.                             Templ: pTemplate;
  3474.                             Lines: pStringColl);
  3475.   VAR R: tRect;
  3476. BEGIN
  3477.   IF What = SaveInsertDef THEN BEGIN
  3478.     Templ^.GetBounds (R);
  3479.     Lines^.Insert (NewStr (GetAssignString (R)));
  3480.     Lines^.Insert (NewStr ('  '+InsertStr+'Insert (New (pStaticText, '+
  3481.                                                        'Init (R, '''+Templ^.Name^+''')));'));
  3482.   END;
  3483. END;
  3484.  
  3485. (* ---------------------------------------------------------------- *)
  3486. (*                            ButtonSource                          *)
  3487. (* ---------------------------------------------------------------- *)
  3488. PROCEDURE ButtonSource (What:  BYTE;
  3489.                         Templ: pTemplate;
  3490.                         Lines: pStringColl);
  3491.   VAR
  3492.     Button: pButton;
  3493.     R:      tRect;
  3494. BEGIN
  3495.   Button := pButton (Templ^.Client);
  3496.   IF What = SaveInsertDef THEN BEGIN
  3497.     Templ^.GetBounds (R);
  3498.     Lines^.Insert (NewStr (GetAssignString (R)));
  3499.     Lines^.Insert (NewStr ('  '+InsertStr+'Insert (New (pButton, '+
  3500.                                                   'Init (R, '''+Button^.Title^+''', '+
  3501.                                                          Int2Str (Button^.Command)+', '+
  3502.                                                          Int2Str (Button^.Flags)+')));'));
  3503.   END;
  3504. END;
  3505.  
  3506. (* ---------------------------------------------------------------- *)
  3507. (*                         InputLineSource                          *)
  3508. (* ---------------------------------------------------------------- *)
  3509. (* Für ein tInputLine-Objekt sind die Befehle zum Einfügen schon    *)
  3510. (* einiges aufwendiger, weil berücksichtigt werden muss, ob die     *)
  3511. (* Template mit einem History-Objekt verknüpft ist. Auch muss das   *)
  3512. (* Label-Objekt eingefügt werden. Ist What=SaveTypeDef, so wird     *)
  3513. (* "StringX: STRING [MaxLänge];" geschrieben, wobei X InputLineNo   *)
  3514. (* ist, ein Zähler, der von tWorkDialog.SaveAsSource auf Null       *)
  3515. (* gesetzt und von InputLineSource erhöht wird, damit bei mehereren *)
  3516. (* Eingabezeilen in einem Dialog keine Probleme mit der Namens-     *)
  3517. (* gebung auftreten. Als MaxLänge wird das Feld MaxLen der Eingabe- *)
  3518. (* zeile (also des Clients) verwendet. - Analog hierzu funktio-     *)
  3519. (* nieren auch die weiteren ItemSource-Prozeduren.                  *)
  3520. (* ---------------------------------------------------------------- *)
  3521. PROCEDURE InputLineSource (What:  BYTE;
  3522.                            Templ: pTemplate;
  3523.                            Lines: pStringColl);
  3524.   VAR
  3525.     InputLine: pInputLine;
  3526.     History:   pHistory;
  3527.     Lab:       pLabel;
  3528.     R:         tRect;
  3529. BEGIN
  3530.   InputLine := pInputLine (Templ^.Client);
  3531.   History   := pExtendedTemplate (Templ)^.History;
  3532.   Lab       := pExtendedTemplate (Templ)^.Lab;
  3533.   IF What = SaveInsertDef THEN BEGIN
  3534.     GetClientBounds (Templ, R);
  3535.     Lines^.Insert (NewStr (GetAssignString (R)));
  3536.     Lines^.Insert (NewStr ('  View := New (pInputLine, '+
  3537.                                           'Init (R, '+Int2Str (InputLine^.MaxLen)+'));'));
  3538.     Lines^.Insert (NewStr ('  '+InsertStr+'Insert (View);'));
  3539.     IF Lab^.Text^ <> '' THEN BEGIN
  3540.       GetLabelBounds (Templ, R);
  3541.       Lines^.Insert (NewStr (GetAssignString (R)));
  3542.       Lines^.Insert (NewStr ('  '+InsertStr+'Insert (New (pLabel, '+
  3543.                                                          'Init (R, '''+Lab^.Text^+''', View)));'));
  3544.     END;
  3545.     IF History <> NIL THEN BEGIN
  3546.       History^.GetBounds (R);
  3547.       Lines^.Insert (NewStr (GetAssignString (R)));
  3548.       Lines^.Insert (NewStr ('  '+InsertStr+'Insert (New (pHistory, '+
  3549.                                                            'Init  (R, pInputLine (View), '+
  3550.                                                                    Int2Str (History^.HistoryID)+')));'));
  3551.     END;
  3552.   END ELSE BEGIN
  3553.     Lines^.Insert (NewStr ('      String'+Int2Str (InputLineNo)+': STRING ['+Int2Str (InputLine^.MaxLen)+'];'));
  3554.     Inc (InputLineNo);
  3555.   END;
  3556. END;
  3557.  
  3558. (* ---------------------------------------------------------------- *)
  3559. (*                           ListBoxSource                          *)
  3560. (* ---------------------------------------------------------------- *)
  3561. PROCEDURE ListBoxSource (What:  BYTE;
  3562.                          Templ: pTemplate;
  3563.                          Lines: pStringColl);
  3564.   VAR
  3565.     ScrollBarStr: STRING;
  3566.     ScrollBar:    pScrollBar;
  3567.     ListBox:      pListBox;
  3568.     Lab:          pLabel;
  3569.     R:            tRect;
  3570. BEGIN
  3571.   ListBox   := pListBox (Templ^.Client);
  3572.   ScrollBar := pExtendedTemplate (Templ)^.ScrollBar;
  3573.   Lab       := pExtendedTemplate (Templ)^.Lab;
  3574.   IF What = SaveInsertDef THEN BEGIN
  3575.     IF ScrollBar <> NIL THEN BEGIN
  3576.       ScrollBar^.GetBounds (R);
  3577.       Lines^.Insert (NewStr (GetAssignString (R)));
  3578.       Lines^.Insert (NewStr ('  View := New (pScrollBar, '+
  3579.                                             'Init  (R)); '));
  3580.       Lines^.Insert (NewStr ('  pScrollBar (View)^.SetRange (0, 0); '));
  3581.       ScrollBarStr := 'pScrollBar (View)';
  3582.     END ELSE
  3583.       ScrollBarStr := 'NIL';
  3584.  
  3585.     GetClientBounds (Templ, R);
  3586.     Lines^.Insert (NewStr (GetAssignString (R)));
  3587.     Lines^.Insert (NewStr ('  View := New (pListBox, '+
  3588.                                           'Init (R, '+Int2Str (ListBox^.NumCols)+', '+
  3589.                                                ScrollBarStr+'));'));
  3590.     Lines^.Insert (NewStr ('  '+InsertStr+'Insert (View);'));
  3591.  
  3592.     IF Lab^.Text^ <> '' THEN BEGIN
  3593.       GetLabelBounds (Templ, R);
  3594.       Lines^.Insert (NewStr (GetAssignString (R)));
  3595.       Lines^.Insert (NewStr ('  '+InsertStr+'Insert (New (pLabel, '+
  3596.                                                          'Init (R, '''+Lab^.Text^+''', View)));'));
  3597.     END;
  3598.   END ELSE BEGIN
  3599.     Lines^.Insert (NewStr ('      ListPtr'+Int2Str (ListBoxNo)+': pCollection;'));
  3600.     Lines^.Insert (NewStr ('      Focused'+Int2Str (ListBoxNo)+': INTEGER;'));
  3601.     Inc (ListBoxNo);
  3602.   END;
  3603. END;
  3604.  
  3605. (* ---------------------------------------------------------------- *)
  3606. (*                             MemoSource                           *)
  3607. (* ---------------------------------------------------------------- *)
  3608. PROCEDURE MemoSource (What:  BYTE;
  3609.                       Templ: pTemplate;
  3610.                       Lines: pStringColl);
  3611.   VAR
  3612.     ScrollBarStr: STRING;
  3613.     ScrollBar:    pScrollBar;
  3614.     Memo:         pMemo;
  3615.     Lab:          pLabel;
  3616.     R:            tRect;
  3617. BEGIN
  3618.   Memo      := pMemo (Templ^.Client);
  3619.   ScrollBar := pExtendedTemplate (Templ)^.ScrollBar;
  3620.   Lab       := pExtendedTemplate (Templ)^.Lab;
  3621.   IF What = SaveInsertDef THEN BEGIN
  3622.     IF ScrollBar <> NIL THEN BEGIN
  3623.       ScrollBar^.GetBounds (R);
  3624.       Lines^.Insert (NewStr (GetAssignString (R)));
  3625.       Lines^.Insert (NewStr ('  View := New (pScrollBar, '+
  3626.                                             'Init  (R)); '));
  3627.       Lines^.Insert (NewStr ('  '+InsertStr+'Insert (View); '));
  3628.       Lines^.Insert (NewStr ('  pScrollBar (View)^.SetRange (0, 0); '));
  3629.       ScrollBarStr := 'pScrollBar (View)';
  3630.     END ELSE
  3631.       ScrollBarStr := 'NIL';
  3632.  
  3633.     GetClientBounds (Templ, R);
  3634.     Lines^.Insert (NewStr (GetAssignString (R)));
  3635.     Lines^.Insert (NewStr ('  View := New (pMemo, '+
  3636.                                           'Init (R, NIL, '+ScrollBarStr+', NIL, '+Int2Str (Memo^.BufSize)+'));'));
  3637.     Lines^.Insert (NewStr ('  '+InsertStr+'Insert (View);'));
  3638.  
  3639.     IF Lab^.Text^ <> '' THEN BEGIN
  3640.       GetLabelBounds (Templ, R);
  3641.       Lines^.Insert (NewStr (GetAssignString (R)));
  3642.       Lines^.Insert (NewStr ('  '+InsertStr+'Insert (New (pLabel, '+
  3643.                                                          'Init (R, '''+Lab^.Text^+''', View)));'));
  3644.     END;
  3645.   END ELSE BEGIN
  3646.     Lines^.Insert (NewStr ('      TextLen'+Int2Str (MemoNo)+': WORD;'));
  3647.     Lines^.Insert (NewStr ('      TextRec'+Int2Str (MemoNo)+': ARRAY [0..'+Int2Str (Memo^.BufSize)+'] OF CHAR; '));
  3648.     Inc (MemoNo);
  3649.   END;
  3650. END;
  3651.  
  3652. (* ---------------------------------------------------------------- *)
  3653. (*                             ClusterSource                        *)
  3654. (* ---------------------------------------------------------------- *)
  3655. (* ClusterSource ist für das Speichern des Quellcodes für die Er-   *)
  3656. (* zeugung von RadioButtons und CheckBoxes verantwortlich und wird  *)
  3657. (* von RadioButtonsSource und CheckBoxesSource aufgerufen, wobei    *)
  3658. (* TypeOfCluster entweder "pRadioButtons" oder "pCheckBoxes" sein   *)
  3659. (* muss. Die Speicherung ist etwas aufwendig, da die Elemente des   *)
  3660. (* Clusters, also die Strings aus tCluster.Strings, in Anweisungen  *)
  3661. (* der Art "NewSItem (NAME, " umgesetzt werden müssen. WriteItems   *)
  3662. (* übernimmt diese Aufgabe.                                         *)
  3663. (* ---------------------------------------------------------------- *)
  3664. PROCEDURE ClusterSource (What:  BYTE;
  3665.                          Templ: pTemplate;
  3666.                          Lines: pStringColl;
  3667.                          TypeOfCluster: STRING);
  3668.   VAR
  3669.     Cluster: pCluster;
  3670.     Lab:     pLabel;
  3671.     R:       tRect;
  3672.  
  3673.   PROCEDURE WriteItems;
  3674.     CONST
  3675.       FillStr : STRING = '                     ';
  3676.     VAR
  3677.       j, i: INTEGER;
  3678.       s: STRING;
  3679.   BEGIN
  3680.     FOR i := 0 TO Cluster^.Strings.Count-1 DO BEGIN
  3681.       s := String (Cluster^.Strings.Items^[i]^);
  3682.       Lines^.Insert (NewStr (FillStr+'NewSItem ('''+s+''','));
  3683.     END;
  3684.     j := i;
  3685.     s := '';
  3686.     FOR i := 0 TO j DO
  3687.       s := s + ')';
  3688.     s := s+'));';
  3689.     Lines^.Insert (NewStr (FillStr+'NIL'+s));
  3690.   END;
  3691.  
  3692. BEGIN
  3693.   Cluster := pCluster (Templ^.Client);
  3694.   Lab     := pExtendedTemplate (Templ)^.Lab;
  3695.   IF What = SaveInsertDef THEN BEGIN
  3696.     GetClientBounds (Templ, R);
  3697.     Lines^.Insert (NewStr (GetAssignString (R)));
  3698.     Lines^.Insert (NewStr ('  View := New ('+TypeOfCluster+','));
  3699.     Lines^.Insert (NewStr ('               Init (R, '));
  3700.     WriteItems;
  3701.     Lines^.Insert (NewStr ('  '+InsertStr+'Insert (View);'));
  3702.  
  3703.     IF Lab^.Text^ <> '' THEN BEGIN
  3704.       GetLabelBounds (Templ, R);
  3705.       Lines^.Insert (NewStr (GetAssignString (R)));
  3706.       Lines^.Insert (NewStr ('  '+InsertStr+'Insert (New (pLabel, '+
  3707.                                                          'Init (R, '''+Lab^.Text^+''', View)));'));
  3708.     END;
  3709.   END ELSE BEGIN
  3710.     Lines^.Insert (NewStr ('      Cluster'+Int2Str (ClusterNo)+': WORD;'));
  3711.     Inc (ClusterNo);
  3712.   END;
  3713. END;
  3714.  
  3715. (* ---------------------------------------------------------------- *)
  3716. (*                             ClusterSource                        *)
  3717. (* ---------------------------------------------------------------- *)
  3718. PROCEDURE RadioButtonsSource (What:  BYTE;
  3719.                          Templ: pTemplate;
  3720.                          Lines: pStringColl);
  3721. BEGIN
  3722.   ClusterSource (What, Templ, Lines, 'pRadioButtons');
  3723. END;
  3724.  
  3725. (* ---------------------------------------------------------------- *)
  3726. (*                             ClusterSource                        *)
  3727. (* ---------------------------------------------------------------- *)
  3728. PROCEDURE CheckBoxesSource (What:  BYTE;
  3729.                          Templ: pTemplate;
  3730.                          Lines: pStringColl);
  3731. BEGIN
  3732.   ClusterSource (What, Templ, Lines, 'pCheckBoxes');
  3733. END;
  3734.  
  3735. (* ---------------------------------------------------------------- *)
  3736. (*                            RegisterDlgBuild                      *)
  3737. (* ---------------------------------------------------------------- *)
  3738. PROCEDURE RegisterDlgBuild;
  3739. BEGIN
  3740.   RegisterType (rTemplate);
  3741.   RegisterType (rExtendedTemplate);
  3742.   RegisterType (rWorkDialog);
  3743.   RegisterEditors;
  3744. END;
  3745.  
  3746. END.
  3747. (* ---------------------------------------------------------------- *)
  3748. (*                        Ende von DLGBUILD.PAS                     *)
  3749. (* ---------------------------------------------------------------- *)
  3750.