Units zum II. oder: Programmierung in Abschnitten In dem letzten Teil haben wir uns ja mit den grundlegenden Dingen in Sachen Unit-Programmierung beschftigt. Diesesmal wollen wir mit Hilfe einiger Wiederholungen die Benutzung von Units vertiefen und einiges mehr hinzulernen. ALLE: "Jawohl, Herr Lehrer!" Also, wie schon gesagt: Units werden mit Hilfe der USES-Anwei- sung eingebunden, nachdem sie ins TPU-Format mit Hilfe der Taste 'F9' compiliert wurden. Man kann also die im INTERFACE-Teil de- klarierten Prozeduren und Funktionen im Hauptteil des Programms nutzen. ***************************************************************** PROGRAM Test; BEGIN WriteLn('Hallo'); END. ***************************************************************** Hier sehen wir ein kleines Programm, das eine Prozedur enthlt: "WriteLn". Doch woher nehmen wir diese? Nun, beim Starten von Turbo oder Borland Pascal wird automatisch eine Unit immer mitge- laden: SYSTEM. Hier sind alle Prozeduren und Funktionen enthal- ten, die zur Standardprogramierung dazugehren. Die Standard- bibliothek TURBO.TPL enthlt die folgenden Units, die bei jedem Starten mitgeladen werden: SYSTEM, OVERLAY, GRAPH, DOS und CRT. Mit Hilfe des Programmes TPUMOVER.EXE knnen eigene Units dieser TPL (Turbo-Pascal-Library) hinzugefgt werden. Doch hierzu steht noch was in der Rubrik "Tips und Tricks". Also: Beim Zugriff auf WriteLn wird auf die Unit SYSTEM zugegriffen, die als einzige nicht mit der USES-Anweisung deklariert werden mu. Zum Aufbau eigener Units, den man ja wohl eher wissen mu. ALLE: "Jawohl, Herr Lehrer!" Hier einmal der schematische Aufbau einer Unit: ***************************************************************** UNIT ; INTERFACE USES ; {Angabe der allgemein und "ffentlich" genutzten} {Units} ... {Hier kommen die _Kpfe_ der ffentlichen Prozedu- ren und Funktionen hin. Diese knnen dann vom Hauptprogramm aus aufgerufen werden.} IMPLEMENTATION USES ; {Angabe der "privat" genutzten Units} VAR ; {Angabe der fr die Quelltexte bentigten Vars} ... {Hier kommen die _kompletten_ Quelltexte der} {oben angebenen Proz. und Funkt. hin.} {Zustzlich knnen auch Hilfsroutinen, die nicht} {ffentlich zugnglich sind, definiert werden.} BEGIN {BEGIN steht nur, wenn anstelle der folgenden 3} {Punkte Aufrufe von Prozeduren oder Funktionen} {stehen, also eine Initalisierung stattfindet} {Wenn dies nicht der Fall ist, wird nur "END."} {verwendent. Bei Overlays _darf_keine_ Initia-} {lisierung stattfinden!!!} ... END. ***************************************************************** Eigentlich steht die komplette Erklrung der einzelnen Teile oben als Kommentare. Etwas verwirrend scheint mir dennoch die Sache mit der Initialisierung zu sein: Wenn in dem Initialisie- rungsteil BEGIN...END. irgendetwas steht, so findet eine Initia- lisierung statt. Wenn keine Initialisierung stattfinden soll, mu man einfach das "BEGIN" weglassen. Bei als Overlays dekla- rierten Units DARF KEINE Initialisierung stattfinden. Wenn ein Initialisierungsabschnitt vorhanden ist, wird dieser sofort beim Aufruf der Unit durchgefhrt. Diese Abschnitte erfolgen der Reihe nach, d.h. in welcher Reihenfolge die Units in der USES-Anweisung aufgerufen werden. Wenn sich Units gegenseitig aufrufen, wird diese Regel natrlich auer Kraft gesetzt. Wichtig wre auch noch zu sagen, da im INTERFACE-Teil NUR die KOMPLETTEN Prozedur- und FunktionsKPFE der ffentlich zugnglichen Proz. und Funktionen stehen (drfen/mssen). Weiterhin sollte die Unit so heien, wie sie spter abgespei- chert werden soll und mit welchem Namen sie spter auch mit USES eingebunden werden soll. Eine Unit, die unter dem Namen "HOPPEL" abgespeichert werden soll, sollte mit "UNIT Hoppel;" beginnen und vom Hauptprogramm aus mit "USES Hoppel" eingebunden werden. Manche tun sich auch mit dem Compilieren ins TPU-Format ein wenig schwer. Eine im Editor befindliche Unit wird mit Hilfe von "F9" compiliert und in dem in Option/Verzeichnisse/EXE & TPU Verzeichnis (BP7) bzw. Option/Directories/EXE & TPU Directory angegebenen Verzeichnis gespeichert. Wenn die Unit nachher auch wieder gefunden werden soll, dann sollte dieses Verzeichnis sich unter anderem auch den in O/V/Unit-Verzeichnisse (BP7) bzw. O/D/Unit-Directories mglicherweise schon vorhandenen Pfadangaben anschlieen. Soviel dazu. Um noch ein letztes Mal die praktische Programmie- rung von Units zu verdeutlichen, werde ich hier eine Unit mit mehreren kleinen und ntzliche Prozeduren und Funktionen basteln, die man dann in ein eigenes Programm einbinden kann. Der Quell- text ist ja auch vorhanden, so da man auch diese Unit hier noch erweitern kann. ***************************************************************** UNIT Tools; INTERFACE USES Crt; PROCEDURE Wri(x,y : BYTE; VG,HG : BYTE; Text : STRING); PROCEDURE Rahmen(x1, y1, x2, y2 : BYTE; VG,HG : BYTE); PROCEDURE HideCursor; PROCEDURE ShowCursor; PROCEDURE KeyBufClr; PROCEDURE Colors(VG,HG : BYTE); PROCEDURE WaitForKeyPressed(Key : CHAR); IMPLEMENTATION {Schreibt "Text" an Position x,y im Textmodus mit Farbe VG auf} {Farbe HG} PROCEDURE Wri(x,y : BYTE; VG,HG : BYTE; Text : STRING); VAR OldTextAttr : BYTE; BEGIN OldTextAttr := TextAttr; GotoXY(x,y); Colors(VG,HG); Write(Text); TextAttr := OldTextAttr; END; {Zeichnet einen Rahmen im Textmodus von Stelle x1,y1 bis zur} {Stelle x2,y2 mit Farbe VG auf Farbe HG} PROCEDURE Rahmen(x1, y1, x2, y2 : BYTE; VG,HG : BYTE); VAR i, j, OldTextAttr : BYTE; BEGIN OldTextAttr := TextAttr; Colors(VG,HG); Wri(x1,y1,VG,HG,#201); Wri(x1,y2,VG,HG,#200); Wri(x2,y1,VG,HG,#187); Wri(x2,y2,VG,HG,#188); FOR i := x1+1 TO x2-1 DO Wri(i,y1,VG,HG,#205); FOR i := x1+1 TO x2-1 DO Wri(i,y2,VG,HG,#205); FOR i := y1+1 TO y2-1 DO Wri(x1,i,VG,HG,#186); FOR i := y1+1 TO y2-1 DO Wri(x2,i,VG,HG,#186); FOR i := x1+1 TO x2-1 DO FOR j := y1+1 TO y2-1 DO Wri(i,j,VG,HG,' '); TextAttr := OldTextAttr; END; {Lt den ewig blinkenden Cursor verschwinden} PROCEDURE HideCursor; Assembler; ASM MOV AH,$01; MOV CH,$20; MOV CL,$20; INT $10; END; {Lt den verschwundenen Cursor wieder erscheinen} PROCEDURE ShowCursor; Assembler; ASM MOV ah,$01; MOV cx,$0607; INT $10; END; {Setzt Vordergrundfarbe VG und Hintergrundfarbe HG} {VG und HG mssen als Zahlen bergeben werden} PROCEDURE Colors(VG,HG : BYTE); BEGIN TextColor(VG); TextBackGround(HG); END; {Lscht den Tastaturspeicher} PROCEDURE KeyBufClr; VAR Dummy : CHAR; BEGIN REPEAT IF KeyPressed THEN Dummy := ReadKey; UNTIL KeyPressed = FALSE; END; {Wartet auf den mit "Key" bergebenen Buchstaben, bis dieser} {gedrckt wird. "Key" mu entweder als Buchstabe in Hochkommas} {oder als # nach der ASCII-Tabelle bergeben werden.} PROCEDURE WaitForKeyPressed(Key : CHAR); VAR Ok : BOOLEAN; BEGIN KeyBufClr; Ok := FALSE; REPEAT IF KeyPressed THEN IF ReadKey = Key THEN Ok := TRUE; UNTIL Ok = TRUE; END; {Kein Initialisierungsteil => nur END.} END. ***************************************************************** Da hier sher viel mit Farben gearbeitet wird, die als BYTEs de- klariert sind, man also fr eine Farbe eine Zahl bergeben mu, will ich hier mal die Farben mit den zugehrigen Zahlen angeben. 0 Schwarz 1 Blau 2 Grn 3 Cyan 4 Rot 5 Lila 6 Braun 7 Hellgrau 8 Dunkelgrau 9 Hellblau 10 Hellgrn 11 Hellcyan 12 Hellrot 13 Hellila 14 Gelb 15 Wei Dabei ist mir aufgefallen, da man die Farben 9-15 nicht als Hintergrundfarbe benutzen kann. Es erscheint dann immer eine um 8 verringerte Farbe. Hellcyan wird also im Hintergrund zum einfachen Cyan. Ich hab' keine Ahnung, woran das liegt. Fr diese Ausgabe der Unit-Reihe liegen ein paar Programme dem Sources-Pfad bei: TOOLS.PAS ist der QuellCode fr die Unit TOOLS. TOOLS.TPU ist die compilierte Form der Unit TOOLS. DEMOUNIT.PAS ist der QuellCode zum Beispiel-Prog, das die Unit TOOLS nutzt. DEMOUNIT.EXE ist die compilierte Form des Beispiel-Progs. Alle Compilierungen wurden mit Borland Pascal 7 durchgefhrt. Als Abschlu noch der Quelltext des Beispiel-Progs DEMOUNIT.PAS: (Da wo ein "+" steht, mute ich die Zeile aufgrund des Listers abschneiden. Im Original ist das aber nicht so.) ***************************************************************** PROGRAM DemoUnit; USES Crt,Tools; BEGIN Colors(7,0); ClrScr; HideCursor; Rahmen(5,10,70,15,12,1); Wri(17,12,14,1,'Dies ist das Demo-Prog zur Unit TOOLS.'); Wri(17,13,14,1,'Bitte jetzt ''W'' drcken...'); WaitForKeyPressed('W'); {Hier wird ein _groes_ 'W' gefordert!} {Eine einfache Bettigung der Taste 'w'} {reicht nicht. Es mu zustzlich die} {SHIFT-Taste gedrckt werden.} Colors(2,2); ClrScr; Rahmen(5,7,70,12,14,12); Wri(12,8,14,12,'Dies ist das zweite Fenster. Hier kann man' + 'auch den'); Wri(12,9,14,12,'Effekt erkennen, da das Fenster schwarz' + 'unterlegt ist.'); Wri(17,10,14,12,'Bitte jetzt ''p'' drcken...'); WaitForKeyPressed('p'); {Hier kann man jetzt einfach nur} die Taste 'p' drcken, da ein _kleines_} 'p' gefordert wird.} ShowCursor; Colors(7,0); ClrScr; END. ***************************************************************** Bei Fragen wendet euch an uns. ERIC DER SCHRECKLICHE Ŀ ٳ ALLE: "Jawohl, Herr Lehrer!"