home *** CD-ROM | disk | FTP | other *** search
- Unit AltCrt2 ;
-
- {
- Copyright (c) 1991-1995 by Oliver Fromme <fromme@rz.tu-clausthal.de>.
- Freely usable, freely distributable.
-
- Last edit: 3-Feb-1995 Oliver Fromme
-
- This unit is intended to be used for Borland/Turbo Pascal 7.0.
- It provides a lot of utility routines which are very useful in the
- everyday life of every Pascal programmer. Once you get used to it,
- you'll never want to miss it.
- Sorry, all comments are currently in German, but you should be able
- to figure out what each of the procs/funcs is good for. If you really
- need a translation, ask me and I'll probably translate it.
-
- Important: Do not use both Crt and AltCrt2 at the same time!
- }
-
- {$A+,B-,D+,E-,F-,G+,I-,L+,N-,O-,P+,Q-,R-,S-,T-,V+,X+,Y+}
-
- {---------------------------------------------------------------------------}
-
- Interface
-
- Uses Dos,Strings ;
-
- Const EarthExists = True ; {z.B. für `While EarthExists Do' :-) }
- EndOfUniverse = False ; {z.B. für `Repeat Until EndOfUniverse' :-) }
- EmptyString = '' ;
- CrLf = #13#10 ; {Carriage Return + Line Feed}
-
- Type ExText = File ; {Für ExWriteLn/ExReadLn, siehe unten.}
- Str2 = String[2] ; {Für die Byte-Hex-Funktionen.}
- Str4 = String[4] ; {Für die Word-Hex-Funktionen.}
- Str8 = String[8] ; {Für die LongInt-Hex-Funktionen.}
- Str10 = String[10] ; {Für die Lead-Funktionen.}
- NExtStr = String[12] ; {Für Dateinamen mit Extension.}
-
- Var TextAttr : Byte ; {Wird bei Read/Write ignoriert.}
- Var MaxX,MaxY : Word ; {Werden beim Start initialisiert, Zählung
- beginnt bei 0. Werden auch bei speziellen
- SVGA-Modi richtig gesetzt (z.B. 99/39 im
- Modus 100x40 des Tseng-ET4000).}
- Var mx,my : Word ; {Enthält die Mauskoordinaten des letzten Aufrufes
- von GetMouse, siehe unten.}
-
- {Die folgenden Prozeduren/Funktionen sind funktionell mit denen von
- Crt identisch. Man beachte die folgenden Punkte:
- - TextAttr wird bei Read/Write ignoriert.
- - Aktuelles Window ist stets der ganze Bildschirm.
- - Read/Write erfolgt über DOS, d.h. Umleitungen und Pipes sind möglich.
- - Alle anderen Bildschirm-Funktionen erfolgen über das BIOS,
- d.h. sie funktionieren auch in SVGA-Modi, die das jeweilige VGA-BIOS
- unterstützt. TextAttr wird berücksichtigt.
- - KeyPressed und ReadKey verwenden Int16, d.h. sie sind systemkonform.
- - Delay ist unabhängig von Rechnertyp und Takfrequenz, die Abweichung
- beträgt nur wenige Taktzyklen.}
-
- Procedure ClrScr ;
- Procedure GotoXY (x,y : Byte) ;
- Function WhereX : Byte ;
- Function WhereY : Byte ;
- Procedure InsLine ;
- Procedure DelLine ;
- Function KeyPressed : Boolean ;
- Function ReadKey : Char ;
- Procedure Sound (Hz : Word) ;
- Procedure NoSound ;
- Procedure Delay (w : Word) ;
-
- {Die folgenden Prozeduren/Funktionen sind im Standard-Crt nicht
- implementiert, sind aber ganz brauchbar und gehören thematisch
- hierher. TextAttr wird, wo sinnvoll, beachtet.}
-
- Procedure FeedKey (k : Char) ;
- {Täuscht den Tastendruck 'k' (ASCII) vor. KeyPressed liefert dann
- solange True, bis man den Tastendruck mit ReadKey abgeholt hat.}
- Procedure ClrLine ;
- {Löscht die Zeile, in der der Cursor steht. Kein Scrolling.
- Cursorposition bleibt unverändert.}
- Procedure ClrLines (yy1,yy2 : Integer) ;
- {Löscht die Zeilen yy1 bis yy2, Zählung beginnt bei 0. Kein Scrolling.
- Cursorposition wird an den Anfang der ersten gelöschten Zeile gesetzt.}
- Procedure Center (s : String) ;
- Procedure LeftAlign (s : String) ;
- Procedure RightAlign (s : String) ;
- {Diese drei Prozeduren schreiben den angegebenen String zentriert, links-
- bzw. rechtsbündig in die aktuelle Bildschirmzeile. Direktzugriff auf
- Bildschrimspeicher, funktioniert nur bei Farb-Karten!
- TextAttr wird beachtet. Cursorposition bleibt unverändert.}
- Procedure ClrKeyBuf ;
- {Der Tastaturpuffer wird geleert.}
- Function Counter : Word ;
- {Für sehr feine Zeitmessungen: Liefert den momentanen Zählerstand
- von Timer 0, wird 1.193.180 mal pro Sekunde dekrementiert. Ein
- Unterlauf tritt 18,2 mal pro Sekunde auf.
- Benötigt nur 29 Taktzyklen (80386, ohne call/ret).}
- Function LCounter : LongInt ;
- {Dito, für längere, aber genauso feine Zeitmessungen. Ein Unterlauf
- tritt genau 1 mal pro Stunde auf. Auch negative Werte möglich.
- Benötigt 51 Taktzyklen (80386, ohne call/ret).}
- Procedure Beep ;
- {Gibt einen Ton von 1000 Hz für 100 ms aus.}
- Procedure Buup ;
- {Gibt einen Ton von 450-250 Hz für 200 ms aus (z.B. bei Fehler).}
- Procedure WaitVerticalRetrace ;
- {Wartet darauf, daß der Elektronenstrahl am unteren Bildrand angekommen
- ist und zum Bildanfang zurückkehrt. Befindet sich der Elektronenstrahl
- bereits auf der Rückkehr, wird bis zum nächsten Bildende gewartet.
- Funktioniert sowohl im Text- als auch im Grafikmodus.
- Kann z.B. verwendet werden, um Bildschirmaktionen flackerfrei zu
- gestalten, oder um die Videofrequenz zu messen.}
- Procedure WriteStdErr (Const s : String) ;
- {Schreibt s direkt auf den Bildschirm, eine eventuelle Umleitung der
- Ausgabe via DOS wird ignoriert.}
-
- {---------------------------------------------------------------------------}
-
- {Die folgenden Prozeduren/Funktionen stammen ursprünglich aus der Unit
- AllgUtil. Sie implementieren alle möglichen nützlichen Sachen.}
-
- {Allgemeine/Sonstiges}
-
- Procedure Nothing ; Inline ($90) ; {"Fast" nichts (2 Taktzyklen).}
- {Nützlich für Konstrukte wie "While ... Do Nothing".}
- Procedure Move (Var Source,Dest ; Count : Word) ;
- {Schneller als das Original, da 16-Bit-Transfer verwendet wird.}
- Procedure FillByte (Var X ; Count : Word ; Value : Byte) ;
- {Entspricht FillChar, ist aber schneller (16-Bit-Transfer).
- Value darf nur ein Byte-Typ sein, bei Char-Typen muß man ein
- Typecasting Char(...) verwenden.}
- Procedure FillWord (Var X ; Count : Word ; Value : Word) ;
- Procedure Fill3Byt (Var X ; Count : Word ; Value : LongInt) ;
- Procedure FillLong (Var X ; Count : Word ; Value : LongInt) ;
- {Dito für 2-, 3- und 4-Byte-Variablen.}
- Procedure FillGen (Var X ; Count : Word ; Value : LongInt ; size : Byte) ;
- {Dito, allgemeine Version (size = Größe der Variablen in Byte).}
- Function Quest (Cond : Boolean ; a,b : LongInt) : LongInt ;
- {Entspricht dem "?:"-Operator in C: liefert a, wenn Cond=True, sonst b.}
- Function CQuest (Cond : Boolean ; a,b : Char) : Char ;
- {Dito für Char-Typen.}
- Function SQuest (Cond : Boolean ; Const a,b : String) : String ;
- {Dito für String-Typen.}
- Function Quest2 (Cond1,Cond0 : Boolean ; a00,a01,a10,a11 : LongInt) : LongInt ;
- {Entsprechend für zwei Bedingungen.}
- Function LoCase (c : Char) : Char ;
- {Wandelt Groß- in Kleinbuchstaben, analog zu UpCase.}
- Function UpperCase (Const s : String) : String ;
- {Liefert den String in Großbuchstaben.}
- Function LowerCase (Const s : String) : String ;
- {Liefert den String in Kleinbuchstaben.}
- Function IDist (i1,i2,x : LongInt) : LongInt ;
- {Abstand von x vom Intervall [i1,i2] (mit i1<=i2).
- Es gilt: Diff (a,x) = IDist (a,a,x).}
- Function Bound (x,min,max : LongInt) : LongInt ;
- Function Max (w1,w2 : LongInt) : LongInt ;
- Function Min (w1,w2 : LongInt) : LongInt ;
- Function Even (x : LongInt) : Boolean ;
- Function ggT (a,b : LongInt) : LongInt ;
- Function kgV (a,b : LongInt) : LongInt ;
- Function Sgn (x : LongInt) : ShortInt ; {-1, 0, 1}
- Function Diff (a,b : LongInt) : LongInt ; {a-b bzw. b-a}
- {-Ohne Worte-}
-
- {Utilities für DOS}
-
- Function GetPDir (Const n : String) : DirStr ;
- {Liefert Laufwerk+Verzeichnis einer Pfadangabe (incl. "\").}
- Function GetRawDir (Const n : String) : DirStr ;
- {Liefert das Verzeichnis (ohne Laufwerk und ohne "\").}
- Function GetName (Const n : String) : NameStr ;
- {Liefert den Namen einer Pfadangabe (ohne Suffix, max. 8 Zeichen).}
- Function GetExt (Const n : String) : ExtStr ;
- {Liefert den Suffix einer Pfadangabe (incl. ".", max. 4 Zeichen).}
- Function GetXt (Const n : String) : ExtStr ;
- {Liefert den Suffix einer Pfadangabe (ohne ".", max. 3 Zeichen).}
- Function GetNExt (Const n : String) : NExtStr ;
- {Liefert Namen+Suffix einer Pfadangabe (max 12 Zeichen).}
- Function GetDName (Const n : String) : PathStr ;
- {Liefert Verzeichnis+Name einer Pfadangabe (ohne Suffix).}
- Function GetDrive (Const n : String) : Str2 ;
- {Liefert das Laufwerk einer Pfadangabe, z.B. 'C:'.}
- Function ExtPath (Const n,e : String) : PathStr ;
- {Liefert n, falls n ein Suffix enthält (auch leer, d.h. "XXX."),
- ansonsten n+'.'+e.}
- Function NormName (n : NExtStr) : NExtStr ;
- {Fügt in einen Dateinamen Leerzeichen (und eventuell einen Punkt) ein,
- um ihn auf eine Länge von 12 Zeichen zu bringen.}
- Function NormDirn (Const n : NExtStr) : NExtStr ;
- {Dito, ersetzt den Punkt aber durch ein Leerzeichen, falls kein Suffix
- vorhanden ist, außerdem Sonderbehandlung für '.' und '..'.}
- Procedure NormDir (Var d : DirStr) ;
- Function fNormDir (Const d : DirStr) : DirStr ;
- {Hängt an d nötigenfalls ein '\' an.}
- Function NormChDir (d : DirStr) : DirStr ;
- {Entfernt ein angehängtes '\', falls nicht das Wurzelverzeichnis gemeint
- ist. Dos.ChDir und Exists benötigen diese Form.}
- Function WildExpand (n : NExtStr) : NExtStr ;
- {Normalisiert (siehe NormName) und expandiert '*' zu '?'.}
- Function Matches (n : NExtStr ; Const mask : NExtStr) : Boolean ;
- {Liefert True, wenn n der Maske mask entspricht, letztere darf '?',
- aber nicht '*' enthalten, und muß die Länge 12 haben (siehe WildExpand).}
- Function TempDir : PathStr ;
- {Liefert Namen eines Temp-Dirs incl. '\'.}
- Type PathProc = Procedure (Dir : DirStr ; Fil : SearchRec) ;
- Const Recursive = 1 ;
- Function ProcessFiles (Const mask : PathStr ; opt : Word ; job : PathProc)
- : LongInt ;
- {Führt die Prozedur job für jede Datei aus, die zum Muster mask paßt
- (kann '?' und/oder '*' enthalten). Für opt können eine oder mehrere der
- folgenden Optionen verwendet werden:
- - Recursive: es werden ebenfalls die Inhalte aller Unterverzeichnisse
- rekursiv bearbeitet.
- Funktionsergebnis ist die Anzahl der bearbeiteten Dateien (= Anzahl
- der Aufrufe von job), was natürlich auch 0 sein kann (wenn keine
- passenden Dateien gefunden wurden).
- Das an die job-Prozedur übergebene Dir endet immer mit einem '\'.}
- Function PathEq (n : String) : PathStr ;
- {Hängt an n soviele Leerzeichen an, daß es lang ist wie bei
- maximaler Ausnutzung der Dateinamenlänge.}
- Procedure ChangeDir (d : String) ;
- {Wechselt das aktuelle Verzeichnis. Im Gegensatz zu System.ChDir wird aber
- nicht das aktuelle Laufwerk gewechselt, falls d eine Laufwerksangabe
- enthält, sondern nur das aktuelle Verzeichnis auf dem angegebenen
- Laufwerk. Trailing '\' ist egal.}
- Function QuietFileSize (Const n : PathStr) : LongInt ;
- {Liefert die Größe der Datei in Bytes, ohne daß die Datei geöffnet wird.
- Ergebnis ist -1 bei einem Verzeichnis oder Volume Label, -2 bei einem
- Fehler (siehe Dos.DosError).}
- Function Exists (Const n : String) : Boolean ;
- {Liefert True, falls n existiert (File, Verzeichnis, Volume Label).}
- Function IsDir (Const n : String) : Boolean ;
- {Liefert True, falls n existiert und ein Verzeichnis ist.}
- Function IsFile (Const n : String) : Boolean ;
- {Liefert True, falls n existiert und eine Datei ist.}
- Function IsEmpty (n : DirStr) : Boolean ;
- {Liefert True, falls das Verzeichnis n (mit oder ohne abschließenden
- "\") leer ist (bis auf "." und "..").}
- Function Writeable (d : Char) : Boolean ;
- {Liefert True, falls man auf das Laufwerk d schreibend zugreifen kann.
- Liefert False, wenn das Laufwerk nicht existiert oder schreibgeschützt
- ist (z.B. CD-ROMs).}
- Function IsOpenFile (Var f : File) : Boolean ;
- {Liefert True, falls die Datei noch offen ist.
- Achtung: Assign (f,...) muß ausgeführt sein!}
- Function IsOpenText (Var f : Text) : Boolean ;
- {Dito für Textfiles.}
-
- {Weitere Utilities zur Ein-/Ausgabe}
-
- Procedure ExWriteLn (Var f : ExText ; s : String) ;
- {WriteLn für eine untypisierte Datei (File).
- Muß mit Reset/ReWrite (f,1) geöffnet worden sein.}
- Procedure ExReadLn (Var f : ExText ; Var s : String) ;
- {ReadLn für eine untypisierte Datei (File).
- Muß mit Reset/ReWrite (f,1) geöffnet worden sein.}
- Function TextFilePos (Var t : Text) : LongInt ;
- {FilePos für Text-Dateien.}
- Function TextFileSize (Var t : Text) : LongInt ;
- {FileSize für Text-Dateien.}
- Procedure TextSeek (Var t : Text ; Pos : LongInt) ;
- {Seek für Text-Dateien. Diese Prozedur und die vorhergehenden beiden
- Funktionen können genauso angewendet werden wie ihre entsprechenden
- Gegenstücke für nicht-Text-Dateien (aus der Unit DOS); Fehler können
- wie gewohnt mit IOResult abgefragt werden.}
- Procedure WaitKey ;
- {Wartet auf einen beliebigen Tastendruck.
- Der Tastaturpuffer wird vorher und hinterher gelöscht.}
- Function GetOption (s : String) : Char ;
- {Wartet auf ein Taste, deren ASCII-Code in s enthalten ist.
- Das Zeichen wird zurückgegeben und außerdem auf dem Bildschirm
- ausgegeben. Kleinbuchstaben werden in Großbuchstaben gewandelt.
- Der Tastaturpuffer wird vorher und hinterher gelöscht.}
- Function GetQuietOption (s : String) : Char ;
- {Dito, ohne Bildschirmausgabe.}
- Function GetJaNein : Boolean ;
- {Spezialfall: "GetJaNein := GetOption('JN')='J'"}
- Function GetYesNo : Boolean ;
- {Spezialfall: "GetYesNo := GetOption('YN')='Y'"}
-
- {Noch mehr Utilities für den Bildschirm}
-
- Procedure ScrollUp (x1,y1,x2,y2,nr,at : Byte) ;
- {Scrollt das angegebene Rechteck um nr Zeilen nach oben, freiwerdende
- Zeile werden mit dem Attribut at gefüllt. Zählung beginnt bei 0.}
- Procedure ScrollDown (x1,y1,x2,y2,nr,at : Byte) ;
- {Dito, scrollt nach unten.}
- Procedure PrintAt (x,y : Integer ; Const s : String ; at : Byte) ;
- {Gibt den String s mit dem Attribut at an der Position x/y aus, die
- Zählung beginnt bei 1. Verwendet die aktuelle Cursorposition, wenn
- x=0 und/oder y=0. Führt auch nötigenfalls ein Scrolling durch.}
- Function Tab (n : Integer) : String ;
- {Am besten ein Beispiel: "WriteLn ('abc',Tab(20),'xyz')". Die
- Zählung beginnt bei 1. Ist die betreffende Position bereits
- überschritten, ändert sich nichts (man bekommt einen Leerstring).}
- Function LeftEq (Const s : String ; n : Integer) : String ;
- {Das Gegenstück zu "WriteLn ('Test':15)": "WriteLn (LeftEq('Test',15))".
- Ist der String zu lang, wird rechts abgeschnitten.}
- Procedure StringOf (Var s : String ; c : Char ; b : Byte) ;
- {Erzeugt einen String, der das Zeichen c b-mal enthält.}
- Function fStringOf (c : Char ; b : Byte) : String ;
- {Dito, als Funktion.}
- Function WordStr (w : Word) : String ;
- Function IntStr (i : Integer) : String ;
- Function LongStr (l : LongInt) : String ;
- {Entsprechen Str als Funktionen, z.B. "WriteLn (LeftEq(WordStr(w),12))".}
- Procedure PingCursor ;
- {Merkt sich die aktuelle Cursorposition.}
- Procedure PongCursor ;
- {Setzt den Cursor auf die zuletzt gemerkte Position.}
- Function Clock : LongInt ;
- {Liefert die Systemzeit (ab Mitternacht) in 1/100 Sekunden, die
- Genauigkeit ist aber nur 1/18.2 Sekunden.}
- Function TimeIdent : LongInt ;
- {Liefert Datum und Uhrzeit DOS-kodiert.}
- Function lShl (l : LongInt ; c : Byte) : LongInt ;
- Function lShr (l : LongInt ; c : Byte) : LongInt ;
- {Shl and Shr fuer LongInts.}
- Function MulDiv (m1,m2,d : Word) : Word ;
- {(LongInt(m1)*LongInt(m2)) Div d}
- Function LongHi (x : LongInt) : Word ;
- Function LongLo (x : LongInt) : Word ;
- {Liefern Hi- bzw. Lo-Word eines 32-Bit-Wertes.}
- Function Hex (l : LongInt) : Str8 ;
- {Liefert l als Hexzahl (soviele Stellen wie nötig).}
- Function Hex2 (b : Byte) : Str2 ;
- {Liefert b als 2stellige Hexzahl.}
- Function Hex4 (w : Word) : Str4 ;
- {Liefert w als 4stellige Hexzahl.}
- Function Hex8 (l : LongInt) : Str8 ;
- {Liefert l als 8stellige Hexzahl.}
- Function Hex2Dec (Const h : Str8 ; Var l : LongInt) : Boolean ;
- {Wandelt eine 0- bis 8-stellige Hexzahl in einen Dezimalwert um.
- Ergebnis ist True bei Erfolg, False bei ungültigen Zeichen
- (nicht in [0..9,a..f,A..F]). Bei False oder h='' ist l=0.}
- Function Lead0 (l : LongInt ; f : Byte) : Str10 ;
- {Liefert l mit führenden Nullen, mind. f Stellen.}
- Function LeadSpc (l : LongInt ; f : Byte) : Str10 ;
- {Liefert l mit führenden Leerzeichen, mind. f Stellen.}
- Function Subst (s : String ; Const old,new : String) : String ;
- {Ersetzt in s alle Vorkommen von 'old' durch 'new';
- 'old' und 'new' müssen nicht gleich lang sein.
- ACHTUNG: 'new' darf nicht 'old' enthalten! In diesem Fall wird ein
- Leerstring geliefert, um eine Endlosrekursion zu vermeiden.}
- Procedure DeComment (Const com : String ; Var s : String) ;
- {Löscht alles, was nach Kommentarzeichen (einschließlich) in s
- folgt, Beispiel: DeComment ('#;%',inputline).}
- Procedure Justify (Var s : String) ;
- {Entfernt führende und abschließende Spaces, wandelt Tabs in Spaces
- um, und komprimiert aufeinanderfolgende Spaces zu einem einzelnen
- Space.}
- Procedure DeSpace (Var s : String) ;
- {Entfernt alle Spaces und Tabs.}
-
- Function PartStr (Const s : String ; c : Char ; x : Integer) : String ;
- {Liefert den x-ten Teilstring. Die einzelnen Teilstrings werden durch
- 'c' getrennt, die Zählung beginnt bei Null. Beipiel:
- PartStr('ABC*123*XYZ','*',1) = '123'
- Wenn s[1]=c gilt, beginnt die Zählung entsprechend bei 1.
- Bei x<0 wird von rechts nach links gezaehlt:
- PartStr('ABC*123*XYZ','*',-1) = 'XYZ'}
- Function PartCount (Const s : String ; c : Char) : Word ;
- {Ermittelt, wieviele Teilstrings s enthält. Mit anderen Worten, das
- Ergebnis gibt an, wie oft c in s vorkommt, plus eins; Ausnahme:
- bei einem Leerstring (s='') ist das Ergebnis Null.}
- Function PartWidth (Const s : String ; c : Char) : Word ;
- {Ermittelt die Länge des längsten Teilstrings in s.
- Die einzelnen Teilstrings werden durch c getrennt.}
-
- Function PPartStr (s : PChar ; c : Char ; x : Integer ; Dest : PChar) : PChar ;
- Function PPartCount (s : PChar ; c : Char) : Word ;
- Function PPartWidth (s : PChar ; c : Char) : Word ;
- {Dito für Nullterminierte Strings bis 65535 Zeichen Länge.}
- Function PPartStart (s : PChar ; c : Char ; x : Integer) : PChar ;
- {Ähnlich PPartStr, liefert aber nur Zeiger auf den Anfang des
- entsprechenden Teilstrings in `s'. Liefert NIL, wenn Teilstring
- nicht enthalten ist oder Länge Null hat.}
-
- Function StrGetMem (Var p : PChar ; Len : Word) : PChar ;
- {Belegt Speicher für einen Z-String mit maximaler Länge `Len'
- (d.h. Len+1 Bytes) und liefert einen Zeiger darauf in `p' und
- als Funktionsergebnis. Im Fehlerfalle (nicht genug Speicher)
- NIL.}
- Procedure StrFreeMem (Var p : PChar ; Len : Word) ;
- {Gibt den Speicher wieder frei und setzt `p' auf NIL.}
-
- Function UpdateCRC32 (InitCRC : LongInt ; Var InBuf ; InLen : Word) : LongInt ;
- {Berechnet einen CRC32 von `InLen' Bytes ab `InBuf', basierend auf
- `InitCRC'. Der anfängliche CRC32 sollte -1 ($ffffffff) sein, und
- der abschließende sollte invertiert werden (Not).
- Kompatibel mit ZIP und Zmodem.}
-
- Type PCProc = Procedure (p : Word ; c : Char ; Cursor : Boolean) ;
- {Schreibt Zeichen c an Position p (Basis 1), mit Cursor wenn
- `Cursor' = True (z.B. invertiert).}
- Function EnterString (s : pChar ; maxlen : Word ; PrintChar : PCProc) : Boolean ;
- {Eingabe eines Strings (mit Vorgabe) s^ mit maximaler Länge `maxlen',
- zum Schreiben wird die Prozedur `PrintChar' benutzt.
- Ergebnis is True, wenn Eingabe mit Enter-Taste bestätigt wurde, bzw.
- False, wenn mit Esc abgebrochen wurde (s^ unverändert).}
-
- {------ Maus-Funktionen ------}
-
- Function InitMouse : Boolean ;
- {Initialisiert den Maustreiber und liefert True, wenn einer
- installiert ist. Der Mauszeiger ist noch nicht sichtbar.}
- Procedure ResetMouse ;
- {Nur Software-Reset.}
- Procedure HideMouse ;
- {Macht den Mauszeiger unsichtbar.}
- Procedure ShowMouse ;
- {Macht den Mauszeiger sichtbar.}
- Procedure SetFrame (x1,y1,x2,y2 : Word) ;
- {Legt den Bereich fest, in dem sich der Mauszeiger bewegen darf.
- Zählung beginnt bei 0.}
- Function GetMouse : Word ;
- {Liefert Tastenstatus: Bit 0 = linke Taste, Bit 1 = rechte Taste,
- Bit 2 = mittlere Taste (falls vorhanden).
- Ein Aufruf dieser Funktion aktualisiert außerdem die Mauskoordinaten
- in mx und my.}
- Procedure SetMouse (x,y : Word) ;
- {Setzt den Mauszeiger auf die angegeben Position.}
- Procedure DefineMickey (Horiz,Vertic : Word) ;
- {Hiermit kann man die Auflösung der Maus einstellen, und damit
- die Geschwindigkeit des Mauszeigers.}
- Procedure GetMickey (Var Horiz,Vertic : Integer) ;
- {Liefert den Stand des Bewegungszählers der Maus.}
- Procedure WaitButton ;
- {Wartet auf das Betätigen einer Maustaste oder einer Taste auf der
- Tastatur. Sollte beim Aufruf bereits eine Maustaste gedrückt sein,
- wird erst gewartet, bis sie losgelassen wird.
- Der Tastaturpuffer wird vorher und hinterher gelöscht.}
- Procedure SetMouseCursor (sm,cm : Word) ;
- {Schaltet auf Software-Mauscursor um und definiert sein Aussehen:
- Der Bildschirm-Wert wird zuerst mit sm AND-verknüpft und dann mit
- cm XOR-verknüpft. Das Low-Byte ist jeweils für den Zeichencode
- zuständig, das High-Byte für das Attribut.}
- Procedure SetMousePointer (Var scm ; hotx,hoty : Integer) ;
- {Definiert das Aussehen das Mauspointers im Grafikmodus. scm ist ein
- Feld von 16 Screenmask(sm)-Worten und 16 Cursormask(cm)-Worten:
- sm=0: cm=0: Schwarz (Farbe 0), cm=1: Weiss (Farbe 15),
- sm=1: cm=0: Transparent, cm=1: Invertierend,
- hotx und hoty geben die Position des "Hot Spot" an, bezogen auf die
- linke obere Ecke des Pointers, sie können Wert von -16 bis 16
- annehmen.}
- Procedure SetUpdateFrame (x1,y1,x2,y2 : Word) ;
- {Definiert einen rechteckigen Bereich, innerhalb dessen ein Update
- (oder irgendeine Grafikaktion) stattfindet. Wenn der Mauspointer diesen
- Bereich berührt, wird ein HideMouse durchgeführt.
- Ein Aufruf von ShowMouse macht diese Prozedur wieder rückgängig (egal,
- ob HideMouse durchgeführt wurde oder nicht).
- Diese Funktion benötigt unbedingt einen Microsoft-kompatiblen Maustreiber,
- bei Genius-Mäusen mindestens Treiberversion 9.06.}
-
- {===========================================================================}
-
-
-
- Implementation
-
- Const HexDig : Array [0..15] Of Char = '0123456789abcdef' ;
-
- Var r : Registers ;
-
- Var x1,y1,x2,y2 : Word ;
-
- Var KeyPends : Boolean ;
- key : Char ;
-
- Var PingX,PingY : Integer ;
-
- Procedure Video (a,b,c,d : Word) ; Assembler ;
- Asm
- mov ax,a
- mov bx,b
- mov cx,c
- mov dx,d
- push bp
- int 10h
- pop bp
- End {Video} ;
-
- Procedure ClrScr ;
- Begin
- Video ($0600,TextAttr Shl 8,y1 Shl 8+x1,y2 Shl 8+x2) ;
- GotoXY (1,1)
- End {ClrScr} ;
-
- Procedure GotoXY (x,y : Byte) ;
- Begin
- Video ($0200,0,0,Word(Pred(y))Shl 8+Pred(x))
- End {GotoXY} ;
-
- Function WhereX : Byte ; Assembler ;
- Asm
- mov ax,0300h
- push bp
- int 10h
- pop bp
- mov al,dl
- inc al
- End {WhereX} ;
-
- Function WhereY : Byte ; Assembler ;
- Asm
- mov ax,0300h
- push bp
- int 10h
- pop bp
- mov al,dh
- inc al
- End {WhereY} ;
-
- Function KeyPressed : Boolean ;
- Begin
- If KeyPends Then Begin
- KeyPressed := True ;
- Exit
- End ;
- r.ah := $01 ;
- Intr ($16,r) ;
- KeyPressed := r.flags And $40=0
- End {KeyPressed} ;
-
- Function ReadKey : Char ;
- Begin
- If KeyPends Then Begin
- KeyPends := False ;
- ReadKey := Key
- End
- Else Begin
- r.ah := 0 ;
- Intr ($16,r) ;
- ReadKey := Char(r.al) ;
- If r.al=0 Then Begin
- KeyPends := True ;
- Key := Char(r.ah)
- End
- End
- End {ReadKey} ;
-
- Procedure FeedKey (k : Char) ;
- Begin
- KeyPends := True ;
- Key := k
- End {FeedKey} ;
-
- Procedure InsLine ; Assembler ;
- Asm
- mov ax,0300h
- push bp
- int 10h
- mov ax,0701h
- mov bh,TextAttr
- xor bl,bl
- mov ch,dh
- mov cl,Byte Ptr x1
- mov dh,Byte Ptr y2
- mov dl,Byte Ptr x2
- int 10h
- pop bp
- End {InsLine} ;
-
- Procedure DelLine ; Assembler ;
- Asm
- mov ax,0300h
- push bp
- int 10h
- mov ax,0601h
- mov bh,TextAttr
- xor bl,bl
- mov ch,dh
- mov cl,Byte Ptr x1
- mov dh,Byte Ptr y2
- mov dl,Byte Ptr x2
- int 10h
- pop bp
- End {DelLine} ;
-
- Procedure ClrLine ; Assembler ;
- Asm
- mov ax,0300h
- push bp
- int 10h
- mov ax,0600h
- mov bh,TextAttr
- xor bl,bl
- mov ch,dh
- mov cl,Byte Ptr x1
- mov dl,Byte Ptr x2
- int 10h
- pop bp
- End {DelLine} ;
-
- Procedure ClrLines (yy1,yy2 : Integer) ;
- Begin
- If yy1=-1 Then
- yy1 := y1 ;
- If yy2=-1 Then
- yy2 := y2 ;
- Video ($0600,TextAttr Shl 8,yy1 Shl 8+x1,yy2 Shl 8+x2) ;
- GotoXY (1,Succ(yy1))
- End {ClrScr} ;
-
- Procedure Center (s : String) ;
- Var i,a : Word ;
- Begin
- a := Succ(MaxX)*Pred(WhereY) Shl 1-2 ;
- i := Succ(MaxX-Length(s))Shr 1 ;
- Move (s[1],s[Succ(i)],Length(s)) ;
- FillChar (s[1],i,32) ;
- FillChar (s[Succ(length(s)+i)],Succ(MaxX)-Length(s)-i,32) ;
- For i:=1 To Succ(MaxX) Do
- MemW[Segb800:a+i Shl 1] := TextAttr Shl 8+Byte(s[i])
- End {Center} ;
-
- Procedure LeftAlign (s : String) ;
- Var i,a : Word ;
- Begin
- a := Succ(MaxX)*Pred(WhereY) Shl 1-2 ;
- FillChar (s[Succ(length(s))],Succ(MaxX)-Length(s),32) ;
- For i:=1 To Succ(MaxX) Do
- MemW[Segb800:a+i Shl 1] := TextAttr Shl 8+Byte(s[i])
- End {LeftAlign} ;
-
- Procedure RightAlign (s : String) ;
- Var i,a : Word ;
- Begin
- a := Succ(MaxX)*Pred(WhereY) Shl 1-2 ;
- i := Succ(MaxX-Length(s)) ;
- Move (s[1],s[Succ(i)],Length(s)) ;
- FillChar (s[1],i,32) ;
- For i:=1 To Succ(MaxX) Do
- MemW[Segb800:a+i Shl 1] := TextAttr Shl 8+Byte(s[i])
- End {RightAlign} ;
-
- Procedure ClrKeyBuf ;
- Begin
- While KeyPressed Do
- If ReadKey=#0 Then
- If ReadKey=#0 Then
- End {ClrKeyBuf} ;
-
- Procedure Beep ;
- Begin
- Sound (1000) ;
- Delay (100) ;
- NoSound
- End {Beep} ;
-
- Procedure Buup ;
- Var w : Word ;
- Begin
- For w := 450 DownTo 250 Do Begin
- Sound (w) ;
- Delay (1)
- End ;
- NoSound
- End {Buup} ;
-
- Procedure WaitVerticalRetrace ; Assembler ;
- Asm
- mov dx,03dah
- @vr: in al,dx
- test al,08h
- jnz @vr
- @nvr: in al,dx
- test al,08h
- jz @nvr
- End {WaitVerticalRetrace} ;
-
- Procedure WriteStdErr (Const s : String) ;
- Var w : Word ;
- c : Char ;
- Begin
- For w:=1 To Length(s) Do Begin
- c := s[w] ;
- Asm
- mov ah,0eh
- mov al,c
- xor bx,bx
- push bp
- int 10h
- pop bp
- End
- End
- End {WriteStdErr} ;
-
- Procedure Sound (Hz : Word) ;
- Var bbb : Byte ;
- Begin
- If Hz<=18 Then
- Exit ;
- Hz := $1234dd Div Hz ;
- bbb := Port[$61] ;
- If bbb And $03=0 Then Begin
- Port[$61] := bbb Or $03 ;
- Port[$43] := $b6 {Binaer, Modus 3, Lo/Hi-Byte, Counter 2}
- End ;
- Port[$42] := Lo(Hz) ;
- Port[$42] := Hi(Hz)
- End {Sound} ;
-
- Procedure NoSound ;
- Begin
- Port[$61] := Port[$61] And $fc
- End {NoSound} ;
-
- Function Counter : Word ; Assembler ;
- Asm
- in al,$40
- mov ah,al
- in al,$40
- xchg ah,al
- End {Counter} ;
-
- Function LCounter : LongInt ; Assembler ;
- Asm
- pushf
- cli
- in al,$40
- mov ah,al
- in al,$40
- xchg ah,al
- mov dx,Seg0040
- mov es,dx
- mov dx,Word Ptr es:$006c
- not dx
- popf
- End {Counter} ;
-
- Procedure WaitApprox (w : Word) ;
- Begin
- While Counter-w<49152 Do
- End {WaitApprox} ;
-
- Procedure Delay (w : Word) ;
- Var wll : LongInt ;
- tm : Word ;
- Begin
- tm := Counter ;
- wll := LongInt(w)*1193 ;
- While wll>65535 Do Begin
- WaitApprox (tm XOr $8000) ;
- WaitApprox (tm) ;
- Dec (wll,65536)
- End ;
- If wll>32767 Then
- WaitApprox (tm XOr $8000) ;
- WaitApprox (tm-Word(wll))
- End {Delay} ;
-
- Procedure Move (Var Source,Dest ; Count : Word) ; Assembler ;
- Asm
- push ds
- mov cx,Count
- jcxz @1
- lds si,[Source]
- les di,[Dest]
- cld
- test di,1
- jz @0
- movsb
- dec cx
- @0: shr cx,1
- rep movsw
- jnc @1
- movsb
- @1: pop ds
- End {Move} ;
-
- Procedure FillByte (Var X ; Count : Word ; Value : Byte) ; Assembler ;
- Asm
- mov cx,Count
- jcxz @1
- mov al,Value
- mov ah,al
- les di,[X]
- cld
- test di,1
- jz @0
- stosb
- dec cx
- @0: shr cx,1
- rep stosw
- jnc @1
- stosb
- @1:
- End {FillByte} ;
-
- Procedure FillWord (Var X ; Count : Word ; Value : Word) ; Assembler ;
- Asm
- mov cx,Count
- jcxz @1
- mov ax,Value
- les di,[X]
- cld
- test di,1
- jz @0
- stosb
- xchg al,ah
- dec cx
- jz @2
- rep stosw
- @2: stosb
- jmp @1
- @0: rep stosw
- @1:
- End {FillWord} ;
-
- Procedure Fill3Byt (Var X ; Count : Word ; Value : LongInt) ; Assembler ;
- Asm
- mov cx,Count
- jcxz @1
- mov ax,Word Ptr Value
- mov bl,Byte Ptr Value+2
- les di,[X]
- cld
- @0: stosw
- mov es:[di],bl
- inc di
- loop @0
- @1:
- End {Fill3Byt} ;
-
- Procedure FillLong (Var X ; Count : Word ; Value : LongInt) ; Assembler ;
- Asm
- mov cx,Count
- jcxz @1
- mov ax,Word Ptr Value
- mov bx,Word Ptr Value+2
- mov dx,2
- les di,[X]
- cld
- @0: stosw
- mov es:[di],bx
- add di,dx
- loop @0
- @1:
- End {FillLong} ;
-
- Procedure FillGen (Var X ; Count : Word ; Value : LongInt ; size : Byte) ;
- Begin
- Case size Of
- 1 : FillByte (X,Count,Value) ;
- 2 : FillWord (X,Count,Value) ;
- 3 : Fill3Byt (X,Count,Value) ;
- 4 : FillLong (X,Count,Value)
- End
- End {FillGen} ;
-
- Function Quest (Cond : Boolean ; a,b : LongInt) : LongInt ;
- Begin
- If Cond Then
- Quest := a
- Else
- Quest := b
- End {Quest} ;
-
- Function CQuest (Cond : Boolean ; a,b : Char) : Char ;
- Begin
- If Cond Then
- CQuest := a
- Else
- CQuest := b
- End {CQuest} ;
-
- Function SQuest (Cond : Boolean ; Const a,b : String) : String ;
- Begin
- If Cond Then
- SQuest := a
- Else
- SQuest := b
- End {SQuest} ;
-
- Function Quest2 (Cond1,Cond0 : Boolean ; a00,a01,a10,a11 : LongInt) : LongInt ;
- Begin
- If Cond1 Then
- If Cond0 Then
- Quest2 := a11
- Else
- Quest2 := a10
- Else
- If Cond0 Then
- Quest2 := a01
- Else
- Quest2 := a00
- End {Quest2} ;
-
- Function LoCase (c : Char) : Char ;
- Begin
- If c In ['A'..'Z'] Then Asm
- mov al,c
- add al,20h
- mov @result,al
- End
- Else
- LoCase := c
- End {LoCase} ;
-
- Function UpperCase (Const s : String) : String ;
- Var i : Integer ;
- Begin
- UpperCase[0] := s[0] ;
- For i:=1 To Length(s) Do
- UpperCase[i] := UpCase(s[i])
- End {UpperCase} ;
-
- Function LowerCase (Const s : String) : String ;
- Var i : Integer ;
- Begin
- LowerCase[0] := s[0] ;
- For i:=1 To Length(s) Do
- LowerCase[i] := LoCase(s[i])
- End {LowerCase} ;
-
- Function IDist (i1,i2,x : LongInt) : LongInt ;
- Begin
- If x<i1 Then
- IDist := i1-x
- Else
- If x>i2 Then
- IDist := x-i2
- Else
- IDist := 0
- End {IDist} ;
-
- Function Bound (x,min,max : LongInt) : LongInt ;
- Begin
- If x<min Then
- Bound := min
- Else If x>max Then
- Bound := max
- Else
- Bound := x
- End {Bound} ;
-
- Function Max (w1,w2 : LongInt) : LongInt ;
- Begin
- if w1>w2 Then
- Max := w1
- Else
- Max := w2
- End {Max} ;
-
- Function Min (w1,w2 : LongInt) : LongInt ;
- Begin
- if w1<w2 Then
- Min := w1
- Else
- Min := w2
- End {Min} ;
-
- Function Even (x : LongInt) : Boolean ;
- Begin
- Even := Not Odd(x)
- End {Even} ;
-
- Function ggT (a,b : LongInt) : LongInt ;
- Var c,d : LongInt ;
- Begin
- d := a Mod b ;
- While d<>0 Do Begin
- c := b ;
- b := d ;
- a := c ;
- d := a Mod b
- End ;
- ggT := b
- End {ggT} ;
-
- Function kgV (a,b : LongInt) : LongInt ;
- Var c : LongInt ;
- Begin
- c := ggT(a,b) ;
- If c<>0 Then
- kgV := (a Div c)*b
- Else
- kgV := 0
- End {kgV} ;
-
- Function Sgn (x : LongInt) : ShortInt ; Assembler ;
- Asm
- xor ax,ax
- mov bx,word ptr x+2
- test bh,80h
- jnz @neg
- or bx,word ptr x
- jz @z
- mov ax,1
- jmp @z
- @neg: not ax
- @z:
- End {Sgn} ;
-
- Function Diff (a,b : LongInt) : LongInt ;
- Begin
- If a<b Then
- Diff := b-a
- Else
- Diff := a-b
- End {Diff} ;
-
- Function GetPDir (Const n : String) : DirStr ;
- Var Dir : DirStr ;
- Name : NameStr ;
- Ext : ExtStr ;
- Begin
- FSplit (n,Dir,Name,Ext) ;
- GetPDir := Dir
- End {GetPDir} ;
-
- Function GetRawDir (Const n : String) : DirStr ;
- Var Dir : DirStr ;
- Name : NameStr ;
- Ext : ExtStr ;
- Begin
- FSplit (n,Dir,Name,Ext) ;
- GetRawDir := Copy(Dir,3,Length(Dir)-3)
- End {GetRawDir} ;
-
- Function GetName (Const n : String) : NameStr ;
- Var Dir : DirStr ;
- Name : NameStr ;
- Ext : ExtStr ;
- Begin
- FSplit (n,Dir,Name,Ext) ;
- GetName := Name
- End {GetName} ;
-
- Function GetExt (Const n : String) : ExtStr ;
- Var Dir : DirStr ;
- Name : NameStr ;
- Ext : ExtStr ;
- Begin
- FSplit (n,Dir,Name,Ext) ;
- GetExt := Ext
- End {GetExt} ;
-
- Function GetXt (Const n : String) : ExtStr ;
- Var Dir : DirStr ;
- Name : NameStr ;
- Ext : ExtStr ;
- Begin
- FSplit (n,Dir,Name,Ext) ;
- GetXt := Copy(Ext,2,3)
- End {GetXt} ;
-
- Function GetNExt (Const n : String) : NExtStr ;
- Var Dir : DirStr ;
- Name : NameStr ;
- Ext : ExtStr ;
- Begin
- FSplit (n,Dir,Name,Ext) ;
- GetNExt := Name+Ext
- End {GetNExt} ;
-
- Function GetDName (Const n : String) : PathStr ;
- Var Dir : DirStr ;
- Name : NameStr ;
- Ext : ExtStr ;
- Begin
- FSplit (n,Dir,Name,Ext) ;
- GetDName := Dir+Name
- End {GetDName} ;
-
- Function GetDrive (Const n : String) : Str2 ;
- Begin
- GetDrive := UpperCase(Copy(n,1,2))
- End {GetDrive} ;
-
- Function ExtPath (Const n,e : String) : PathStr ;
- Var i : Integer ;
- Begin
- i:=Length(n) ;
- While (i>0)And(n[i]<>'.')And(n[i]<>'\') Do
- Dec(i) ;
- If (i=0)Or(n[i]='\') Then
- ExtPath:=n+'.'+e
- Else
- ExtPath:=n
- End {ExtPath} ;
-
- Function NormName (n : NExtStr) : NExtStr ;
- Var nam : NameStr ;
- ext : ExtStr ;
- p : Word ;
- Begin
- p := Pos('.',n) ;
- If p=0 Then Begin
- n := n+'.' ;
- p := Succ(Length(n))
- End ;
- FillByte (nam[1],8,32) ;
- FillByte (ext[1],3,32) ;
- nam := Copy(n,1,Pred(p)) ;
- ext := Copy(n,Succ(p),3) ;
- nam[0] := #8 ;
- ext[0] := #3 ;
- NormName := nam+'.'+ext
- End {NormName} ;
-
- Function NormDirn (Const n : NExtStr) : NExtStr ;
- Var nam : NameStr ;
- ext : ExtStr ;
- p : Word ;
- Begin
- If n[1]='.' Then
- p := Succ(Length(n))
- Else Begin
- p := Pos('.',n) ;
- If p=0 Then
- p := Succ(Length(n))
- End ;
- FillByte (nam[1],8,32) ;
- FillByte (ext[1],3,32) ;
- nam := Copy(n,1,Pred(p)) ;
- ext := Copy(n,Succ(p),3) ;
- nam[0] := #8 ;
- ext[0] := #3 ;
- If ext=' ' Then
- NormDirn := nam+#32+ext
- Else
- NormDirn := nam+'.'+ext
- End {NormDirn} ;
-
- Procedure NormDir (Var d : DirStr) ;
- Begin
- If d[Length(d)]<>'\' Then
- d := d+'\'
- End {NormDir} ;
-
- Function fNormDir (Const d : DirStr) : DirStr ;
- Begin
- If d[Length(d)]<>'\' Then
- fNormDir := d+'\'
- Else
- fNormDir := d
- End {fNormDir} ;
-
- Function NormChDir (d : DirStr) : DirStr ;
- Begin
- If (d[Length(d)]='\') And ((Length(d)<>3) Or (d[2]<>':')) Then
- Dec (d[0]) ;
- NormChDir := d
- End {NormChDir} ;
-
- Function WildExpand (n : NExtStr) : NExtStr ;
- Var p : Word ;
- Begin {WildExpand}
- n := NormName(n) ;
- p := Pos('*',n) ;
- If (p<>0) And (p<9) Then Begin
- For p:=p To 8 Do
- n[p] := '?' ;
- p := Pos('*',n)
- End ;
- If p<>0 Then
- For p:=p To 12 Do
- n[p] := '?' ;
- WildExpand := n
- End {WildExpand} ;
-
- Function Matches (n : NExtStr ; Const mask : NExtStr) : Boolean ;
- Var i : Word ;
- Begin
- n := NormName(n) ;
- Matches := False ;
- For i:=1 To 12 Do
- If mask[i]<>'?' Then
- If mask[i]<>n[i] Then
- Exit ;
- Matches := True
- End {Matches} ;
-
- Function TempDir : PathStr ;
- Var t : PathStr ;
- Begin
- t := GetEnv('TEMP') ;
- If t[0]=#0 Then Begin
- t := GetEnv('TMP') ;
- If t[0]=#0 Then
- t := 'C:\'
- End ;
- If t[Length(t)]<>'\' Then
- t := t+'\' ;
- TempDir := t
- End {TempDir} ;
-
- Function ProcessFiles (Const mask : PathStr ; opt : Word ; job : PathProc) : LongInt ;
- Var Search : SearchRec ;
- Dir : DirStr ;
- NExt : NExtStr ;
- Count : LongInt ;
- Begin
- Count := 0 ;
- Dir := GetPDir(mask) ;
- NExt := GetNExt(mask) ;
- Search.Name := NExt ;
- FindFirst (mask,$3f,Search) ;
- While DosError=0 Do Begin
- job (Dir,Search) ;
- Inc (Count) ;
- FindNext (Search)
- End ;
- If opt And Recursive<>0 Then Begin
- Search.Name := '*.*' ;
- FindFirst (Dir+'*.*',$33,Search) ;
- While DosError=0 Do Begin
- If (Search.Attr And $10)=$10 Then
- If (Search.Name<>'.') And (Search.Name<>'..') Then
- Inc (Count,ProcessFiles(Dir+Search.Name+'\'+NExt,opt,job)) ;
- FindNext (Search)
- End
- End ;
- ProcessFiles := Count
- End {ProcessFiles} ;
-
- Function PathEq (n : String) : PathStr ;
- Var slash,i : Integer ;
- Begin
- slash := 0 ;
- For i:=Length(n) DownTo 1 Do
- If (n[i]='\') Or (n[i]='\') Then Begin
- slash := i ;
- Break
- End ;
- While Length(n)<slash+12 Do
- n := n+#32 ;
- PathEq := n
- End {PathEq} ;
-
- Procedure ChangeDir (d : String) ;
- Begin
- d := NormChDir(d)+#0 ;
- r.ah := $3b ;
- r.dx := Ofs(d[1]) ;
- r.ds := Seg(d[1]) ;
- Intr ($21,r) ;
- If r.flags And fcarry <>0 Then
- InOutRes := 3
- End {ChangeDir} ;
-
- Function QuietFileSize (Const n : PathStr) : LongInt ;
- Var s : SearchRec ;
- Begin
- s.Name := GetNExt(n) ;
- FindFirst (n,$3f,s) ;
- If DosError<>0 Then
- QuietFileSize := -2
- Else If s.Attr And $18 <>0 Then
- QuietFileSize := -1
- Else
- QuietFileSize := s.Size
- End {QuietFileSize} ;
-
- Function Exists (Const n : String) : Boolean ;
- Var f : File ;
- a : Word ;
- Begin
- Assign (f,n) ;
- GetFAttr (f,a) ;
- Exists := DosError=0
- End {Exists} ;
-
- Function IsDir (Const n : String) : Boolean ;
- Var f : File ;
- a : Word ;
- Begin
- If n[Length(n)]='\' Then
- IsDir := True
- Else Begin
- Assign (f,n) ;
- GetFAttr (f,a) ;
- IsDir := (a And $10=$10) And (DosError=0)
- End
- End {IsDir} ;
-
- Function IsFile (Const n : String) : Boolean ;
- Var f : File ;
- a : Word ;
- Begin
- Assign (f,n) ;
- GetFAttr (f,a) ;
- IsFile := (a And $18=0) And (DosError=0)
- End {IsFile} ;
-
- Function IsEmpty (n : DirStr) : Boolean ;
- Var s : SearchRec ;
- Begin
- NormDir (n) ;
- s.Name := '*.*' ;
- FindFirst (n+'*.*',$3f,s) ;
- While (DosError=0)
- And ((s.Name='.') Or (s.Name='..') Or (s.Attr And $08=$08)) Do
- FindNext (s) ;
- IsEmpty := DosError=18
- End {IsEmpty} ;
-
- Function Writeable (d : Char) : Boolean ;
- Var f : File ;
- Begin
- Assign (f,d+':\awritest.$$$') ;
- ReWrite (f,1) ;
- If IOResult<>0 Then
- Writeable := False
- Else Begin
- Close (f) ;
- Erase (f) ;
- Writeable := IOResult=0
- End
- End {Writeable} ;
-
- Function IsOpenFile (Var f : File) : Boolean ;
- Begin
- IsOpenFile := FileRec(f).Mode <> fmClosed
- End {IsOpenFile} ;
-
- Function IsOpenText (Var f : Text) : Boolean ;
- Begin
- IsOpenText := TextRec(f).Mode <> fmClosed
- End {IsOpenText} ;
-
- Procedure ExWriteLn (Var f : ExText ; s : String) ;
- Begin
- s := s+CrLf ;
- BlockWrite (f,s[1],Length(s))
- End {ExWriteLn} ;
-
- Procedure ExReadLn (Var f : ExText ; Var s : String) ;
- Var t : String ;
- p : LongInt ;
- e : Integer ;
- r : Word ;
- Begin
- p := FilePos(f) ;
- BlockRead (f,t[1],255,r) ;
- t[0] := Char(r) ;
- e := Pos(CrLf,t) ;
- If e>0 Then
- t[0] := Char(Pred(e)) ;
- Seek (f,p+Byte(t[0])+2) ;
- s := t
- End {ExReadLn} ;
-
- Function TextFilePos (Var t : Text) : LongInt ;
- Begin
- r.ax := $4201 ;
- r.bx := TextRec(t).Handle ;
- r.cx := 0 ;
- r.dx := 0 ;
- Intr ($21,r) ;
- If r.flags And fcarry=0 Then
- TextFilePos := LongInt(r.dx)*65536+r.ax+TextRec(t).BufPos
- -TextRec(t).BufEnd
- Else Begin
- InOutRes := r.ax ;
- TextFilePos := 0
- End
- End {TextFilePos} ;
-
- Function TextFileSize (Var t : Text) : LongInt ;
- Var l : LongInt ;
- Begin
- If TextRec(t).Mode=fmInput Then Begin
- l := TextFilePos(t) ;
- r.ax := $4202 ;
- r.bx := TextRec(t).Handle ;
- r.cx := 0 ;
- r.dx := 0 ;
- Intr ($21,r) ;
- If r.flags And fcarry=0 Then
- TextFileSize := LongInt(r.dx)*65536+r.ax
- Else Begin
- InOutRes := r.ax ;
- TextFileSize := 0
- End ;
- TextSeek (t,l)
- End
- Else If TextRec(t).Mode=fmOutput Then
- TextFileSize := TextFilePos(t)
- Else Begin
- InOutRes := 1 ;
- TextFileSize := 0
- End
- End {TextFileSize} ;
-
- Procedure TextSeek (Var t : Text ; Pos : LongInt) ;
- Var w : Record l,h : Word End Absolute Pos ;
- Begin
- If TextFilePos(t)=Pos Then
- Exit ;
- If TextRec(t).Mode=fmOutput Then
- Flush (t) ;
- TextRec(t).BufPos := 0 ;
- TextRec(t).BufEnd := 0 ;
- r.ax := $4200 ;
- r.bx := TextRec(t).Handle ;
- r.cx := w.h ;
- r.dx := w.l ;
- Intr ($21,r) ;
- If r.flags And fcarry<>0 Then
- InOutRes := r.ax
- End {TextSeek} ;
-
- Procedure WaitKey ;
- Begin
- ClrKeyBuf ;
- While Not KeyPressed Do Nothing ;
- ClrKeyBuf
- End {WaitKey} ;
-
- Function GetJaNein : Boolean ;
- Begin
- GetJaNein := GetOption('JN')='J'
- End {GetJaNein} ;
-
- Function GetYesNo : Boolean ;
- Begin
- GetYesNo := GetOption('YN')='Y'
- End {GetYesNo} ;
-
- Function GetOption (s : String) : Char ;
- Var c : Char ;
- Begin
- s := UpperCase(s) ;
- ClrKeyBuf ;
- Repeat
- c := ReadKey ;
- If c=#0 Then
- c := Chr(0*Ord(ReadKey)) ;
- c := UpCase(c)
- Until Pos(c,s)<>0 ;
- WriteLn (c) ;
- GetOption := c ;
- ClrKeyBuf
- End {GetOption} ;
-
- Function GetQuietOption (s : String) : Char ;
- Var c : Char ;
- Begin
- s := UpperCase(s) ;
- ClrKeyBuf ;
- Repeat
- c := ReadKey ;
- If c=#0 Then
- c := Chr(0*Ord(ReadKey)) ;
- c := UpCase(c)
- Until Pos(c,s)<>0 ;
- GetQuietOption := c ;
- ClrKeyBuf
- End {GetQuietOption} ;
-
- Procedure ScrollUp(x1,y1,x2,y2,nr,at : Byte) ;
- Begin
- r.al := nr ;
- r.ch := y1 ;
- r.cl := x1 ;
- r.dh := y2 ;
- r.dl := x2 ;
- r.bh := at ;
- r.ah := 6 ;
- Intr ($10,r)
- End {ScrollUp} ;
-
- Procedure ScrollDown(x1,y1,x2,y2,nr,at : Byte) ;
- Begin
- r.al := nr ;
- r.ch := y1 ;
- r.cl := x1 ;
- r.dh := y2 ;
- r.dl := x2 ;
- r.bh := at ;
- r.ah := 7 ;
- Intr ($10,r)
- End {ScrollDown} ;
-
- Procedure PrintAt(x,y : Integer ; Const s : String ; at : Byte) ;
- Var i : Integer ;
- Begin
- If x<=0 Then x := WhereX ;
- If y<=0 Then y := WhereY ;
- For i:=1 To Length(s) Do Begin
- GotoXY (x,y) ;
- r.al := Byte(s[i]) ;
- r.bl := at ;
- r.bh := 0 ;
- r.ah := $09 ;
- r.cx := 1 ;
- Intr ($10,r) ;
- Inc (x)
- End
- End {PrintAt} ;
-
- {
- ************
- * Anwendungsbeispiel:
- * WriteLn ('abc',Tab(20),'xyz') ;
- * Offset ist 1. Hat der Cursor die angegebene Spalte schon überschritten,
- * wird ein Leerstring übergeben.
- ************}
-
- Function Tab (n : Integer) : String ;
- Var h : String ;
- z : Integer ;
- Begin
- z := n-WhereX ;
- If z<1 Then
- Tab := ''
- Else Begin
- FillChar (h[1],z,32) ;
- h[0] := Chr(z) ;
- Tab := h
- End ;
- End {Tab} ;
-
- {
- **********
- * Anwendungsbeispiel:
- * WriteLn (LeftEq('abc',20),'xyz') ;
- * Im Ergebnisstring ist s linksbündig enthalten. Ist er kürzer als n, so
- * wird er mit Spaces aufgefüllt; ist er länger, wird rechts abgeschnit-
- * ten. Eine rechtsbündige Ausgabe ist mit der normalen Write-Formatierung
- * (per Doppelpunkt) zu erreichen.
- **********}
-
- Function LeftEq (Const s : String ; n : Integer) : String ;
- Var h : String ;
- Begin
- If Length(s)=n Then
- LeftEq := s
- Else
- If Length(s)>n Then
- LeftEq := Copy(s,1,n)
- Else Begin
- FillChar (h[1],n,32) ;
- h := s ;
- h[0] := Chr(n) ;
- LeftEq := h
- End
- End {LeftEq} ;
-
- {StringOf() schreibt in den String s das Zeichen c b-mal.}
- Procedure StringOf (Var s : String ; c : Char ; b : Byte) ;
- Begin
- FillChar (s[1],b,c) ;
- s[0] := Char(b)
- End {StringOf} ;
-
- Function fStringOf (c : Char ; b : Byte) : String ;
- Var s : String ;
- Begin
- FillChar (s[1],b,c) ;
- s[0] := Char(b) ;
- fStringOf := s
- End {fStringOf} ;
-
- Function WordStr (w : Word) : String ;
- Var s : String[5] ;
- Begin
- Str (w,s) ;
- WordStr := s
- End {WordStr} ;
-
- Function IntStr (i : Integer) : String ;
- Var s : String[6] ;
- Begin
- Str (i,s) ;
- IntStr := s
- End {IntStr} ;
-
- Function LongStr (l : LongInt) : String ;
- Var s : String[11] ;
- Begin
- Str (l,s) ;
- LongStr := s
- End {LongStr} ;
-
- Procedure PingCursor ;
- Begin
- PingX := WhereX ;
- PingY := WhereY
- End {PingCursor} ;
-
- Procedure PongCursor ;
- Begin
- GotoXY (PingX,PingY)
- End {PongCursor} ;
-
- Function Clock : LongInt ;
- Var h,m,s,s100 : Word ;
- Begin
- GetTime (h,m,s,s100) ;
- Clock := 360000*h+6000*LongInt(m)+100*s+s100
- End {Clock} ;
-
- Function TimeIdent : LongInt ;
- Var dt : DateTime ;
- id : LongInt ;
- dummy : Word ;
- Begin
- GetTime (dt.hour,dt.min,dt.sec,dummy) ;
- GetDate (dt.year,dt.month,dt.day,dummy) ;
- PackTime (dt,id) ;
- TimeIdent := id
- End {TimeIdent} ;
-
-
- Function Hex2 (b : Byte) : Str2 ;
- Begin
- Hex2[0] := #2 ;
- Hex2[1] := HexDig[b Shr 4] ;
- Hex2[2] := HexDig[b And 15]
- End {Hex2} ;
-
- Function Hex4 (w : Word) : Str4 ;
- Begin
- Hex4[0] := #4 ;
- Hex4[1] := HexDig[Hi(w) Shr 4] ;
- Hex4[2] := HexDig[Hi(w) And 15] ;
- Hex4[3] := HexDig[Lo(w) Shr 4] ;
- Hex4[4] := HexDig[w And 15]
- End {Hex4} ;
-
- Function Hex8 (l : LongInt) : Str8 ;
- Var w : Record l,h : Word End Absolute l ;
- Begin
- Hex8[0] := #8 ;
- Hex8[1] := HexDig[Hi(w.h) Shr 4] ;
- Hex8[2] := HexDig[Hi(w.h) And 15] ;
- Hex8[3] := HexDig[Lo(w.h) Shr 4] ;
- Hex8[4] := HexDig[w.h And 15] ;
- Hex8[5] := HexDig[Hi(w.l) Shr 4] ;
- Hex8[6] := HexDig[Hi(w.l) And 15] ;
- Hex8[7] := HexDig[Lo(w.l) Shr 4] ;
- Hex8[8] := HexDig[w.l And 15]
- End {Hex8} ;
-
- Function lShl (l : LongInt ; c : Byte) : LongInt ; Assembler ;
- Asm
- mov cl,c
- cmp cl,16
- je @e16
- ja @a16
- mov ax,Word Ptr l
- mov dx,Word Ptr l+2
- mov bx,ax
- shl ax,cl
- shl dx,cl
- sub cl,16
- neg cl
- shr bx,cl
- or dx,bx
- jmp @z
- @e16: mov dx,Word Ptr l
- xor ax,ax
- jmp @z
- @a16: mov dx,Word Ptr l
- xor ax,ax
- sub cl,16
- shl dx,cl
- @z:
- End {lShl} ;
-
- Function lShr (l : LongInt ; c : Byte) : LongInt ; Assembler ;
- Asm
- mov cl,c
- cmp cl,16
- je @e16
- ja @a16
- mov ax,Word Ptr l
- mov dx,Word Ptr l+2
- mov bx,dx
- shr ax,cl
- shr dx,cl
- sub cl,16
- neg cl
- shl bx,cl
- or ax,bx
- jmp @z
- @e16: mov ax,Word Ptr l+2
- xor dx,dx
- jmp @z
- @a16: mov ax,Word Ptr l+2
- xor dx,dx
- sub cl,16
- shr ax,cl
- @z:
- End {lShr} ;
-
- Function MulDiv (m1,m2,d : Word) : Word ; Assembler ;
- Asm
- mov ax,m1
- mul m2
- div d
- End {MulDiv} ;
-
- Function LongHi (x : LongInt) : Word ; Assembler ;
- Asm
- mov ax,Word Ptr x+2
- End {LongHi} ;
-
- Function LongLo (x : LongInt) : Word ; Assembler ;
- Asm
- mov ax,Word Ptr x
- End {LongLo} ;
-
- Function Hex2Dec (Const h : Str8 ; Var l : LongInt) : Boolean ;
- Var tl : LongInt ;
- i : Integer ;
- Begin
- Hex2Dec := False ;
- l := 0 ;
- tl := 0 ;
- For i:=1 To Length(h) Do
- Case UpCase(h[i]) Of
- '0'..'9' : tl := lShl(tl,4) Or (Byte(h[i])-Byte('0')) ;
- 'A'..'F' : tl := lShl(tl,4) Or (Byte(UpCase(h[i]))-Byte('A')+10)
- Else
- Exit
- End ;
- Hex2Dec := True ;
- l := tl
- End {Hex2Dec} ;
-
- Function Hex (l : LongInt) : Str8 ;
- Var t : Str8 ;
- Begin
- t := Hex8(l) ;
- While (t[0]>#1) And (t[1]='0') Do
- Delete (t,1,1) ;
- Hex := t
- End {Hex} ;
-
- Function Lead0 (l : LongInt ; f : Byte) : Str10 ;
- Var ts : Str10 ;
- Begin
- Str (l:f,ts) ;
- f := 1 ;
- While ts[f]=#32 Do Begin
- ts[f] := '0' ;
- Inc (f)
- End ;
- Lead0 := ts
- End {Lead0} ;
-
- Function LeadSpc (l : LongInt ; f : Byte) : Str10 ;
- Var ts : Str10 ;
- Begin
- Str (l:f,ts) ;
- LeadSpc := ts
- End {LeadSpc} ;
-
- Function Subst (s : String ; Const old,new : String) : String ;
- Var p : Integer ;
- Begin
- If Pos(old,new)<>0 Then
- Subst := ''
- Else Begin
- p := Pos(old,s) ;
- While p<>0 Do Begin
- s := Copy(s,1,Pred(p))+new+Copy(s,p+Length(old),255) ;
- p := Pos(old,s)
- End ;
- Subst := s
- End
- End {Subst} ;
-
- Procedure DeComment (Const com : String ; Var s : String) ;
- Var i,p : Integer ;
- Begin
- For i:=1 To Length(com) Do Begin
- p := Pos(com[i],s) ;
- If p<>0 Then
- Delete (s,p,255)
- End
- End {DeComment} ;
-
- Procedure Justify (Var s : String) ;
- Var i : Integer ;
- Begin
- {Convert tabs to spaces:}
- For i:=1 To Length(s) Do
- If s[i]=#9 Then
- s[i] := #32 ;
- {Delete preceding spaces:}
- For i:=1 To Length(s) Do
- If s[i]<>#32 Then
- Break ;
- If i>Length(s) Then Begin
- s[0] := #0 ;
- Exit
- End ;
- If i>1 Then
- Delete (s,1,Pred(i)) ;
- {Delete trailing spaces:}
- For i:=Length(s) DownTo 1 Do
- If s[i]<>#32 Then
- Break ;
- If i<Length(s) Then
- Delete (s,Succ(i),255) ;
- {Compress spaces:}
- i:=2 ;
- While i<=Length(s)-2 Do Begin
- While (s[i]=#32) And (s[Succ(i)]=#32) Do
- Delete (s,i,1) ;
- Inc (i)
- End
- End {Justify} ;
-
- Procedure DeSpace (Var s : String) ;
- Var p : Byte ;
- Begin
- p := Pos(#9,s) ;
- While p<>0 Do Begin
- Delete (s,p,1) ;
- p := Pos(#9,s)
- End ;
- p := Pos(#32,s) ;
- While p<>0 Do Begin
- Delete (s,p,1) ;
- p := Pos(#32,s)
- End
- End {DeSpace} ;
-
- Function PartStr (Const s : String ; c : Char ; x : Integer) : String ;
- Var i,j,p : Word ;
- Begin
- If x<0 Then Begin
- j := 0 ;
- For i:=1 To Length(s) Do
- If s[i]=c Then
- Inc (j) ;
- Inc (x,Succ(j))
- End ;
- i := 1 ;
- p := 0 ;
- While (i<=Length(s)) And (p<x) Do Begin
- If s[i]=c Then
- Inc (p) ;
- Inc (i)
- End ;
- If i>Length(s) Then Begin
- PartStr := '' ;
- Exit
- End ;
- j := i ;
- While (j<=Length(s)) And (p=x) Do Begin
- If s[j]=c Then
- Inc (p) ;
- Inc (j)
- End ;
- If p>x Then
- Dec (j) ;
- PartStr := Copy(s,i,j-i)
- End {PartStr} ;
-
- Function PartCount (Const s : String ; c : Char) : Word ;
- Var w,i : Word ;
- Begin
- If s[0]=#0 Then Begin
- PartCount := 0 ;
- Exit
- End ;
- w := 1 ;
- For i:=1 To Length(s) Do
- If s[i]=c Then
- Inc (w) ;
- PartCount := w
- End {PartCount} ;
-
- Function PartWidth (Const s : String ; c : Char) : Word ;
- Var w,maxw,i : Word ;
- Begin
- w := 0 ;
- maxw := 0 ;
- For i:=1 To Length(s) Do
- If s[i]=c Then Begin
- If w>maxw Then
- maxw := w ;
- w := 0
- End
- Else
- Inc (w) ;
- If w>maxw Then
- PartWidth := w
- Else
- PartWidth := maxw
- End {PartWidth} ;
-
- Function PPartStart (s : PChar ; c : Char ; x : Integer) : PChar ;
- Var p : Word ;
- tp,tp2 : PChar ;
- Begin
- PPartStart := NIL ;
- If (s=NIL) Or (s[0]=#0) Then
- Exit ;
- If x<0 Then Begin {x in positiven Wert umwandeln}
- p := 0 ; {zählt die Parts}
- tp := s ;
- While True Do Begin
- tp := StrScan(tp,c) ;
- Inc (p) ;
- If tp=NIL Then
- Break
- Else
- Inc (tp)
- End ;
- Inc (x,p)
- End ;
- p := 0 ; {zählt die Parts}
- tp := s ;
- While (p<x) Do Begin
- tp := StrScan(tp,c) ;
- Inc (p) ;
- If tp=NIL Then
- Break
- Else
- Inc (tp)
- End ; {tp zeigt auf Trennzeichen+1, oder NIL}
- If (tp[0]=#0) Or (tp[0]=c) Then
- PPartStart := NIL
- Else
- PPartStart := tp
- End {PPartStart} ;
-
- Function PPartStr (s : PChar ; c : Char ; x : Integer ; Dest : PChar) : PChar ;
- Var tp,tp2 : PChar ;
- Begin
- PPartStr := Dest ;
- If Dest=NIL Then
- Exit ;
- Dest[0] := #0 ;
- tp := PPartStart(s,c,x) ;
- If tp=NIL Then
- Exit ;
- tp2 := StrScan(tp,c) ;
- If tp2=NIL Then
- tp2 := StrEnd(tp) ;
- StrLCopy (Dest,tp,tp2-tp)
- End {PPartStr} ;
-
- Function PPartCount (s : PChar ; c : Char) : Word ;
- Var p : Word ;
- Begin
- p := 0 ;
- If (s=NIL) Or (s[0]=#0) Then Begin
- PPartCount := 0 ;
- Exit
- End ;
- While True Do Begin
- s := StrScan(s,c) ;
- Inc (p) ;
- If s=NIL Then
- Break
- Else
- Inc (s)
- End ;
- PPartCount := p
- End {PPartCount} ;
-
- Function PPartWidth (s : PChar ; c : Char) : Word ;
- Var w,maxw : Word ;
- l : PChar ;
- Begin
- maxw := 0 ;
- If (s=NIL) Or (s[0]=#0) Then Begin
- PPartWidth := 0 ;
- Exit
- End ;
- While True Do Begin
- l := s ;
- s := StrScan(l,c) ;
- If s=NIL Then
- s := StrEnd(l) ;
- w := s-l ;
- If w>maxw Then
- maxw := w ;
- If s[0]=#0 Then
- Break
- End ;
- PPartWidth := maxw
- End {PPartWidth} ;
-
- Function StrGetMem (Var p : PChar ; Len : Word) : PChar ;
- Begin
- If MaxAvail<=Succ(Len) Then
- p := NIL
- Else
- GetMem (p,Succ(Len)) ;
- StrGetMem := p
- End {StrGetMem} ;
-
- Procedure StrFreeMem (Var p : PChar ; Len : Word) ;
- Begin
- If p<>NIL Then Begin
- FreeMem (p,Succ(Len)) ;
- p := NIL
- End
- End {StrFreeMem} ;
-
- Function UpdateCRC32 (InitCRC : LongInt ; Var InBuf ; InLen : Word) : LongInt ;
- External ; {$L CRC32.OBJ}
-
- Function EnterString (s : pChar ; maxlen : Word ; PrintChar : PCProc) : Boolean ;
- Const CursorOff = False ;
- CursorOn = True ;
- Var w,actp : Word ;
- Ready,Cancel : Boolean ;
- st : String ;
- c : Char ;
- Begin
- st := StrPas(s) ;
- For w:=1 To Length(st) Do
- PrintChar (w,st[w],CursorOff) ;
- actp := Succ(Length(st)) ;
- PrintChar (actp,#32,CursorOn) ;
- For w:=Succ(actp) To maxlen Do
- PrintChar (w,#32,CursorOff) ;
- Ready := False ;
- Cancel := False ;
- ClrKeyBuf ;
- Repeat
- c := ReadKey ;
- If actp>Length(st) Then
- PrintChar (actp,#32,CursorOff)
- Else
- PrintChar (actp,st[actp],CursorOff) ;
- Case c Of
- #0 : Case ReadKey Of
- #75 : If actp>1 Then {left}
- Dec (actp) ;
- #77 : If actp<=Length(st) Then {right}
- Inc (actp) ;
- #71 : actp := 1 ; {home}
- #79 : actp := Succ(Length(st)) ; {end}
- #83 : If actp<=Length(st) Then Begin {delete}
- Delete (st,actp,1) ;
- For w:=Succ(actp) To Length(st) Do
- PrintChar (w,st[w],CursorOff) ;
- PrintChar (Succ(Length(st)),#32,CursorOff)
- End ;
- #115 : If actp>1 Then
- Repeat
- Dec (actp)
- Until (actp=1) Or
- (st[actp]<>#32) And (st[actp-1]=#32) ;
- #116 : If actp<=Length(st) Then
- Repeat
- Inc (actp)
- Until (actp>Length(st)) Or
- (st[actp]<>#32) And (st[actp-1]=#32) ;
- Else
- Beep ;
- ClrKeyBuf
- End ;
- #8 : If actp>1 Then Begin
- Dec (actp) ;
- Delete (st,actp,1) ;
- For w:=actp To Length(st) Do
- PrintChar (w,st[w],w=actp) ;
- PrintChar (Succ(Length(st)),#32,CursorOff)
- End ;
- #13 : Ready := True ;
- #27 : Cancel := True
- Else
- If Length(st)<maxlen Then Begin
- st := Copy(st,1,Pred(actp))+c+Copy(st,actp,Succ(Length(st)-actp)) ;
- Inc (actp) ;
- For w:=Pred(actp) To Length(st) Do
- PrintChar (w,st[w],CursorOff)
- End
- Else Begin
- Beep ;
- ClrKeyBuf
- End
- End ;
- If actp>Length(st) Then
- PrintChar (actp,#32,CursorOn)
- Else
- PrintChar (actp,st[actp],CursorOn)
- Until Ready Or Cancel ;
- If Ready Then
- StrPCopy (s,st) ;
- EnterString := Ready
- End {EnterString} ;
-
- {*************************
- *** Maus-Funktionen ***
- *************************}
-
- Function InitMouse : Boolean ; Assembler ;
- Asm
- mov ax,3533h
- int 21h {get int vector 33h}
- xor ax,ax
- test bx,bx
- jnz @t
- mov bx,es
- test bx,bx
- jz @f
-
- @t: int 33h {ax still 0}
- test ax,ax
- jz @f {0 = no mouse driver}
- mov ax,0001h
- @f:
- End {InitMouse} ;
-
- Procedure ResetMouse ; Assembler ;
- Asm
- mov ax,0021h
- int 33h
- End {ResetMouse} ;
-
- Procedure ShowMouse ; Assembler ;
- Asm
- mov ax,0001h
- int 33h
- End {ShowMouse} ;
-
- Procedure HideMouse ; Assembler ;
- Asm
- mov ax,0002h
- int 33h
- End {HideMouse} ;
-
- Procedure SetFrame (x1,y1,x2,y2 : Word) ; Assembler ;
- Asm
- mov ax,0007h
- mov cx,x1
- mov dx,x2
- int 33h
- mov ax,0008h
- mov cx,y1
- mov dx,y2
- int 33h
- End {SetFrame} ;
-
- Function GetMouse : Word ; Assembler ;
- Asm
- mov ax,0003h
- xor bx,bx
- int 33h
- mov mx,cx
- mov my,dx
- mov ax,bx
- End {GetMouse} ;
-
- Procedure SetMouse (x,y : Word) ; Assembler ;
- Asm
- mov ax,0004h
- mov cx,x
- mov dx,y
- int 33h
- End {SetMouse} ;
-
- Procedure DefineMickey (Horiz,Vertic : Word) ; Assembler ;
- Asm
- mov ax,000fh
- mov cx,Horiz
- mov dx,Vertic
- int 33h
- End {DefineMickey} ;
-
- Procedure GetMickey (Var Horiz,Vertic : Integer) ; Assembler ;
- Asm
- mov ax,000bh
- int 33h
- les di,Horiz
- mov es:[di],cx
- les di,Vertic
- mov es:[di],dx
- End {GetMickey} ;
-
- Procedure WaitButton ;
- Begin
- While GetMouse<>0 Do Nothing ;
- ClrKeyBuf ;
- While Not KeyPressed And (GetMouse=0) Do Nothing ;
- ClrKeyBuf
- End {WaitButton} ;
-
- Procedure SetMouseCursor (sm,cm : Word) ; Assembler ;
- Asm
- mov ax,000ah
- xor bx,bx
- mov cx,sm
- mov dx,cm
- int 33h
- End {SetMouseCursor} ;
-
- Procedure SetMousePointer (Var scm ; hotx,hoty : Integer) ; Assembler ;
- Asm
- mov ax,0009h
- mov bx,hotx
- mov cx,hoty
- les dx,scm
- int 33h
- End {SetMousePointer} ;
-
- Procedure SetUpdateFrame (x1,y1,x2,y2 : Word) ; Assembler ;
- Asm
- mov ax,0010h
- mov cx,x1
- mov dx,y1
- mov si,x2
- mov di,y2
- int 33h
- End {SetUpdateFrame} ;
-
- Begin
- MaxX := Pred(Mem[Seg0040:$004a]) ;
- MaxY := Mem[Seg0040:$0084] ;
- If (MaxY<24) Or (MaxY>95) Then
- MaxY := 24 ;
- x1 := 0 ;
- y1 := 0 ;
- x2 := MaxX ;
- y2 := MaxY ;
- TextAttr := Mem[SegB800:Succ(MaxY*Succ(MaxX)Shl 1)] ;
- KeyPends := False ;
- Port[$43] := $34 ; {Binaer, Modus 2, Lo/Hi-Byte, Counter 0}
- Port[$40] := 0 ;
- Port[$40] := 0
- End.
-