home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d5xx
/
d573
/
mtoollibrary.lha
/
MToolLibrary
/
German
/
Doc
next >
Wrap
Text File
|
1991-12-22
|
20KB
|
456 lines
MToolLibrary V 2.20
===================
© by Rüdiger Dreier 1988-91
DER AUTOR ÜBERNIMMT KEINERLEI HAFTUNG FÜR SCHÄDEN, DIE AUS DER SACH- ODER
UNSACHGEMÄSSEN BENUTZUNG DES PROGRAMMS ENTSTEHEN !!
WEITERHIN WIRD KEINE HAFTUNG FÜR DIE FEHLERFREIHEIT DES PROGRAMMS
ÜBERNOMMEN !!
BENUTZUNG AUF EIGENE GEFAHR !
Die mtool.library ist eine Amiga-Shared-Library und kann genauso wie jede
andere Library benutzt werden. Um diese Library benutzen zu können,
müssen im LIBS: Ordner noch die beiden folgenden Libraries vorhanden
sein:
mathieeedoubbas.library
mathieeedoubtrans.library
Die mtool.library ist im LIBS: Ordner natürlich am Besten aufgehoben....
DER NAME
========
Ursprünglich hieß diese Library mal "tool.library", aber dann entdeckte
ich, daß es eine weitere Library dieses Namens gibt. Also habe ich meine
Library in "mtool.library" umbenannt (das "m" steht für Mathe...). Ich
hoffe, daß keiner auf die Idee kommt/gekommen ist, seine/ihre Library
nun "mtool.library" zu nennen. Ältere Programme, die meine "tool.library"
benutzen müssen also leicht überarbeitet werden (ToolBase wurde in
"MToolBase" umbenannt).
FÜR PROGRAMMIERER
=================
Die Funktionen der Library unterteilen sich in die Bereiche
Stringbearbeitung, Intuition/Graphikunterstützung und Mathematik. Jedes
Programm, daß die tool.library benutzen soll, muß tool.h einbinden.
Öffnen der Library:
struct MToolBase *MToolBase; /* Global */
MToolBase=(struct MToolBase *)OpenLibrary("mtool.library,0");
Die Struktur MToolBase enthält Zeiger auf IntuitionBase, GfxBase und die
beiden MathIeee....Base's. Ein Programm, daß die tool.library öffnet,
braucht daher diese vier Libraries nicht mehr selbst zu öffnen, sonder
kann direkt an sie gelangen über:
IntuitionBase=MToolBase->IntuitionBase etc.
Das ist vielleicht nicht ganz legitim, aber diese vier Libraries werden
von mtool.library einmal geöffnet und erst wieder geschloßen, wenn
mtool.library aus dem Speicher entfernt wird. Daher ist sichergestellt,
daß die Libraries auch im Speicher sind, sollange tool.library geöffnet
ist.
Achtung : Auf Rechner mit FPU verhalten sich einige Funktionen nicht wie
gewohnt, wenn man die Libraries nicht explizit öffnet, besonders die
Funktion IEEEDPFix() fängt plötzlich an zu Runden....
Die beiden Mathe-Libraries sollten also besser von Hand geöffnet werden.
STRINGBEARBEITUNG:
==================
VOID left (char *Ziel,char *Source,LONG Anzahl)(a0,a1,d0)
VOID right(char *Ziel,char *Source,LONG Anzahl)(a0,a1,d0)
VOID mid (char *Ziel,char *Source,LONG Start,LONG Anzahl)(a0,a1,d0,d1)
Diese 3 Funktionen entsprechen den gleichnamigen Basic- Funktionen. Ziel
muß ein Zeiger auf einen genügend großen String (Array of char...) sein,
da sonst andere Daten oder Programmteile überschrieben werden können.
Ziel muß mind. Anzahl+1 Zeichen aufnehmen können (Anzahl Zeichen werden
kopiert und mit NULL abgeschloßen). ACHTUNG: mid arbeitet (im Gegensatz
zu Basic) nur in einer Richtung, eine Konstruktion wie mid(...)=string
ist natürlich nicht erlaubt.
VOID copy(LONG start,LONG anzahl,char *ziel,char *source)(d0,d1,d2,d3)
Entspricht im wesentlichen der mid-Funktion, aus Kompatibilitäts- gründen
noch enthalten.
LONGcheck (LONG Zeichen1,LONG Zeichen2,LONG Start,LONG Ende,char *String)
(d0,d1,d2,d3,a0)
LONG checkback(LONG Zeichen1, LONG Zeichen2, LONG Start, LONG Ende, char
*String)
(d0,d1,d2,d3,a0)
Diese beiden Funktionen suchen nach dem ersten (check) bzw. letzten
(checkback) Auftauchen eines der beiden Zeichen (1 und 2, müssen als LONG
übergeben werden) unter Beachtung von Klammerebenen (nur runde Klammern).
Beispiel: Es soll nach + und - in dem String
1+(2-3)
0123456 gesucht werden. check würde eine 1 zurückliefern, checkback
ebenfalls, da das Minuszeichen in der Klammer eingeschlossen ist. Diese
beiden Funktionen werden intensiv von Init_Block benutzt.
LONG AnzahlKlammern(char *String)(a0)
Diese Funktion überprüft, ob in einem String alle Klammern (nur runde)
paarig sind.
Rückgabe: 0: paarig
<0: zu viele )
>0: zu viele (
INTUITION/GRAFIKUNTERSTÜTZUNG
=============================
LONG request(char *ja,char *nein,char *body)(d0,d1,d2)
Diese Routine eröffnet auf dem aktuellen Screen einen AutoRequester und
zeigt in diesem die übergebenen Texte an. *ja und *nein werden als Text
in den Gadgets (wo sonst Retry und Cancel steht) angezeigt, *body als
Haupttext. Dieser Haupttext darf nicht länger sein, als in eine Zeile
paßt. Rückgabe: 0 oder 1, je nachdem, was vom Benutzer angewählt wurde.
LONG NewRequest(struct Window *Window,ja,nein,body)(a0,d0,d1,d2)
Diese Funktion ist der vorigen sehr ähnlich, nur daß man hier noch das
Fenster angeben kann, auf dem der Requester erscheinen soll. Die anderen
Parameter und die Rückgabewerte entsprechen denen von request.
LONG EventAbfrage(struct Window *Window,struct info *msginfo)(a0,a1)
Diese Funktion füllt die Struktur msginfo (definiert in Tool.h) mit den
Werten von Class, Code und IAddress (Class wird in msginfo NachrichtenArt
genannt, Code wird als code bezeichnet). Diese Funktion führt kein Wait()
aus.
Zusätzlich wird Class noch ausgegeben.
VOID Print(struct RastPort *RP,
char *text,
LONG col,
LONG xpos,
LONG ypos)(a1,a0,d0,d1,d2)
Diese Funktion gibt den Text text auf dem RastPort RP in der Farbe col ab
der Position xpos/ypos aus. Ganz einfach.
VOID Center(struct Window *Window,
char *text,
LONG Farbe,
LONG yPos)(a1,a0,d0,d1)
Wieder eine sehr ähnliche Funktion. Nur das diesmal der Text zentriert
ausgegeben wird. Dafür braucht die Funktion dann aber auch einen Zeiger
auf das entsprechende Fenster (Aufpassen !).
VOID Box(struct RastPort *RP,
LONG x1,y1,x2,y2)(a1,d0,d1,d2,d3)
Diese Funktion (erraten) zeichnet im angegebenen RastPort ein Rechteck
mit die Ecken x1/y1 und x2/y2
VOID Gadget_On (struct Gadget *Gadget,struct Window *Window)(a0,a1)
VOID Gadget_Off(struct Gadget *Gadget,struct Window *Window)(a0,a1)
Diese beiden Funktionen ersetzen die Systemfunktionen OnGadget und
OffGadget. Gadget_On sorgt dafür, daß das Gadget wieder korrekt
gezeichnet wird (OnGadget läßt meistens das "Gitter" stehen, obwohl das
Gadget wieder anwählbar ist).
LONG GetPropPosH(struct Gadget *Gadget,LONG MaxPos)(a0,d0)
LONG GetPropPosV(struct Gadget *Gadget,LONG MaxPos)(a0,d0)
Diese beiden Funktionen geben die aktuelle vertikale/horizontale Position
eines PropGadgets zurück. Die zurückgegebenen Werte bewegen sich dabei
zwischen 0 und MaxPos.
VOID SetPropPosH( struct Gadget *Gadget,
struct Window *Window,
LONG MaxPos,
LONG Schrittweite,
LONG NewPos)(a0,a1,d0,d1,d2)
VOID SetPropPosV( struct Gadget *Gadget,
struct Window *Window,
LONG MaxPos,
LONG Schrittweite,
LONG NewPos)(a0,a1,d0,d1,d2)
Diese beiden Funktionen setzten die aktuelle Position eines PropGadgets
auf den Wert NewPos, wobei MaxPos für 100% steht. Schrittweite gibt an,
wie viele Positionen der Regler maximal haben soll, wenn neben ihn in das
Gadget geklickt wird. Dazu ein Beispiel. Man will einen File-Requester
erstellen. Dabei ergibt sich die Situation, daß man 5 Zeilen gleichzeitig
darstellen kann, es aber 15 Files gibt. Am Anfang steht der Regler ganz
oben (GetPropPosV würde 0 zurückgeben). Steht der Regler ganz unten, dann
soll 10 zurückgegeben werden. Damit gibt es 11 abfragbare Positionen und
dies ist auch der Wert für MaxPos. Klickt der Anwender aber in das Gadget
neben den Regler, dann soll der Regler den gesammten Bereich in 3
Sprüngen zurücklegen. Dafür setzt man Schrittweite auf 3. Steht vorher
der Regler auf 0, dann steht er nach einem Klick auf 5 und danach auf 10.
HINWEIS: Bei diesen Funktionen wird mit Ganzzahlen gerechnet, und da
kommt es schon mal vor, daß (bes. wenn der Anwender den Regler direkt
verschoben hat) ein Sprung etwas weiter ist, als man ihn gerne hätte. Im
obigen Beispiel passiert das z.B., wenn der Regler so gerade noch auf
Position 9 steht (und noch nicht auf 8) und wird dann neben den Regler
geklickt, dann wird als nächster Wert 3 und nicht 4 angegeben. Dieser
Fehler muß nicht immer auftreten und ist abhängig von der Größe des
Gadgets und der Anzahl Positionen.
LONG PrepareTmpRas(struct RastPort *RP)(a1)
VOID ClearTmpRas (struct RastPort *RP)(a1)
Die erste Funktion bereitet einen RastPort auf die Benutzung des
Flood-Befehls vor (eine weitere Bitmap für den RastPort besorgen). Die
zweite Funktion gibt den Speicher dann wieder frei. Wenn PrepareTmpRas
eine 0 zurückgibt, ist entweder die Bitmap schon besorgt oder nicht
genügend Speicher vorhanden.
LONG PrepareArea(struct RastPort *RP,LONG MaxPoints)(a1,d0)
VOID ClearArea (struct RastPort *RP)(a1)
Diese beiden Funktionen besorgen die Vorbereitungen für die AreaMove/
Draw/ Ellipse Befehle. MaxPoints gibt an, wie viele Punkte maximal mit
AreaMove bzw. Draw angegeben werden. Die Funktionen enthalten einen
Aufruf von PrepareTmpRas bzw. ClearTmpRas. Ein zusätzlicher Aufruf dieser
Funktionen ist nicht nötig. Wurde erst PrepareTmpRas aufgerufen, dann
versagt PrepareArea. PrepareArea gibt wieder 0 zurück, wenn etwas schief
gegangen ist.
MENUUNTERSTÜTZUNG
=================
Diese Funktionssammlung dient dazu, schnell ein Standartmenu zu
erstellen, ohne daß Strukturen statisch definiert werden müssen. Durch
einen einzigen Befehl wird jeweils ein Menu, ein Item oder ein Subitem
angefügt.
struct Menu *AddMenu(struct Menu *menu,
char *Titel,
unsigned short Flags);
Diese Funktion fügt ein Menu an. Beim ersten Aufruf muß menu NULL sein.
Der Rückgabewert des ERSTEN Aufrufs wird für alle weiteren Aufrufe (auch
der anderen Funktionen) als Argument verwendet.
struct Item *AddItem(struct Menu *menu,
char *Titel,
unsigned short Flags,
char HotKey);
Diese Funktion fügt an das zuletzt definierte Menu ein Item an. menu ist
der Rückgabewert des ersten Aufrufs von AddMenu. Titel kann ein Zeiger
auf einen String sein, dann muß aber auch ITEMTEXT in Flags gesetzt sein.
Es wird dann aber nur Speicher für die IntuiText-Struktur reserviert, der
Speicher für den
String wird direkt benutzt. Eine Konstruktion wie :
char Text[50];
strcpy(Text,"Text 1");
AddItem(Menu,Text,Flags,Hotkey);
strcpy(Text,"Text 2");
AddItem(Menu,Text,Flags,Hotkey);
bringt darum nicht den gewünschten Erfolg. Dafür funktioniert:
char Text1[50],Text2[50];
AddItem(Menu,Text1,Flags,Hotkey); /* Das Item wird aber nicht breit
genug */
AddItem(Menu,Text2,Flags,Hotkey);
strcpy(Text1,"Text 1");
strcpy(Test2,"Text 2");
Dann muß aber vorher der String in der char-Deklaration groß genug
reserviert worden sein, sonst gibt es dort Probleme. Ist ITEMTEXT nicht
gesetzt, so wird Titel als Zeiger auf eine ImageStruktur interpretiert.
Titel darf kein Zeiger auf eine IntuiText-Struktur sein (Menus verwenden
IntuiText). Diese Struktur wird, wenn benötigt, automatisch erstellt.
HotKey ist die Tastaturabkürzung für das Item. COMMSEQ muß zusätzlich
gesetzt sein.
struct Item *AddSub(struct Menu *menu,
char *Titel,
unsigned short Flags,
char HotKey);
Wie bei AddItem, nur wird an das letzte Item ein weiteres SubItem
angehängt.
Die Rückgabewerte dieser drei Funktionen sind jeweils die Zeiger auf die
erstelle Menu- bzw. Item-Struktur. Außer beim ersten Aufruf von AddMenu
kann der Rückgabewert ignoriert werden. Der Rückgabewert wird NULL, wenn
nicht mehr genügend Speicher vorhanden ist. Trotzdem sollten weitere
Aufrufe von Add... Funktionen nicht zum Absturz führen. Der Rückgabewert
ist interessant, wenn man selbst die StandartMenus noch ein wenig
manipulieren möchte (z.B. eine andere Farbe als die voreingestellte für
den Text). Verändert man dabei die Liste im Speicher, so muß man auch
dafür sorgen, daß beim Freigeben des Speichers alles freigegeben und
nichts doppelt freigegeben wird. Einstellungen für Farbe und Draw-Mode
werden von ersten Item des ersten Menus übernommen !
VOID NewSetMenuStrip(struct Window *Window,struct Menu *menu);
Diese Funktion ersetzt SetMenuStrip. Alle Items innerhalb eines Menus und
alle Subs innerhalb eines Items werden auf gleiche Breite gebracht (siehe
Beispiel). Außerdem wird natürlich SetMenuStrip aufgerufen.
VOID ClearMenu(struct Menu *menu);
Diese Funktion gibt den belegten Speicher wieder frei. Vorher MUß noch
ClearMenuStrip aufgerufen werden.
struct Menu *LastMenu(struct Menu *menu);
struct MenuItem *LastItem(struct Menu *menu);
struct MenuItem *LastSub(struct Menu *menu);
Diese drei Funktionen geben jeweils einen Zeiger auf das letzte
definierte Element zurück. Diese Funktionen werden intern benutzt.
struct Menu *FreeMenu(struct Menu *menu);
struct MenuItem *FreeItem(struct MenuItem *item);
Diese beiden Funktionen geben den Speicher für ein Item (incl. IntuiText,
falls vorhanden) bzw. ein Menu wieder frei. Werden von ClearMenu
aufgerufen.
MATHEMATISCHE FUNKTIONEN
========================
VOID UmwFtoS(char *Ziel,DOUBLE *Zahl,LONG Nachkomma)(a0,a1,d0)
Diese Funktion wandelt eine doppeltgenaue Fließkommazahl in einen String
um. Die Anzahl der Nachkommastellen kann angegeben werden. Die Anzahl der
Vorkommastellen bestimmt die Funktion selbst. Ist die Zahl groß (oder
klein bei negativen Zahlen), dann wird die Zahl im wissenschaftlichen
Format ausgegeben.
VOID UmwStoF(DOUBLE *Ziel,char *Source)(a0,a1)
Genau, die Umkehrfunktion. Sie wandelt einen String in eine doppeltgenaue
Fließkommazahl.
VOID Fak(DOUBLE *Ziel,LONG a)(a0,d0)
VOID NuK(DOUBLE *Ziel,LONG a,LONG b)(a0,d0,d1)
Die erste Funktion ermittelt die Fakultät der Zahl a, die zweite Funktion
den Wert von "n über k". a und b sollten positive Zahlen sein.
APTR Init_Konst()()
Diese Funktion reserviert einen Speicherbereich für 26 Zahlen vom Typ
DOUBLE.
LONG Set_Konst_P(APTR Zeiger,LONG Nummer,DOUBLE *Wert)(a0,d0,d1)
Hier wird die Zahl mit der Nummer Nummer innerhalb des Speicherbereichs
auf den Wert Wert gesetzt. Passierte ein Fehler, dann wird NO_KONST
zurückgegeben, sonst 0.
VOID GetKonst_P(DOUBLE *Ziel,APTR Zeiger,LONG Nummer)(a0,a1,d1)
Man will die Werte ja auch mal wieder auslesen können.....
VOID Free_Konst(APTR Zeiger)(a0)
Und schließlich muß man den Speicher auch wieder freigeben können.
struct Block *Init_Mem(char *Zeiger)(a0)
LONG Init_Block(struct Block *Zeiger)(a0)
LONG PreCalc(struct Block *Zeiger,APTR Konstanten)(d0,d1)
LONG Calc_P(DOUBLE *Ziel,struct Block *Zeiger,DOUBLE *Wert)(a0,a1,a2)
VOID Free_Block(struct Block *Zeiger)(a0)
Jetzt wirds schwierig und interessant. Mit diesen 5 Funktionen kann man
recht bequem und schnell einen String auswerten und bekommt dafür eine
Zahl zurück. Der String muß eine korrekte mathe. Funktion darstellen.
Erkannt werden die 4 Grundrechenarten (+-*/), Potenzen (^),
Trigonometrische Funktionen ((a)sin, (a)cos, (a)tan), log (Basis 10), ln
(Basis e), abs (Absolut), sgn (Vorzeichen), int (Vorkomma) und sqr
(Wurzel). Weiterhin ist vorbelegt die Zeichenfolge pi (3.141...) und e
(2.718...). Eine weitere Sonderstellung nimmt x ein. Alle anderen
Buchstaben (a-z) können als Konstanten benutzt werden. Zahlen in der Form
-1.2345 und -123e-4 werden auch erkannt (Alles muß kleingeschrieben
sein).
Init_Mem() belegt den benötigten Speicher im Rechner und gibt den Zeiger
darauf zurück. Diesen Zeiger braucht man für alle weiteren Arbeiten.
Init_Block() "zerpflückt" die Funktion. Zwischen Init_Mem und Init_Block
darf der Speicherbereich, in dem die Funktion steht, nicht angetastet und
auf keinen Fall freigegeben werden. Init_Mem merkt sich, wo der String
steht und Init_Block greift darauf zu. Init_Block gibt einen Fehlerwert
zurück. Die Bedeutung der einzelnen Bits ist in Tool.h aufgeführt. Wird
NULL zurückgegeben, dann wurde alles erkannt. Nach Init_Block() kann das
Programm mit dem Speicher für den String wieder machen, was es will......
PreCalc() belegt die in der Funktion gebrauchten Konstanten (a-z ohne x
und e) mit Werten. Diese holt sich die Funktion aus dem Speicherbereich,
den man sich mit Init_Konst() anfordern kann. Wird mit Set_Konst() eine
von der Funktion gebrauchte Konstante geändert, dann muß PreCalc() wieder
aufgerufen werden. Außerdem rechnet PreCalc schon so weit, wie zu dem
Zeitpunkt alles bekannt ist. Die einzige Unbekannte ist nur noch x.
Besteht die Funktion nur aus Konstanten und Zahlen, dann steht nach
PreCalc() in Zeiger->Wert bereits der Wert der Funktion.
HINWEIS: Die Routinen gehen an die Funktion von hinten heran. Lautet die
Funktion z.B: x+1+2+3, dann wird das zerlegt in:
- Summe aus 3 und dem Bereich davor
Bereich davor in:
- Summe aus 2 und dem Bereich davor usw.
Lautet die Funktion aber 1+2+3+x, dann wird die zerlegt in:
- Summe aus x und Bereich davor, und der Bereich davor wird bereits
korrekt zu 6 bereichnet. Die nächste Funktion braucht also nicht mehr so
viel zu rechnen, wenn man die Variable x immer möglichst weit nach hinten
schiebt.
PreCalc() liefert wieder einen Fehlercode zurück, z.B. wenn in der
Funktion die Wurzel aus etwas negativen (was dort bereits als negativ
erkannt wird, x ist ja noch nicht bekannt) gezogen werden soll.
Und jetzt die vorletzte und wichtigste Funktion:
Calc_P(). Sie benötigt zusätzlich zu dem von Init_Mem gelieferten Zeiger
den Wert für x und eine Variable, in der sie das Ergebnis ablegen soll.
Calc_P() kann beliebig oft mit unterschiedlichen Werten für x aufgerufen
werden. Geht bei der Berechnung etwas schief, wird in Ziel eine 0
zurückgeliefert. In Zeiger->Fehler steht, was passiert ist, dieser Wert
wird auch zurückgegeben.
FreeMem() schließlich gibt den benötigten Speicher wieder frei.
Wenn klar ist, daß von einer Funktion nur ein Funktionswert zu bestimmen
ist, dann ist der Aufwand ein wenig groß. Dafür gibt es dann noch die
Funktion:
VOID berechnen(DOUBLE *Ziel,char *string,
DOUBLE *x,
struct Konstanten *konstanten,
LONG *fehler)(a0,d0,d1,d2,d3)
Hier wird auf einmal alles nötige übergeben. Es können aber nur 4
Konstanten in der Struktur Konstanten übergeben werden. Es kann für
Konstanten auch NULL angegeben werden. In Fehler werden die gleichen
Fehlercodes übergeben wie bei den Funktionen oben.
DIE HINWEISE IN TOOLLIBRARY.README BEACHTEN !!